线性回归

1 模型定义

线性回归是个非常简单的模型,它的形式如下:
y=Ax+by=Ax+by=Ax+b
其中x∈Rn,A∈Rm×n,b∈Rm,y∈Rmx \in R^n,A\in R^{m\times n},b\in R^m,y\in R^mxRnARm×nbRmyRm
假设输入xxx和输出yyy之间是线性关系,根据训练数据集合YYYXXX来学习出最优的参数AAAbbb

2 准备数据

简单起见,假设x和y都是一维的实数。我们希望生成的数据中是“真实”的,所以在数据上加上了随机的高斯噪声,模拟真实情况下存在的噪声。

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
x_vals = np.linspace(0,10,100)              	# 生成100个在区间[1,10]的实数
print(x_vals)									# 输出查看
realA = 2.5										
realb = -5										
y_reals = realA * x_vals + realb				# 假设真实的y和x符合一维线性分布
y_vals = y_reals + np.random.normal(0, 1, 100)	# 在y上加上随机的高斯噪声


# Plot the reasults,查看生成的训练数据
plt.plot(x_vals, y_vals, 'o', label='Data')
plt.plot(x_vals, y_vals, 'r-', label='Best fit line', linewidth=3)
plt.legend(loc='upper left')
plt.show()

生成的数据集如下图所示
在这里插入图片描述

SGD训练

下面的公式是简单的梯度计算
y^i=Axi+b \widehat{y}_i = Ax_i + b y i=Axi+b
L(y^i,yj)=12∑i(y^i−yi)2L(\widehat{y}_i,y_j) = \frac{1}{2}\sum_{i}(\widehat{y}_i-y_i)^2L(y i,yj)=21i(y iyi)2
dLdA=∑i(y^i−yi)xi\frac{dL}{dA}=\sum_i(\widehat{y}_i-y_i)x_idAdL=i(y iyi)xi
dLdb=∑i(y^i−yi)\frac{dL}{db}=\sum_i(\widehat{y}_i-y_i)dbdL=i(y iyi)

# SGD训练
A = np.random.normal(0,1)
b = 0
print("init A={0},b={1}".format(A, b))          # 生成初始的参数A和b

epoches=1000                                    # 设置训练迭代次数,总共迭代1000次,每次都进行loss计算
losses = []                                     # 设置losses列表记录每次迭代后loss的变化
batch_size = 10                                 # 设置批处理大小,每次从所有的数据点中随机出10个计算损失函数梯度
learning_rate = 0.001                           # 设置学习率
for i in range(epoches):
    rand_index = np.random.choice(len(x_vals), size=batch_size) # 随机生成10个点的索引
    rand_x = x_vals[rand_index]
    rand_y = y_vals[rand_index]
    #forward 前驱函数
    pred_y = A * rand_x + b                     # 按照当前的参数进行预测
    loss = np.sum((pred_y - rand_y)*(pred_y - rand_y))/2    # 计算当前结果的损失
    losses.append(loss)                         # 记录损失
    dLdA = np.sum((pred_y - rand_y)*rand_x)     # 计算参数A的梯度
    dLdb = np.sum(pred_y - rand_y)              # 计算参数b的梯度
    A = A - learning_rate * dLdA
    b = b - learning_rate * dLdb                # 将参数A和b进行微调修改

print("final A={0}, b={1}".format(A,b))         # 输出训练以后的参数

训练结果如图
在这里插入图片描述

3 结果显示

# 结果显示plot the reasult
y_pred = A * x_vals + b
plt.plot(x_vals, y_vals, 'o', label='Data Points')
plt.plot(x_vals, y_reals, 'r-', label='Best fit line', linewidth=3)
plt.plot(x_vals, y_pred, 'b-', label='learning line', linewidth=3)

plt.legend(loc='upper left')
plt.title('Linear Regression')
plt.show()                              # 红线为真实线性分布,蓝线为预测出的线性分布

# Plot loss over time
plt.plot(losses, 'k-')
plt.title('L2 Loss per Generation')
plt.xlabel('Generation')
plt.ylabel('L2 Loss')
plt.show()                              # 查看所有轮次的loss值

展示结果如图。
在这里插入图片描述
在这里插入图片描述

4 完整代码

import numpy as np
import matplotlib.pyplot as plt
# %matplotlib inline
x_vals = np.linspace(0,10,100)              	# 生成100个在区间[1,10]的实数
print(x_vals)									# 输出查看
realA = 2.5
realb = -5
y_reals = realA * x_vals + realb				# 假设真实的y和x符合一维线性分布
y_vals = y_reals + np.random.normal(0, 1, 100)	# 在y上加上随机的高斯噪声


# Plot the reasults,查看生成的训练数据
plt.plot(x_vals, y_vals, 'o', label='Data')
plt.plot(x_vals, y_vals, 'r-', label='Best fit line', linewidth=3)
plt.legend(loc='upper left')
plt.show()

# SGD训练
A = np.random.normal(0,1)
b = 0
print("init A={0},b={1}".format(A, b))          # 生成初始的参数A和b

epoches=1000                                    # 设置训练迭代次数,总共迭代1000次,每次都进行loss计算
losses = []                                     # 设置losses列表记录每次迭代后loss的变化
batch_size = 10                                 # 设置批处理大小,每次从所有的数据点中随机出10个计算损失函数梯度
learning_rate = 0.001                           # 设置学习率
for i in range(epoches):
    rand_index = np.random.choice(len(x_vals), size=batch_size) # 随机生成10个点的索引
    rand_x = x_vals[rand_index]
    rand_y = y_vals[rand_index]
    #forward 前驱函数
    pred_y = A * rand_x + b                     # 按照当前的参数进行预测
    loss = np.sum((pred_y - rand_y)*(pred_y - rand_y))/2    # 计算当前结果的损失
    losses.append(loss)                         # 记录损失
    dLdA = np.sum((pred_y - rand_y)*rand_x)     # 计算参数A的梯度
    dLdb = np.sum(pred_y - rand_y)              # 计算参数b的梯度
    A = A - learning_rate * dLdA
    b = b - learning_rate * dLdb                # 将参数A和b进行微调修改

print("final A={0}, b={1}".format(A,b))         # 输出训练以后的参数


# 结果显示plot the reasult
y_pred = A * x_vals + b
plt.plot(x_vals, y_vals, 'o', label='Data Points')
plt.plot(x_vals, y_reals, 'r-', label='Best fit line', linewidth=3)
plt.plot(x_vals, y_pred, 'b-', label='learning line', linewidth=3)

plt.legend(loc='upper left')
plt.title('Linear Regression')
plt.show()                              # 红线为真实线性分布,蓝线为预测出的线性分布

# Plot loss over time
plt.plot(losses, 'k-')
plt.title('L2 Loss per Generation')
plt.xlabel('Generation')
plt.ylabel('L2 Loss')
plt.show()                              # 查看所有轮次的loss值
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐