深度学习
基础知识和各种网络结构实战 ...前言
使用pytorch搭建AlexNet一、介绍
在这之前我们应当阅读一下AlexNet这篇论文,了解一下AlexNet得框架结构。
我们可以指导它是由卷积5层+全连接3层组成的
二、框架搭载
2.1 导入库
import torch
import torch.nn as nn
from torchsummary import summary
torchsummary 用来打印显示网络结构和参数
2.2 AlexNet类
前5层是卷积层,后三层是全连接层
已知:输入图像均为2242243
网络结构为8层,卷积5层+全连接3层
第1层:卷积层 卷积核为11113 步长为4 2块GPU共96个卷积核 激活函数为:ReLu 池化层为:MaxPooling
第2层:卷积层 输入为262696 激活函数为:ReLu 池化层为:MaxPooling
第3层:卷积层 激活函数为:ReLu 无池化
第4层:卷积层 激活函数为:ReLu 无池化
第5层:卷积层 激活函数为:ReLu 池化层为:MaxPooling
第6层:全连接层 输入4096
第7层:全连接层 输入4096
第8层:全连接层 输出为1000
class AlexNet(nn.Module):
def __init__(self,nums_classify):
super(AlexNet,self).__init__()
self.nums=nums_classify#分类数
#5层卷积层
self.conv=nn.Sequential(
#第一层:输入:224*224*3 输出:54*54*96
nn.Conv2d(in_channels=3,out_channels=96,kernel_size=11,stride=4,padding=0),
nn.ReLU(),
nn.MaxPool2d(kernel_size=3,stride=2),#最大池化 输入:54*54*96 输出:26*26*96
#第二层:输入26*26*96
nn.Conv2d(in_channels=96,out_channels=256,kernel_size=5,stride=1,padding=2),
nn.ReLU(),
nn.MaxPool2d(kernel_size=3,stride=2),#最大池化 输入:26*26*256 输出:12*12*256
#第三层:
nn.Conv2d(in_channels=256,out_channels=384,kernel_size=3,stride=1,padding=1),
#第四层:
nn.Conv2d(in_channels=384,out_channels=256,kernel_size=3,stride=1,padding=1),
nn.ReLU(),
#第五层:
nn.Conv2d(in_channels=256,out_channels=256,kernel_size=3,stride=1,padding=1),
nn.ReLU(),
# 池化层 输入:12*12*256 输出:5*5*256
nn.MaxPool2d(kernel_size=3, stride=2)
)
#定义池化层,规定输出size
self.avg_pool=nn.AdaptiveAvgPool2d((5,5))
#3层全连接层
self.fc=nn.Sequential(
#第6层:
#输入:5*5*256 -> 4096
nn.Linear(in_features=5 * 5 * 256, out_features=4096),
nn.ReLU(),
nn.Dropout(),
#第7层
nn.Linear(in_features=4096, out_features=4096),
nn.ReLU(),
nn.Dropout(),
#第8层 output
nn.Linear(in_features=4096, out_features=1000)
)
def forward(self, x):
x = self.conv(x)
x = self.avg_pool(x)
x = x.view(x.size(0), -1)
print(x.size())
x = self.fc(x)
return x
super(Net, self).__init__()
意思是首先找到Net的父类(比如是类NNet),然后把类Net的对象self转换为类NNet的对象,然后“被转换”的类NNet对象调用自己的init函数
三、测试数据
x = torch.rand((2, 3, 227, 227))
alex = AlexNet(1000)
print(alex)
out = alex(x)
print(out)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
alex = alex.to(device)
# 打印网络模型数据流程及参数信息
summary(alex, (3, 227, 227))
得到:
AlexNet(
(conv): Sequential(
(0): Conv2d(3, 96, kernel_size=(11, 11), stride=(4, 4))
(1): ReLU()
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(96, 256, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU()
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(256, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): ReLU()
(9): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(10): ReLU()
(11): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avg_pool): AdaptiveAvgPool2d(output_size=(5, 5))
(fc): Sequential(
(0): Linear(in_features=6400, out_features=4096, bias=True)
(1): ReLU()
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): ReLU()
(5): Dropout(p=0.5, inplace=False)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
)
torch.Size([2, 6400])
tensor([[ 0.0230, -0.0033, -0.0077, ..., -0.0096, 0.0007, 0.0089],
[ 0.0146, 0.0039, -0.0071, ..., -0.0053, 0.0025, 0.0020]],
grad_fn=<AddmmBackward>)
torch.Size([2, 6400])
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Conv2d-1 [-1, 96, 55, 55] 34,944
ReLU-2 [-1, 96, 55, 55] 0
MaxPool2d-3 [-1, 96, 27, 27] 0
Conv2d-4 [-1, 256, 27, 27] 614,656
ReLU-5 [-1, 256, 27, 27] 0
MaxPool2d-6 [-1, 256, 13, 13] 0
Conv2d-7 [-1, 384, 13, 13] 885,120
Conv2d-8 [-1, 256, 13, 13] 884,992
ReLU-9 [-1, 256, 13, 13] 0
Conv2d-10 [-1, 256, 13, 13] 590,080
ReLU-11 [-1, 256, 13, 13] 0
MaxPool2d-12 [-1, 256, 6, 6] 0
AdaptiveAvgPool2d-13 [-1, 256, 5, 5] 0
Linear-14 [-1, 4096] 26,218,496
ReLU-15 [-1, 4096] 0
Dropout-16 [-1, 4096] 0
Linear-17 [-1, 4096] 16,781,312
ReLU-18 [-1, 4096] 0
Dropout-19 [-1, 4096] 0
Linear-20 [-1, 1000] 4,097,000
================================================================
Total params: 50,106,600
Trainable params: 50,106,600
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.59
Forward/backward pass size (MB): 10.27
Params size (MB): 191.14
Estimated Total Size (MB): 202.00
----------------------------------------------------------------
框架先打好,下一步我将完整复现AlexNet
总结
期待大家和我交流,留言或者私信,一起学习,一起进步!