load package


In [5]:
import os
import glob

import torch
import torch.nn as nn
import torch.utils.data as data_utils
import torch.nn.parallel
import torch.backends.cudnn as cudnn
import torch.optim as opti
from torch.autograd import Variable

import torchvision.datasets as datasets
import torchvision.models as models
import torchvision.transforms as transforms

import cv2
from PIL import Image

import numpy as np
from numpy.linalg import inv
from scipy import sparse
from scipy.sparse import lil_matrix, csr_matrix
from scipy.sparse.linalg import spsolve
from scipy.sparse.linalg import inv as spinv

Configurations


In [2]:
class Args(object):
    pass
args = Args()
args.epoches = 20
args.epoches_unary_threshold = 0
args.base_lr = 1e-5
args.train_dir = '/home/albertxavier/dataset/sintel/images/'
args.arch = "resnet18"
args.img_extentions = ["png",'jpg']
args.image_w = 256
args.image_h = 256

Custom DataLoader


In [3]:
def default_loader(path):
    return Image.open(path).convert('RGB')

def make_dataset(dir):
    images_paths = glob.glob(os.path.join(dir, 'clean', '*', '*.png'))
    albedo_paths = images_paths[:]
    shading_paths = images_paths[:]
    pathes = []
    for img_path in images_paths:
        sp = img_path.split('/'); sp[-3] = 'albedo'; sp = ['/'] + sp; albedo_path = os.path.join(*sp)
        sp = img_path.split('/'); sp[-3] = 'albedo'; sp = ['/'] + sp; shading_path = os.path.join(*sp)
        pathes.append((img_path, albedo_path, shading_path))
    return pathes

class MyImageFolder(data_utils.Dataset):
    def __init__(self, root, transform=None, target_transform=None,
                loader=default_loader):
        imgs = make_dataset(root)
        if len(imgs) == 0:
            raise(RuntimeError("Found 0 images in subfolders of: " + root + "\n"
                               "Supported image extensions are: " + ",".join(args.img_extentions)))

        self.root = root
        self.imgs = imgs
        self.transform = transform
        self.target_transform = target_transform
        self.loader = loader
        
    def __getitem__(self, index):
        img_path, albedo_path, shading_path = self.imgs[index]
        
        img = self.loader(img_path)
        albedo = self.loader(albedo_path)
        shading = self.loader(shading_path)
        
        if self.transform is not None: img = self.transform(img)
        if self.transform is not None: albedo = self.transform(albedo)
        if self.transform is not None: shading = self.transform(shading)

        return img, albedo, shading
    
    def __len__(self):
        return len(self.imgs)
    
dataset= MyImageFolder(args.train_dir, 
                       transforms.Compose(
        [transforms.RandomCrop((args.image_h, args.image_w)),
         transforms.ToTensor()]
    ))

train_loader =data_utils.DataLoader(dataset,1,True,num_workers=1)

Functions


In [ ]:

My nn Functions


In [ ]:
class CrfLossFunction(torch.autograd.Function):

    def getBestPredictY(self, unary_, pairwise_):
        n,c,h,w = pairwise_.numpy().shape
        imgsize = c*h*w
        R_data_np, ind_np = generateR(pairwise_)
        diagonals = np.sum(pairwise_, axis=1).reshape((1,-1)).tile()
        R_np = csr_matrix((R_data_np, (ind_np[0,:], ind_np[1,:])), shape=(imgsize,imgsize))
        I_np = sparse.eye(imgsize, format="csr")
        D_np = sparse.diags(diagonals, shape=(imgsize, imgsize))
        A_np = I_np + D_np - R_np
        z_np = unary_.numpy().reshape((-1,1))
        y_np = spsolve(A_np, a_np)
        y_np_ = y_np.reshape(unary_.shape)
        return torch.from_numpy(y_np_)

    def generateR(self, pairwise_):

        n,_,h,w = pairwise_.numpy().shape
        c = 3

        nele = n*c*h*w 
        planesize = h*w
        imgsize = c*h*w
        p0 = np.linspace(0, planesize-1, planesize, dtype=np.uint32)
        q0_up = (p0.copy() - w).clip(0,planesize-1)
        q0_right = (p0.copy() + 1).clip(0,planesize-1)
        q0_down = (p0.copy() + w).clip(0,planesize-1)
        q0_left = (p0.copy() -1).clip(0,planesize-1)

        p0 = p0.reshape((1,-1))
        q0_up = q0_up.reshape((1,-1))
        q0_right = q0_right.reshape((1,-1))
        q0_down = q0_down.reshape((1,-1))
        q0_left = q0_left.reshape((1,-1))


        p = None
        q = None
        Rdata = None

        for c in range(0, 3):
            for d in range(0,4):
                p = cat(p, p0 + planesize*c)
                Rdata = cat(Rdata, pairwise[p0 + planesize*d])
            q = cat(q, q0_up + planesize*c)
            q = cat(q, q0_right + planesize*c)
            q = cat(q, q0_down + planesize*c)
            q = cat(q, q0_left + planesize*c)


        ind = np.zeros((2, p.size))
        ind[0,:] = p
        ind[1,:] = q
        return Rdata, ind
    
    def generateA(self, pairwise_):
        
        
    def forward(self, unary_, pairwise_):
        y_best = getBestPredictY(unary_, pairwise_)
        A = generateA(pairwise_)

My nn Modules


In [ ]:
class CommonModel(nn.Module):
    def __init__(self, original_model, arch):
        super(CommonModel, self).__init__()
        if arch.startswith('resnet') :
            self.unary_2M = nn.Sequential(*list(original_model.children())[0:7])
            self.unary_1M = nn.Sequential(*list(original_model.children())[7:8])
    def forward(self, x):
        _2M = self.unary_2M(x) 
        _1M = self.unary_1M(_2M)
        return _2M, _1M

class PotentialModel(nn.Module):
    def __init__(self, arch, output_channels):
        super(PotentialModel, self).__init__()
        
        # Scale 1
        self.unary_2M_to_8M = nn.ConvTranspose2d(kernel_size=8, stride=4, padding=2, in_channels=256, out_channels=256, groups=256, bias=False)
        self.unary_1M_to_8M = nn.ConvTranspose2d(kernel_size=16, stride=8, padding=4, in_channels=512, out_channels=512, groups=512, bias=False)

        tmp_model = models.__dict__[args.arch](pretrained=True)
        
        # Scale 2
        tmp_model.inplanes = 3
        self.unary_layer_raw = tmp_model._make_layer(models.resnet.BasicBlock, 128, 2, stride=4)
        
        # Merged
        tmp_model.inplanes = 896
        self.unary_layer1 = tmp_model._make_layer(models.resnet.BasicBlock, 256, 2, stride=1)
        tmp_model.inplanes = 256
        self.unary_layer2 = tmp_model._make_layer(models.resnet.BasicBlock, 128, 2, stride=1)

        self.unary_deconv = nn.ConvTranspose2d(kernel_size=8, stride=4, padding=2, in_channels=128, out_channels=output_channels, bias=True)
        
        
    def forward(self, x, _2M, _1M):
        raw = self.unary_layer_raw(x)
        col1 = self.unary_2M_to_8M(_2M)
        col2 = self.unary_1M_to_8M(_1M)
        cat = torch.cat([raw, col1, col2], 1)
        logcat = torch.log1p(cat)
        layer1 = self.unary_layer1(logcat)
        layer2 = self.unary_layer2(layer1)
        output = self.unary_deconv(layer2)
#         output = deconv.view(deconv.nelement(), -1)
        return output

My Network


In [11]:
"""
    FineTuneModel: https://gist.github.com/panovr/2977d9f26866b05583b0c40d88a315bf
    
    ResNet: 
        https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py
        
        Layer Size:
            0: (0:4) 1/4
            1: (4:5) 1/4
            2: (5:6) 1/8
            3: (6:7) 1/16
            4: (7:8) 1/32
            5: (8:9) 1/32


"""



        
class Net(nn.Module):
    def __init__(self, original_model, CommonModel, PotentialModel, CrfLossModel=None):
        super(Net, self).__init__()
        self.common_net = CommonModel(original_model, args.arch)
        self.unary_net = PotentialModel(args.arch, output_channels=3)
        self.pairwise_net = PotentialModel(args.arch, output_channels=4)
        self.softplus = nn.Softplus()
#         self.crfloss_net = CrfLossModel() 
        self.sigmoid = nn.
    def forward(self,x, gt):
        _2M, _1M = self.common_net(x)
        unary_ = self.unary_net(x, _2M, _1M)
        
        pairwise_ = self.pairwise_net(x, _2M, _1M)
        pairwise_ = self.softplus(pairwise_)
        
        R_data_np, ind_np = generateR(pairwise_)
        
def cat(a, b, axis=0):
    if a is None:
        a = b
    else:
        a = np.concatenate((a,b), axis=axis)
    return a

Define Optimizer and Loss Function


In [12]:
original_model = models.__dict__[args.arch](pretrained=True)
# print original_model.state_dict()
net = Net(original_model=original_model, CommonModel=CommonModel, PotentialModel=PotentialModel)

mse_loss = nn.MSELoss()
mse_loss_best = nn.MSELoss()


optimizer = optim.SGD(net.parameters(), lr=args.base_lr)

Training Loop


In [13]:
n,c,h,w = 1,3,args.image_h,args.image_w
# input_img = Variable(torch.rand((1,3,args.image_h,args.image_w))) 
# gt_albedo = Variable(torch.rand((1,3,args.image_h,args.image_w))) 

# predict_unary, predict_pairwise = net((input_img), (gt_albedo))
# loss_unary = mse_loss(predict_unary, (gt_albedo))

best_predict_model = BestPredictModule(n,c,h,w)
predict_unary = Variable(torch.rand((1,3,args.image_h,args.image_w))) 
predict_pairwise = Variable(torch.rand((1,3,args.image_h,args.image_w))) 
gt_albedo = torch.rand((1,3,args.image_h,args.image_w))
best_predict = best_predict_model((predict_unary), (predict_pairwise), Variable(gt_albedo))
loss_best = mse_loss_best(best_predict, Variable(gt_albedo))
loss_best.backward()


self.imgsize =  196608
row size =  (1, 65536)
col_up size =  (1, 65536)
tmp1size =  (1, 65536)
tmp2size =  (1, 65536)
pairwise shape =  (196608, 1)

row size =  (1, 65536)
col_up size =  (1, 65536)
tmp1size =  (1, 65536)
tmp2size =  (1, 65536)
pairwise shape =  (196608, 1)

row size =  (1, 65536)
col_up size =  (1, 65536)
tmp1size =  (1, 65536)
tmp2size =  (1, 65536)
pairwise shape =  (196608, 1)

row size =  (1, 65536)
col_up size =  (1, 65536)
tmp1size =  (1, 65536)
tmp2size =  (1, 65536)
pairwise shape =  (196608, 1)

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-13-e46dd822f31a> in <module>()
     12 best_predict = best_predict_model((predict_unary), (predict_pairwise), Variable(gt_albedo))
     13 loss_best = mse_loss_best(best_predict, Variable(gt_albedo))
---> 14 loss_best.backward()

/home/albertxavier/anaconda2/lib/python2.7/site-packages/torch/autograd/variable.pyc in backward(self, gradient, retain_variables)
    144                     'or with gradient w.r.t. the variable')
    145             gradient = self.data.new().resize_as_(self.data).fill_(1)
--> 146         self._execution_engine.run_backward((self,), (gradient,), retain_variables)
    147 
    148     def register_hook(self, hook):

RuntimeError: there are no graph nodes that require computing gradients

In [6]:
for epoch in range(args.epoches): 
    run_loss = 0.
    for i, data in enumerate(train_loader, 0):
        input_img, gt_albedo, gt_shading = data
        input_img = Variable(input_img)
        gt_albedo = Variable(gt_albedo)
        gt_shading = Variable(gt_shading)
#         input_img = input_img.cuda()
#         gt_albedo = gt_albedo.cuda()
#         gt_shading = gt_shading.cuda()
        
        optimizer.zero_grad()
        predict_unary, predict_pairwise = net((input_img), (gt_albedo))
        if epoch < args.epoches_unary_threshold:
            loss_unary = mse_loss(predict_unary, (gt_albedo))
            print "loss unary = ", loss_unary
            loss_unary.backward()
            optimizer.step()
        else:
            n,c,h,w = 1,3,args.image_h,args.image_w
            best_predict_model = BestPredictModule(n,c,h,w)
            best_predict = best_predict_model((predict_unary), (predict_pairwise), (gt_albedo))
            loss_best = mse_loss_best((best_predict), (gt_albedo))
            print "loss best = ", loss_best
            loss_best.backward()
            optimizer.step()


self.imgsize =  196608
row size =  (1, 65536)
col_up size =  (1, 65536)
tmp1size =  (1, 65536)
tmp2size =  (1, 65536)
pairwise shape =  (262144, 1)

row size =  (1, 65536)
col_up size =  (1, 65536)
tmp1size =  (1, 65536)
tmp2size =  (1, 65536)
pairwise shape =  (262144, 1)

row size =  (1, 65536)
col_up size =  (1, 65536)
tmp1size =  (1, 65536)
tmp2size =  (1, 65536)
pairwise shape =  (262144, 1)

row size =  (1, 65536)
col_up size =  (1, 65536)
tmp1size =  (1, 65536)
tmp2size =  (1, 65536)
pairwise shape =  (262144, 1)

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-6-af9bb7a93a28> in <module>()
     20             n,c,h,w = 1,3,args.image_h,args.image_w
     21             best_predict_model = BestPredictModule(n,c,h,w)
---> 22             best_predict = best_predict_model((predict_unary), (predict_pairwise), (gt_albedo))
     23             loss_best = mse_loss_best((best_predict).type(torch.FloatTensor), (gt_albedo))
     24             print "loss best = ", loss_best

/home/albertxavier/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.pyc in __call__(self, *input, **kwargs)
    200 
    201     def __call__(self, *input, **kwargs):
--> 202         result = self.forward(*input, **kwargs)
    203         for hook in self._forward_hooks.values():
    204             hook_result = hook(self, input, result)

<ipython-input-4-6ab1b1cad7bf> in forward(self, unary_, pairwise_, gt_)
    187 
    188     def forward(self, unary_, pairwise_, gt_):
--> 189         return BestPredictFunc()(unary_, pairwise_, gt_)

RuntimeError: save_for_backward can only save tensors, but argument 0 is of type torch.Size

In [210]:
cre = nn.MSELoss()
a = Variable(torch.Tensor([1,2]))
b = Variable(torch.Tensor([0,0]))
out = cre(a,b)
out
aa = torch.Tensor([[1,2],[3,4]])
torch.sum(aa)


Out[210]:
10.0

In [86]:
def main():
    original_model = models.__dict__[args.arch](pretrained=True)
    common_model = CommonModel(original_model, args.arch)
    model = PotentialModel(args.arch)
    print model
if __name__ == '__main__':
    main()


PotentialModel (
  (unary_2M_to_8M): ConvTranspose2d(256, 256, kernel_size=(8, 8), stride=(4, 4), padding=(2, 2), groups=256, bias=False)
  (unary_1M_to_8M): ConvTranspose2d(512, 512, kernel_size=(16, 16), stride=(8, 8), padding=(4, 4), groups=512, bias=False)
  (unary_layer_raw): Sequential (
    (0): BasicBlock (
      (conv1): Conv2d(3, 128, kernel_size=(3, 3), stride=(4, 4), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
      (relu): ReLU (inplace)
      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
      (downsample): Sequential (
        (0): Conv2d(3, 128, kernel_size=(1, 1), stride=(4, 4), bias=False)
        (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
      )
    )
    (1): BasicBlock (
      (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
      (relu): ReLU (inplace)
      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
    )
  )
  (unary_layer1): Sequential (
    (0): BasicBlock (
      (conv1): Conv2d(768, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)
      (relu): ReLU (inplace)
      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)
      (downsample): Sequential (
        (0): Conv2d(768, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)
      )
    )
    (1): BasicBlock (
      (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)
      (relu): ReLU (inplace)
      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)
    )
  )
  (unary_layer2): Sequential (
    (0): BasicBlock (
      (conv1): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
      (relu): ReLU (inplace)
      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
      (downsample): Sequential (
        (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
      )
    )
    (1): BasicBlock (
      (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
      (relu): ReLU (inplace)
      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
    )
  )
  (unary_output): ConvTranspose2d(128, 3, kernel_size=(8, 8), stride=(4, 4), padding=(2, 2))
)

Visualize Graph


In [98]:
from graphviz import Digraph
import torch
from torch.autograd import Variable


def make_dot(var, params=None):
    """ Produces Graphviz representation of PyTorch autograd graph

    Blue nodes are the Variables that require grad, orange are Tensors
    saved for backward in torch.autograd.Function

    Args:
        var: output Variable
        params: dict of (name, Variable) to add names to node that
            require grad (TODO: make optional)
    """
    if params is not None:
        assert isinstance(params.values()[0], Variable)
        param_map = {id(v): k for k, v in params.items()}

    node_attr = dict(style='filled',
                     shape='box',
                     align='left',
                     fontsize='12',
                     ranksep='0.1',
                     height='0.2')
    dot = Digraph(node_attr=node_attr, graph_attr=dict(size="12,12"))
    seen = set()

    def size_to_str(size):
        return '('+(', ').join(['%d' % v for v in size])+')'

    def add_nodes(var):
        if var not in seen:
            if torch.is_tensor(var):
                dot.node(str(id(var)), size_to_str(var.size()), fillcolor='orange')
            elif hasattr(var, 'variable'):
                u = var.variable
                name = param_map[id(u)] if params is not None else ''
                node_name = '%s\n %s' % (name, size_to_str(u.size()))
                dot.node(str(id(var)), node_name, fillcolor='lightblue')
            else:
                dot.node(str(id(var)), str(type(var).__name__))
            seen.add(var)
            if hasattr(var, 'next_functions'):
                for u in var.next_functions:
                    if u[0] is not None:
                        dot.edge(str(id(u[0])), str(id(var)))
                        add_nodes(u[0])
            if hasattr(var, 'saved_tensors'):
                for t in var.saved_tensors:
                    dot.edge(str(id(t)), str(id(var)))
                    add_nodes(t)
    add_nodes(var.creator)
    return dot

In [110]:
def make_dot2(var):
    node_attr = dict(style='filled',
                     shape='box',
                     align='left',
                     fontsize='12',
                     ranksep='0.1',
                     height='0.2')
    dot = Digraph(node_attr=node_attr, graph_attr=dict(size="12,12"))
    seen = set()

    def add_nodes(var):
        if var not in seen:
            if isinstance(var, Variable):
                value = '('+(', ').join(['%d'% v for v in var.size()])+')'
                dot.node(str(id(var)), str(value), fillcolor='lightblue')
            else:
                dot.node(str(id(var)), str(type(var).__name__))
            seen.add(var)
            if hasattr(var, 'previous_functions'):
                for u in var.previous_functions:
                    dot.edge(str(id(u[0])), str(id(var)))
                    add_nodes(u[0])
    add_nodes(var.creator)
    return dot

In [129]:
test_original_model = models.__dict__[args.arch](pretrained=True)
test_common_model = CommonModel(test_original_model, args.arch)
test_unary_model = PotentialModel(args.arch, output_channels=3, output_height=args.image_h, output_width=args.image_w)
test_pairwise_model = PotentialModel(args.arch, output_channels=4, output_height=args.image_h, output_width=args.image_w)

test_img = torch.rand(1,3,args.image_h,args.image_w)
test_img = Variable(test_img)
test_2M, test_1M = test_common_model(test_img)

out_unary = test_unary_model(test_img, test_2M, test_1M)
out_pairwise = test_pairwise_model(test_img, test_2M, test_1M)

make_dot2(out_unary)


Out[129]:
%3 4995752416 View 4995752216 ConvNd 4995752216->4995752416 4995752016 Threshold 4995752016->4995752216 6089154840 Add 6089154840->4995752016 6089155440 BatchNorm 6089155440->6089154840 6089156840 ConvNd 6089156840->6089155440 6089156640 Threshold 6089156640->6089156840 6089156440 BatchNorm 6089156440->6089156640 6089156240 ConvNd 6089156240->6089156440 6089155640 Threshold 6089155640->6089154840 6089155640->6089156240 6089155240 Add 6089155240->6089155640 4886725288 BatchNorm 4886725288->6089155240 4886726488 ConvNd 4886726488->4886725288 4886726288 Threshold 4886726288->4886726488 4886728488 BatchNorm 4886728488->4886726288 4886725688 ConvNd 4886725688->4886728488 4886728288 Threshold 4886728288->4886725688 4886726688 ConvNd 4886728288->4886726688 4995815256 Add 4995815256->4886728288 4995814456 BatchNorm 4995814456->4995815256 4995817056 ConvNd 4995817056->4995814456 4995816856 Threshold 4995816856->4995817056 4995816656 BatchNorm 4995816656->4995816856 4995816456 ConvNd 4995816456->4995816656 4995816256 Threshold 4995816256->4995815256 4995816256->4995816456 4995816056 Add 4995816056->4995816256 4995815456 BatchNorm 4995815456->4995816056 4995814856 ConvNd 4995814856->4995815456 4995814656 Threshold 4995814656->4995814856 4995815056 BatchNorm 4995815056->4995814656 4995817256 ConvNd 4995817256->4995815056 4995813856 Log1p 4995813856->4995817256 4995815656 ConvNd 4995813856->4995815656 4995813656 Concat 4995813656->4995813856 4735263600 Threshold 4735263600->4995813656 4735266200 Add 4735266200->4735263600 4735263200 BatchNorm 4735263200->4735266200 4735263000 ConvNd 4735263000->4735263200 4735264200 Threshold 4735264200->4735263000 4735266400 BatchNorm 4735266400->4735264200 4735263800 ConvNd 4735263800->4735266400 4832083352 Threshold 4832083352->4735266200 4832083352->4735263800 4832082552 Add 4832082552->4832083352 4832083552 BatchNorm 4832083552->4832082552 4832083752 ConvNd 4832083752->4832083552 4832082152 Threshold 4832082152->4832083752 4832082352 BatchNorm 4832082352->4832082152 4832083152 ConvNd 4832083152->4832082352 4825795184 (1, 3, 256, 256) 4825795184->4832083152 4832082952 ConvNd 4825795184->4832082952 4692185568 ConvNd 4825795184->4692185568 5027265232 (128, 3, 3, 3) 5027265232->4832083152 5027266000 (128) 5027266000->4832082352 5027263312 (128) 5027263312->4832082352 5027262736 (128, 128, 3, 3) 5027262736->4832083752 5027264368 (128) 5027264368->4832083552 5027264560 (128) 5027264560->4832083552 4832082752 BatchNorm 4832082752->4832082552 4832082952->4832082752 5027264944 (128, 3, 1, 1) 5027264944->4832082952 5027263504 (128) 5027263504->4832082752 5027263888 (128) 5027263888->4832082752 5027264080 (128, 128, 3, 3) 5027264080->4735263800 5027263696 (128) 5027263696->4735266400 5027264656 (128) 5027264656->4735266400 5027264272 (128, 128, 3, 3) 5027264272->4735263000 5027264176 (128) 5027264176->4735263200 5027265328 (128) 5027265328->4735263200 4735264000 ConvNd 4735264000->4995813656 4706712784 Threshold 4706712784->4735264000 4706712584 ConvNd 4706712784->4706712584 6414034376 ConvNd 4706712784->6414034376 4706712984 Add 4706712984->4706712784 4706713184 BatchNorm 4706713184->4706712984 4706713384 ConvNd 4706713384->4706713184 4693246032 Threshold 4693246032->4706713384 4693246232 BatchNorm 4693246232->4693246032 4693246432 ConvNd 4693246432->4693246232 6089227072 Threshold 6089227072->4706712984 6089227072->4693246432 6089227672 Add 6089227672->6089227072 6089227872 BatchNorm 6089227872->6089227672 6089228072 ConvNd 6089228072->6089227872 6089227272 Threshold 6089227272->6089228072 4628092960 BatchNorm 4628092960->6089227272 4628094560 ConvNd 4628094560->4628092960 4628094360 Threshold 4628094360->4628094560 6089226872 ConvNd 4628094360->6089226872 4628094760 Add 4628094760->4628094360 4749094696 BatchNorm 4749094696->4628094760 4749092696 ConvNd 4749092696->4749094696 4749094296 Threshold 4749094296->4749092696 4749094496 BatchNorm 4749094496->4749094296 4749094096 ConvNd 4749094096->4749094496 4749093896 Threshold 4749093896->4628094760 4749093896->4749094096 4749091696 Add 4749091696->4749093896 4749093096 BatchNorm 4749093096->4749091696 4749093496 ConvNd 4749093496->4749093096 4749093296 Threshold 4749093296->4749093496 4749092096 BatchNorm 4749092096->4749093296 4749091096 ConvNd 4749091096->4749092096 4749091296 Threshold 4749091296->4749091096 4749092896 ConvNd 4749091296->4749092896 4749091496 Add 4749091496->4749091296 4749090896 BatchNorm 4749090896->4749091496 4716396624 ConvNd 4716396624->4749090896 4716396824 Threshold 4716396824->4716396624 4693093384 BatchNorm 4693093384->4716396824 4693093584 ConvNd 4693093584->4693093384 4693093784 Threshold 4693093784->4749091496 4693093784->4693093584 4693093984 Add 4693093984->4693093784 4693094184 BatchNorm 4693094184->4693093984 4693090984 ConvNd 4693090984->4693094184 4693091184 Threshold 4693091184->4693090984 4693091384 BatchNorm 4693091384->4693091184 4693091584 ConvNd 4693091584->4693091384 4693091984 MaxPool2d 4693091984->4693093984 4693091984->4693091584 4693092184 Threshold 4693092184->4693091984 4693092384 BatchNorm 4693092384->4693092184 4692185568->4693092384 4707107280 (64, 3, 7, 7) 4707107280->4692185568 4707110160 (64) 4707110160->4693092384 4707110352 (64) 4707110352->4693092384 6414096432 (64, 64, 3, 3) 6414096432->4693091584 4523581520 (64) 4523581520->4693091384 6414096720 (64) 6414096720->4693091384 6414096912 (64, 64, 3, 3) 6414096912->4693090984 6414095184 (64) 6414095184->4693094184 6414094704 (64) 6414094704->4693094184 6414097584 (64, 64, 3, 3) 6414097584->4693093584 6414098256 (64) 6414098256->4693093384 6414094416 (64) 6414094416->4693093384 6414095664 (64, 64, 3, 3) 6414095664->4716396624 6414098064 (64) 6414098064->4749090896 6414094800 (64) 6414094800->4749090896 6414095088 (128, 64, 3, 3) 6414095088->4749091096 6414097776 (128) 6414097776->4749092096 4709524400 (128) 4709524400->4749092096 4709523920 (128, 128, 3, 3) 4709523920->4749093496 4709524592 (128) 4709524592->4749093096 4709524688 (128) 4709524688->4749093096 4749091896 BatchNorm 4749091896->4749091696 4749092896->4749091896 6414097104 (128, 64, 1, 1) 6414097104->4749092896 6414094896 (128) 6414094896->4749091896 6414097968 (128) 6414097968->4749091896 4709524016 (128, 128, 3, 3) 4709524016->4749094096 4709524112 (128) 4709524112->4749094496 4709524208 (128) 4709524208->4749094496 4709524496 (128, 128, 3, 3) 4709524496->4749092696 4709524304 (128) 4709524304->4749094696 4709524784 (128) 4709524784->4749094696 4709525168 (256, 128, 3, 3) 4709525168->4628094560 4709524976 (256) 4709524976->4628092960 4709525456 (256) 4709525456->4628092960 4709526704 (256, 256, 3, 3) 4709526704->6089228072 4709525552 (256) 4709525552->6089227872 4709526608 (256) 4709526608->6089227872 6089227472 BatchNorm 6089227472->6089227672 6089226872->6089227472 4709525072 (256, 128, 1, 1) 4709525072->6089226872 4709525264 (256) 4709525264->6089227472 4709524880 (256) 4709524880->6089227472 4709526320 (256, 256, 3, 3) 4709526320->4693246432 4709526416 (256) 4709526416->4693246232 4709526032 (256) 4709526032->4693246232 4709526128 (256, 256, 3, 3) 4709526128->4706713384 4709525360 (256) 4709525360->4706713184 4709523536 (256) 4709523536->4706713184 4833267248 (256, 1, 8, 8) 4833267248->4735264000 4995813456 ConvNd 4995813456->4995813656 5161323528 Threshold 5161323528->4995813456 5161324328 Add 5161324328->5161323528 5161323328 BatchNorm 5161323328->5161324328 5161323728 ConvNd 5161323728->5161323328 5161323928 Threshold 5161323928->5161323728 4715167528 BatchNorm 4715167528->5161323928 6414035976 ConvNd 6414035976->4715167528 6414034776 Threshold 6414034776->5161324328 6414034776->6414035976 6414035376 Add 6414035376->6414034776 6414033376 BatchNorm 6414033376->6414035376 6414033176 ConvNd 6414033176->6414033376 6414033776 Threshold 6414033776->6414033176 6414033576 BatchNorm 6414033576->6414033776 4706712584->6414033576 4709526224 (512, 256, 3, 3) 4709526224->4706712584 4709523824 (512) 4709523824->6414033576 4709525744 (512) 4709525744->6414033576 4709525840 (512, 512, 3, 3) 4709525840->6414033176 4709526896 (512) 4709526896->6414033376 4709525648 (512) 4709525648->6414033376 6414035576 BatchNorm 6414035576->6414035376 6414034376->6414035576 4709523632 (512, 256, 1, 1) 4709523632->6414034376 4709526512 (512) 4709526512->6414035576 4709523728 (512) 4709523728->6414035576 4709526800 (512, 512, 3, 3) 4709526800->6414035976 4709525936 (512) 4709525936->4715167528 4741909200 (512) 4741909200->4715167528 4741907472 (512, 512, 3, 3) 4741907472->5161323728 4709355440 (512) 4709355440->5161323328 5001339728 (512) 5001339728->5161323328 4833266672 (512, 1, 16, 16) 4833266672->4995813456 5027263600 (256, 896, 3, 3) 5027263600->4995817256 5027266096 (256) 5027266096->4995815056 5027265904 (256) 5027265904->4995815056 5027263024 (256, 256, 3, 3) 5027263024->4995814856 5027265040 (256) 5027265040->4995815456 5027264464 (256) 5027264464->4995815456 4995815856 BatchNorm 4995815856->4995816056 4995815656->4995815856 5027262640 (256, 896, 1, 1) 5027262640->4995815656 5027266192 (256) 5027266192->4995815856 5027265136 (256) 5027265136->4995815856 5027265520 (256, 256, 3, 3) 5027265520->4995816456 5027266288 (256) 5027266288->4995816656 5027266480 (256) 5027266480->4995816656 5027262928 (256, 256, 3, 3) 5027262928->4995817056 5027266384 (256) 5027266384->4995814456 5027265712 (256) 5027265712->4995814456 5027263792 (128, 256, 3, 3) 5027263792->4886725688 5027263120 (128) 5027263120->4886728488 5027263408 (128) 5027263408->4886728488 5027265808 (128, 128, 3, 3) 5027265808->4886726488 5027265616 (128) 5027265616->4886725288 4696870992 (128) 4696870992->4886725288 4886726888 BatchNorm 4886726888->6089155240 4886726688->4886726888 5027264848 (128, 256, 1, 1) 5027264848->4886726688 5027262832 (128) 5027262832->4886726888 5027264752 (128) 5027264752->4886726888 4696871088 (128, 128, 3, 3) 4696871088->6089156240 4696871184 (128) 4696871184->6089156440 4696871280 (128) 4696871280->6089156440 4696871376 (128, 128, 3, 3) 4696871376->6089156840 4696871472 (128) 4696871472->6089155440 4696871568 (128) 4696871568->6089155440 4696871664 (128, 3, 8, 8) 4696871664->4995752216 4696871760 (3) 4696871760->4995752216