学深度学习ep02-梯度下降
·
损失函数对权重求导数-->上升方向
导数负方向-->最小值所在方向-->w=w-alpha* alpha为学习率
不一定得到全局最优,局部最优解-----需注意鞍点:gradient=0 无法继续迭代
学习率过大可能导致学习失败
针对同样的回归任务,梯度下降法实现如下
import matplotlib.pyplot as plt
import numpy as np # 导入 numpy 用于生成平滑的线条
# 1. 原始数据
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
# 2. 初始化模型参数
w = 1.0
w_initial = w # 保存初始权重,用于后续可视化比较
# 3. 模型、损失函数、梯度函数定义
def forward(x):
"""模型的前向传播"""
return x * w
def cost(xs, ys):
"""计算均方误差损失 (Mean Squared Error)"""
cost_val = 0
for x, y in zip(xs, ys):
y_pred = forward(x)
cost_val += (y_pred - y) ** 2
return cost_val / len(xs)
def gradient(xs, ys):
"""计算损失函数关于权重 w 的梯度"""
grad = 0
# BUG修复:梯度需要累加所有样本的影响,而不是只用最后一个
for x, y in zip(xs, ys):
grad += 2 * x * (x * w - y) # 使用 += 进行累加
return grad / len(xs)
# 4. 训练过程
cost_list = []
epoch_list = []
print(f'Predict (before training) for x=4: {forward(4):.3f}') # 格式化输出
# 学习率
learning_rate = 0.01
for epoch in range(100):
# 计算损失并记录
cost_val = cost(x_data, y_data)
cost_list.append(cost_val)
epoch_list.append(epoch)
# 计算梯度并更新权重
grad_val = gradient(x_data, y_data)
w -= learning_rate * grad_val
# 打印训练过程
if epoch % 10 == 0: # 每10次迭代打印一次
print(f'Epoch: {epoch}, w = {w:.3f}, loss = {cost_val:.3f}')
print(f'Predict (after training) for x=4: {forward(4):.3f}')
# 5. 可视化
# 创建一个大画布,包含两个子图
plt.figure(figsize=(12, 5))
# --- 图 1: 损失随迭代次数的变化 ---
plt.subplot(1, 2, 1) # 1行2列的第1个图
plt.plot(epoch_list, cost_list)
plt.title("Cost (Loss) vs. Epoch")
plt.xlabel("Epoch")
plt.ylabel("Cost (MSE Loss)")
plt.grid(True)
# --- 图 2: 模型拟合效果对比 ---
plt.subplot(1, 2, 2) # 1行2列的第2个图
# 绘制原始数据点
plt.scatter(x_data, y_data, color='red', label='Actual Data')
# 绘制训练前的拟合线
x_range = np.linspace(0, 4, 100) # 生成 0到4 之间的100个点来画平滑的线
y_pred_before = w_initial * x_range
plt.plot(x_range, y_pred_before, color='orange', linestyle='--', label=f'Prediction Before (w={w_initial:.2f})')
# 绘制训练后的拟合线
y_pred_after = w * x_range # 使用最终训练好的w
plt.plot(x_range, y_pred_after, color='green', label=f'Prediction After (w={w:.2f})')
plt.title("Model Fit: Before vs. After Training")
plt.xlabel("x")
plt.ylabel("y")
plt.legend() # 显示图例
plt.grid(True)
plt.tight_layout() # 调整子图布局,防止重叠
plt.show()
梯度下降法-->随机梯度下降(stochastic gradient descent)w=w-alpha*
cost为所有loss的均值,随机梯度下降代表从N个loss里随机选一个
why? 对有鞍点的cost function,在鞍点位置梯度=0,无法继续学习
利用每个样本的随机噪声,可能可以继续推动跨越鞍点学习
import matplotlib.pyplot as plt
import numpy as np # 导入 numpy 用于生成平滑的线条
# 1. 原始数据
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
# 2. 初始化模型参数
w = 1.0
w_initial = w # 保存初始权重,用于后续可视化比较
# 3. 模型、损失函数、梯度函数定义
def forward(x):
"""模型的前向传播"""
return x * w
def loss(x,y):
y_pred=forward(x)
return (y_pred-y)**2
# def cost(xs, ys):
# """计算均方误差损失 (Mean Squared Error)"""
# cost_val = 0
# for x, y in zip(xs, ys):
# y_pred = forward(x)
# cost_val += (y_pred - y) ** 2
# return cost_val / len(xs)
# def gradient(xs, ys):
# """计算损失函数关于权重 w 的梯度"""
# grad = 0
# # BUG修复:梯度需要累加所有样本的影响,而不是只用最后一个
# for x, y in zip(xs, ys):
# grad += 2 * x * (x * w - y) # 使用 += 进行累加
# return grad / len(xs)
def gradient(x,y):
return 2*x*(x*w-y)
# 4. 训练过程
cost_list = []
epoch_list = []
print(f'Predict (before training) for x=4: {forward(4):.3f}') # 格式化输出
# 学习率
learning_rate = 0.01
for epoch in range(100):
# # 计算损失并记录
# cost_val = cost(x_data, y_data)
# cost_list.append(cost_val)
# epoch_list.append(epoch)
#
# # 计算梯度并更新权重
# grad_val = gradient(x_data, y_data)
# w -= learning_rate * grad_val
for x,y in zip(x_data,y_data):
grad=gradient(x,y)
w-=grad*learning_rate
l=loss(x,y)
print('epoch=',epoch,'w=',w,'loss=',l)
print(f'Predict (after training) for x=4: {forward(4):.3f}') # 格式化输出
随机梯度下降每一次的w是由上一次的w计算来的-->无法进行并行计算
梯度下降可进行并行计算
如何折中?batch 进行批量的随机梯度下降,每次去batch size为一组求梯度,进行更新
更多推荐



所有评论(0)