AlexNet 论文精读&&代码逐行解析


在这里插入图片描述

前言

笔者从人工智能小白的角度,力求能够从原文中解析出最高效率的知识。
之前看了很多博客去学习AI,但发现虽然有时候会感觉很省时间,但到了复现的时候就会傻眼,因为太多实现的细节没有提及。而且博客具有很强的主观性,因此我建议还是搭配原文来看。

请下载原文《ImageNet Classification with Deep Convolutional Neural Networks》搭配阅读本文,会更高效哦!

一、论文精读

0 摘要标题和结论

《ImageNet Classification with Deep Convolutional Neural Networks》首先,看完标题,摘要和结论,我了解到了以下信息:

  1. 把ImageNet数据集用监督学习的方法去训练,并利用GPU 加速,与当时前沿的技术结果进行了对比,取得了不错的分类效果。
  2. 把图片上倒数第二层的向量取出,然后找到给定图片在向量上比较相似的那些图片,最后发现向量值相似度高的种类图片相似度也高。即训练出来的最后的向量在语义空间的表示特别好。这点让我想到了机器学习当中的简单分离器,就可以很好的根据特征去进行分类的原因。

1.Introduction

训练数据集的方法也是先用小的数据集再过渡到ImageNet。打算用CNN,然后想办法把CNN网络做大。但是没有提到前人所做过的工作,也就是Related work。Section3会讨论文章所采用的新的网络架构。因为文章采用CNN网络架构很大,就很容易出现overfitting,于是section4会提及防止过拟合方法(我推测当时应该是讨论dropout等)。然后讨论了深度网络的必要性。

2.The Dataset

创新性的点在于端到端(End-to-End)。

3.The Architecture

  1. 提出了非饱和型非线性层ReLu比饱和型线性层sigmoid,tanh快很多。(这个观点在现在看来其实是不那么正确的,现在我们还在用ReLu层,可能是因为ReLu比较简单。)
  2. 多个GPU做训练,如何分开网络。
  3. 正则归一化。用Normalization避免饱和。(存疑)
  4. 对传统Pooling进行了改动,效果不错。
  5. 整个架构由5个卷积层,3个全连接层,最后用了一个softmax。输入的是原始的图片,2242243。用两个GPU 训练,在第三个卷积层进行了输出通道合并。随着层数增多,卷积层大小在减小,意味着空间信息在压缩,但增加了通道数,提高了对特定模式的识别。最后一张图片会表示成4096维度的向量,这个向量有很好的语义信息,再用线性分类去做链接。(让我想到深度学习的精髓就在于,把人能看到的信息进行压缩,最后变成机器能够识别的一种模式,再利用这种模式去进行应用操作。)

(我认为这个架构没有很好的通用性,实现比较复杂,架构限制了就是使用两个GPU去切片,而与实际上出入可能比较多。除非真的遇到非常大的模型比如BERT)

4.Reducing Overfitting

  1. 数据增强:两种方法。第一种是人工抠出图片的一部分,然后再放大抠出来的图片。第二种是改变颜色通道,用的是主成分分析(PCA)(我想起,这个方法在遥感影像里面用的也比较多。)
  2. Dropout:随机把一些隐藏层变成50%概率设为0。更像是一个正则的效果。(把Dropout放在了前两个全连接上面,所以训练速度会别其他模型慢两倍。而且这么大的全连接,导致GPU放不进去,这个地方其实我认为是一种设计缺陷。)

5.Details of learning

  1. 优化器:选择的是SGD,其噪声能够很好地提高模型的泛化能力。并采用momentum,防止在local minima时,model就走不动了。
  2. 采用了权重衰减L2正则项(weight decay)
  3. 权重初始化:0+0.01高斯分布。
  4. 动态调整learning rate:走不动就降低十倍。(现在主流做法可能是先从小值开始,然后先变大,再变小,因为前期太小的话可能会出现比较明显的震荡,后期太大又会卡住。)

二、代码阅读

1.卷积层

class AlexNet(nn.Module):
    def __init__(self,num_classes=2):
        super(AlexNet, self).__init__()
        self.features=nn.Sequential(
            nn.Conv2d(3,48, kernel_size=11),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3,stride=2),
            nn.Conv2d(48,128, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3,stride=2),
            nn.Conv2d(128,192,kernel_size=3,stride=1,padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(192,192,kernel_size=3,stride=1,padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(192,128,kernel_size=3,stride=1,padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3,stride=2),
)

2.全连接层

self.classifier=nn.Sequential(
            nn.Linear(6*6*128,2048),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),
            nn.Linear(2048,2048),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(2048,num_classes),
)

3.数据增强

def DataEnhance(sourth_path,aim_dir,size):
    name=0
    #得到源文件的文件夹
    file_list=os.listdir(sourth_path)
    #创建目标文件的文件夹
    if not os.path.exists(aim_dir):
        os.mkdir(aim_dir)
 
    for i in file_list:
        img=Image.open('%s\%s'%(sourth_path,i))
 
        name+=1
        transform1=transforms.Compose([
            transforms.ToTensor(),
            transforms.ToPILImage(),
            transforms.Resize(size),
        ])
        img1=transform1(img)
        img1.save('%s/%s'%(aim_dir,name))

代码整体架构算是比较简单,通过PyTorch搭建的代码,整体比较典型。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

湘粤Ian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值