Разработка модели CNN с 2 сверточными слоями, 2 остаточными единицами и полностью связанным слоем, за которым следует слой классификации - PullRequest
0 голосов
/ 26 марта 2019

Здесь я пытаюсь разработать модель CNN с 2 сверточными слоями, 2 остаточными единицами и полностью связанным слоем, за которым следует слой классификации. Мы используем

-3x3 сверточных ядра (шаг 1 в реснет-единицах и шаг 2 в сверточных слоях) -ReLU для функции активации -макс пулинг с ядром 2х2 и шагом 2 только после сверточных слоев.

Я хочу определить количество карт объектов в скрытых слоях следующим образом: 16, 16, 16, 32, 32, 32, 64 (1-й слой, ..., 7-й слой).

Ввод -> Convolution1 -> ResNetBlock1 -> Convolution2 -> ResNetBlock2 -> FC -> Выход

Я написал свой код здесь. ПРИМЕЧАНИЕ. Я много ссылался на этот урок.

http://www.pabloruizruiz10.com/resources/CNNs/ResNet-PyTorch.html

import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision

#3x3 kernel=3
def conv3x3(in_channels, out_channels, stride=1):
    return nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        #pooling 2
        self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2, padding=1)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2, padding=1)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
            residual = x

            out = self.conv1(x)
            out = self.maxpool(out)
            out = self.relu(out)

            out = self.conv2(out)
            out = self.maxpool(out)

            if self.downsample is not None:
                residual = self.downsample(x)

            out += residual
            out = self.relu(out)

            return out

class Convnet_Resnet_Layer(nn.Module):

    def __init__(self, block, layers, num_classes=2):
        self.inplanes = 1
        super(Convnet_Resnet_Layer, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=2, padding=3,
                               bias=False)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(block, 16, layers[0])
        self.conv2 = nn.Conv2d(32, 32, kernel_size=3, stride=2, padding=3,
                               bias=False)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        #connect 64 on the last layer, with the 2 blocks
        self.fc = nn.Linear(64 * block.expansion, num_classes)

        # make sure that dimensions check out. 
    def _make_layer(self, block, planes, blocks, stride=1):
            downsample = None
            if stride != 1 or self.inplanes != planes * block.expansion:
                downsample = nn.Sequential(
                    nn.Conv2d(self.inplanes, planes * block.expansion,
                              kernel_size=1, stride=stride, bias=False),
                )

            layers = []
            layers.append(block(self.inplanes, planes, stride, downsample))
            self.inplanes = planes * block.expansion
            for i in range(1, blocks):
                layers.append(block(self.inplanes, planes))

            return nn.Sequential(*layers)

    def forward(self, x):
            x = self.conv1(x)    # 224x224   
            x = self.relu(x)
            x = self.maxpool(x)  # 112x112
            x = self.layer1(x)   # 56x56

            x = self.conv2(x)        
            x = self.relu(x)
            x = self.maxpool(x)  
            x = self.layer2(x)   # 28x28

            # I did average pooling here. Can just omit if you want, but parameters will change
            x = self.avgpool(x)  # 1x1

            x = x.view(x.size(0), -1)
            x = self.out(x)

            return x
# call the model and pass the list with the information of the blocks for each layer
model1 = Convnet_Resnet_Layer(BasicBlock, [2, 3,4 ])
print(model1)

Результаты следующие:

Convnet_Resnet_Layer ( (conv1): Conv2d (1, 16, kernel_size = (3, 3), stepde = (2, 2), padding = (3, 3), смещение = False) (relu): ReLU (на месте) (maxpool): MaxPool2d (размер ядра = 3, шаг = 2, отступ = 1, расширение = 1, ceil_mode = False) (layer1): последовательный ( (0): базовый блок ( (conv1): Conv2d (1, 16, kernel_size = (3, 3), stepde = (1, 1), padding = (1, 1), смещение = False) (maxpool): MaxPool2d (размер ядра = 2, шаг = 2, отступ = 1, расширение = 1, ceil_mode = False) (relu): ReLU (на месте) (conv2): Conv2d (16, 16, kernel_size = (3, 3), stepde = (1, 1), padding = (1, 1), смещение = False) (вниз): последовательный ( (0): Conv2d (1, 16, kernel_size = (1, 1), stepde = (1, 1), смещение = False) ) ) (1): базовый блок ( (conv1): Conv2d (16, 16, kernel_size = (3, 3), stepde = (1, 1), padding = (1, 1), смещение = False) (maxpool): MaxPool2d (размер ядра = 2, шаг = 2, отступ = 1, расширение = 1, ceil_mode = False) (relu): ReLU (на месте) (conv2): Conv2d (16, 16, kernel_size = (3, 3), stepde = (1, 1), padding = (1, 1), смещение = False) ) ) (conv2): Conv2d (32, 32, kernel_size = (3, 3), stepde = (2, 2), padding = (3, 3), смещение = False) (fc): линейный (in_features = 64, out_features = 2, смещение = True) )

После (conv2) у меня нет максимального пула или показа в модели.

Буду признателен за любую помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...