首页 > 其他分享 >个人学习笔记5-2:动手学深度学习pytorch版-李沐

个人学习笔记5-2:动手学深度学习pytorch版-李沐

时间:2024-09-07 22:53:28浏览次数:14  
标签:输出 nn 卷积 torch 汇聚 学习 pytorch 李沐 通道

#深度学习# #人工智能# #神经网络#

卷积神经网络(convolutional neural network,CNN)

6.4 多输入多输出通道

6.4.1 多输入通道

当输入包含多个通道时,需要构造一个与输入数据具有相同输入通道数的卷积核,以便与输入数据进行互相关运算。

例子:两个输入通道的二维互相关运算的示例。阴影部分是第一个输出元素以及用于计算这个输出的输入和核张量元素:(1 × 1 + 2 × 2 + 4 × 3 + 5 × 4) + (0 × 0 + 1 × 1 + 3 × 2 + 4 × 3) = 56。

例子:多输入通道互相关运算

#导入相关工具包
import torch
from d2l import torch as d2l
#定义:多输入通道相关运算函数
def corr2d_multi_in(X, K):#假设x、k军事3D
    # 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起
    return sum(d2l.corr2d(x, k) for x, k in zip(X, K))#zip会对最外围通道做遍历,即输入通道

#验证
#构造值相对应的输入张量X和核张量K,以验证互相关运算的输出。
X = torch.tensor([[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]],
               [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]])
K = torch.tensor([[[0.0, 1.0], [2.0, 3.0]], [[1.0, 2.0], [3.0, 4.0]]])

corr2d_multi_in(X, K)

结果输出:

6.4.2 多个输出通道:

在最流行的神经网络架构中,随着神经网络层数的加深,我们常会增加输出通道的维数,通过减少空间分辨率以获得更大的通道深度。

例子:计算多个通道的输出的互相关函数

def corr2d_multi_in_out(X, K):
    # 迭代“K”的第0个维度,每次都对输入“X”执行互相关运算。
    # 最后将所有结果都叠加在一起
    return torch.stack([corr2d_multi_in(X, k) for k in K], 0)

#通过将核张量K与K+1(K中每个元素加1)和K+2连接起来,构造了一个具有3个输出通道的卷积核
K = torch.stack((K, K + 1, K + 2), 0)
K.shape

结果输出:

对输入张量X与卷积核张量K执行互相关运算。现在的输出包含3个通道,第一个通道的结果与先前
输入张量X和多输入单输出通道的结果一致。

corr2d_multi_in_out(X, K)

结果输出:

6.4.3 1 × 1 卷积层

1 × 1卷积,即kh = kw = 1,看起来似乎没有多大意义。毕竟,卷积的本质是有效提取相邻像素间的相关特征,而1 × 1卷积显然没有此作用。

因为使用了最小窗口,1 × 1卷积失去了卷积层的特有能力——在高度和宽度维度上,识别相邻元素间相互作用的能力。1 × 1卷积层需要的权重维度为co × ci,再额外加上一个偏置。

标准二维卷积层参数及计算复杂度计算FLOP:

验证1x1卷积等价于全连接:

1.使用全连接层实现1 × 1卷积。请注意,我们需要对输入和输出的数据形状进行调整。

def corr2d_multi_in_out_1x1(X, K):
    c_i, h, w = X.shape
    c_o = K.shape[0]
    X = X.reshape((c_i, h * w))
    K = K.reshape((c_o, c_i))
    # 全连接层中的矩阵乘法
    Y = torch.matmul(K, X)
    return Y.reshape((c_o, h, w))

X = torch.normal(0, 1, (3, 3, 3))
K = torch.normal(0, 1, (2, 3, 1, 1))

#执行1 × 1卷积运算时,上述函数相当于先前实现的互相关函数corr2d_multi_in_out。

#验证
Y1 = corr2d_multi_in_out_1x1(X, K)
Y2 = corr2d_multi_in_out(X, K)
print(Y1)
print(Y2)
assert float(torch.abs(Y1 - Y2).sum()) < 1e-6#assert句当为真时,通过无输出。当为假时,会抛出AssertionError。

结果输出:

6.5 汇聚层(pooling层)

通常当我们处理图像时,希望逐渐降低隐藏表示的空间分辨率、聚集信息,这样随着神经网络中层叠的上升,每个神经元对其敏感的感受野(输入)就越大。

pooling层具有双重目的:降低卷积层对位置的敏感性,同时降低对空间降采样表示的敏感性。

6.5.1 最大汇聚层和平均汇聚层

与卷积层类似,汇聚层运算符由一个固定形状的窗口组成,该窗口根据其步幅大小在输入的所有区域上滑动,为固定形状窗口(有时称为汇聚窗口)遍历的每个位置计算一个输出。然而,不同于卷积层中的输入与卷积核之间的互相关计算,汇聚层不包含参数。相反,池运算是确定性的,我们通常计算汇聚窗口中所有元素的最大值或平均值。这些操作分别称为最大汇聚层(maximum pooling)和平均汇聚层(average pooling)。在汇聚窗口到达的每个位置,它计算该窗口中输入子张量的最大值或平均值。计算最大值或平均值是取决于使用了最大汇聚层还是平均汇聚层。

最大池化层:

平均池化层:

池化层返回窗口中最大或平均值;缓解卷积层对于位置的敏感性;同样有窗口大小、填充、和步幅作为超参数;池化层不影响模型的大小。

例子:pool2d函数,实现汇聚层的前向传播:

import torch
from torch import nn
from d2l import torch as d2l
#定义池化层,默认参数最大池化
def pool2d(X, pool_size, mode='max'):
    p_h, p_w = pool_size
    Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            if mode == 'max':
                Y[i, j] = X[i: i + p_h, j: j + p_w].max()
            elif mode == 'avg':
                Y[i, j] = X[i: i + p_h, j: j + p_w].mean()
    return Y

#构建输入张量X,验证二维最大汇聚层的输出。
X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
pool2d(X, (2, 2))

结果输出:

验证平均池化层:

pool2d(X, (2, 2), 'avg')

结果输出:

6.5.2 填充和步幅

通过填充和步幅以获得所需的输出形状。下面,用深度学习框架中内置的二维最大汇聚层,来演示汇聚层中填充和步幅的使用。

#首先构造了一个输入张量X,它有四个维度,其中样本数和通道数都是1
X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
X

结果输出:

深度学习框架中的步幅与汇聚窗口的大小相同。因此,如果我们使用形状为(3, 3)的汇聚窗口,
那么默认情况下,我们得到的步幅形状为(3, 3)。

pool2d = nn.MaxPool2d(3)#3表示3x3的窗口,pytorch默认步幅=窗口大小也是3
pool2d(X)

结果输出:

填充和步幅可以手动设定:

pool2d = nn.MaxPool2d(3, padding=1, stride=2)#窗口大小为3x3
pool2d(X)

结果输出:

以设定一个任意大小的矩形汇聚窗口,并分别设定填充和步幅的高度和宽度。

pool2d = nn.MaxPool2d((2, 3), stride=(2, 3), padding=(0, 1))#窗口2x3,步幅2,3;padding=0,1
pool2d(X)

结果输出:

6.5.3 多个通道

在处理多通道输入数据时,汇聚层在每个输入通道上单独运算,而不是像卷积层一样在通道上对输入进行汇总。这意味着汇聚层的输出通道数与输入通道数相同。下面,我们将在通道维度上连结张量X和X + 1,以构建具有2个通道的输入。

X = torch.cat((X, X + 1), 1)
X

结果输出:

汇聚后输出通道的数量仍然是2:

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)

结果输出:

6.6 卷积神经网络(LeNet)

softmax回归模型和多层感知机模型应用于Fashion‐MNIST数据集中的服装图片时,为了能够应用softmax回归和多层感知机,首先将每个大小为28 × 28的图像展平为一个784维的固定长度的一维向量,然后用全连接层对其进行处理。

现在,卷积层的处理方法,可以在图像中保留空间结构。同时,用卷积层代替全连接层的另一个好处是:模型更简洁、所需的参数更少。

6.6.1 LeNet

LeNet(LeNet‐5)由两个部分组成:1.卷积编码器:由两个卷积层组成;2.全连接层密集块:由三个全连接层组成。
每个卷积块中的基本单元是一个卷积层、一个sigmoid激活函数和平均汇聚层。每个卷积层使用5 × 5卷积核和一个sigmoid激活函数。这些层将输入映射到多个二维特征输出,通常同时增加通道的数量。第一卷积层有6个输出通道,而第二个卷积层有16个输出通道。每个2 × 2池操作(步幅2)通过空间下采样将维数减少4倍。卷积的输出形状由批量大小、通道数、高度、宽度决定。原LeNet该架构如下图所示。

本书中的修改应用版本结构如下图:

其代码实现:

import torch
from torch import nn
from d2l import torch as d2l

net = nn.Sequential(
    nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
    nn.Linear(120, 84), nn.Sigmoid(),
    nn.Linear(84, 10))
#对原始模型做了一点小改动,去掉了最后一层的高斯激活。除此之外,这个网络与最初的LeNet‐5一致

#定义一个大小为28 × 28的单通道(黑白)图像通过LeNet。通过在每一层打印输出的形状,我们可以检查模型。
X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:#在net中作迭代,将每一层拿出来
    X = layer(X)
    print(layer.__class__.__name__,'output shape: \t',X.shape)

结果输出:

其简化结构如图:

6.6.2 模型训练

后续续接

标签:输出,nn,卷积,torch,汇聚,学习,pytorch,李沐,通道
From: https://blog.csdn.net/2301_79619145/article/details/141970293

相关文章

  • 【Python学习笔记】 第4章 介绍Python对象类型
    在Python中,数据以对象的形式出现,包括内置对象和自己创建的对象。在这一章中,我们首先了解Python的内置对象。Python知识结构Python程序可以分为模块、语句、表达式以及对象:程序由模块构成模块包含语句语句包含表达式表达式创建并处理对象为什么使用内置类型内置对象使程......
  • Mininet MAC地址学习:通过Mininet模拟二层交换机和两个主机,通过两个主机通信来了解交换
    一.MAC地址学习1.登录我们创建mininet的虚拟机,创建一个线型拓扑,控制器设置为无。2.查看全部节点,查看链路信息,然后查看节点信息3.再打开一个终端(Terminal窗口2),然后打开交换机s1和交换机s2的二层(因为交换机s1和交换机s2是两个SDN交换机,在启动Mininet时没有指定任何控制器,交......
  • 用户空间的系统调用是如何链接到内核空间的系统调用的——MIT6.S081学习记录
    用户态调用了sysinfo()后,系统会从user/user.h里找到相关声明。用户空间的系统调用函数(如sysinfo())是通过链接到usys.S中的汇编代码来实现的。usys.S文件定义了所有系统调用的入口点,这些入口点使用.global指令使函数名在链接时可见。当用户程序中调用sysinfo()时,链接器会......
  • 面向对象编程的学习路线
    一、基础概念面向对象编程的基本概念面向对象编程是一种编程范式,它将数据和操作数据的方法封装在对象中。通过使用类和对象,我们可以更好地组织和管理代码。在面向对象编程中,我们可以使用继承、多态和封装等特性来提高代码的可重用性、可扩展性和可维护性。学习面向对象编程的基本概......
  • Java中Runtime类的学习
    Runtime类目录Runtime类什么是RuntimeRuntime类有哪些方法,有什么用什么是RuntimeRuntime(运行时),每个Java程序在运行时都相当于启动了一个JVM实例,每个JVM实例都对应一个Runtime对象。Runtime对象是由JVM负责实例化的,因此我们无法通过传统的方式实例化一个Runtime对象,只能通过调......
  • 【动手学深度学习】04 数据操作 + 数据预处理(个人向笔记)
    数据操作N维数组是机器学习和神经网络的主要数据结构其中2-d矩阵中每一行表示每一行表示一个样本当维度来到三维的时候则可以表示成一张图片,再加一维就可以变成多张图片,再加一维则可以变成一个视频访问元素冒号表示从冒号左边的元素到冒号右边的前一个元素(开区间),其中......
  • Python3 学习笔记4-列表、元组、字典、集合、条件控制和循环语句
    目录一、列表:(1)Python3 列表: (2) 访问列表中的值: (3)列表更新:(4)列表元素删除: (5)列表脚本操作符 : (6)列表截取与拼接: (7)嵌套列表: (8)列表之间比较: (9)列表函数使用方法: 二、元组:(1)创建元组:(2)访问元组元素:(3)元组切片:(4)元组拼接:(5)元组重复:(7)元组内置函数:(8)元组比较:(9)注意......
  • 第二周9.7周六学习总结——二分
    while(l<r){intmid=l+r>>1; //(l+r)/2if(check(mid))r=mid;//check()判断mid是否满足性质elsel=mid+1;} while(l<r){intmid=l+r+1>>1; //(l+r+1)/2,往右找答案要加1......
  • 基于Node.js+vue基于JavaWeb的在线英语学习管理系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着全球化进程的加速和互联网技术的飞速发展,英语作为国际通用语言的重要性日益凸显。然而,传统英语学习方式受限于时间、地点及教学资源等因素,难以满足广大......
  • IDA 远程调试学习
    例题https://github.com/bluesadi/SCUCTF-Backup/tree/main/SCUCTF新生赛2021/RE3_DebugMe很明显flag在这个位置然后分析要获取到flag需要满足v27==2和v24==v22两个条件v27==2好满足,只要在命令行中传入一个参数就可以了但是v22经过一顿非常麻烦的计算才能获取,所以打算......