神经网络-Neural NetWork

目录

nn.Module

简单介绍

Containers

Module

练习:熟系神经网络

卷积操作

conv2d

参数

 练习

卷积层

参数

练习:卷积处理数据并写入日志文件中

 

池化层

 参数

练习

作用

练习:使用最大池化并将处理前后的数据写入日志文件

非线性激活

ReLU

参数

练习

Sigmoid

参数

练习:经过Sigmoid层并写入日志文件

线性层及其它层介绍

正则化层:Normlization Layers

BATCHNORM2D

循环层:Recurrent Layers

Transformer层:Transformer Layers

核心特点

结构

线性层:Liner Layers

练习

随机失活层:Dropout Layers

稀疏层:Sparse Layers

距离函数:Distance Function

损失函数:Loss Function

L1Loss

练习

MSELoss

练习

练习

练习:损失函数用于网络模型中

debug

优化器

练习

多轮优化

Containers——Sequential

练习:实现一个网络模型了解sequential

sequential改写上述练习代码并写入日志文件


nn.Module

简单介绍

nn.Module是所有神经网络模块的基类,其作用主要是构建和组成复杂的神经网络架构。主要作用:

1、借助继承nn.module,能够自定义神经网络层和模型。要自定义模型,需要重写__init__方法来定义网络组件,同时重写forward方法来规定数据的前向传播路径。

2、..........

从PyTorch打开其官方文档,可查看该基类中含有的各种处理方式

其中Containers为torch.nn提供了一个骨架(结构),我们只需向这个结构中放入不同的内容,从而组成一个神经网络

Containers下方的是要往骨架中填充的内容

Convolution Layers为卷积层

Pooling Layers为池化层,Non-liner Activations为非线性激活

Normlization Layer为正则化层,等等。。。

Containers

Containers中分为多个模块,其中Module是较为常用的一个模块,其是对于所有的神经网络的一个基本的类,提供一个基本的骨架

Module

使用方法,自定义类构建神经网络,类继承Module

示例

import torch.nn as nn
import torch.nn.functional as F

class Model(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.conv2 = nn.Conv2d(20, 20, 5)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        return F.relu(self.conv2(x))

主要实现的功能函数为__init__和forward

__init__函数:主要是实例化神经网络的类的对象时,将神经网络中所需处理层的类进行实例化对象,示例代码中的就是完成了相应的卷积层的实例化对象

forward函数:在神经网络中,我们向神经网络中输入一个input数据,经过神经网络的处理层得到一个返回的结果,这一处理过程就是forward实现的功能,即前向传播

示例代码中forward处理:输入x数据经过一层卷积,然后经过一次非线性,然后再经过一层卷积,然后再经过一层非线性,将得到的结果返回

练习:熟系神经网络

import torch
from torch import nn

class myclass(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
        output = x + 1
        return output

obj = myclass()
x = torch.tensor(1.0)
print(obj(x))

卷积操作

打开PyTorch官网,查看相关文档

点击torch.nn中的Convolution Layers(卷积层)

其中1d代表处理一维的数据,2d代表处理二维的数据,依次类推 

conv2d

参数

打开官方文档,查看该方法所需的参数

input:处理的图像数据,图像的数据类型要求为Tensor数据类型,数据要求要设置minibatch、通道、高、宽

weight:权重(卷积核)

bias:偏置

stride:决定卷积核移动的步长,数据可以是一个int类型数据(决定水平、竖直方向上的步长)也可以是一个元组(两个int类型数据,分别决定水平、竖直方向上的步长),默认为1

padding:决定填充的大小,数据可以是一个int类型数据(会在左右、上下各插入几列,其中数据设置为0(根据padding_mode))也可以是一个元组(两个int类型数据,分别决定在左右、上下插入的列数),默认为0,即不进行填充

stride参数

卷积操作:

图像矩阵与卷积核矩阵对应的数字相乘,每个结果再相加,得到一个结果,卷积核移动stride

stride=1时的结果: 

 练习

import torch
import torch.nn.functional as F

# 处理的数据 Tensor类对象
input = torch.tensor([[1, 2, 0, 3, 1],
                      [0, 1, 2, 3, 1],
                      [1, 2, 1, 0, 0],
                      [5, 2, 3, 1, 1],
                      [2, 1, 0, 1, 1]])

# 卷积核
kernel = torch.tensor([[1, 2, 1],
                       [0, 1, 0],
                       [2, 1, 0]])

print(f'数据尺寸:{input.shape}')
print(f'卷积核尺寸:{kernel.shape}')

input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))

print(f'数据尺寸:{input.shape}')
print(f'卷积核尺寸:{kernel.shape}')

output = F.conv2d(input, kernel, stride=1)
print(f"stride=1时:{output}")

output = F.conv2d(input, kernel, stride=2)
print(f"stride=2时:{output}")

output = F.conv2d(input, kernel, stride=1, padding=1)
print(f"padding设置为1:{output}")

卷积层

进入PyTorch官网,打开Convolution中的conv2d,查看官方文档

参数

in_channels:输入图像时的一个通道数

out_channels:通过卷积层之后的结果的通道数

kernel_size:int or tuple,决定卷积核的大小

stride:与torch.nn.function中的卷积操作一样,决定卷积核在输入图像中水平、竖直方向上的移动的步长

padding:与torch.nn.function中的卷积操作一样,决定在输入图像的边缘进行填充

padding_mode:填充方式,默认zeros即用0填充

dilation:卷积过程中,卷积核内部的距离(空洞卷积)

groups:常设置为1

bias:偏置,常设置为True,即给卷积处理之后的结果加上一个常数

打开:torch.nn->convolution Layers->nn.Conv2d->link

卷积的可视化操作,便于对参数功能的理解

out_channels设置为2时,会生成两个卷积核,两次对输入的图像进行卷积操作,并将得到的结果输出,如

练习:卷积处理数据并写入日志文件中

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10('../CIFAR10',
                                       train=False,
                                       transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=64)

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv2d = Conv2d(in_channels=3, out_channels=6, kernel_size=3, padding=0, stride=1)

    def forward(self, x):
        x = self.conv2d(x)
        return x

obj = NetWork()
print(obj)

writer = SummaryWriter('../logs')
step = 0
for data in dataloader:
    image, target = data
    output = obj(image)
    print(f"卷积层处理前尺寸:{image.shape};卷积层处理后尺寸:{output.shape}")
    writer.add_images("input", image, step)
    writer.add_images("output", output, step)
    step += 1

运行会发现程序报错,原因为通道数的变化

可使用torch中的reshape方法,进行变化

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10('../CIFAR10',
                                       train=False,
                                       transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=64)

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv2d = Conv2d(in_channels=3, out_channels=6, kernel_size=3, padding=0, stride=1)

    def forward(self, x):
        x = self.conv2d(x)
        return x

obj = NetWork()
print(obj)

writer = SummaryWriter('../logs')
step = 0
for data in dataloader:
    image, target = data
    output = obj(image)
    print(f"卷积层处理前尺寸:{image.shape};卷积层处理后尺寸:{output.shape}")
    writer.add_images("input", image, step)
    output = torch.reshape(output, (-1, 3, 30, 30))
    writer.add_images("output", output, step)
    step += 1
writer.close()

打开日志文件

池化层

打开PyTorch官网,进入池化层(pooling Layers)官方文档,进入MaxPool2d(下采样)

 参数

kernel_size:设置一个窗口的大小,这个窗口用来去取最大值,与卷积层的kernel_size参数类似

stride:与卷积层的stride类似,决定水平、竖直方向上的步长,默认值为kernel_size

最大池化操作

取每次窗口中最大的一个数字

当窗口移动到某个位置,并且该位置已不足kernel_size个数,如何取舍要看cell_mode参数

cell_mode为True时,继续对不足kernel_size个数字进行最大池化操作;为False则舍弃

练习

import torch
import torchvision
from torch import nn
from torch.nn import MaxPool2d

input = torch.tensor([[1, 2, 0, 3, 1],
                      [0, 1, 2, 3, 1],
                      [1, 2, 1, 0, 0],
                      [5, 2, 3, 1, 1],
                      [2, 1, 0, 1, 1]])
print(f"数据尺寸:{input.shape}")
input = torch.reshape(input, (-1, 1, 5, 5))
print(f"数据尺寸:{input.shape}")

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.maxpool2d = MaxPool2d(kernel_size=3, ceil_mode=True)

    def forward(self, x):
        x = self.maxpool2d(x)
        return x

obj = NetWork()
output = obj(input)
print(output)

运行会发现报错

将input中的数据变为浮点数,即:

input = torch.tensor([[1, 2, 0, 3, 1],
                      [0, 1, 2, 3, 1],
                      [1, 2, 1, 0, 0],
                      [5, 2, 3, 1, 1],
                      [2, 1, 0, 1, 1]], dtype=torch.float32)

MaxPool2d中ceil_mode参数设置为False,其他代码不变,输出结果为:

作用

最大池化的目的是保留输入图像的特征,同时把数据量减小

练习:使用最大池化并将处理前后的数据写入日志文件

import torch
import torchvision
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10(root="../CIFAR10",
                                       train=False,
                                       transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=64)
class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.maxpool2d = MaxPool2d(kernel_size=3, ceil_mode=False)

    def forward(self, x):
        x = self.maxpool2d(x)
        return x

obj = NetWork()
writer = SummaryWriter('../logs2')
step = 0
for data in dataloader:
    image, target = data
    output = obj(image)
    writer.add_images("input", image, step)
    writer.add_images("output", output, step)
    step += 1
writer.close()

打开日志文件

隐约可以看出图片的特征

非线性激活

打开PyTorch官网,发现两种非线性激活

非线性激活的作用是给我们的神经网络引入一些非线性的特质,其中比较常见的为ReLU

ReLU

参数

inplace:为True时,直接把结果覆盖掉原有的值(如input=-1,经过ReLU层后,input=0)

为False时,会将结果返回出来,不会覆盖输入的原有的值(input=-1,经过ReLU层后,input=-1,返回给output一个0的值)

常设置为False,保留原始数据,防止数据丢失

练习

import torch
from torch import nn
from torch.nn import ReLU

input = torch.tensor([[1, -0.5],
                      [-1, 3]])
input = torch.reshape(input, (-1, 1, 2, 2))

print(input)

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.ReLU = ReLU(inplace=False)

    def forward(self, x):
        x = self.ReLU(x)
        return x

obj = NetWork()
output = obj(input)
print(output)

Sigmoid

参数

练习:经过Sigmoid层并写入日志文件

import torch
import torchvision
from torch import nn
from torch.nn import ReLU, Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

input = torch.tensor([[1, -0.5],
                      [-1, 3]])
input = torch.reshape(input, (-1, 1, 2, 2))

dataset = torchvision.datasets.CIFAR10(root="../CIFAR10",
                                       train=False,
                                       download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)


class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.ReLU = ReLU(inplace=False)
        self.sigmoid = Sigmoid()

    def forward(self, x):
        x = self.sigmoid(x)
        return x

obj = NetWork()
step = 0
writer = SummaryWriter('logs3')
for data in dataloader:
    image, target = data
    writer.add_images("input", image, step)
    output = obj(image)
    writer.add_images("output", output, step)
    step += 1
writer.close()

线性层及其它层介绍

正则化层:Normlization Layers

对我们输入的数据进行一个正则化处理,加快神经网络的训练速度

BATCHNORM2D

参数主要设置num_features(其中C代表channels,即通道数),其他参数默认值即可

循环层:Recurrent Layers

主要应用于文字识别等

Transformer层:Transformer Layers

Transformer Layers是一种基于自注意力机制的深度学习框架。与传统的循环层不同,Transformer完全摒弃了递归结构,通过 注意力机制并行处理序列数据,显著提升了长序列建模能力和训练速率。

核心特点

(1)自注意力机制:允许模型同时关注序列中所有位置的信息,捕捉长距离依赖关系。

(2)并行计算:所有位置的输出可以并行计算,无需像 RNN 那样按顺序处理,大幅提高训练速度。

(3)多头注意力:将输入分割成多个头(head),每个头独立计算注意力,增强模型表达能力。

(4)位置编码:通过添加位置信息(如正弦 / 余弦函数),弥补缺失的序列顺序信息。

结构

标准的Transformer结构:一个完整的Transformer由Encoder(编码器)和Decoder(解码器)组成

编码器层

(1)多头自注意力机制:处理输入序列。

(2)残差连接:

(3)前馈神经网络:两个线性变换(ReLU 激活)。

(4)残差连接:

解码器层掩码

(1)多头自注意力:防止关注未来位置(仅在训练时使用)。(2)编码器 - 解码器注意力:关注编码器的输出。

(3)前馈神经网络:同编码器。

线性层:Liner Layers

线性连接示例图

参数有weight权重和偏置

如上图,每个Layers层间每两个之间的连线都为一个线性关系(weight*xn + bias)

weight和bias的取值:

练习

flatten介绍

可将DataLoader打包好的一组数据摊平,摆放成一列,大致如Example

reshape的功能更强大,可以指定变换之后的尺寸,flatten只能把数据变为一行

import torch
import torchvision
from torch import nn
from torch.nn import ReLU, Sigmoid, Linear
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

input = torch.tensor([[1, -0.5],
                      [-1, 3]])
input = torch.reshape(input, (-1, 1, 2, 2))

dataset = torchvision.datasets.CIFAR10(root="../CIFAR10",
                                       train=False,
                                       download=True,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.liner = Linear(in_features=196608, out_features=10)

    def forward(self, x):
        x = self.liner(x)
        return x

obj = NetWork()

for data in dataloader:
    image, target = data
    # 尺寸变化[64, 3, 32, 32] -> [1, 1, 1, 196608] -> [1, 1, 1, 10]
    print("=====================")
    print(image.shape)
    input = torch.flatten(image)  # 替换掉input = torch.reshape(image, (1, 1, 1, -1))
    print(input.shape)
    output = obj(input)
    print(output.shape)

随机失活层:Dropout Layers

功能:经过该处理层时,会对输入的Tensor数据类型数据中的一些元素变为0(失活),随机失活的概率为p(如图)

稀疏层:Sparse Layers

用于自然语言处理

距离函数:Distance Function

计算两个值之间的误差

损失函数:Loss Function

得到一个Loss,Loss(越小越好)是用来衡量神经网络中的输出和我们真实想要的一个结果的中间的差距。

作用:

1、计算实际输出和目标之间的差距。

2、为我们更新输出提供一定的依据(反向传播)为神经网络中每一个卷积成的卷积核提供一个参数grad(梯度),当我们采用反向传播的时候,每一个结点(每一个要更新的参数)得到一个梯度,当我们对模型进行优化的时候,就会根据这个梯度对其中的参数进行一个优化,达到对Loss值降低的目的

1例如:

一张试卷分数分布:选择30、填空20、解答50

实际得分选择10、填空10、解答10

则Loss=(30-10)+(20-10)+(50-10)=70

通过Loss提供的的差距,使我们的神经网络模型在较弱部分进行着重训练。

2例如:梯度下降

当采用反向传播时,会得到当前所在结点的梯度(即图中的Gradient)当结点更新时,会根据这个梯度对参数进行更新,从而达到对Loss的减小

反向传播:依据链式法则,从输出层往回逐层推导,算出损失(Loss)对各层参数(如权重、偏置 )的梯度(即图中 “Gradient” ,反映参数变化对 Loss 的影响率 )


L1Loss


输入为x,target为y

比如,输入的x为1、2、3,target y为1、2、5

L1Loss = ((1-1)+(2-2)+(5-30))/3=0.6

练习
import torch
from torch.nn import L1Loss

inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
target = torch.tensor([1, 2, 5], dtype=torch.float32)

inputs = torch.reshape(inputs, (1, 1, 1, 3))
target = torch.reshape(target, (1, 1, 1, 3))

loss = L1Loss()
result = loss(inputs, target)
print(result)

MSELoss

结合上述示例,该方法的计算方式为((1-1)^2+(2-2)^2+(5-3)^2)/3=1.3

练习
import torch
from torch.nn import L1Loss, MSELoss

inputs = torch.tensor([1, 2, 3], dtype=torch.float32)
target = torch.tensor([1, 2, 5], dtype=torch.float32)

inputs = torch.reshape(inputs, (1, 1, 1, 3))
target = torch.reshape(target, (1, 1, 1, 3))

loss = L1Loss()
result = loss(inputs, target)

loss_MSE = MSELoss()
result_MSE = loss_MSE(inputs, target)
print(result_MSE)

示例:

向神经网络模型中放入一张狗的图片(输入),输出结果为三个数,分别代表预测图片为人、狗、猫的概率,target即为公式中的class,为图片的类别的索引,output即为公式中的x

代入公式,loss=-0.2+log(exp(0.1)+exp(0.2)+exp(0.3))

此处公式log为以e为底及ln

练习
import torch
from torch.nn import CrossEntropyLoss

x = torch.tensor([0.1, 0.2, 0.3])
y = torch.tensor([1])
x = torch.reshape(x, (1, 3))
loss_cross = CrossEntropyLoss()
result_cross = loss_cross(x, y)
print(result_cross)

练习:损失函数用于网络模型中

先把经过模型处理之后的数据输出,根据结果选择要使用的损失函数

print(output, target)

使用交叉熵CrossEntropyLoss

import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear, CrossEntropyLoss
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10(root="../CIFAR10",
                                       download=True,
                                       train=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=dataset, batch_size=1)

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )


    def forward(self, x):
        x = self.model1(x)
        return x
Loss_Cross = CrossEntropyLoss()
obj = NetWork()
for data in dataloader:
    image, target = data
    output = obj(image)
    result_cross = Loss_Cross(output, target)
    print(result_cross)

输出结果即为:神经网络的输出与真实输出之间 的误差

debug
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear, CrossEntropyLoss
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10(root="../CIFAR10",
                                       download=True,
                                       train=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=dataset, batch_size=1)

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )


    def forward(self, x):
        x = self.model1(x)
        return x
Loss_Cross = CrossEntropyLoss()
obj = NetWork()
for data in dataloader:
    image, target = data
    output = obj(image)
    result_cross = Loss_Cross(output, target)
    result_cross.backward() 
    print(1)

在result_cross.backward()该代码行打上断点,进入:

obj->model1->保护属性->_modules->'0'(卷积层)->weight(权重)->grad(梯度),执行result_cross.backward()前,grad为None

执行该断点所在行的代码result_cross.backward(),grad变化

若没有该代码,grad属性始终为None

优化器

对于损失函数部分,反向传播的使用,为神经网络模型提供一个grad梯度(每一个要调节的参数),因此我们可以选择相应的优化器,对神经网络模型中的参数进行优化。

打开PyTorch官网,进入官方文档,查看使用的流程

使用实例

每次要进入优化前,都要先将优化的梯度清0

特定的优化器中的lr参数(learning rate),即学习速率

练习
import torch
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear, CrossEntropyLoss
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10(root="../CIFAR10",
                                       download=True,
                                       train=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=dataset, batch_size=1)

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )


    def forward(self, x):
        x = self.model1(x)
        return x

Loss_Cross = CrossEntropyLoss()
obj = NetWork()
optim = torch.optim.SGD(params=obj.parameters(), lr=0.01)  # 优化器:随机梯度下降
for data in dataloader:
    optim.zero_grad()  # 梯度清零
    image, target = data
    output = obj(image)
    result_cross = Loss_Cross(output, target)
    result_cross.backward()  # 反向传播 提供梯度
    optim.step() # 调优

分别在optim.zero_grad()、result_cross.backward()、optim.step()加上断点进行debug,查看grad相关参数

优化器梯度清0:

反向传播:

优化:

多轮优化

对神经网络模型进行多轮优化,查看每轮的Loss之和,直观感受优化器的优化功能

import torch
import torchvision
from torch import nn
from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear, CrossEntropyLoss
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10(root="../CIFAR10",
                                       download=True,
                                       train=False,
                                       transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset=dataset, batch_size=1)

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )


    def forward(self, x):
        x = self.model1(x)
        return x

Loss_Cross = CrossEntropyLoss()
obj = NetWork()
optim = torch.optim.SGD(params=obj.parameters(), lr=0.01)  # 优化器:随机梯度下降
for epoch in range(20):
    runningLoss = 0.0
    for data in dataloader:
        optim.zero_grad()  # 梯度清零
        image, target = data
        output = obj(image)
        result_cross = Loss_Cross(output, target)
        result_cross.backward()  # 反向传播 提供梯度
        optim.step() # 调优
        runningLoss += result_cross
    print(runningLoss)

Containers——Sequential

使用sequential,使代码看起来更简洁、易懂

练习:实现一个网络模型了解sequential

第一层的卷积层padding的计算,根据下列公式

代入第一个公式,Hin(输入数据的高)为32,padding未知,dilation为1(非空洞卷积,默认值为1),kernel_size为5,stride未知,输出的高为Hout为32,即:

(32+2*padding-1*(5-1)-1)/stride=31

stride设置为1,则27+2*padding=31,padding=2

第三层的卷积层padding的计算

代入公式,Hin为16,padding未知,dilation为1,kernel_size为5,stride位置,Hout为16

(16+2*padding-1*(5-1)-1)/stride=15

stride设置为1,则11+2*padding=15,padding=2
剩下的卷积层计算以此类推...

torch中存在一些方法,可指定数据及数据的形状,便于我们验证搭建好的网络模型(如torch.ones为全是1的数据)

若对于中间处理之后的数据的部分参数不知道其大小,可暂时删去后续的处理,打印当前阶段的尺寸信息,得到相应数据

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear

dataset = torchvision

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = Conv2d(3, 32, 5, padding=2)
        self.maxpool1 = MaxPool2d(2)
        self.conv2 = Conv2d(32, 32, 5, padding=2)
        self.maxpool2 = MaxPool2d(2)
        self.conv3 = Conv2d(32, 64, 5, padding=2)
        self.maxpool3 = MaxPool2d(2)
        self.flatten = Flatten()  # 数据尺寸 1024=64*4*4

        # 经过Flatten层之后 还需经过线性层处理
        self.linear1 = Linear(1024, 64)
        self.linear2 = Linear(64, 10)


    def forward(self, x):
        x = self.conv1(x)
        x = self.maxpool1(x)
        x = self.conv2(x)
        x = self.maxpool2(x)
        x = self.conv3(x)
        x = self.maxpool3(x)
        x = self.flatten(x)
        x = self.linear1(x)
        x = self.linear2(x)
        return x

obj = NetWork()
print(obj)
input = torch.ones((64, 3, 32, 32))
output = obj(input)
print(output.shape)

sequential改写上述练习代码并写入日志文件

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter

class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )


    def forward(self, x):
        x = self.model1(x)
        return x

obj = NetWork()
print(obj)
input = torch.ones((64, 3, 32, 32))
output = obj(input)
print(output.shape)
writer = SummaryWriter("../logs4")
writer.add_graph(obj, input)
writer.close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值