AlexNet 用于花朵分类
一、AlexNet 简单介绍
AlexNet 是由 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 在 2012 年 ImageNet 图像分类竞赛中提出的一种经典的卷积神经网络。当时,AlexNet 在 ImageNet 大规模视觉识别竞赛中取得了优异的成绩,把深度学习模型在比赛中的正确率提升到一个前所未有的高度。因此,它的出现对深度学习发展具有里程碑式的意义。
论文原文:ImageNet Classification with Deep Convolutional Neural Networks
论文笔记:https://zhuanlan.zhihu.com/p/433682901
什么是过拟合呢?
随着训练的进行,模型受噪声影响大,模型过于精确
Dropout
全连接-> 更加简单的随机连接
二、模型代码(model.py)
2.1 大致思路
- 卷积池化——逐步提取特征
- Dropout 随机失活一些神经元
- 全连接层——实现分类
- 定义前向传播函数
2.2 几个小白问题,帮助回忆神经网络
-
为啥要卷积层?
- 作用:提取图像的局部特征,例如边缘、纹理等
- 参数设置:
-
为啥要池化层?
- 作用:对卷积层的输出进行降维和压缩,例如取最大值或平均值等操作,从而减少特征的数量和计算量
-
为啥要卷积池化交叉进行?
逐渐提取图像的高级特征,从而使得模型更加准确地进行分类。 -
全连接层之间插入 ReLU 的作用?
全连接层之间加入非线性激活函数可以增加模型的非线性能力,从而使得模型可以更好地拟合复杂的数据分布
2.3 model.py 展示
import torch.nn as nn
import torch
_# 用途:图像分类_
_# 网络组成:5个卷积层、3个全连接层_
class AlexNet(nn.Module):
_#num_class:输出是一个1000维的向量,init_weights:是否初始化权重_
_ _def __init__(self, num_classes=1000, init_weights=False):
super(AlexNet, self).__init__()
_# features:专门用于提取图像特征的结构_
_ _self.features = nn.Sequential(
_#(输入通道数,输出通道数,卷积核的大小是11*11,卷积核每次移动的步长是4,图像边缘填充是2行/列)_
_ _nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=2), _# input[3, 224, 224] output[48, 55, 55]_
_ # ReLU被用作卷积层之后的激活函数,即在每个卷积层的输出上应用ReLU函数,好处是可以增加模型的非线性,使计算简单_
_ _nn.ReLU(inplace=True),
_# 最大池化(下采样):就是取池化核的最大值输出_
_ # 作用:降低特征图(feature maps)的空间尺寸(即高度和宽度),同时保留重要的特征信息_
_ _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]_
_ _)
self.classifier = nn.Sequential(
nn.Dropout(p=0.5),
nn.Linear(128 * 6 * 6, 2048),
nn.ReLU(inplace=True),
nn.Dropout(p=0.5),
nn.Linear(2048, 2048),
nn.ReLU(inplace=True),
nn.Linear(2048, num_classes),
)
if init_weights:
self