如何绘制梯度下降法线性回归后的损失曲面?
如何绘制线性回归的损失曲面(以斜率m为X轴、截距c为Y轴、损失为Z轴)
我已经用以下Python代码实现了基于梯度下降的线性回归,得到了最优斜率m和截距c。现在想绘制损失曲面,要求以斜率为X轴、截距为Y轴、损失函数为Z轴,请问该怎么实现?
# Making the imports import numpy as np import pandas as pd import matplotlib.pyplot as plt plt.rcParams['figure.figsize'] = (12.0, 9.0) # Preprocessing Input data data = pd.read_csv('data.csv') X = data.iloc[:, 0] Y = data.iloc[:, 1] plt.scatter(X, Y) # Building the model m = 0 c = 0 L = 0.0001 # The learning Rate epochs = 1000 # The number of iterations to perform gradient descent n = float(len(X)) # Number of elements in X # Performing Gradient Descent for i in range(epochs): Y_pred = m*X + c # The current predicted value of Y D_m = (-2/n) * sum(X * (Y - Y_pred)) # Derivative wrt m D_c = (-2/n) * sum(Y - Y_pred) # Derivative wrt c m = m - L * D_m # Update m c = c - L * D_c # Update c print (m, c) # Making predictions Y_pred = m*X + c plt.scatter(X, Y) plt.plot([min(X), max(X)], [min(Y_pred), max(Y_pred)], color='red') # regression line plt.show()
实现方案
要绘制损失曲面,核心是生成覆盖m和c合理范围的网格点,计算每个点对应的损失值,再通过3D绘图工具可视化。以下是具体步骤和代码:
1. 核心思路
- 定义损失函数:用线性回归的均方误差(MSE)作为损失指标,公式为:
$$J(m,c) = \frac{1}{n}\sum_{i=1}^n (Y_i - (mX_i + c))^2$$ - 生成参数网格:围绕最终得到的最优
m和c,取合理范围生成密集网格点 - 批量计算损失:遍历网格点,计算每个点对应的损失值
- 3D可视化:用
matplotlib的3D模块绘制曲面,可额外标记最优解和梯度下降路径
2. 完整代码示例
在原代码基础上添加以下内容:
# 导入3D绘图模块 from mpl_toolkits.mplot3d import Axes3D # 定义均方误差损失函数 def compute_loss(m, c, X, Y): n = len(X) Y_pred = m * X + c return np.sum((Y - Y_pred)**2) / n # 生成m和c的网格范围(可根据实际最优值调整范围) m_range = np.linspace(m - 2, m + 2, 100) c_range = np.linspace(c - 20, c + 20, 100) M, C = np.meshgrid(m_range, c_range) # 计算所有网格点的损失值 Z = np.array([compute_loss(m_val, c_val, X, Y) for m_val, c_val in zip(np.ravel(M), np.ravel(C))]) Z = Z.reshape(M.shape) # 创建3D绘图 fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(111, projection='3d') # 绘制损失曲面 ax.plot_surface(M, C, Z, cmap='viridis', alpha=0.7) # 标记最优解位置 ax.scatter(m, c, compute_loss(m, c, X, Y), color='red', s=100, label='最优解') # 设置坐标轴与标题 ax.set_xlabel('斜率 m') ax.set_ylabel('截距 c') ax.set_zlabel('损失 J(m,c)') ax.set_title('线性回归损失曲面') ax.legend() plt.show()
3. 额外优化:添加梯度下降路径
若想展示梯度下降过程中参数的变化轨迹,可在原梯度下降循环中记录每一步的m、c和损失值,再在3D图中绘制:
修改梯度下降循环代码:
# 初始化列表保存迭代过程 m_history = [] c_history = [] loss_history = [] # Performing Gradient Descent for i in range(epochs): Y_pred = m*X + c # The current predicted value of Y D_m = (-2/n) * sum(X * (Y - Y_pred)) # Derivative wrt m D_c = (-2/n) * sum(Y - Y_pred) # Derivative wrt c m = m - L * D_m # Update m c = c - L * D_c # Update c # 记录每一步的参数和损失 m_history.append(m) c_history.append(c) loss_history.append(compute_loss(m, c, X, Y)) print (m, c)
在3D绘图部分添加路径绘制:
# 绘制梯度下降路径 ax.plot(m_history, c_history, loss_history, color='orange', linewidth=2, label='梯度下降路径') ax.legend()
内容的提问来源于stack exchange,提问作者방준호
相关产品推荐
相关产品推荐

