zoukankan      html  css  js  c++  java
  • 第二次作业:卷积神经网络Part3

    第二次作业:卷积神经网络Part3

    一、代码练习

    1.HybridSN

    模型的网络结构为如下图所示:

    • 三维卷积:
      conv1:(1, 30, 25, 25), 8个 7x3x3 的卷积核 ==>(8, 24, 23, 23)
      conv2:(8, 24, 23, 23), 16个 5x3x3 的卷积核 ==>(16, 20, 21, 21)
      conv3:(16, 20, 21, 21),32个 3x3x3 的卷积核 ==>(32, 18, 19, 19)

    • 接下来要进行二维卷积,因此把前面的 32*18 reshape 一下,得到 (576, 19, 19)

    • 二维卷积:(576, 19, 19) 64个 3x3 的卷积核,得到 (64, 17, 17)

    • 接下来是一个 flatten 操作,变为 18496 维的向量,

    • 接下来依次为256,128节点的全连接层,都使用比例为0.4的 Dropout,

    • 最后输出为 16 个节点,是最终的分类类别数。

    HybridSN 类的代码:

    class_num = 16
    
    class HybridSN(nn.Module):
      def __init__(self):
        super(HybridSN, self).__init__()
    
        # conv1:(1, 30, 25, 25), 8个 7x3x3 的卷积核 ==>(8, 24, 23, 23)
        self.conv1 = nn.Sequential(
            nn.Conv3d(1, 8, kernel_size=(7, 3, 3), stride=1, padding=0),
            nn.BatchNorm3d(8),
            nn.ReLU()
        )
        # conv2:(8, 24, 23, 23), 16个 5x3x3 的卷积核 ==>(16, 20, 21, 21) 
        self.conv2 = nn.Sequential(
            nn.Conv3d(8, 16, kernel_size=(5, 3, 3), stride=1, padding=0),
            nn.BatchNorm3d(16),
            nn.ReLU()
        )
        # conv3:(16, 20, 21, 21),32个 3x3x3 的卷积核 ==>(32, 18, 19, 19)
        self.conv3 = nn.Sequential(
            nn.Conv3d(16, 32, kernel_size=(3, 3, 3), stride=1, padding=0),
            nn.BatchNorm3d(32),
            nn.ReLU()
        )
        # conv4: (576, 19, 19), 64个 3x3 的卷积 ==> (64, 17, 17)
        self.conv4 = nn.Sequential(
            nn.Conv2d(576, 64, kernel_size=(3, 3), stride=1, padding=0),
            nn.BatchNorm2d(64),
            nn.ReLU()
        )
        
        self.fc1 = nn.Linear(18496, 256)
        self.fc2 = nn.Linear(256, 128)
    
        self.fc3 = nn.Linear(128, class_num)
    
        self.dropout = nn.Dropout(p=0.4)
      
      def forward(self, x):
        # 进行三维卷积
        out = self.conv1(x)
        out = self.conv2(out)
        out = self.conv3(out)
    
        # 进行二维卷积,把前面 32*18 reshape 一下,得到 (576, 19, 19)
        out = self.conv4(out.reshape(out.shape[0], -1, 19, 19))  # out.shape[0]--Batchsize; out.shape[1]--channel;
    
        # 接下来是一个 flatten 操作,变为 18496 维的向量
        out = out.reshape(out.shape[0], -1)
    
        # 接下来依次为256,128节点的全连接层,都使用比例为0.4的 Dropout
        out = self.fc1(out)
        out = self.dropout(out)
        out = self.fc2(out)
        out = self.dropout(out)
    
        # 最后输出为 16 个节点,是最终的分类类别数
        out = self.fc3(out)
    
        return out
    
    # 随机输入,测试网络结构是否通
    x = torch.randn(1, 1, 30, 25, 25)
    net = HybridSN()
    y = net(x)
    print(y.shape)
    print(y)
    

    经过训练后,精确度为 96.78%

    2.SENet

    上图是 SENet 的 Block 单元,图中的 (F_{tr}) 是传统的卷积结构, X 和 U 是 (F_{tr}) 的输入和输出,这些都是以往结构中已存在的。SENet 增加的部分是U后的结构:对 U 先做一个 Global Average Pooling(图中的(F_{sq}(.)),即 Squeeze 过程),输出的 1x1xC 数据再经过两级全连接(图中的(F_{ex}(.)),即Excitation),最后用sigmoid 限制到 [0,1] 的范围,把这个值作为 scale 乘到 U 的 C 个通道上, 作为下一级的输入数据。

    总的来说,Squeeze-and-Excitation:
    · Squeeze: 通过全局平均池化来生成信道统计信息
    · Excitation: FC--限制模型复杂度
           Relu
           FC--重新激活
           Sigmoid--限制输出范围为 [0,1]

    引入 SENet 的 HybridSN:

    class SELayer(nn.Module):
      def __init__(self, channel, r=16):
        super(SELayer, self).__init__()
        # Squeeze
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        # Excitation
        self.fc1 = nn.Linear(channel,round(channel/r))
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(round(channel/r),channel)
        self.sigmoid = nn.Sigmoid() 
          
      def forward(self,x):
        out = self.avg_pool(x)
        out = out.view(out.shape[0], out.shape[1])
        out = self.fc1(out)
        out = self.relu(out)
        out = self.fc2(out)
        out = self.sigmoid(out)
        out = out.view(out.shape[0], out.shape[1], 1, 1)
        return x * out     
    
    class_num = 16
    
    class HybridSN(nn.Module):
      def __init__(self):
        super(HybridSN, self).__init__()
    
        self.conv1 = nn.Sequential(
            nn.Conv3d(1, 8, kernel_size=(7, 3, 3), stride=1, padding=0),
            nn.BatchNorm3d(8),
            nn.ReLU()
        )
        self.conv2 = nn.Sequential(
            nn.Conv3d(8, 16, kernel_size=(5, 3, 3), stride=1, padding=0),
            nn.BatchNorm3d(16),
            nn.ReLU()
        )
        self.conv3 = nn.Sequential(
            nn.Conv3d(16, 32, kernel_size=(3, 3, 3), stride=1, padding=0),
            nn.BatchNorm3d(32),
            nn.ReLU()
        )
        self.conv4 = nn.Sequential(
            nn.Conv2d(576, 64, kernel_size=(3, 3), stride=1, padding=0),
            nn.BatchNorm2d(64),
            nn.ReLU()
        )
        self.SELayer = SELayer(64, 16)
        self.fc1 = nn.Linear(18496, 256)
        self.fc2 = nn.Linear(256, 128)
        self.fc3 = nn.Linear(128, class_num)
        self.dropout = nn.Dropout(p=0.4)
      
      def forward(self, x):
        out = self.conv1(x)
        out = self.conv2(out)
        out = self.conv3(out)
        out = self.conv4(out.reshape(out.shape[0], -1, 19, 19)) 
        out = self.SELayer(out)  # 二维卷积后面添加SENet
        out = out.reshape(out.shape[0], -1)
        out = self.fc1(out)
        out = self.dropout(out)
        out = self.fc2(out)
        out = self.dropout(out)
        out = self.fc3(out)
        return out
    

    经过训练后,精确度为97.85%,比没有 SENet 的网络有所提高。因为通过 SENet 控制 scale 的大小,把重要的特征增强,不重要的特征减弱。

    二、视频学习

    1.《语义分割中的自注意力机制和低秩重建》-李夏

    • 语义分割:对每一个像素都同时地产生一个 Label
    • 传统的完全由卷积层组成的网络结构,感受野获得的有用信息是有限的。
    • Nonlocal Network:为了推测某一位置上的物品信息,需要建立此位置像素和其他像素之间的关系
    • A^2-Nets: 认为一张图是由若干个关键内容组合成的,首先发现这些组合因子,然后再将这些组合因子映射回来。
    • A^2-Nets 与 Nonlocal Network 的区别:相当于矩阵的结合律,但是计算量会减小很多。
    • EM Attention Networks

    2.《 图像语义分割前沿进展》-程明明

    在计算机视觉发展过程中,在对图像的理解方面,一直在追求对多尺度信息的理解。如果我们能够做到更好的多尺度的感受,我们就可以更好的理解图像,对图像进行分割。卷积神经网络有三个非常重要的层,分别是:卷积、激活、池化,我们分别从卷积和池化两个角度出发,来改进网络,从而获得更好的多尺度信息。

    • Res2Net
      富尺度空间的深度神经网络通用架构

      左图为经典的ResNet的结构,右图在此基础上将输入分为多组进行分组卷积,可以更好地提取不同尺度信息,同时可以与其它结构相兼容(如SENet)。

    • Strip Pooling(带状池化)
      在进行语义分割的过程中,我们既需要细节信息,同时又需要捕捉全局的信息。
      捕捉全局信息的方法,如:Non-local modules,Self-Attention,需要计算一个很大的affinity matrix; Dilated convolution,Pyramid/globlal pooling,很难获得各向异性的信息。
      采用 Strip pooling 可以在一个方向上获得全局的信息,同时在另一个方向上获得细节信息。
      采用横向和纵向的条状池化可以获得各向异性的信息。

    三、论文阅读

    《Selective Kernel Networks》

    https://www.cnblogs.com/anxifeng/p/13516319.html

  • 相关阅读:
    20169207 2016-2017-2 《移动平台应用开发实践》第五周学习总结
    20169212 2016-2017-2《网络攻防实践》第八周学习总结
    20169212 2016-2017-2 《网络攻防实践》第七周学习总结
    20169212 2016-2017-2 《网络攻防实践》第六周学习总结
    20169212 2016-2017-2 《网络攻防实践》第五周学习总结
    20169212 2016-2017-2 《网络攻防实践》第四周学习总结
    20169212 2016-2017-2 《网络攻防实践》第三周学习总结
    20169212 2016-2017-2 《网络攻防实践》第二周学习总结
    20169212《网络攻防实践》第一周学习总结
    20169212《Linux内核原理与分析》课程总结
  • 原文地址:https://www.cnblogs.com/anxifeng/p/13508397.html
Copyright © 2011-2022 走看看