关于神经网络的基础知识,这里就不给大家叙述了,感兴趣的可以看我之前的一篇文章:神经网络基础(以BP神经网络为例),本文主要分介绍使用Pytorch实现一个简单的机器学习项目.
首先,我们先明确好思路:
(1)导入需要的程序库 ,在这里我们主要使用torch
(2)设置训练数据(必要的话可以进行可视化操作) ,这里我们自己造个伪数据即可
(3)设置权重和偏置,以及学习率(对于神经网络来说,这里我们一般设置优化器,损失函数
我们这里的损失函数直接加载训练程序部分了,从后面程序部分可以看到咱就求了一个均方差)
(4)训练模型 , for 循环实现
(5)可视化训练效果 , 这里我们使用matplotlib中的pyplot
那我们现在开始,我们首先来实现一个简单的系数推导,首先我们导入需要的库:
import torch # torch是我们常用的深度学习库之一
from matplotlib import pyplot as plt # 画图的
数据我们自己创建(自己创建的数据,规律肯定咱知道的,要不咋检测最后的预测结果对于否呢):
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # [100, 1]
y = 3*x.pow(2)+2+torch.rand_like(x)*0.2
第一行:创建一个等差数列即在-1与1之间生成100个数据,第二行是每个数据的标签,显然标签y和数据x之间的关系是,后面是我们加的一个噪音torch.rand_like(x)*0.2.
接下来我们设置一下权重和偏置,注意这里我们设置的权重与偏置分别是用来推导y与x之间关系的x平方系数3与常数2的.
w = torch.rand(1, 1, requires_grad=True)
b = torch.rand(1, 1, requires_grad=True)
lr = 0.05
可见w,b都是随机设置的.我们将学习率设置为0.05.
下面我们开始训练,我们设置预测公式为prediction = x.pow(2)*w + b,让其通过梯度下降算法自动的去寻找合适的w与b是的样本的预测值与标签值的误差最小(也就是让我们这里的损失值loss最小)
for i in range(2000):
prediction = x.pow(2)*w + b
loss_func = 0.5 * (prediction - y).pow(2)
loss = loss_func.sum()/100
loss.backward()
# 更新权重与偏置
with torch.no_grad():
w -= lr * w.grad
b -= lr * b.grad
# 梯度清零
w.grad.zero_()
b.grad.zero_()
loss.backward()是将损失值依据损失函数进行反向传播计算变量梯度,也就是计算w与b的梯度,这样我们就可以通过w.grad和b.grad来获得对应梯度值了, w -= lr * w.grad, b -= lr * b.grad,这就是我们说的梯度下降了,参数按照梯度的反方向进行更新(这里不清楚的看之前我写的:神经网络基础(以BP神经网络为例)),最后记得将梯度清零,防止梯度的历史值进行累加.
训练完后面就是画图了,我们用得出来的w与b 构建prediction = x.pow(2)*w + b并将其画出,然后我们将我们的原始数据x与y以散点图的形式也在图上显示出来,如果散点图和曲线良好拟合则可以说明我们采用梯度下降计算的w与b是接近真实值的,最后我们将w,b打印出来看看是不是和3与2接近。
图像:
打印w与b:
还是很接近的。
下面是画图与打印的程序:
# 画图
plt.plot(x.numpy(), prediction.detach().numpy(), 'r-', label='predict') # predict
plt.scatter(x.numpy(), y.numpy(), color='blue', marker='o', label='true') # true data
plt.xlim(-1, 1)
plt.ylim(2, 6)
plt.legend() # 开图标
plt.show()
print(w, b)
其实,我们这里做的实例是非常简单的,可以说是只用了一个梯度下降,验证了梯度下降的可行性。
下面我们对这个程序进行更改,我们直接建立一个BP神经网络来进行预测,解释部分已经加到代码里了,文章部分不再加说明,大家感兴趣可以复制程序,进行测试。
""" 实现简单的机器学习(no layers)使用BGD"""
# 导入库
import torch
from matplotlib import pyplot as plt
import torch.nn as nn # 这是一个神经网络库,里面定义了各种各样的神经网络层
import torch.nn.functional as F # 这里面有很多激活函数的定义
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # [100, 1]
y = 3*x.pow(2)+2+torch.rand_like(x)*0.2
class BP(nn.Module): # 把网络定义好
def __init__(self):
super(BP, self).__init__()
self.bp1 = nn.Linear(1, 10) # 两层网络
self.bp2 = nn.Linear(10, 1)
def forward(self, data):
data= self.bp1(data)
data = F.relu(data)
y = self.bp2(data)
return y
bp_net = BP() # 网络实例化
optimizer = torch.optim.SGD(bp_net.parameters(), lr=0.05, momentum=0.8) # 设置优化器,这里采用的是带动量的SGD,
# 但计算的时候,我们直接用的全部数据因此实际是个带动量的BGD
# 4 训练
for i in range(2000):
prediction = bp_net(x)
loss_func = 0.5 * (prediction - y).pow(2)
loss = loss_func.sum()/100
loss.backward() # 梯度计算
optimizer.step() # 梯度更新
optimizer.zero_grad() # 梯度清零
# 画图,这里我们直接用训练数据检测了,实际应用测试数据检测。
plt.plot(x.numpy(), bp_net(x).detach().numpy(), 'r-', label='predict') # predict
plt.scatter(x.numpy(), y.numpy(), color='blue', marker='o', label='true') # true data
plt.xlim(-1, 1)
plt.ylim(2, 6)
plt.legend() # 开图标
plt.show()