您现在的位置是:首页 >技术杂谈 >[PyTorch][chapter 35][经典卷积神经网络-1 ]网站首页技术杂谈

[PyTorch][chapter 35][经典卷积神经网络-1 ]

明朝百晓生 2024-06-26 14:23:55
简介[PyTorch][chapter 35][经典卷积神经网络-1 ]

前言:

   

 ILSVRC(ImageNet Large Scale Visual Recognition Challenge)是近年来机器视觉领域最受追捧也是最具权威的学术竞赛之一,代表了图像领域的最高水平。

ImageNet数据集是ILSVRC竞赛使用的是数据集,由斯坦福大学李飞飞教授主导,包含了超过1400万张全尺寸的有标记图片。ILSVRC比赛会每年从ImageNet数据集中抽出部分样本,以2012年为例,比赛的训练集包含1281167张图片,验证集包含50000张图片,测试集为100000张图片。

ImageNet的分类发展历史

   我们通过test top-5 可以看到错误率在逐步的降低。

    AlexNet- VGG- GoogleNet-ResNet

 

目录:

    1    LeNet-5

    2     AlexNet


一 LeNet-5

    1.1 简介

LeNet-5是一个经典的深度卷积神经网络,由Yann LeCun在1998年提出,旨在解决手写数字识别问题,被认为是卷积神经网络的开创性工作之一。该网络是第一个被广泛应用于数字图像识别的神经网络之一,也是深度学习领域的里程碑之一。本文首先介绍了卷积神经网络的基本原理,然后介绍了LeNet-5的基本结构和训练过程,并给出了LeNet-5的pytorch代码实现,最后说明了LeNet-5对深度学习的贡献。

    Yoshua Bengio, Yann Lecun, Geoffrey Hinton

1.2  应用:

    该网络在手写数字识别上精度可以达到99.2%,在邮政编码识别

以及支票识别上面,占据了美国50%以上的市场份额。

   

 1.3 网络结构

  LeNet-5的基本结构包括7层网络结构(不含输入层),其中包括2个卷积层、2个降采样层(池化层)、2个全连接层和输出层。

参数

L1-输入层 

输入层接收大小为 32×32 的手写数字图像,其中包括灰度值(0-255

L2-卷积层C1

卷积层C1包括6个卷积核,每个卷积核的大小为 5×5 ,步长为1,填充为0

因此,每个卷积核会产生一个大小为 28×28 的特征图(输出通道数为6

L3-采样层S2

采样层S2采用最大池化(max-pooling)操作,每个窗口的大小为 2×2 ,步长为2。因此,每个池化操作会从4个相邻的特征图中选择最大值,产生一个大小为 14×14 的特征图(输出通道数为6)。这样可以减少特征图的大小,提高计算效率,并且对于轻微的位置变化可以保持一定的不变性。

L4-卷积层C3

卷积层C3包括16个卷积核,每个卷积核的大小为 5×5 ,步长为1,填充为0。因此,每个卷积核会产生一个大小为 10×10 的特征图(输出通道数为16)。

L5-采样层S4

采样层S4采用最大池化操作,每个窗口的大小为 2×2 ,步长为2。因此,每个池化操作会从4个相邻的特征图中选择最大值,产生一个大小为 5×5 的特征图(输出通道数为16

L6-全连接层C5

C5将每个大小为 5×5 的特征图拉成一个长度为400的向量,并通过一个带有120个神经元的全连接层进行连接。120是由LeNet-5的设计者根据实验得到的最佳值。

L7-全连接层F6

全连接层F6120个神经元连接到84个神经元。

L8-输出层

输出层由10个神经元组成,每个神经元对应0-9中的一个数字,并输出最终的分类结果。在训练过程中,使用交叉熵损失函数计算输出层的误差,并通过反向传播算法更新卷积核和全连接层的权重参数。

# -*- coding: utf-8 -*-
"""
Created on Thu May 25 16:15:33 2023

@author: chengxf2
"""

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
from torchvision import transforms
from visdom import Visdom


class LeNet5(nn.Module):
    
    def __init__(self):
        
        super(LeNet5,self).__init__()
        
        #灰度图,只有一个通道
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5,stride=1) 
        self.pool1 = nn.AvgPool2d(kernel_size=2, stride=2)
        
        #feature map [16,6,5,5]
        self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5, stride=1)
        self.pool2 = nn.AvgPool2d(kernel_size=2, stride=2)
        
        #全连接层
        self.fc1 = nn.Linear(in_features=16 * 4 * 4, out_features=120)
        self.fc2 = nn.Linear(in_features=120, out_features=84)
        self.fc3 = nn.Linear(in_features=84, out_features=10)
        
        
    
    def forward(self, x):
        
        conv_1 = self.conv1(x)
        pool_1 = self.pool1(torch.relu(conv_1))
        
        conv_2 = self.conv2(pool_1)
        pool_2 = self.pool2(torch.relu(conv_2))
       
        x = pool_2.view(-1, 16 * 4 * 4)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        
        return x
    

def run():
    # 加载MNIST数据集
    train_dataset = datasets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True)
    test_dataset = datasets.MNIST(root='./data', train=False, transform=transforms.ToTensor())

    # 定义数据加载器
    train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
    test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)

    # 定义模型、损失函数和优化器
    model = LeNet5()
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters())
    
    vis = Visdom()
    vis.line([0],[0],win ='test_acc',opts = dict(title='test_acc'))
    
    # 训练模型
    for epoch in range(10):
        for i, (images, labels) in enumerate(train_loader):
            optimizer.zero_grad()
            outputs = model(images)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
        
            if (i+1) % 200 == 0:
                print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, 10, i+1, len(train_loader), loss.item()))
        
        # 测试模型
        model.eval()
        #表明当前计算不需要反向传播,使用之后,强制后边的内容不进行计算图的构建
        with torch.no_grad():
            correct = 0
            total = 0
            
            for images, labels in test_loader:
                outputs = model(images) #[64, 10]
              
                #该函数返回由最大值以及最大值处的索引组成元组(max,max_indices)
                _, predicted = torch.max(outputs.data, 1)
                total += labels.size(0)
                correct += (predicted == labels).sum().item()
            acc = correct / total
            vis.line([acc],[epoch+1], win='test_acc',update='append')
            print('Test Accuracy: [{}/{}]={:.2f}%'.format(correct,total,100 * correct / total))



if __name__ == "__main__":

     run()

 

假如输入图像大小为m*n,过滤器(filter)为f*f,padding为p,步长(stride)为s,则输出大小为:如果商不是整数,向下取整,即floor函数。参考:

[frac{m+2p-f}{s}+1]*[frac{n+2p-f}{s}+1]


二  AlexNet

  2.1 简介

    AlexNet经典网络由Alex Krizhevsky、Hinton等人在2012年提出,发表在NIPS,论文名为《ImageNet Classification with Deep Convolutional Neural Networks》

 2.2 创新点

2012年前图像处理主流是SVM,AlexNet 创新点如下

创新点

1 激活函数使用ReLU替代TanhSigmoid加快训练速度,解决网络较深时梯度弥散问题

2 .训练时使用Dropout随机忽略一部分神经元,以避免过拟合

3使用重叠最大池化(Overlapping Max Pooling),避免平均池化时的模糊化效果;并且让步长比池化核的尺寸小,提升特征丰富性。filter的步长stride小于filterwidthheight。一般,kernel(filter)的宽和高是相同的,深度(depth)是和通道数相同的

4使用LRN对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其它反馈较小的神经元,增强了模型泛化能力。LRN只对数据相邻区域做归一化处理,不改变数据的大小和维度

5 .数据扩充(Data Augmentation):训练时随机地从256*256的原始数据中截取227*227大小的区域,水平翻转;光照变换。增加了数据量,大大减少过拟合,提升泛化能力。

6GPU并行运算。

  第一次使用了两张GTX580,把卷积核放在两张gpu

AlexNet输入是一种属于1000种不同类别的一张BGR图像,大小为227*227,输出是一个向量,大小为1000。输出向量的第i个元素值被解释为输入图像属于第i类的概率。因此,输出向量的所有元素的总和为1

2.3 网络结构

    AlexNet架构:5个卷积层(Convolution、ReLU、LRN、Pooling)+3个全连接层(InnerProduct、ReLU、Dropout),predict时对各层进行说明

 

 

介绍训练参数
输入层图像大小227*227*3。 
convolution_1+ReLU+LRN使用96个11*11的filter,stride为4,padding为0,输出为55*55*96,96个feature maps(11*11*3*96)+96=34944
最大池化层_1filter为3*3,stride为2,padding为0,输出为27*27*96,96个feature maps。 
convolution_2+ReLU+LRN使用256个5*5的filter,stride为1,padding为2,输出为27*27*256,256个feature maps(5*5*96*256)+256=614656。
最大池化层_2filter为3*3,stride为2,padding为0,输出为13*13*256,256个feature maps。 
convolution_3+ReLU使用384个3*3的filter,stride为1,padding为1,输出为13*13*384,384个feature maps(3*3*256*384)+384=88512
convolution_4+ReLU使用384个3*3的filter,stride为1,padding为1,输出为13*13*384,384个feature maps(3*3*384*384)+384=1327488
convolution_5+ReLU使用256个3*3的filter,stride为1,padding为1,输出为13*13*256,256个feature maps(3*3*384*256)+256=884992
最大池化层_3filter为3*3,stride为2,padding为0,输出为6*6*256,256个feature maps。 
全连接层1+ReLU+Dropout有4096个神经元(6*6*256)*4096=37748736
全连接层2+ReLU+Dropout有4096个神经元4096*4096=16777216
全连接层3有1000个神经元4096*1000=4096000
输出层(Softmax)输出识别结果 1000个分类可能 

 

参考:

经典网络AlexNet介绍_fengbingchun的博客-CSDN博客

https://www.cnblogs.com/TimVerion/p/11378949.html

卷积神经网络经典回顾之LeNet-5 - 知乎

课时69 经典卷积网络 LeNet5,AlexNet, VGG, GoogLeNet-1_哔哩哔哩_bilibili

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。