第三次作业:卷积神经网络基础

本文详细介绍了卷积神经网络的基础概念,包括卷积、池化、全连接层,以及典型结构如AlexNet、VGG16和ResNet。通过代码实践,运用CNN对MNIST和CIFAR10数据集进行分类,展示了CNN在图像识别中的优势。同时,讨论了训练过程中的关键问题,如dataloader的shuffle、transform的选择、epoch与batch的区别,以及1×1卷积和残差学习的作用。
摘要由CSDN通过智能技术生成

Assginment3:Basis of CNN

本博客为OUC2022秋季软件工程第三次作业

文章目录


一、视频学习

第一部分:卷积神经网络相关概念

概括

  • 卷积神经网络的应用:分类、检索、检测、分割;人脸识别、图像生成、智能驾驶。

  • 深度学习三部曲:搭建神经网络结构,提取特征;合适的损失函数;合适的优化参数;

  • 传统神经网络和卷积神经网络:
    使用传统神经网络:参数太多,会导致过拟合现象,泛化性能差
    卷积神经网络:局部关联;参数共享
    相同之处:层级结构

  • 卷积神经网络基本组成结构:卷积;池化;全连接

卷积

  • 一维卷积
    应用:信号处理,计算信号延迟累计
    滤波器(卷积核) f=[f1,f2,f3]长度为m
    信号序列 x=[x1,x2,x3,…]
    卷积:
    在这里插入图片描述

  • 二维卷积
    用于图像处理
    矩阵内积Y=WX+b
    在这里插入图片描述

  • 卷积的具体操作举例
    在这里插入图片描述
    输入有多个channel时,如(R,G,B),使用两个三维权重矩阵
    在这里插入图片描述
    大小不匹配时,进行零填充(padding)
    在这里插入图片描述
    在这里插入图片描述

  • 输出特征图的大小的计算
    行列数=(N+padding*2-F)/stride+1
    N–输入大小
    F–卷积核大小
    stride–步长
    padding–填充大小

  • 深度的概念;
    depth/channel=filter个数

  • 输出=特征图大小*深度

  • 参数量=(单个filter大小+1)×filter个数
    在这里插入图片描述

  • 卷积的可视化理解:不同的卷积核关注不同的特征

池化

  • 相当于缩放,参数量0,有filter和stride
  • 作用:保留主要特征,减少参数量和计算量,防止过拟合,提高模型泛化能力
  • 位于卷积层与卷积层间、全连接层与全连接层之间
  • 常用方法:
    最大值池化(分类)
    平均值池化
    在这里插入图片描述

全连接

一般放在卷积神经网络的尾部,参数量大

小结

第二部分:卷积神经网络典型结构

发展历程

AlexNet

在这里插入图片描述
在这里插入图片描述

  • 影响最大的是收敛速度
  • 总结用到的一些优化方法:
    1.ReLU激活函数
    2.DropOut(随机失活):从减少参数量方面考虑,训练时每次随机关闭一些神经元以降低参数量,整合时使用全部。
    3.水平翻转:增加样本量
    4.改变EGB通道强度:对rgb空间做高斯扰动。

VGG16

  • VGG的思想:增加深度,通过固定参数实现训练

GoogleNet

是模型结构的改进:除了类别输出层没有额外的全连接层

  • inception模块:通过多个卷积核增加特征多样性
    inceptionV2:降维
    inceptionV3:继续降维,裂变,用小的卷积核替代大的卷积核
    优点:降低参数量;增加了非线性激活函数(裂变)

ResNet

残差学习网络,深度152层而无梯度消失问题,适用于很深的网络。

  • 与传统卷积网络的差异
    结构比较:
    在这里插入图片描述
  • 传统结构:复合函数f(h…)求导,结果是乘积形式。
    残差block:f(h…)+x求导,结果为1+?的形式,解决了梯度消失问题。
  • 灵活性考虑极端情况:
    f(x)=0此时输出f(x)+x=x,可以自调节结构深度

疑问

1.为什么最大值池化更适用于分类问题?
2.filter和stride是如何选取的?

二、代码练习

(一)练习1 MNIST 数据集分类:构建简单的CNN对 mnist 数据集进行分类。

1.引入所需库,加载数据集(MNIST)

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import numpy

# 一个函数,用来计算模型中有多少参数
def get_n_params(model):
    np=0
    for p in list(model.parameters()):
        np += p.nelement()
    return np

# 使用GPU训练,可以在菜单 "代码执行工具" -> "更改运行时类型" 里进行设置
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

PyTorch里包含了 MNIST, CIFAR10 等常用数据集,调用 torchvision.datasets
即可把这些数据由远程下载到本地,下面给出MNIST的使用方法:

torchvision.datasets.MNIST(root, train=True, transform=None,
target_transform=None, download=False) root 为数据集下载到本地后的根目录,包括
training.pt 和 test.pt 文件
train,如果设置为True,从training.pt创建数据集,否则从test.pt创建。 download,如果设置为True,
从互联网下载数据并放到root文件夹下 transform, 一种函数或变换,输入PIL图片,返回变换之后的数据。
target_transform 一种函数或变换,输入目标,进行变换。
另外值得注意的是,DataLoader是一个比较重要的类,提供的常用操作有:batch_size(每个batch的大小),
shuffle(是否进行随机打乱顺序的操作), num_workers(加载数据的时候使用几个子进程)

input_size  = 28*28   # MNIST上的图像尺寸是 28x28
output_size = 10      # 类别为 0 到 9 的数字,因此为十类

train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('./data', train=True, download=True,
        transform=transforms.Compose(
            [transforms.ToTensor(),
             transforms.Normalize((0.1307,), (0.3081,))])),
    batch_size=64, shuffle=True)

test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('./data', train=False, transform=transforms.Compose([
             transforms.ToTensor(),
             transforms.Normalize((0.1307,), (0.3081,))])),
    batch_size=1000, shuffle=True)

显示数据集中的部分图像

plt.figure(figsize=(8, 5))
for i in range(20): #元素总数=行*列
    plt.subplot(4, 5, i + 1)  #4行5列
    image, _ = train_loader.dataset.__getitem__(i)
    plt.imshow(image.squeeze().numpy(),'gray')
    plt.axis('off');

在这里插入图片描述

2.构建网络

  • Softmax函数常用的用法是指定参数dim就可以:
    (1)dim=0:对每一列的所有元素进行softmax运算,并使得每一列所有元素和为1。
    (2)dim=1:对每一行的所有元素进行softmax运算,并使得每一行所有元素和为1。

  • LogSoftmax其实就是对softmax的结果进行log,即Log(Softmax(x))
    LogSoftmax的作用:
    速度变快,数据稳定(些值经过softmax后概率非常低, 会下溢出. 所以一般会取概率的log表示概率)

  • forward 函数定义了网络的结构,按照一定顺序,把上面构建的一些结构组织起来。

  • x.view()将向量铺平,便于传入全连接层,比如使矩阵的每行存放一张图片的各个参数,即使每行对应一张图片。

  • 网络层次:卷积-relu激活-池化-卷积-激活-池化-矩阵变形处理(便于传入全连接层)-全连接-激活-全连接-输出

class FC2Layer(nn.Module):
    def __init__(self, input_size, n_hidden, output_size):
        # nn.Module子类的函数必须在构造函数中执行父类的构造函数
        # 下式等价于nn.Module.__init__(self)        
        super(FC2Layer, self).__init__()
        self.input_size = input_size
        # 这里直接用 Sequential 就定义了网络,注意要和下面 CNN 的代码区分开
        self.network = nn.Sequential(
            nn.Linear(input_size, n_hidden), 
            nn.ReLU(), 
            nn.Linear(n_hidden, n_hidden), 
            nn.ReLU(), 
            nn.Linear(n_hidden, output_size), 
            nn.LogSoftmax(dim=1)  #Log(Softmax(x))
        )
    def forward(self, x):
        # view一般出现在model类的forward函数中,用于改变输入或输出的形状
        # x.view(-1, self.input_size) 的意思是多维的数据展成二维
        # 代码指定二维数据的列数为 input_size=784,行数 -1 表示我们不想算,电脑会自己计算对应的数字
        # 在 DataLoader 部分,我们可以看到 batch_size (行)是64,所以得到 x 的行数是64
        # 大家可以加一行代码:print(x.cpu().numpy().shape)
        # 训练过程中,就会看到 (64, 784) 的输出,和我们的预期是一致的

        # forward 函数的作用是,指定网络的运行过程,这个全连接网络可能看不啥意义,
        # 下面的CNN网络可以看出 forward 的作用。
        x = x.view(-1, self.input_size)
        return self.network(x)



class CNN(nn.Module):
    def __init__(self, input_size, n_feature, output_size):
        # 执行父类的构造函数,所有的网络都要这么写
        super(CNN, self).__init__()
        # 下面是网络里典型结构的一些定义,一般就是卷积和全连接
        # 池化、ReLU一类的不用在这里定义
        self.n_feature = n_feature
        #卷积层
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=n_feature, kernel_size=5)
        #输入、输出、卷积核
        self.conv2 = nn.Conv2d(n_feature, n_feature, kernel_size=5)
        #全连接层
        self.fc1 = nn.Linear(n_feature*4*4, 50)
        self.fc2 = nn.Linear(50, 10)  #最后分为10类    
    
    # 下面的 forward 函数,定义了网络的结构,按照一定顺序,把上面构建的一些结构组织起来
    # 意思就是,conv1, conv2 等等的,可以多次重用
    def forward(self, x, verbose=False)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值