首页 > 其他分享 >从零开始学神经网络 2

从零开始学神经网络 2

时间:2023-01-09 12:34:26浏览次数:38  
标签:loss nn grad torch 神经网络 从零开始 Variable data

大家好,我是gdut本科生一枚,本文是我的学习笔记,内容来自目前正在学习的神经网络课程,内容部分来自csdn博客,视频来源于b站,如有侵权请联系我删除,谢谢。内容写的一般,希望这个博客能帮助大家学到东西,共同进步。本文的主要内容:torch.nn实战;pytorch搭建神经网络;各种搭建神经网络方式的代码。

神经网络实战

一、PyTorch 之 torch.nn

1、torch.nn.Sequential

torch.nn.Sequential类是torch.nn中的一种序列容器,通过在容器中嵌套各种实现神经网络模型的搭建,最主要的是,参数会按照我们定义好的序列自动传递下去。

models = torch.nn.Sequential(
torch.nn.Linear(input_data,hidden_layer),
torch.nn.ReLU(),
torch.nn.Linear(hidden_layer,output_data)
)

 

2、torch.nn.Linear

torch.nn.Linear类用于定义模型的线性层,即完成前面提到的不同的层之间的线性变换。 线性层接受的参数有3个:分别是输入特征数、输出特征数、是否使用偏置,默认为True,使用torch.nn.Linear类,会自动生成对应维度的权重参数和偏置,对于生成的权重参数和偏置,我们的模型默认使用一种比之前的简单随机方式更好的参数初始化方式。

3、torch.nn.ReLU

torch.nn.ReLU属于非线性激活分类,在定义时默认不需要传入参数。当然,在torch.nn包中还有许多非线性激活函数类可供选择,比如PReLU、LeaKyReLU、Tanh、Sigmoid、Softmax等。

4、torch.nn.MSELoss

torch.nn.MSELoss类使用均方误差函数对损失值进行计算,定义类的对象时不用传入任何参数,但在使用实例时需要输入两个维度一样的参数方可进行计算。

x = Variable(torch.randn(100,100))
y = Variable(torch.randn(100,100))
loss = loss_f(x,y)
loss.data

 

5、torch.nn.L1Loss

torch.nn.L1Loss类使用平均绝对误差函数对损失值进行计算,定义类的对象时不用传入任何参数,但在使用实例时需要输入两个维度一样的参数方可进行计算。

6、torch.nn.CrossEntropyLoss

torch.nn.CrossEntropyLoss类用于计算交叉熵,定义类的对象时不用传入任何参数,但在使用实例时需要输入两个满足交叉熵的计算条件的参数。

二、代码

1、实现一个完整的神经网络

import torch
from torch.autograd import Variable

batch_n = 100 # 一个批次输入数据的数量
hidden_layer = 100 # 隐藏层神经元的个数
input_data = 1000 # 输入层的神经元个数
output_data = 10 # 输出的个数

x = Variable(torch.randn(batch_n, input_data), requires_grad=False)
y = Variable(torch.randn(batch_n, output_data), requires_grad=False)
# 用Variable对tensor数据进行封装,并判断是否需要在计算过程中保留梯度

w1 = Variable(torch.randn(input_data, hidden_layer), requires_grad=True)
w2 = Variable(torch.randn(hidden_layer, output_data), requires_grad=True)
# 用Variable对tensor数据进行封装,并判断是否需要在计算过程中保留梯度,由于权重是我们最后需要的,故必须保留

epoch_n = 10000 # 迭代次数
learn_rate = 1e-6 # 学习率,学习步长

# 这是一个两层的神经网络
for epoch in range(epoch_n):

h1 = x.mm(w1) # 输入层输入后叉乘权重
h1 = h1.clamp(min=0) # 经过激活函数后成为第一层的输出,第二层的输入
h2 = h1.mm(w2) # 第二层输入后叉乘权重后输出
loss = (h2 - y).pow(2).sum() # 定义损失函数
print("epoch:{},loss:{:.4f}".format(epoch,loss.data)) # 输出过程

loss.backward() # 损失反向传播
w1.data -= learn_rate*w1.grad.data # 更新参数值
w2.data -= learn_rate*w2.grad.data # 更新参数值

w1.grad.data.zero_() # 清空梯度值,用于下次更新
w2.grad.data.zero_() # 清空梯度值,用于下次更新

 

2、除了使用自动梯度的方法,还可使用torch.nn.Module类来完成这个任务

import torch
from torch.autograd import Variable

batch_n = 50 # 一个批次输入数据的数量
hidden_layer = 100 # 隐藏层神经元的个数
input_data = 1000 # 输入层的神经元个数
output_data = 10 # 输出的个数

class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()

def forward(self, inp, w1, w2):
x = torch.mm(inp, w1)
x = torch.clamp(x, min=0)
x = torch.mm(x, w2)
return x

def backward(self):
pass


model = Model()
x = Variable(torch.randn(batch_n,input_data),requires_grad=False)
y = Variable(torch.randn(batch_n,output_data),requires_grad=False)
w1 = Variable(torch.randn(input_data,hidden_layer),requires_grad=True)
w2 = Variable(torch.randn(hidden_layer,output_data),requires_grad=True)

epoch_n = 30
lr = 1e-6
for epoch in range(epoch_n):
y_p = model.forward(x, w1, w2)
loss = (y_p - y).pow(2).sum()
print("epoch:{},loss:{:.4f}".format(epoch, loss.data))
loss.backward()
w1.data -= lr*w1.grad.data
w2.data -= lr*w2.grad.data
w1.grad.data.zero_()
w2.grad.data.zero_()

 

3、使用torch.optim的神经网络

import torch
from torch.autograd import Variable

batch_n = 100 # 一个批次输入数据的数量
hidden_layer = 100
input_data = 1000 # 每个数据的特征为1000
output_data = 10

x = Variable(torch.randn(batch_n, input_data), requires_grad=False)
y = Variable(torch.randn(batch_n, output_data), requires_grad=False)
# 用Variable对Tensor数据类型变量进行封装的操作。requires_grad如果是F,表示该变量在进行自动梯度计算的过程中不会保留梯度值。

models = torch.nn.Sequential(
torch.nn.Linear(input_data, hidden_layer),
torch.nn.ReLU(),
torch.nn.Linear(hidden_layer, output_data)
)
# torch.nn.Sequential括号内就是我们搭建的神经网络模型的具体结构,Linear完成从隐藏层到输出层的线性变换,再用ReLU激活函数激活
# torch.nn.Sequential类是torch.nn中的一种序列容器,通过在容器中嵌套各种实现神经网络模型的搭建,
# 最主要的是,参数会按照我们定义好的序列自动传递下去。

epoch_n = 10000
lr = 1e-4
loss_fn = torch.nn.MSELoss()

optimzer = torch.optim.Adam(models.parameters(), lr=lr)
# 使用torch.optim.Adam类作为我们模型参数的优化函数,这里输入的是:被优化的参数和学习率的初始值。
# 因为我们需要优化的是模型中的全部参数,所以传递的参数是models.parameters()

# 进行,模型训练的代码如下:
for epoch in range(epoch_n):

y_pred = models(x)

loss = loss_fn(y_pred, y)
print("Epoch:{},Loss:{:.4f}".format(epoch, loss.data))
optimzer.zero_grad() # 将模型参数的梯度归0

loss.backward()
optimzer.step() # 使用计算得到的梯度值对各个节点的参数进行梯度更新

 

5、使用损失函数的神经网络

import torch
from torch.autograd import Variable

x = Variable(torch.randn(100, 100))
y = Variable(torch.randn(100, 100))

batch_n = 100 # 一个批次输入数据的数量
hidden_layer = 100
input_data = 1000 # 每个数据的特征为1000
output_data = 10

x = Variable(torch.randn(batch_n, input_data), requires_grad=False)
y = Variable(torch.randn(batch_n, output_data), requires_grad=False)
# 用Variable对Tensor数据类型变量进行封装的操作。requires_grad如果是F,表示该变量在进行自动梯度计算的过程中不会保留梯度值。

models = torch.nn.Sequential(
torch.nn.Linear(input_data, hidden_layer),
torch.nn.ReLU(),
torch.nn.Linear(hidden_layer, output_data)
)
# torch.nn.Sequential括号内就是我们搭建的神经网络模型的具体结构,Linear完成从隐藏层到输出层的线性变换,再用ReLU激活函数激活
# torch.nn.Sequential类是torch.nn中的一种序列容器,通过在容器中嵌套各种实现神经网络模型的搭建,
# 最主要的是,参数会按照我们定义好的序列自动传递下去。

epoch_n = 10000
lr = 1e-6
optimzer = torch.optim.Adam(models.parameters(), lr=lr)

for epoch in range(epoch_n):

y_pre = models(x)

# loss = (y_pre-y).pow(2).sum()
loss_fn = torch.nn.L1Loss()

loss = loss_fn(y_pre, y)
print("epoch:{},loss:{:.4f}".format(epoch, loss.data))
models.zero_grad()

optimzer.zero_grad() # 将模型参数的梯度归0
loss.backward()
optimzer.step() # 使用计算得到的梯度值对各个节点的参数进行梯度更新

 

标签:loss,nn,grad,torch,神经网络,从零开始,Variable,data
From: https://www.cnblogs.com/godxumyblog/p/17036662.html

相关文章