线性回归---基于PyTorch,tensorflow的实现

本文将首先介绍线性回归的数学原理,并借助目前主流的框架进行实现。

1.线性回归的目标

找到一条直线,使得 f ( x i ) = w x i + b f\left( x_i \right) =wx_i+b f(xi)=wxi+b
如何确定w,b,使损失函数值最小
( w ∗ , b ∗ ) = arg ⁡ min ⁡ ( w , b ) ∑ i = 1 m ( f ( x i ) − y i ) 2 = arg ⁡ min ⁡ ( w , b ) ∑ i = 1 m ( y i − w x i − b ) 2 . \begin{aligned}\left(w^{*}, b^{*}\right) &=\underset{(w, b)}{\arg \min } \sum_{i=1}^{m}\left(f\left(x_{i}\right)-y_{i}\right)^{2} \\ &=\underset{(w, b)}{\arg \min } \sum_{i=1}^{m}\left(y_{i}-w x_{i}-b\right)^{2} . \end{aligned} (w,b)=(w,b)argmini=1m(f(xi)yi)2=(w,b)argmini=1m(yiwxib)2.
根据梯度下降法可知,当变量沿着梯度方向移动时,函数值增大最快,当变量沿着梯度反方向时,函数值减小最快。
目前,我们要求损失函数的最小值,当然是将变量沿着梯度反方向移动。
假设移动步长为lr,也就是常说的学习率。移动步长过高和过低,都会对我们的结果有一定的影响。通常lr=0.05
w k + 1 = w k − ∂ E ∂ w ⋅ l r w^{k+1}=w^k-\frac{\partial E}{\partial w}\cdot lr wk+1=wkwElr
b k + 1 = b k − ∂ E ∂ b ⋅ l r b^{k+1}=b^k-\frac{\partial E}{\partial b}\cdot lr bk+1=bkbElr
更新w,b后重新计算损失函数的值,如果损失函数的值不小于我们预先设定的值,则继续进行更新参数,直到损失函数的值足够小后,结束。输出w,b。

2.PyTorch实现线性回归

import torch
torch.manual_seed(10)

lr = 0.05  # 学习率

# 创建训练数据
x = torch.rand(20, 1) * 10  # x data (tensor), shape=(20, 1)
# torch.randn(20, 1) 用于添加噪声
y = 2*x + (5 + torch.randn(20, 1))  # y data (tensor), shape=(20, 1)

# 构建线性回归参数
w = torch.randn((1), requires_grad=True) # 设置梯度求解为 true
b = torch.zeros((1), requires_grad=True) # 设置梯度求解为 true

# 迭代训练 1000for iteration in range(1000):

    # 前向传播,计算预测值
    wx = torch.mul(w, x)
    y_pred = torch.add(wx, b)

    # 计算 MSE loss
    loss = (0.5 * (y - y_pred) ** 2).mean()

    # 反向传播
    loss.backward()

    # 更新参数
    b.data.sub_(lr * b.grad)
    w.data.sub_(lr * w.grad)

    # 每次更新参数之后,都要清零张量的梯度
    w.grad.zero_()
    b.grad.zero_()

	if loss.data.numpy() < 1:
		break

3.tensorflow2.0实现线性回归

# https://blog.csdn.net/qq_40643699/article/details/108836622
import tensorflow as tf
import numpy as np
 
# 前期准备---数据处理:归一化
x_row = np.array([2013, 2014, 2015, 2016, 2017], dtype=np.float32)
y_row = np.array([12000, 14000, 15000, 16500, 17500], dtype=np.float32)
# 数据归一化需要用np容器类型的数据,因为TensorFlow没有x.min和x.max操作
x = (x_row - x_row.min()) / (x_row.max() - x_row.min())
y = (y_row - y_row.min()) / (y_row.max() - y_row.min())
 
# 利用TensorFlow2.0来线性回归
 
X = tf.constant(x)
Y = tf.constant(y)     # 数据类型转换:因为使用到了TensorFlow的库,所以在这里所有变量都需要时Tensor类型了
a = tf.Variable(initial_value=0.)
b = tf.Variable(initial_value=0.)
variable = [a, b]
epoch = 30000
optimizer = tf.keras.optimizers.SGD(learning_rate=0.00001)
 
for i in range(epoch):
    with tf.GradientTape() as tape:
        Y_predict = a * X + b
        loss = tf.reduce_sum(tf.square(Y_predict - Y))
    grad = tape.gradient(loss, variable)
    print('gradient', grad)
    optimizer.apply_gradients(grads_and_vars=zip(grad, variable))
    print('a', a, 'b', b)
    

你可能感兴趣的:(pytorch,tensorflow,线性回归)