Alex Net 论文学习笔记(含代码)

ImageNet Classification with Deep Convolutional Neural Network

历史意义

1、拉开卷积神经网络统治计算机视觉的序幕
2、加速计算机视觉应用落地

Abstract

1、比赛数据集上运行效果极佳
2、AlexNet由五个conv层和3个fullconnection层构成,参数众多(the net contains eight layers with weights : first five are convolutional and the remaining three are fully-connected)
3、采用ReLu作为激活函数,同时使用GPU加快训练
4、采用Dropout减轻过拟合

Introduction and dataset

AlexNet’s struction

在这里插入图片描述

结构特点

1、ReLu Nonlinearrity
(1)使网络训练更快(2)防止梯度消失(相较于Sigmoid,没有饱和点)(3)使网络具有稀疏性
2、Training on Multiple GPUs
3、Local Response Normalization(LRN,局部响应标准化){现在已经被BN取代}
有助于AlexNet泛化能力提升,灵感来自于真实神经元的侧抑制(lateral inhibition)
侧抑制:细胞分化时,他对周围cell产生抑制信号,阻止其他cell向相同方向分化,最终表现为细胞命运的不同
在这里插入图片描述
(i表示channel_size;j平方累加索引,代表从j-i的像素值平方求和;x,y表示像素位置;a表示feature map中i对应像素的具体值;N表示feature map里面最内层向量的列数;其余参量均为超参数)
4、Overlapping Pooling(重叠池化)
通过设置stride=2,kernel_size=3实现池化探测区域存在重叠部分

训练技巧

1、Data Augmentation(数据增强)
针对位置
训练阶段:
(1)图片统一缩放至256256
(2)随机位置裁剪出224
224区域
(3)随机进行水平翻转
测试阶段:
(1)图片统一缩放至256256
(2)裁剪出5个224
224区域
(3)均进行水平翻转,共得到10张224*224图片
针对颜色
通过PCA方法修改RGB通道的像素值,实现颜色扰动
2、Dropout(随机失活)
随机:dropout probability(p=0.5)【训练和测试两个阶段的数据尺度变化测试时,神经元输出值乘以p】
失活:weight = 0

Summary

1、ReLU;2、LRN;3、Overlapping;4、Augmentation;5、Dropout

代码复现

ps:博主手撕的是pytorch里面封装的AlexNet,里面部分参数可能会和原文有所差异

import torch
import torch.nn as nn


class AlexNet(nn.Module):

    def __init__(self, num_classes):
        super(AlexNet, self).__init__()
        # 第一次卷积操作
        self.conv1 = nn.Sequential(nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
                                   nn.ReLU(inplace=True))
        # 第一次池化操作
        self.pool1 = nn.MaxPool2d(kernel_size=3, stride=2)
        # 第二次卷积操作
        self.conv2 = nn.Sequential(nn.Conv2d(64, 192, kernel_size=5, padding=2),
                                   nn.ReLU(inplace=True))
        # 第二次池化
        self.pool2 = nn.MaxPool2d(kernel_size=3, stride=2)
        # 第三次卷积操作
        self.conv3 = nn.Sequential(nn.Conv2d(192, 384, kernel_size=3, padding=1),
                                   nn.ReLU(inplace=True))
        # 第四次卷积操作
        self.conv4 = nn.Sequential(nn.Conv2d(384, 256, kernel_size=3, padding=1),
                                   nn.ReLU(inplace=True))
        # 第五次卷积操作
        self.conv5 = nn.Sequential(nn.Conv2d(256, 256, kernel_size=3, padding=1),
                                   nn.ReLU(inplace=True))
        # 第三次池化
        self.pool3 = 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: torch.Tensor):
        print("输入图像尺寸为{}".format(x.size()))
        x = self.conv1(x)
        print("经过第一次卷积后图像尺寸为{}".format(x.size()))
        x = self.pool1(x)
        print("经过第一次池化后图像尺寸为{}".format(x.size()))
        x = self.conv2(x)
        print("经过第二次卷积后图像尺寸为{}".format(x.size()))
        x = self.pool2(x)
        print("经过第二次池化后图像尺寸为{}".format(x.size()))
        x = self.conv3(x)
        print("经过第三次卷积后图像尺寸为{}".format(x.size()))
        x = self.conv4(x)
        print("经过第四次卷积后图像尺寸为{}".format(x.size()))
        x = self.conv5(x)
        print("经过第五次卷积后图像尺寸为{}".format(x.size()))
        x = self.pool3(x)
        print("经过第三次池化后图像尺寸为{}".format(x.size()))
        x = self.avgpool(x)
        print("经过平均池化后图像尺寸为{}".format(x.size()))
        x = torch.flatten(x, 1)  # flatten(x,1)是按照x的第1个维度拼接(按照列来拼接,横向拼接)
        print("经过拉伸后图像尺寸为{}".format(x.size()))
        x = self.classifier(x)
        print("经过三层全连接后图像尺寸为{}".format(x.size()))
        return x


if __name__ == "__main__":
    import torch as t
    input = t.randn(1, 3, 224, 224)

    net = AlexNet(2)

    out = net(input)

运行效果

在这里插入图片描述
1、模型接受的是4D的tensor,因此再导入模型时需要将3D彩图转换为含有batch_size的tensor

2、不使用LRN

3、增加AdaptiveAvgPool2d

4、pytorch中封装的kernel_num有所变化

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ZRX_GIS

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

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

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

打赏作者

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

抵扣说明:

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

余额充值