美文网首页鱼的深度学习
深度学习(七)一些神经网络的构架

深度学习(七)一些神经网络的构架

作者: 升不上三段的大鱼 | 来源:发表于2020-08-01 23:16 被阅读0次
    1. 多层感知器

    前馈神经网络,也可以叫多层感知器(multi-layer perceptron, MLP),是由多个感知器组成的神经网络。与单个感知器不同的是,MLP能够学习到非线性的特征,因此在回归和分类里都有很多应用。
    MLP一般由一层输入层,几层隐藏层和一个输出层,就像下图。

    A fully connected MLP on three inputs with two hidden layers, each with four perceptrons
    隐藏层和输出层里都是有激活函数的,每一层的神经元与同一层的其他神经元没有关联,与上一层的所有神经元都有联系(全连接)。
    关于前馈神经网络,深度学习笔记(1)--前馈神经网络
    接下来利用pytorch实现上面图里的神经网络。
    class NeuralNet(nn.Module):
        def __init__(self, input_size, hidden_size, num_classes):
            super(NeuralNet, self).__init__()
            self.fc1 = nn.Linear(input_size, hidden_size) 
            self.relu = nn.ReLU()
            self.fc2 = nn.Linear(hidden_size, num_classes)  
        
        def forward(self, x):
            out = self.fc1(x)
            out = self.relu(out)
            out = self.fc2(out)
            return out
    
    model = NeuralNet(input_size=3, 
    
    1. 卷积神经网络

    卷积神经网络适合用于图像处理,卷积操作可以提取出图片的特征。一般的卷积神经网络包括卷积层、池化层和全连接层。卷积层提取信息,池化层降维,全连接层输出结果。卷积层和池化层会多次使用,以达到提出特征的目的,比如LeNet的结构:


    LeNet

    pytorch 实现一个简单的卷积神经网络:

    class Net(nn.Module):
    
        def __init__(self):
            super(Net, self).__init__()
            # 1 input image channel, 6 output channels, 3x3 square convolution
            # kernel
            self.conv1 = nn.Conv2d(1, 6, 3)
            self.conv2 = nn.Conv2d(6, 16, 3)
            # an affine operation: y = Wx + b
            self.fc1 = nn.Linear(16 * 6 * 6, 120)  # 6*6 from image dimension
            self.fc2 = nn.Linear(120, 84)
            self.fc3 = nn.Linear(84, 10)
    
        def forward(self, x):
            # Max pooling over a (2, 2) window
            x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
            # If the size is a square you can only specify a single number
            x = F.max_pool2d(F.relu(self.conv2(x)), 2)
            x = x.view(-1, self.num_flat_features(x))
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x
    
        def num_flat_features(self, x):
            size = x.size()[1:]  # all dimensions except the batch dimension
            num_features = 1
            for s in size:
                num_features *= s
            return num_features
    
    net = Net()
    

    卷积神经网络 – CNN

    接下来就是一些经典的CNN模型

    1. LeNet

    结构就是上面那张图,1998年提出来的,包括两个卷积层+池化层,一个flatten层,两个全连接层和一个softmax的分类器。
    特点:

    • 使用卷积提取空间特征
    • 使用average pooling做采样
    • 使用tanh作为非线性的激活函数
    • S2和C3之间的连接
      LeNet 提出的卷积-池化-非线性激活函数的顺序,为以后的许多结构提供了基础。
    1. AlexNet
    AlexNet来自作者Alex Krizhevsky,是2012年ImageNet challenge的第一,当时CNN的重大突破。AlexNet的结构很简单,包括5个卷积层和3个全连接层,结构如下图。图中有上下两层表示的是使用了两个GPU,仅在某些层有连接。 AlexNet

    特点:

    • AlexNet中用到了ReLU,虽然在现在大家都用ReLU,以至于这一条显得平平无奇。
    • AlexNet还使用了两个GPU并行训练,也就是上面结构图里的上下两层,每个GPU只用一半的神经元,并且在某些层进行连接。这样做能让训练相对快一点,并且降低了错误率。
    • 使用了重叠池化,stride=2,size=3,这个操作也能减少错误率。
    • dropout,减少过拟合。神仙一样的方法,以0.5的概率把隐藏层神经元的输出设为0,被设为0的神经元在反向的时候也没有梯度。作者在前两个全连接层上使用了dropout。
    • mini-batch SGD+momentum (0.9 )+ weight decay(0.0005)。具体的参数迭代规则是这样的: update rule for weight
      pytorch 可以直接调用 torchvision.models.alexnet(), 在这里放上具体的结构实现:
    class AlexNet(nn.Module):
    
        def __init__(self, num_classes=1000):
            super(AlexNet, self).__init__()
            self.features = nn.Sequential(
                nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(kernel_size=3, stride=2),
                nn.Conv2d(64, 192, kernel_size=5, padding=2),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(kernel_size=3, stride=2),
                nn.Conv2d(192, 384, kernel_size=3, padding=1),
                nn.ReLU(inplace=True),
                nn.Conv2d(384, 256, kernel_size=3, padding=1),
                nn.ReLU(inplace=True),
                nn.Conv2d(256, 256, kernel_size=3, padding=1),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(kernel_size=3, stride=2),
            )
            self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
            self.classifier = nn.Sequential(
                nn.Dropout(),
                nn.Linear(256 * 6 * 6, 4096),
                nn.ReLU(inplace=True),
                nn.Dropout(),
                nn.Linear(4096, 4096),
                nn.ReLU(inplace=True),
                nn.Linear(4096, num_classes),
            )
    
        def forward(self, x):
            x = self.features(x)
            x = self.avgpool(x)
            x = torch.flatten(x, 1)
            x = self.classifier(x)
            return x
    

    AlexNet论文
    深度学习卷积神经网络-AlexNet

    1. Network In Network


      Network in network结构,包括三个mlpcov层和一个GAP层

    特点:

    • 1x1卷积核,提供非线性,减少参数
    • 全局平均池化,避免过拟合

    CNN中的卷积操作可以看作是一种广义的线性操作,对于高度非线性的特征,CNN可能需要许多滤波器来进行特征提取,从而导致模型的参数过多。
    Network in network提出使用多层感知器作为通用函数逼近器来对局部的特征进行提取。使用多层感知器的原因是,首先,多层感知器与使用反向传播训练的卷积神经网络结构兼容。 其次,多层感知器本身可以是一个深层模型,这符合特征复用的思想。
    使用多个级联的1x1的卷积核对特征图做卷积,可以实现特征图的非线性组合,同时使用1x1卷积核还可以减少或者增加通道数,实现降维或者升维,减少参数。
    NIN的另一个进步之处在于使用了全局平均池化(Global Average Pooling, GAP)取代全连接层作为最后一层,具体做法是取每个特征图的平均值,然后将所得的向量直接输入softmax层实现分类,这样做的优点是,在全局平均池中没有要优化的参数,减小了参数规模,避免了过拟合。此外,全局平均池汇总了空间信息,因此对输入的空间转换更加健壮。

    class NIN(nn.Module):
    
        def __init__(self, num_classes=1000):
            super(NIN, self).__init__()
            self.num_classes = num_classes
            self.features = nn.Sequential(
                nn.Conv2d(3, 192, 5, padding=2),
                nn.ReLU(inplace=True),
                nn.Conv2d(192, 160, 1),
                nn.ReLU(inplace=True),
                nn.Conv2d(160, 96, 1),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(3, stride=2, ceil_mode=True),
                nn.Dropout(inplace=True),
    
                nn.Conv2d(96, 192, 5, padding=2),
                nn.ReLU(inplace=True),
                nn.Conv2d(192, 192, 1),
                nn.ReLU(inplace=True),
                nn.Conv2d(192, 192, 1),
                nn.ReLU(inplace=True),
                nn.AvgPool2d(3, stride=2, ceil_mode=True),
                nn.Dropout(inplace=True),
    
                nn.Conv2d(192, 192, 3, padding=1),
                nn.ReLU(inplace=True),
                nn.Conv2d(192, 192, 1),
                nn.ReLU(inplace=True),
                nn.Conv2d(192, self.num_classes, 1),
                nn.ReLU(inplace=True),
                nn.AvgPool2d(8, stride=1)
            )
            self._initialize_weights()
    
        def forward(self, x):
            x = self.features(x)
            x = x.view(x.size(0), self.num_classes)
            return x
    
        def _initialize_weights(self):
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    m.weight.data.normal_(0, 0.05)
                    if m.bias is not None:
                        m.bias.data.zero_()
    

    Network in Network
    Network in Network代码
    深度学习基础模型NIN(Network in Network)+Pytorch

    1. VGG

    VGG于2014年由牛津大学Visual Geometry Group组提出的,在AlexNet的基础上加深了网络。
    特点:

    • 使用多个较小的卷积核(3x3)组合以获得更大的感受野,但是所需要的参数更少
    • 比较难训练,常被用作预训练
    VGG系列的网络结构和参数设置

    下面是pytorch里vgg11的代码,可以看出来结构与AlexNet很相似,不过层数更多:

    class VGG(nn.Module):
    
        def __init__(self, features, num_classes=1000, init_weights=True):
            super(VGG, self).__init__()
            self.features = nn.Sequential(
                nn.Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
                nn.ReLU(inplace=True)
                nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
                nn.Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
                nn.ReLU(inplace=True)
                nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
                nn. Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
                nn. ReLU(inplace=True)
                nn. Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
                nn. ReLU(inplace=True)
                nn. MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
                nn.Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
                nn. ReLU(inplace=True)
                nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
                nn. ReLU(inplace=True)
                nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
                nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
                nn. ReLU(inplace=True)
                nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
                nn.ReLU(inplace=True)
                nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      )
            self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
            self.classifier = nn.Sequential(
                nn.Linear(512 * 7 * 7, 4096),
                nn.ReLU(True),
                nn.Dropout(),
                nn.Linear(4096, 4096),
                nn.ReLU(True),
                nn.Dropout(),
                nn.Linear(4096, num_classes),
            )
            if init_weights:
                self._initialize_weights()
    
        def forward(self, x):
            x = self.features(x)
            x = self.avgpool(x)
            x = torch.flatten(x, 1)
            x = self.classifier(x)
            return x
    
    1. GoogleNet
      (Inception-v1)
    • bottleneck layer
    1. ResNet
      随着网络结构的加深,人们发现深层的网络的训练和测试误差比浅层的网络还要大,并且这一现象并不是由过拟合造成的。原因就在于在深层的网络中随着层数的加深,特征和梯度传递可能会发生偏移。
      Residual Block

    9.MobileNet

    1. EfficientNet

    相关文章

      网友评论

        本文标题:深度学习(七)一些神经网络的构架

        本文链接:https://www.haomeiwen.com/subject/bfyurktx.html