天天看点

使用Pytroch实现一个简单的机器学习(入门来看)

        关于神经网络的基础知识,这里就不给大家叙述了,感兴趣的可以看我之前的一篇文章:神经网络基础(以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之间的关系是

使用Pytroch实现一个简单的机器学习(入门来看)

,后面是我们加的一个噪音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接近。

图像:

使用Pytroch实现一个简单的机器学习(入门来看)

打印w与b:

使用Pytroch实现一个简单的机器学习(入门来看)

还是很接近的。

下面是画图与打印的程序:

# 画图
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()
           

继续阅读