图像分类篇——使用pytorch搭建AlexNet


本文为学习记录和备忘录,对代码进行了详细注释,以供学习。
内容来源:
★github: https://github.com/WZMIAOMIAO/deep-learning-for-image-processing

★b站:https://space.bilibili.com/18161609/channel/index

★CSDN:https://blog.csdn.net/qq_37541097


1. AlexNet网络详解

1.1 AlexNet网络概述

AlexNet是2012年ILSVRC 2012(ImageNet Large Scale Visual Recognition Challenge)竞赛的冠军网络。

论文链接:ImageNet Classification with Deep Convolutional Neural Networks

AlexNet网络的亮点:

  • 首次利用 GPU 进行网络加速训练。
  • 使用了 ReLU 激活函数,而不是传统的 Sigmoid 激活函数以及 Tanh 激活函数。
  • 使用了 LRN 局部响应归一化(Local Response Normalization)。
  • 在全连接层的前两层中使用了 Dropout 随机失活神经元操作,以减少过拟合。

1.2 Dropout

  • 使用 Dropout 的方式在网络正向传播过程中随机失活一部分神经元,可以减少过拟合。
  • 过拟合:根本原因是特征维度过多,模型假设过于复杂,参数过多,训练数据过少,噪声过多,导致拟合的函数完美的预测训练集,但对新数据的测试集预测结果差。 过度的拟合了训练数据,而没有考虑到泛化能力。
    Dropout

1.3 AlexNet网络结构和详细参数

AlexNet结构图
AlexNet参数图

  • 卷积计算公式:
    经卷积后的矩阵尺寸大小计算公式为:N = (W − F + 2P ) / S + 1
    其中输入图片大小 W×W;Filter大小 F×F;步长 S;padding的像素数 P。
    详细参数如下表:
    AlexNet参数表

2. Pytorch搭建

对于代码的解释都在注释中,方便对照查看学习。

2.1 model.py

  • nn.Sequential()可以将一系列层结构进行打包,组合成新的模块,对于网络层次多的网络,借助其精简代码.
  • 在这里的卷积中,padding只能传入两种类型的变量,一种是int整型,一种是tuple类型。如果传入的是int整型,如padding=1,则会在上方、下方各补1行0,左侧、右侧各补1列0。如果传入tuple类型的话,如tuple:(1, 2),1代表上下方各补1行0,2代表左右侧各补2列0。
    如果想精确地在左侧补1列,右侧补2列的话,则需要nn.ZeroPad2d((1, 2, 1, 2)),左侧补1列,右侧补2列,上方补1行,下方补2行。
  • 卷积或池化计算结果为小数时:卷积层向下取整,池化层向上取整。
  • nn.ReLU(inplace=True), 其中的inplace可理解为增加计算量且降低内存使用量的一种方法。
  • nn.Dropout(p=0.5), 其中0.5代表神经元失活比例,默认等于0.5。
  • x = torch.flatten(x, start_dim=1) ,完成的是展平操作,从index=1开始(torch的tensor排列顺序为[batch,channel,height,width]),即从channel这个维度开始展平,展成一个一维向量,也可用view(x.shape[0],-1)来完成展平。
    模型部分全部代码如下:
import torch.nn as nn
import torch


class AlexNet(nn.Module):
    def __init__(self, num_classes=1000, init_weights=False):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(  # nn.Sequential可以将一系列层结构进行打包,组合成新的模块,对于网络层次多的网络,借助其精简代码
            # 取名为features,代表专门提取图像特征的结构
            nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=2),  # input[3, 224, 224]  output[48, 55, 55]
            nn.ReLU(inplace=True),  # inplace可理解为增加计算量且降低内存使用量的一种方法
            nn.MaxPool2d(kernel_size=3, stride=2),                  # output[48, 27, 27]
            nn.Conv2d(48, 128, kernel_size=5, padding=2),           # output[128, 27, 27]
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),                  # output[128, 13, 13]
            nn.Conv2d(128, 192, kernel_size=3, padding=1),          # output[192, 13, 13]
            nn.ReLU(inplace=True),
            nn.Conv2d(192, 192, kernel_size=3, padding=1),          # output[192, 13, 13]
            nn.ReLU(inplace=True),
            nn.Conv2d(192, 128, kernel_size=3, padding=1),          # output[128, 13, 13]
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),                  # output[128, 6, 6]
            # AlexNet架构为:Conv1,Maxpool1,Conv2,Maxpool2,Conv3,Conv4,Conv5,Maxpool3
        )
        self.classifier = nn.Sequential(  # 借助nn.Sequential将全连接层打包为新的模块
            nn.Dropout(p=0.5),  # 在展平与FC1之间加上Dropout,0.5代表失活比例,默认等于0.5
            nn.Linear(128 * 6 *
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值