1. 损失函数和梯度
1.1 损失函数的概念
- 对于给定的输入 x x x,由 f ( x ) f(x) f(x)给出相应的输出,这个实际输出值和原先预期值Y可能不一致,所以需要定义一个损失函数(LossFunction),也有称之为代价函数(CostFunction)来度量这二者之间的“差异”程度。
- 损失函数是用来度量预测值和实际值之间的差异的。
1.2 常见损失函数:均方误差
- 均方误差(Meansquare error)损失函数。均方误差是回归问题常用的损失函数,它是预测值与目标值之间差值的平方和,其公式和图像如下所示:
- 交叉熵:交叉熵是Shannon信息论中一个重要概念,主要用于度量两个概率分布间的差异性信息,在机器学习中用来作为分类问题的损失函数。假设有两个概率分布,tk与yk ,其交叉熵函数公式及图形如下所示:
1.3 梯度的概念
- 梯度(gradient)是一个向量(矢量,有方向),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大。
- 损失函数沿梯度相反方向收敛最快(即能最快找到极值点)。
2. 反向传播计算
2.1 反向传播过程
- 考虑函数$y = f(x) $*, 输出为E,反向传播的计算顺序是,将信号E乘以节点的局部导数(偏导数),传递给前面的节点。
2.2 符合函数的反向传播过程
- 考虑复合函数:
- z z z对于x的导数( x x x变化对 z z z的影响率)可以表示为:
- 复合函数 z z z的反向传播过程
3. 线性回归实现
步骤一:准备数据 y = w x + b y=wx+b y=wx+b
x = torch.rand([50])
y = 3 * x + 0.8
w = torch.rand(1, requires_grad=True)
b = torch.rand(1, requires_grad=True)
步骤二:构造损失函数
def loss_fn(y, y_predict):
loss = (y_predict - y).pow(2).mean()
for i in [w, b]:
# 每次反向传播前把梯度置为0
if i.grad is not None:
i.grad.data.zero_()
# [i.grad.data.zero_() for i in [w,b] if i.grad is not None]
loss.backward()
return loss.data
步骤三: 更新参数
def optimize(learning_rate):
# print(w.grad.data,w.data,b.data)
w.data -= learning_rate * w.grad.data
b.data -= learning_rate * b.grad.data
步骤四:训练参数,计算预测值
for i in range(3000):
# 2. 计算预测值
y_predict = x * w + b
# 3.计算损失,把参数的梯度置为0,进行反向传播
loss = loss_fn(y, y_predict)
if i % 500 == 0:
print(i, loss)
# 4. 更新参数w和b
optimize(0.01)
步骤五:绘制图形,观察训练结束的预测之和真实值
# 绘制图形,观察训练结束的预测值和真实值
predict = x * w + b # 使用训练后的w和b计算预测值
plt.scatter(x.data.numpy(), y.data.numpy(), c="r")
plt.plot(x.data.numpy(), predict.data.numpy())
plt.show()
print("w", w)
print("b", b)