2_pytorch神经网络搭建

 接下来,我们将正式进入神经网络的搭建环节。首先介绍的是roech中用于神经网络搭建的函数。

nn.Module的使用

官方网址:Module — PyTorch 2.4 documentation

 上示例:

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

'''我们的模型类必须继承nn.Module'''
class Model(nn.Module):
'''
    我们可以自行修改其中的部分,来创建我们自己的神经网络
    一般来说,我们定义的模型类主要就是重写以下的两个函数
'''
    def __init__(self):
        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))

 我们来仔细讲解一下上述代码中的forward()这个函数。这部分不懂的建议先去学习以下深度学习的理论知识。

在__init__()函数中,我们定义了两个参数,分别是self.conv1和self.conv2,这两个实际上是定义了两个卷积层,它们被用在forward()函数中,F.relu()其实是激活函数,如果看过深度学习的相关书籍,那么这个你应该认识,它的函数图像是这个样子的:

相当于,它对我们的卷积结果进行了一次非线性运算。所以实际上这个forward()函数所做的事情如下:

上面的例子是官网上的,接下来我自己定义一个简单的神经网络看一下:

from torch import nn
import torch
class mynn(nn.Module):
    def __init__(self) :
        super().__init__()
    #这个网络简单的实现将数据+1的操作
    def forward(self,input):
        return input+1
    
mynn1=mynn()
x=torch.tensor(1.0)
output=mynn1(x)
print(output)

输出结果:

tensor(2.)

卷积层(Convolution)

上面的小例子我们简单地使用了卷积。这里将再详细讲一下卷积层。

强烈建议直接去看视频土堆说卷积操作(可选看)_哔哩哔哩_bilibili

 这里只记录一下关键点,用作备忘录

网址:torch.nn.functional.conv2d — PyTorch 2.4 documentation

 打开网址可以看到:

 其实差别就是1维数据、2维数据、3维数据,用法大差不差,卷积层多用于处理图像,因此我们以二维来讲解。

它的一些参数:

  •  input:输入,输入包括四个参数,batch_size,channels(通道数),H高,W宽。详细来说:batch_size:表示一次传入网络的样本数目,即批量大小(batch size)。它决定了在每次训练迭代中,神经网络同时处理的样本数量。in_channels 输入数据的通道数,例如 RGB 图像的通道数为 3。
  • weigt:卷积核或权重
  • bias:偏置项
  • stride:步长,经过每一步计算后,卷积核移动多少距离
  • padding:填充输入边界,默认没有填充

 小例子:

from torch import nn
import torch
import torch.nn.functional as F
class mynn(nn.Module):
    def __init__(self) :
        super().__init__()
    
    def forward(self,input):
        return input+1
    

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]])

#以上定义的数据不符合卷积层输入的要求,使用reshape调整尺寸
input=torch.reshape(input,(1,1,5,5))
kernel=torch.reshape(kernel,(1,1,3,3))

result=F.conv2d(input=input,weight=kernel,stride=1)
print(result)

result=F.conv2d(input=input,weight=kernel,stride=2)
print(result)
'''
输出结果:
tensor([[[[10, 12, 12],
          [18, 16, 16],
          [13,  9,  3]]]])
tensor([[[[10, 12],
          [13,  3]]]])
'''

池化层(Pooling)

与卷积层一样,这一部分也涉及基础理论知识,建议看视频学。放一些学习笔记在这里。

官网:torch.nn — PyTorch 2.4 documentation

 最重要的是上图中画线的方法,也是我们常说的下采样(最大池化)。

 没有默认值的参数只有kernel_size(池化核)。

这里单独提一下参数dilation,它用于实现空洞卷积。

池化层的作用是减少特征数量,从而防止过拟合。来看一个最大池化的例子,理解一下什么是池化层。

假设这里是下采样,池化核为3*3大小的窗口(kernel_size=3,而如果不设置stride参数,那么默认stride=kernel_size),池化核就像卷积核一样在输入数据上不停移动,每次筛出池化核圈住的最大值(下采样,最大池化)。如果被圈住的数据不足,那么就看ceil_mode参数设置的是什么了,如果为True,则保留,即取不足的数中的最大值;反之,则舍弃。

从这个过程应该不难看出,下采样的池化核是没有值的。

接下来是代码部分:

首先,老师的视频应该是几年前做的,现在对于池化层,输入有两种方式,这点要注意:

from torch import nn
import torch
#建立神经网络
class mynn(nn.Module):
    def __init__(self) :
        super().__init__()
        self.maxPool1=nn.MaxPool2d(kernel_size=3,ceil_mode=True)
    
    def forward(self,input):
        return self.maxPool1(input)
    
#池化层的输入必须是float32,因此可以在定义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]],dtype=torch.float32)



#以上定义的数据不符合池化层输入的要求,使用reshape调整尺寸
input=torch.reshape(input,(1,1,5,5))
MyNn=mynn()
output=MyNn(input)
print(output)


运行结果:

tensor([[[[2., 3.],
          [5., 1.]]]])

如果把参数ceil_mode设置为False,那么结果就不同了:

tensor([[[[2.]]]])

我们也可以拿之前使用的图像数据集来查看一下下采样效果:

from torch import nn
import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10("../dataset",train=False,download=True,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset,batch_size=64)
#建立神经网络
class mynn(nn.Module):
    def __init__(self) :
        super().__init__()
        self.maxPool1=nn.MaxPool2d(kernel_size=3,ceil_mode=False)
    
    def forward(self,input):
        return self.maxPool1(input)
    

writer=SummaryWriter('Logs')
step=0
mynn1=mynn()
for data in dataloader:
    imgs,targets=data
    writer.add_images('input',imgs,step)
    output=mynn1(imgs)
    writer.add_images('output',output,step)
    step=step+1

writer.close()

使用tensorboard打开:

 填充层(Padding)

这个比较少用。

Padding Layers(填充层)主要用于在图像处理或序列处理中调整输入的尺寸,以便与期望的输入尺寸或模型结构匹配。

  1. 保持特征图尺寸

    • 当应用卷积操作时,特征图的尺寸通常会缩小(根据卷积核的大小和步幅)。如果需要在不改变特征图深度的情况下保持特征图的尺寸,就可以使用Padding Layer在特征图的边缘填充额外的值(通常是0),以扩展特征图的尺寸。
  2. 处理边界效应

    • 在卷积神经网络中,卷积操作会在输入的边缘上产生边界效应,这可能导致输出特征图尺寸减小。通过在输入的边缘填充,可以减少或消除这种边界效应,确保输出特征图的尺寸与预期的一致性。
  3. 处理变长序列

    • 在处理文本等变长序列时,可以使用填充层将序列扩展到统一的长度,以便进行批处理操作。这种填充通常使用特殊的值(如0)填充序列的末尾,这样可以告知模型忽略填充部分。

 非线性激活 

网址:torch.nn — PyTorch 2.4 documentation

 之前稍微提到过的ReLU函数就属于这里。

 另外一个比较常用的是Sigmoid函数:Sigmoid — PyTorch 2.4 documentation

 

from torch import nn
import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10("../dataset",train=False,download=True,transform=torchvision.transforms.ToTensor())
dataloader=DataLoader(dataset,batch_size=64)
#建立神经网络
class mynn(nn.Module):
    def __init__(self) :
        super().__init__()
        self.relu1=nn.ReLU()
        self.sigmoid1=nn.Sigmoid()
    
    def forward(self,input):
        output=self.sigmoid1(input)
        return output
    


writer=SummaryWriter('Logs')
step=0
mynn1=mynn()
for data in dataloader:
    imgs,targets=data
    writer.add_images('input',imgs,step)
    output=mynn1(imgs)
    writer.add_images('output',output,step)
    step=step+1

writer.close()


同样,在tensorboard中打开看:

  • 28
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您介绍一下使用 PyTorch 搭建神经网络的基本步骤。 1.导入 PyTorch 库和其他必要的库 ```python import torch import torch.nn as nn import torch.optim as optim ``` 2.定义神经网络模型 ```python class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.fc1 = nn.Linear(10, 5) self.fc2 = nn.Linear(5, 2) def forward(self, x): x = torch.relu(self.fc1(x)) x = self.fc2(x) return x ``` 在这个例子中,我们定义了一个两层的全连接网络,输入层大小为 10,隐藏层大小为 5,输出层大小为 2。 3.定义损失函数和优化器 ```python criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.1) ``` 这里我们选择了交叉熵损失函数和随机梯度下降优化器。 4.训练模型 ```python for epoch in range(100): running_loss = 0.0 for i, data in enumerate(trainloader, 0): inputs, labels = data optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() print('Epoch %d loss: %.3f' % (epoch + 1, running_loss / len(trainloader))) ``` 这里我们使用了一个简单的训练循环,每个 epoch 中遍历训练集并计算损失和梯度,然后使用优化器更新模型参数。在训练过程中,我们还可以使用验证集来评估模型的性能。 5.测试模型 ```python correct = 0 total = 0 with torch.no_grad(): for data in testloader: inputs, labels = data outputs = net(inputs) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy on test set: %d %%' % (100 * correct / total)) ``` 这里我们使用测试集来评估模型的准确率。 这是一个简单的 PyTorch 神经网络搭建过程的例子。在实际应用中,我们还需要考虑数据预处理、模型调参等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值