@ptrblck
Thank you!!
If you need .ipynb file I can give you by email then send me mail (dnjscjf92@ajou.ac.kr)
Umm…
My purpose is after crop half the cifar10 image like 16x32, make two input up and down data sets, to put in each model input size is 16x32.
After put in these data to VGG16’s first layer, concat two feature map like before crop, and flow it as normal VGG16 model.
Your comment might be save me.
Thank you.
Under is my foolish code!!

import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
from torchsummary import summary
from torchvision import datasets, transforms
import numpy as np
from tqdm import tqdm
import time
import os
import torch.backends.cudnn as cudnn
import matplotlib.pyplot as plt

# Loda data
train_dataset = datasets.CIFAR10(root='../data/cifar10/',
                                 train=True,
                                 download=True)

test_dataset = datasets.CIFAR10(root='../data/cifar10/',
                                train=False)

#crop 
def crop_half(img):
    up = transforms.functional.crop(img,0,0,16,32)
    down = transforms.functional.crop(img,16,0,16,32)    
    return up, down

ToPIL = transforms.ToPILImage()
ToTensor = transforms.ToTensor()

#train
train_up = torch.tensor([])
train_down = torch.tensor([])

for i in tqdm(range(train_dataset.data.shape[0])):
    img = ToPIL(train_dataset.data[i])
    up,down = crop_half(img)
    train_up = torch.cat((train_up, ToTensor(up)), dim=0)
    train_down = torch.cat((train_down, ToTensor(down)), dim=0)
    
train_up = train_up.reshape(train_dataset.data.shape[0],3,16,32)
train_down = train_down.reshape(train_dataset.data.shape[0],3,16,32)

#test
test_up = torch.tensor([])
test_down = torch.tensor([])

for i in tqdm(range(test_dataset.data.shape[0])):
    img = ToPIL(test_dataset.data[i])
    up,down = crop_half(img)
    test_up = torch.cat((test_up, ToTensor(up)), dim=0)
    test_down = torch.cat((test_down, ToTensor(down)), dim=0)
    
test_up = test_up.reshape(test_dataset.data.shape[0],3,16,32)
test_down = test_down.reshape(test_dataset.data.shape[0],3,16,32)

#model
os.environ["CUDA_VISIBLE_DEVICES"] = '0'
start_time = time.time()
batch_size = 128
learning_rate = 0.1

# 'head' means first layer with 16x32 cropped image data 
class Vgg16_head(nn.Module):
    def __init__(self, num_classes=10):
        super(Vgg16_head, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(True),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

class Vgg16(nn.Module):
    def __init__(self, num_classes=10):
        super(Vgg16, self).__init__()
        
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(True),
            nn.Conv2d(128, 128, kernel_size=3, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            nn.Conv2d(128, 256, kernel_size=3, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.BatchNorm2d(256),
            nn.ReLU(True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            nn.Conv2d(256, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.BatchNorm2d(512),
            nn.ReLU(True),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )
        
        self.classifier = nn.Linear(2048, num_classes)

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

model_head = Vgg16_head()
optimizer = optim.SGD(model_head.parameters(), lr=learning_rate, momentum=0.9, weight_decay=1e-4)
criterion = nn.CrossEntropyLoss().cuda()
model_head = nn.DataParallel(model_head)
cudnn.benchmark = True
model_head.cuda()

model = Vgg16()
optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=0.9, weight_decay=1e-4)
criterion = nn.CrossEntropyLoss().cuda()
model = nn.DataParallel(model)
cudnn.benchmark = True
model.cuda()

targets = torch.tensor(train_dataset.targets).reshape(-1,125)

def train_head(epoch):
#     model_head.train()
    model.train()
    train_loss = 0
    total = 0
    correct = 0
    
    for data_idx, (data, target) in enumerate(zip(train_up, targets)):
        if torch.cuda.is_available():
            data, target = Variable(data.cuda()), Variable(target.cuda())
        else:
            data, target = Variable(data), Variable(target)

        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

        train_loss += loss.data
        _, predicted = torch.max(output.data, 1)
        total += target.size(0)
        correct += predicted.eq(target.data).cpu().sum()
        if batch_idx % 10 == 0:
            print('Epoch: {} | Batch: {} |  Loss: ({:.4f}) | Acc: ({:.2f}%) ({}/{})'
                  .format(epoch, batch_idx, train_loss/(batch_idx+1), 100.*correct/total, correct, total))

def test():
    model.eval()
    test_loss = 0
    correct = 0
    total = 0
    for batch_idx, (data, target) in enumerate(zip(test_up, targets)):
        if torch.cuda.is_available():
            data, target = Variable(data.cuda()), Variable(target.cuda())
        else:
            data, target = Variable(data), Variable(target)

        outputs = model(data)
        loss = criterion(outputs, target)

        test_loss += loss.data
        _, predicted = torch.max(outputs.data, 1)
        total += target.size(0)
        correct += predicted.eq(target.data).cpu().sum()
        if batch_idx % 10 == 0:
            print('TEST : Loss: ({:.4f}) | Acc: ({:.2f}%) ({}/{})'
                  .format(test_loss/(batch_idx+1), 100.*correct/total, correct, total))

# The last cell
# run model train
for epoch in range(0, 165):
    if epoch < 80:
        learning_rate = learning_rate
    elif epoch < 120:
        learning_rate = learning_rate * 0.1
    else:
        learning_rate = learning_rate * 0.01
    for param_group in optimizer.param_groups:
        param_group['learning_rate'] = learning_rate

    train_head(epoch)
    test()
# print("start_time", start_time)
print("--- Total %s seconds ---" % (time.time() - start_time))

(The last cell occur under error message)
RuntimeError                              Traceback (most recent call last)
<ipython-input-115-bdeec26048b8> in <module>
      9         param_group['learning_rate'] = learning_rate
     10 
---> 11     train_head(epoch)
     12     test()
     13 

<ipython-input-113-cb7193d6e59e> in train_head(epoch)
     13 
     14         optimizer.zero_grad()
---> 15         output = model(data)
     16         loss = criterion(output, target)
     17         loss.backward()

~/.local/lib/python3.5/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

~/.local/lib/python3.5/site-packages/torch/nn/parallel/data_parallel.py in forward(self, *inputs, **kwargs)
    139         inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids)
    140         if len(self.device_ids) == 1:
--> 141             return self.module(*inputs[0], **kwargs[0])
    142         replicas = self.replicate(self.module, self.device_ids[:len(inputs)])
    143         outputs = self.parallel_apply(replicas, inputs, kwargs)

~/.local/lib/python3.5/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

<ipython-input-85-4b17a74fdecd> in forward(self, x)
     32         x = self.features(x)
     33         x = x.view(x.size(0), -1)
---> 34         x = self.classifier(x)
     35         return x

~/.local/lib/python3.5/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

~/.local/lib/python3.5/site-packages/torch/nn/modules/linear.py in forward(self, input)
     65     @weak_script_method
     66     def forward(self, input):
---> 67         return F.linear(input, self.weight, self.bias)
     68 
     69     def extra_repr(self):

~/.local/lib/python3.5/site-packages/torch/nn/functional.py in linear(input, weight, bias)
   1350     if input.dim() == 2 and bias is not None:
   1351         # fused op is marginally faster
-> 1352         ret = torch.addmm(torch.jit._unwrap_optional(bias), input, weight.t())
   1353     else:
   1354         output = input.matmul(weight.t())

RuntimeError: size mismatch, m1: [125 x 4096], m2: [2048 x 10] at /pytorch/aten/src/THC/generic/THCTensorMathBlas.cu:266