神经网络工具nn

实现神经网络

torch 将张量转换为torch.cuda.TensorFloat并在GPU上进行计算
torch.autograd 构建计算图并自动获取梯度
torch.nn 具有共享层和损失函数的神经网络库
torch.optim 通用优化算法

神经网络基本结构
网络层:神经网络的基本模型
网络模型:层构成的网络
损失函数:参数学习的目标函数,通过最小化损失函数来更新参数
优化器:使损失函数最小

torch.nn模块

1. 构建网络模型

通过nn.Modulenn.functional构建网络层,前者继承自Module类,包含各网络层的定义及forward方法,会自动提取可学习参数,只要实现了forward函数,backward函数就会利用autograd自动实现

  1. nn.Xxx继承自nn.Module,需先实例化并传入参数,能很好的与nn.Sequential结合,而nn.functional.xxx无法与之结合使用
  2. nn.Xxx不需要自己定义和管理weightbias参数,而nn.functional.xxx需要自己定义,且每次调用时都需要手动传入,不利于代码复用
  3. Dropout操作在训练和测试阶段是有区别的,使用nn.Xxx定义Dropout,在调用model.eval()时,自动实现状态转换,而nn.functional.xxx无此功能

一般,卷积层,全连接层,Dropout层含有可学习参数的一般使用nn.Module,激活函数,池化层不含可学习参数的使用nn.functional

nn.Sequential()构建网络模型,若要对每层进行命名,采用nn.Sequential组合网络层,通过add_module()添加每一层,并给每一层进行命名

class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv= torch.nn.Sequential(
            OrderedDict([
                ("conv1", torch.nn.Conv2d(3, 32, 3, 1, 1)),
                ("relu1", torch.nn.ReLU()),
                ("pool", torch.nn.MaxPool2d(2)),
            ])
        )
        self.dense= torch.nn.Sequential(
            OrderedDict([
                ("dense1", torch.nn.Linear(32*3*3, 128)),
                ("relu2", torch.nn.ReLU()),
                ("dense2", torch.nn.Linear(128, 10)),
            ])
        )

2. 前向传播

forward()函数将输入层,网络层,输出层连接,实现数据的前向传导

3. 反向传播

loss.backward()利用复合函数的链式法则

4. 训练模型

训练阶段,需使模型处于训练模式,model.train()会将所有的module设置为训练模式

测试阶段,model.eval()会将所有的training属性设置为False

缺省情况下梯度累加,需用optimizer.zero_grad()手工将梯度初始化或清零

计算损失值,再调用loss.backward()自动生成梯度,再使用optimizer.step()执行优化器,将梯度反向传播

用GPU训练,需将模型,训练数据,测试数据to(device),若要用多GPU,需要用模型和数据引用nn.DataParallel

网络的可学习参数可通过net.parameters()返回,net.named_parameters()可同时返回可学习参数及名称,

forward()的输入输出都是Variable,只有Variable有自动求导能力,Tensor是没有的

net.zero_grad()清空梯度

torch.nn只支持mini_batches,一次输入一个batch,可用 input.unsqueeze(0)将batch_size设置为1

torch.nn实现了大多数的损失函数,如nn.MSELoss均方误差,nn.CrossEntropyLoss交叉熵损失

构建神经网络

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
class Net(nn.Module):
    def __init__(self) -> None:
        super(Net,self).__init__()
        # 卷积层1 表示输入图像为单通道,6表示输出通道数
        # 表示卷积核为 5*5
        self.conv1= nn.Conv2d(1, 6, 5)
        self.conv2= nn.Conv2d(6, 16, 5)
        # 仿射层/全连接层,y= wx+ b
        self.fc1= nn.Linear(16*5*5, 120)
        self.fc2= nn.Linear(120, 84)
        self.fc3= nn.Linear(84, 10)
    def forward(self, x):
        # 卷积-> 激活-> 池化
        x= F.max_pool2d(F.relu(self.conv1(x)), (2,2))
        x= F.max_pool2d(F.relu(self.conv2(x)), 2)
        # reshape -1表示自适应
        x= x.view(x.size()[0], -1)
        x= F.relu(self.fc1(x))
        x= F.relu(self.fc2(x))
        x= self.fc3(x)
        return x

net= Net()
print(net)

for name,parameters in net.named_parameters():
    print(name,":",parameters.size())

input= Variable(torch.randn(1,1,32,32))
output= net(input)
print(output.size())
net.zero_grad()
output.backward(Variable(torch.ones(1,10)))

target= Variable(torch.arange(0,10))
criterion= nn.MSELoss()
loss= criterion(output, target)
print(net.conv1.bias.grad)

learning_rate= 0.01
for f in net.parameters():
    f.data.sub_(f.grad.data* learning_rate)
posted @ 2024-11-02 18:28  sgqmax  阅读(11)  评论(0编辑  收藏  举报