【PyTorch深度学习实践】从零构建线性回归模型:手动计算损失与可视化分析

张开发
2026/4/20 1:55:47 15 分钟阅读

分享文章

【PyTorch深度学习实践】从零构建线性回归模型:手动计算损失与可视化分析
1. 线性回归模型的核心思想线性回归可能是机器学习中最简单的模型但它却是理解深度学习的重要基石。记得我第一次接触这个概念时总觉得用直线拟合数据听起来太简单了直到真正动手实现才发现其中蕴含的深刻思想。线性回归的本质是寻找一条最佳拟合直线来描述自变量x和因变量y之间的关系。这个关系可以用一个简单的数学公式表示y w * x b。其中w是权重斜率b是偏置截距。在我们的简化示例中我们先忽略b专注于理解w的作用。为什么要从线性回归开始因为它完美展示了机器学习的三个核心步骤定义模型这里是线性函数定义评估模型好坏的指标损失函数找到使指标最优化的参数w和b我刚开始学习时犯过一个典型错误 - 试图一次性理解所有概念。后来发现最好的方式是像这样拆解问题先固定b0只调整w等完全理解了再引入b。这种分阶段的学习方法让我事半功倍。2. 手动实现前向传播与损失计算2.1 准备示例数据我们先定义一组简单的训练数据x_data [1.0, 2.0, 3.0] # 输入特征 y_data [2.0, 4.0, 6.0] # 对应标签这组数据看似简单但非常适合教学。我建议初学者不要急于使用复杂数据先用这种人工构造的、有明显规律的数据练习可以更直观地观察模型行为。2.2 实现前向传播函数前向传播就是根据输入x计算预测值y_hat的过程def forward(x): return x * w # 最简单的线性模型这个函数简单到令人怀疑它是否有用但这就是深度学习的起点所有复杂的神经网络最终都是在做类似的事情 - 将输入通过一系列变换得到输出。2.3 实现损失函数损失函数衡量预测值与真实值的差距我们使用最常用的均方误差(MSE)def loss(x, y): y_pred forward(x) return (y_pred - y) ** 2 # 平方误差MSE的优点是对大误差惩罚更重因为平方这使得优化过程会更关注减少大的错误。我在实践中发现理解损失函数的选择对模型性能影响很大这是调参时的重要杠杆。3. 参数搜索与可视化分析3.1 遍历参数空间我们不使用任何优化算法而是暴力遍历可能的w值w_list [] mse_list [] for w in np.arange(0.0, 4.0, 0.1): # w从0到4步长0.1 l_sum 0 for x_val, y_val in zip(x_data, y_data): l_sum loss(x_val, y_val) mse l_sum / len(x_data) # 计算平均损失 w_list.append(w) mse_list.append(mse)这段代码做了几件重要的事情尝试不同的w值0.0, 0.1, 0.2,...,4.0对每个w计算所有训练样本的损失总和计算平均损失(MSE)3.2 可视化损失曲线绘制损失随w变化的曲线plt.plot(w_list, mse_list) plt.xlabel(w) plt.ylabel(Loss) plt.show()这个可视化结果非常关键我第一次看到这条U型曲线时才真正理解了优化的含义 - 我们就是在寻找曲线的最低点。从图中可以明显看到w2时损失最小这与我们的数据规律完美吻合因为y2x。4. 从线性回归到深度学习4.1 为什么手动实现很重要现在各种深度学习框架让实现模型变得异常简单但我强烈建议初学者像这样手动实现几次。这让我理解了几个关键点所有机器学习本质上都是在最小化损失函数参数更新后面会学的梯度下降只是更高效的搜索方法可视化是理解模型行为的强大工具4.2 常见问题与调试技巧在实现过程中我遇到过几个典型问题变量未初始化比如忘记初始化l_sum0导致报错。这是Python新手常犯的错误。步长选择np.arange的步长不能太小否则计算量剧增也不能太大会错过最优解。0.1是个不错的起点。数值范围w的搜索范围需要合理估计。太窄可能不包含最优解太宽则浪费计算资源。维度匹配当引入多维数据时要特别注意矩阵乘法的维度匹配问题。5. 扩展到更复杂场景虽然我们的例子非常简单但其中体现的思想可以推广多维线性回归可以扩展为y w1x1 w2x2 ... b非线性变换通过添加x²、sin(x)等项实现多项式回归批量计算使用矩阵运算代替循环提高效率这些扩展本质上都是在修改forward函数的形式而损失函数和优化过程保持不变。这种模块化的思想在深度学习中非常重要。6. 完整代码实现以下是整合了所有功能的完整代码我添加了详细注释import numpy as np import matplotlib.pyplot as plt # 训练数据 x_data [1.0, 2.0, 3.0] y_data [2.0, 4.0, 6.0] # 前向传播函数 def forward(x): return x * w # 线性模型 # 损失函数 def loss(x, y): y_pred forward(x) return (y_pred - y) ** 2 # 均方误差 # 存储参数和损失值 w_list [] mse_list [] # 参数搜索 for w in np.arange(0.0, 4.0, 0.1): # w从0到4步长0.1 print(fw {w:.1f}) # 打印当前w值 l_sum 0 # 必须初始化 for x_val, y_val in zip(x_data, y_data): l loss(x_val, y_val) l_sum l print(f\t{x_val}, {y_val} {forward(x_val):.2f}, loss{l:.2f}) mse l_sum / len(x_data) # 计算平均损失 print(fMSE {mse:.2f}\n) # 存储结果用于绘图 w_list.append(w) mse_list.append(mse) # 可视化 plt.plot(w_list, mse_list) plt.xlabel(Weight (w)) plt.ylabel(Mean Squared Error) plt.title(Loss Landscape for Linear Regression) plt.show()运行这段代码你会看到随着w接近2.0MSE逐渐减小并在w2.0时达到最小之后又开始增大。这个简单的实验揭示了机器学习中最核心的优化概念。

更多文章