【每天进步一点点】pytorch的线性模型实现

线性模型实现


这里主要涉及代码实现部分,理论部分的内容较少
在这里插入图片描述

一维线性模型

思路:

1.得到训练数据画出原始图像,并将训练数据通过torch.from_numpy转换成Variable类型的变量;
定义参数w和b,并将参数设置成requires_grad=True,True说明反向传播时自动求导,而一般情况下该属性默认为False

2.构建参数模型即线性模型和损失函数

3.进行训练,训练过程中需要记得归零梯度w.grad.zero_(),利用backward()来自动求导,随后更新参数w和b

在进行训练的时候需要在循环外面先求一次导这样做的目的是loss.backward()先行,防止出现AttributeError: 'NoneType' object has no attribute 'zero_'的错误,或者在循环内先loss.backward(),随后再梯度归零。
总之是不可以让w.grad.zero_()放在前面

4.画图查看训练情况,这里画图需要注意将x_train、y_train和y_的类型进行转换x_train.data.numpy()

实现的代码如下:

import torch
import numpy as np
from torch.autograd import Variable
import matplotlib
import matplotlib.pyplot as plt

# 数据
x_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168], [9.779], [6.182], [7.59], [2.167], [7.042], [10.791],
                    [5.313], [7.997], [3.1]], dtype=np.float32)

y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573], [3.366], [2.596], [2.53], [1.221], [2.827], [3.465],
                    [1.65], [2.904], [1.3]], dtype=np.float32)
# 画出原始图像
plt.plot(x_train, y_train,'bo')
plt.show()

# 转换类型
x_train = torch.from_numpy(x_train)
y_train = torch.from_numpy(y_train)

# 定义w和b参数
w = Variable(torch.randn(1), requires_grad=True)
b = Variable(torch.zeros(1), requires_grad=True)

# 得到参数模型和损失函数


def linear_model(x):
    return x*w+b


def get_loss(y_, y):
    return torch.mean((y_-y_train)**2)


y_ = linear_model(x_train)
loss = get_loss(y_, y_train)
loss.backward()  # 自动求导
w.data = w.data - 1e-2*w.grad.data
b.data = b.data - 1e-2*b.grad.data


for i in range(100):
    # 计算损失函数 
    y_ = linear_model(x_train)
    loss = get_loss(y_, y_train)

    print("loss:{}".format(loss))
    # 归零梯度
    w.grad.zero_()  # 要在外面走一次
    b.grad.zero_()
   
    loss.backward()
    # 更新参数
    w.data = w.data - 1e-2*w.grad.data
    b.data = b.data - 1e-2*b.grad.data
    
y_ = linear_model(x_train)
# 画图
plt.plot(x_train.data.numpy(), y_train.data.numpy(), 'bo', label='real')
plt.plot(x_train.data.numpy(), y_.data.numpy(), 'ro', label='estimated')
plt.legend()
plt.show()

结果

原始数据:
在这里插入图片描述
训练之后:
在这里插入图片描述
误差(部分截图):
在这里插入图片描述


多维线性模型

思路:

1.定义目标函数: 以三维函数为例,首先需要定义具体的函数模型,即向量’w_targetb_target,两个向量是准确的参数;

2.得到数据样本: 选取一定的区域的x_sample变量,随后根据所定义的参数来得到y_sample。随后可以画出图像,对于样本数据需要定义相应的训练数据方便计算;

x_train = np.stack([x_sample**i for i in range(1, 4)], axis=1)  # 因为后面需要w和x矩阵运算因此需要将x训练模型扩展
x_train = torch.from_numpy(x_train).float()
y_train = torch.from_numpy(y_sample).float().unsqueeze(1)

这里涉及unsqueeze()方法和numpy数组中的stack()方法,此部分会在后面进行说明

3.定义训练参数: 该内容与一维的过程同样;

4.定义训练模型和损失参数: 该内容与一维的过程相似,不过需要注意此时是多维运算因此需要用到torch.mm()即向量的乘法运算;

5.训练: 步骤和过程与一维相同,同样需要经历:求y值,随后根据损失函数的求导更新参数w和b,可通过第一次和最后一次画出图像来比较。

实现的代码如下:

# 定义函数
w_target = np.array([0.5, 3, 2.4])
b_target = np.array([0.9])

# 得到数据
x_sample = np.arange(-3, 3.1, 0.1)
y_sample = b_target[0]+w_target[0]*x_sample+w_target[1]*x_sample**2+w_target[2]*x_sample**3
print("the function is:{:.2f}+{:.2f}*x+{:.2f}*x^2+{:.2f}*x^3".format(b_target[0],
                                                                     w_target[0], w_target[1], w_target[2]))
# 画图                                                                     
plt.plot(x_sample, y_sample, label="fitting", color='r')
plt.legend()
plt.show()

# 获得训练模型
x_train = np.stack([x_sample**i for i in range(1, 4)], axis=1)  # 因为后面需要w和x矩阵运算因此需要将x训练模型扩展
x_train = torch.from_numpy(x_train).float()
y_train = torch.from_numpy(y_sample).float().unsqueeze(1)

# 定义参数
w = Variable(torch.randn(3, 1), requires_grad=True)
b = Variable(torch.zeros(1), requires_grad=True)

# 定义模型和损失函数


def multi_model(x):
    return torch.mm(x, w)+b


def get_loss(y_, y):
    return torch.mean((y_-y)**2)


# 多次训练
for i in range(200):
    y_pred = multi_model(x_train)
    loss = get_loss(y_pred, y_train)
    loss.backward()
    w.data = w.data - 0.001 * w.grad.data
    b.data = b.data - 0.001 * b.grad.data
    print("the loss is :{}".format(loss))
    # 第一次和最后一次画出训练图像
    if i == 0 or i == 199:
        y_pred = multi_model(x_train)
        plt.plot(x_train.data.numpy()[:, 0], y_pred.data.numpy()[:, 0], label="fitting", color='b')
        plt.plot(x_train.data.numpy()[:, 0], y_sample, label='real', color='r')
        plt.legend()
        plt.show()

结果

原始数据:
在这里插入图片描述
训练之后:

第一次训练:
第一次训练
最后一次训练:
在这里插入图片描述

最后说明的内容:

unsqueeze()方法:

可以参考:

https://blog.csdn.net/flysky_jay/article/details/81607289

numpy的stack()方法:

可以参考:

https://blog.csdn.net/zzw000000/article/details/52857964

https://blog.csdn.net/csdn15698845876/article/details/73380803?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

————————————————————————————————————

代码的参考:

https://github.com/L1aoXingyu/code-of-learn-deep-learning-with-pytorch

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值