运行神经网络与计算损失
接着上次的笔记接着写,网络定义请见上一篇博文。
这里我用一个随机生成的结果当做是真实值,用于和网络输出的预测值进行计算损失值。只为了说明整个神经网络的训练过程,特别是训练中的损失计算是怎么回事。对于有tf经验的同学来说也没什么好介绍的,记住那几个pytorch的类和方法名称即可。
步骤描述请见注释。
import torch
from torch import nn
from Blog1.build_artificial_neural_network import HappyBKsNet
import torch.optim as optim
if __name__ == "__main__":
happyBKsNet = HappyBKsNet()
if not isinstance(happyBKsNet, torch.nn.Module):
raise Exception()
# 生成随机输入
input_data = torch.randn(1, 1, 32, 32)
# 第一个参数1是minibatch,用于迭代输入指定每次输入的个数
print("input_data:", input_data)
print("input_data.size():", input_data.size())
# 运行神经网络
# 神经网网络输入input_data,然后计算输出
out = happyBKsNet(input_data)
print("out:", out)
print("out.size():", out.size())
# 随机造一个数据,假装是真实值。这里算老夫偷懒,读者自行脑补。
target = torch.randn(2)
target = target.view(1, -1)
print("target:", target)
# 定义损失函数
criterion = nn.L1Loss()
# 计算损失
loss = criterion(out, target)
print("loss:", loss)
# 自己计算一下out和target张量的损失误差,即各维度值的差值的均值。(如果你选的不是L1Loss,那会是其他计算方法)
print(torch.mean(torch.Tensor([(out_value - target_value) for out_value, target_value in zip(out[0], target[0])])))
# 反向传递
# step 1 清除梯度
happyBKsNet.zero_grad() # 反向传递的第一步,要把之前所有梯度都清零
# step 2 自动计算梯度、反向传递
loss.backward()
# 更新权重
# 需要定义一个optimizer,它是权重更新的规则。torch.optim为我们提供了SGD等多种优化器optimizer。
# 我们这里选择SGD优化器,即选定了一种parameters的更新规则
# 更新happyBKsNet中所有的参数parameters,学习速率定义为0.01
optimizer = optim.SGD(happyBKsNet.parameters(), lr=0.01)
optimizer.step()
print("- * - " * 20)
out = happyBKsNet(input_data)
print("out:", out)
print("out.size():", out.size())
# 再次计算损失
loss = criterion(out, target)
print("2th loss:", loss)
输出结果:(本文出自oschina博主happBKs的博文: https://my.oschina.net/happyBKs/blog/3213210 )
input_data: tensor([[[[-0.4273, -1.6075, 2.4832, ..., 0.4475, -2.4186, -0.4658],
[ 3.1069, 0.8172, -0.3205, ..., -2.5557, -2.5024, -0.6236],
[ 1.9379, 0.9700, -0.4495, ..., 0.8723, 0.6513, 0.3023],
...,
[ 0.5625, 1.8791, 0.5486, ..., -1.5633, 0.0362, -1.6457],
[ 1.6296, 1.5020, 0.2229, ..., -1.0967, -0.1033, -1.9203],
[ 0.5569, -0.9142, -1.0734, ..., 0.6477, 0.1006, -0.5091]]]])
input_data.size(): torch.Size([1, 1, 32, 32])
out: tensor([[ 0.0345, -0.0623]], grad_fn=<AddmmBackward>)
out.size(): torch.Size([1, 2])
target: tensor([[-1.3507, -0.8200]])
loss: tensor(1.0714, grad_fn=<L1LossBackward>)
tensor(1.0714)
- * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * - - * -
out: tensor([[-0.0172, -0.1223]], grad_fn=<AddmmBackward>)
out.size(): torch.Size([1, 2])
2th loss: tensor(1.0156, grad_fn=<L1LossBackward>)
损失函数代表了预测值和真实值的差
最简单的损失韩式: |真实值 - 预测值|
常用的损失函数包括:
mean absolute loss 绝对值误差(L1)
mean square loss 均方差(MSE)
cross entroy loss 交叉熵误差
KL-divergence KL散度
损失函数的用途:
用于计算梯度、反向传播、更新网络权重
判断模型是否训练好
判断过拟合、欠拟合(配个图)
上面的代码,是pytorch实现神经网络训练过程的示例。在实际应用实现时,需要迭代上述过程直到模型收敛。