【第4周】MobileNet_ShuffleNet

论文阅读与视频学习

MobileNet V1:是由Google提出的轻量级卷积神经网络架构。它采用了深度意识卷积(Depthwise Convolution)来减少计算量,使得模型在保持较高准确性的情况下,具有更小的模型大小和更快的推理速度。

MobileNet V2:是MobileNet V1的改进版本。它在深度可分离卷积的基础上引入倒残差结构(Inverted Residuals),进一步提高了模型的准确性和效率。

MobileNet V3:是对MobileNet系列的进一步改进。MobileNet V3通过使用自适应激活函数(Hard Swish)和注意力机制((Squeeze-and-Excitation)来进一步提高模型的准确性和效率。MobileNet V3在计算资源有限的设备上,具有更好的性能表现。

ShuffleNet:是一种轻量级神经网络结构,旨在提高计算效率和模型压缩率。它通过使用通道重排(Channel Shuffle)可以降低计算复杂度的同时保持卷积和学习到不同组的特征。ShuffleNet在保持较高准确性的同时,具有更小的模型大小和更快的推理速度。

Channel Shuffle的具体实现方式是对于输入特征input[N,C,H,W]通过变换变为[N,g,C/g,H,W]然后对于第1和2维度进行转置变为[N,C/g,g,H,W],然后再通过变换变为[N,C,H,W]这样便完成了Channel Shuffle。

SENet:是一种注意力机制网络,专注于提高模型的感知能力。SENet通过在卷积神经网络中引入Squeeze-and-Excitation模块,自适应地学习每个通道的权重,从而使得网络能够更好地聚焦于重要的特征。SENet的引入有效地提高了模型的准确性,并在多个任务和数据集上取得了优秀的性能。

Squeeze-and-Excitation操作主要:输入input[N,C,H,W]经过全局池化变为[N,C,1,1]然后经过{全连接层,ReLU激活函数,全连接层,Sigmoid激活函数}得到每一个通道的权重,然后将权重成以input完成该操作。

代码作业

首先加载数据集,虽然因为安全原因导致数据集无法下载,但可以先在浏览器上下载到本地然后上传到colab。

 下面是搭建的网络结构。

class_num = 16

class HybridSN(nn.Module):
  def __init__(self, in_channels=1, out_channels=class_num):
    super(HybridSN, self).__init__()
    self.conv3d_features = nn.Sequential(
        nn.Conv3d(in_channels,out_channels=8,kernel_size=(7,3,3)),
        nn.ReLU(inplace=True),
        nn.Conv3d(in_channels=8,out_channels=16,kernel_size=(5,3,3)),
        nn.ReLU(inplace=True),
        nn.Conv3d(in_channels=16,out_channels=32,kernel_size=(3,3,3)),
        nn.ReLU(inplace=True),
    )
    self.conv2d_features = nn.Sequential(
        nn.Conv2d(in_channels=32 * 18, out_channels=64, kernel_size=(3,3)),
        nn.ReLU(inplace=True),
    )
    self.classifier = nn.Sequential(
        nn.Linear(64 * 17 * 17, 256),
        nn.ReLU(inplace=True),
        nn.Dropout(p=0.4),
        nn.Linear(256, 128),
        nn.ReLU(inplace=True),
        nn.Dropout(p=0.4),
        nn.Linear(128, out_channels)
    )

  def forward(self, x):
    x = self.conv3d_features(x)
    x = x.view(x.size()[0],x.size()[1]*x.size()[2],x.size()[3],x.size()[4])
    x = self.conv2d_features(x)
    x = x.view(x.size()[0],-1)
    x = self.classifier(x)
    return x

训练完之后在测试集上的分类报告。大概可以看出样本数越多准确率和召回率越高。

 下图是光谱分类图,感觉与groundtruth相比效果还是有点差距。

(a)得到的分类图(b)Groundtruth

 3D卷积和2D卷积的区别:2D卷积主要用于图像处理,考虑二维空间结构,输出为二维特征图。3D卷积主要用于视频数据或体积数据处理,考虑三维空间和时间(或其他额外维度)的结构,输出为三维特征图。2D卷积的输入形状为[N,C,H,W],3D卷积的输入形状为[N,C,D,H,W],N表示Batchsize,C为通道数,D为深度,H为高度,W为宽度。2D卷积的卷积核是没有深度的。

思考题

训练HybridSN,然后多测试几次,会发现每次分类的结果都不一样,请思考为什么?

        因为dropout的原因代码中并没有写net.eval来告诉网络现在是测试,不应该再随机丢弃神经元了,这样就不会导致每次分类的结果不一样了。

如果想要进一步提升高光谱图像的分类性能,可以如何改进?

        可以进行数据增强,通过对训练数据进行随机的旋转、翻转增加数据的多样性。

depth-wise conv 和 分组卷积有什么区别与联系?

        depth-wise conv是分组卷积的特例,当分组卷积的组数等于输入特征的通道数是,分组卷积就是depth-wise conv。

SENet 的注意力是不是可以加在空间位置上?

        SENet是用在通道上的,不使用在空间位置上的。

在 ShuffleNet 中,通道的 shuffle 如何用代码实现?

class ChannelShuffle(nn.Module):
    def __init__(self, groups):
        super(ChannelShuffle, self).__init__()
        self.groups = groups

    def forward(self, x):
        batch_size, num_channels, height, width = x.size()
        channels_per_group = num_channels // self.groups

        # 将特征图切分成若干组
        x = x.view(batch_size, self.groups, channels_per_group, height, width)

        # 将每个组内的通道进行重排
        x = x.permute(0, 2, 1, 3, 4)

        # 将重排后的特征图展平
        x = x.view(batch_size, num_channels, height, width)
        return x
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值