pytorch实战2:基于pytorch实现AlexNet模型

基于pytorch实现AlexNet模型

前言

​ 最近在看经典的卷积网络架构,打算自己尝试复现一下,在此系列文章中,会参考很多文章,有些已经忘记了出处,所以就不贴链接了,希望大家理解。

​ 完整的代码在最后。

本系列必须的基础

​ python基础知识、CNN原理知识、pytorch基础知识

本系列的目的

​ 一是帮助自己巩固知识点;

​ 二是自己实现一次,可以发现很多之前的不足;

​ 三是希望可以给大家一个参考。

目录结构

1. 说明:

​ 之前写了篇文章,主要是为了梳理如何使用pytorch从头到尾实现LeNet5这个模型。这个模型非常简单,但是与大部分模型一样,实现起来流程都差不多,无非就是多了些东西或者数据不同。

​ 而现在开始要实现经典的图像分类算法,这些算法本来都是基于ImageNet这个比赛而来的,所以涉及的数据集都很大,比如AlexNet在2012年出现,使用了双GPU的方法,也训练了3天。当然,到现在,肯定不需要这么久的时间了,因为GPU算力得到很大的提升。但是,对于我来说,还是要花不少时间,所以后面的文章,会首先给出模型的实现方法,具体的训练会到最后(指本系列差不多写完了),看有没有机会嫖到老师的服务器来跑,如果实在不行,就只有自己慢慢跑,但是最后还是会补充上去的。

​ ps:后面这段说明不会加上了

2. AlexNet模型介绍:

​ AlexNet在现在看来也不过如此,但是在当时却是轰动一时的存在,主要的原因是它终结了由人手工提取特征的时代,改为了由神经网络自动完成。

​ 而,AlexNet的模型在原论文中为双GPU模型,这是受限于当时GPU太low的原因,现在实现都是单GPU了(指AlexNet),所以这里放的也是单GPU的AlexNet架构:

在这里插入图片描述

3. AlexNet模型构建:

代码参考于pytorch官方实现的版本

​ 首先,导入需要的模块:

# 导入模块
import torch
from torch import nn

​ 其次,把pytorch实现模型的基本结构写出来:

# 创建AlexNet模型
class My_AlexNet(nn.Module):
    def __int__(self):
        super(My_AlexNet, self).__int__()
        # 准备定义模型
    # 前向算法
    def forward(self,x):
        pass

​ 然后,我们先来定义前面的特征提取层,即卷积–池化—卷积–池化…的层:

# 特征提取
self.features = nn.Sequential(
    # 输入通道数为3,因为图片为彩色,三通道
	# 而输出96、卷积核为11*11,步长为4,是由AlexNet模型决定的,后面的都同理
    # conv1
    nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=3,stride=2),
    # conv2
    nn.Conv2d(in_channels=96,out_channels=256,kernel_size=5,padding=2),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=3,stride=2),
    # conv3
    nn.Conv2d(in_channels=256,out_channels=384,padding=1,kernel_size=3),
    nn.ReLU(),
    # conv4
    nn.Conv2d(in_channels=384,out_channels=384,kernel_size=3,padding=1),
    nn.ReLU(),
    # conv5
    nn.Conv2d(in_channels=384,out_channels=256,kernel_size=3,padding=1),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=3,stride=2)
)

​ 然后,我们来实现全连接的部分:

# 全连接层
self.classifier = nn.Sequential(
    # 全连接的第一层,输入肯定是卷积输出的拉平值,即6*6*256
	# 输出是由AlexNet决定的,为4096
    nn.Linear(in_features=6*6*256,out_features=4096),
    nn.ReLU(),
    nn.Dropout(p=0.5),
    nn.Linear(4096,4096),
    nn.ReLU(),
    # 最后一层,输出1000个类别,也是我们所说的softmax层
    nn.Linear(4096,1000)
)

​ 最后,我们定义我们的前向算法:

# 前向算法
def forward(self,x):
    x = self.features(x)
    # 不要忘记在卷积--全连接的过程中,需要将数据拉平,之所以从1开始拉平,是因为我们
	# 批量训练,传入的x为[batch(每批的个数),x(长),x(宽),x(通道数)],因此拉平需要从第1(索引,相当于2)开始拉平
	# 变为[batch,x*x*x]
    x = torch.flatten(x,1)
    result = self.classifier(x)
    return result

4. 总结:

​ AlexNet构建起来很简单,只需要把握住输入、输出通道数和不要忘记卷积到全连接的时候把数据拉平即可。

​ 另外,虽然我这里没有使用数据集来训练它,但是大家可以拓展。因为ImageNet的数据集是开源的,可以在网上下载到。另外,如果不会下载,可以使用上一篇文章中提及的MNIST数据集,不过对于一些地方需要稍微修改,这就看大家的了(后面有机会我也会尝试一下分享出来)。

完整代码

# author: baiCai
# 导入模块
import torch
from torch import nn
from torchvision.models import AlexNet

# 创建AlexNet模型
class My_AlexNet(nn.Module):
    def __int__(self):
        super(My_AlexNet, self).__int__()
        # 特征提取
        self.features = nn.Sequential(
            # 输入通道数为3,因为图片为彩色,三通道
            # 而输出96、卷积核为11*11,步长为4,是由AlexNet模型决定的,后面的都同理
            nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3,stride=2),
            nn.Conv2d(in_channels=96,out_channels=256,kernel_size=5,padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3,stride=2),
            nn.Conv2d(in_channels=256,out_channels=384,padding=1,kernel_size=3),
            nn.ReLU(),
            nn.Conv2d(in_channels=384,out_channels=384,kernel_size=3,padding=1),
            nn.ReLU(),
            nn.Conv2d(in_channels=384,out_channels=256,kernel_size=3,padding=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=3,stride=2)
        )
        # 全连接层
        self.classifier = nn.Sequential(
            # 全连接的第一层,输入肯定是卷积输出的拉平值,即6*6*256
            # 输出是由AlexNet决定的,为4096
            nn.Linear(in_features=6*6*256,out_features=4096),
            nn.ReLU(),
            # AlexNet采取了DropOut进行正则,防止过拟合
            nn.Dropout(p=0.5),
            nn.Linear(4096,4096),
            nn.ReLU(),
            # 最后一层,输出1000个类别,也是我们所说的softmax层
            nn.Linear(4096,1000)
        )

    # 前向算法
    def forward(self,x):
        x = self.features(x)
        # 不要忘记在卷积--全连接的过程中,需要将数据拉平,之所以从1开始拉平,是因为我们
        # 批量训练,传入的x为[batch(每批的个数),x(长),x(宽),x(通道数)],因此拉平需要从第1(索引,相当于2)开始拉平
        # 变为[batch,x*x*x]
        x = torch.flatten(x,1)
        result = self.classifier(x)
        return result
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值