首先考虑 y y y为标量, w w w为标量的情况,那么我们的线性函数为 y = w x + b y=wx+b y=wx+b。每批输入的量batch size 为 1 1 1,每批输入的 x x x为一个标量,设为 x ∗ x^* x∗,标签 y y y同样为一个标量,设为 y ∗ y^* y∗。因此每批训练的损失函数 L L L可以表示为:
L = ( y − y ∗ ) 2 = ( w x ∗ + b − y ∗ ) 2 \begin{aligned} L&=\left(y-y^*\right)^2\\ &=\left(wx^*+b-y^*\right)^2\\ \end{aligned} L=(y−y∗)2=(wx∗+b−y∗)2
每次训练完需要更新参数 w w w和 b b b,我们采用梯度下降方法对这两个参数进行更新的话,需要求出两个参数的梯度,也就是需要求出 ∂ L ∂ w \frac{\partial{L}}{\partial{w}} ∂w∂L和 ∂ L ∂ b \frac{\partial{L}}{\partial{b}} ∂b∂L,结果如下:
∂ L ∂ w = 2 ( w x ∗ + b − y ∗ ) x ∗ \frac{\partial{L}}{\partial{w}}=2(wx^*+b-y^*)x^* ∂w∂L=2(wx∗+b−y∗)x∗
∂ L ∂ b = 2 ( w x ∗ + b − y ∗ ) \frac{\partial{L}}{\partial{b}}=2(wx^*+b-y^*) ∂b∂L=2(wx∗+b−y∗)
训练之前需要对 w w w和 b b b初始化赋值,设定步长 s t e p step step。这样每轮 w w w和 b b b的更新方法为:
w n e w = w − s t e p ∗ 2 ( w x ∗ + b − y ∗ ) x ∗ w_{new}=w-step*2(wx^*+b-y^*)x^* wnew=w−step∗2(wx∗+b−y∗)x∗
b n e w = b − s t e p ∗ 2 ( w x ∗ + b − y ∗ ) b_{new}=b-step*2(wx^*+b-y^*) bnew=b−step∗2(wx∗+b−y∗)
首先考虑 y y y为标量, w w w为标量的情况,那么我们的线性函数为 y = w x + b y=wx+b y=wx+b。每批输入的量batch size 为 N N N,每批输入的 x x x为一个向量,设为 x ∗ \boldsymbol{x}^* x∗,标签 y y y同样为一个向量,设为 y ∗ \boldsymbol{y}^* y∗。因此损失函数可以表示为:
L = ∑ n = 1 N ( y − y ∗ ) 2 = ∑ n = 1 N ( y − y ∗ ) 2 \begin{aligned} L&=\sum_{n=1}^{N}\left(y-y^*\right)^2\\ &=\sum_{n=1}^{N}\left(y-y^*\right)^2\\ \end{aligned} L=n=1∑N(y−y∗)2=n=1∑N(y−y∗)2
下面我们对这种最简单的线性回归模型使用python实现一下:
x = np.array([0.1,1.2,2.1,3.8,4.1,5.4,6.2,7.1,8.2,9.3,10.4,11.2,12.3,13.8,14.9,15.5,16.2,17.1,18.5,19.2])
y = np.array([5.7,8.8,10.8,11.4,13.1,16.6,17.3,19.4,21.8,23.1,25.1,29.2,29.9,31.8,32.3,36.5,39.1,38.4,44.2,43.4])
print(x,y)
plt.scatter(x,y)
plt.show()
回归过程如下:
# 设定步长
step=0.001
# 存储每轮损失的loss数组
loss_list=[]
# 定义epoch
epoch=30
# 定义参数w和b并初始化
w=0.0
b=0.0
#梯度下降回归
for i in range(epoch) :
#计算当前输入x和标签y的索引,由于x和y数组长度一致,因此通过i整除x的长度即可获得当前索引
index = i % len(x)
# 当前轮次的x值为:
cx=x[index]
# 当前轮次的y值为:
cy=y[index]
# 计算当前loss
loss_list.append((w*cx+b-cy)**2)
# 计算参数w和b的梯度
grad_w = 2*(w*cx+b-cy)*cx
grad_b = 2*(w*cx+b-cy)
# 更新w和b的值
w -= step*grad_w
b -= step*grad_b
输出loss如下:
plt.plot(loss_list)
plt.show()
输出拟合函数的结果:
print("y=%.2fx+%.2f" %(w,b))
y=2.46x+0.39
拟合的函数图像与训练数据中的点关系图如下:
可以看到迭代30次后的函数图像,现在迭代次数增加到3000,拟合结果如下:
loss如下:
在batchsize为1的时候,loss波动很大。因此有必要增大batchsize,下一篇我们在此基础上增加batchsize看看线性回归的结果。