土堆Pytorch学习笔记(二)

本文介绍了如何在PyTorch中构建简单的神经网络,包括使用Conv2d进行卷积操作,MaxPool2d进行池化,以及ReLU和Sigmoid作为非线性激活函数。同时,文章提到了线性层在模型中的作用,并展示了如何应用交叉熵损失函数进行反向传播训练。
摘要由CSDN通过智能技术生成

2023.04.01

class NN继承父类:在pycharm中选择code - generate - override methods(重写父类)即可自动生成。

(一)卷积层

在pytorch官网找到torch.nn , nn.Conv2d是我们常用的卷积层,点击查看他的官方案例,一般只有前五个参数需要我们手动设置

一个简单的神经网络(作用为将输入图片(三通道的RGB图片)进行卷积,其中卷积核为3 * 3,步长为1 不进行池化)

整体代码:

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

dataset = torchvision.datasets.CIFAR10('./data_Conv2d', train=False,
                                       transform=torchvision.transforms.ToTensor(),
                                       download=True)
dataloader = DataLoader(dataset, batch_size=64)
# 下面搭建简单的神经网络
class NerualNetwork(nn.Module):
    def __init__(self):
        # 先将父类初始化
        super(NerualNetwork, self).__init__()
        # 然后定义卷积层
        self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3,
                            stride=1, padding=0)
    def forward(self, x):  # x是输出
        # 先让x卷积
        x = self.conv1(x)
        return x

# 初始化网络
nerualnetwork = NerualNetwork()
# 查看网络结构
# print(nerualnetwork)

# 查看每一张图像
for data in dataloader:
    imgs, targets = data
    output = nerualnetwork(imgs)    # 将图片放入网络中处理并返回到output

(二)池化层

最大池化的作用:保留输入特征的同时减少数据量

创建神经网络 - 初始化父类 - 定义池化层 - 初始化网络 - 使用网络处理图片

具体代码:

import torchvision.datasets
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('./data_Conv2d', train=False,
                                       transform=torchvision.transforms.ToTensor()
                                       )
dataloader = DataLoader(dataset, batch_size=64)

# 创建神经网络
class NerualNetwork(nn.Module):
    def __init__(self):
        super(NerualNetwork, self).__init__()
        self.maxpool = MaxPool2d(kernel_size=3, ceil_mode=False)

    def forward(self, input):
        output = self.maxpool(input)
        return output

# 初始化网络
nerualnetwork = NerualNetwork()
writer = SummaryWriter('logs_maxpool')
step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images('input', imgs, step)
    output = nerualnetwork(imgs)
    writer.add_images('output', output, step)
    step += 1

writer.close()

结果:

 (三)非线性激活

3.1 ReLU激活函数

将输入矩阵中小于1的元素输入都置零,在图象上的效果不太直观

3.2 Sigmoid激活函数

self.sigmoid1 = Sigmoid()

整体代码:

mport 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([
    [0, 0.5],
    [-1, 3]])

input = torch.reshape(input, (-1, 1, 2, 2))
print(input.shape)

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

class NerualNetwork(nn.Module):
    def __init__(self):
        super(NerualNetwork, self).__init__()
        self.relu1 = ReLU()
        self.sigmoid1 = Sigmoid()

    def forward(self, input):
        output = self.sigmoid1(input)
        return output

nerualnetwork = NerualNetwork()
# output = nerualnetwork(input)
# print(output)
'''
relu作用:将小于1的输入都置零,在图象上的效果不太直观,以下换一种非线性激活:Sigmoid来说明
'''
writer = SummaryWriter('logs_sigmoid')
step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images('input', imgs, step)
    output = nerualnetwork(imgs)
    writer.add_images('output', output,step)
    step += 1

writer.close()

结果

 (四)线性层

 线性层的作用就是把倒数第二步 64*4*4shape的图片通过 Flatten 后变成 1024 shape的图片 进行映射 将1024映射(或者叫分类?)成64幅图,再将64幅图映射到10幅图。

(五)上图的整体代码为:

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


class NerualNetwork(nn.Module):
    def __init__(self):
        super(NerualNetwork, self).__init__()
        # self.conv1 = Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2)
        # self.maxpool1 = MaxPool2d(kernel_size=2)
        # self.conv2 = Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2)
        # self.maxpool2 = MaxPool2d(kernel_size=2)
        # self.conv3 = Conv2d(32, 64, 5, padding=2)
        # self.maxpool3 = MaxPool2d(2)
        # self.flatten = Flatten()
        # self.linear1 = Linear(1024, 64)
        # self.linear2 = Linear(64, 10)
# 使用 Sequential 来简化代码(注释掉的为复杂版
        self.model1 = nn.Sequential(
            Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            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)
# 简单版调用:
        x = self.model1(x)
        return x
writer = SummaryWriter('logs_Seq')

nerualnetwork = NerualNetwork()
print(nerualnetwork)

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

writer.add_graph(nerualnetwork, input,)
writer.close()

结果为

双击可以查看详细的网络信息

 (六)交叉熵损失函数

loss = nn.CrossEntropyLoss()

 使用交叉熵损失函数时需要使用反向传播:

output = nerualnetwork(imgs)
# 计算交叉熵损失函数
result_loss = loss(output, targets)
# 梯度下降(反向传播
result_loss.backward()

反向传播得到每个参数更新对应的梯度,后面调用优化器时,参数会根据其梯度进行优化,另外每一次循环后梯度应该清零。

这样网络会自动计算出偏置(梯度?grad),以便于实现梯度下降(损失函数最小化?)

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

dataset = torchvision.datasets.CIFAR10('./new_dataset',train=False, transform=torchvision.transforms.ToTensor(), download=True)

dataloader = DataLoader(dataset, batch_size=1)

class NerualNetwork(nn.Module):
    def __init__(self):
        super(NerualNetwork, self).__init__()
        self.model1 = nn.Sequential(
            Conv2d(in_channels=3, out_channels=32, kernel_size=5, padding=2),
            MaxPool2d(kernel_size=2),
            Conv2d(in_channels=32, out_channels=32, kernel_size=5, padding=2),
            MaxPool2d(kernel_size=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 = nn.CrossEntropyLoss()
nerualnetwork = NerualNetwork()

for data in dataloader:
    imgs, targets = data
    output = nerualnetwork(imgs)
    # 计算交叉熵损失函数
    result_loss = loss(output, targets)
    # 梯度下降(反向传播
    result_loss.backward()
    print('ok')   # 用于debug

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值