找回密码
 立即注册
首页 业界区 业界 刘二大人PyTorch深度学习实践第二讲笔记

刘二大人PyTorch深度学习实践第二讲笔记

雌鲳签 2025-11-25 18:30:38
碎碎念:
开个新坑,系统学一遍深度学习好做毕设,能到河工大挺激动的,赶紧给刘二大人投自荐简历,但是已读不回,还是自己太菜了........不过已经到河工大了挺好的,梦校
第二讲

线性模型
1.png

2.png

可能x(输入)到y(答案)是一个线性模型,但是w或者其他的权重值不确定,所以机器随机选取权重数值,看看哪个公式得到的预期答案和真实答案偏差较小,就是训练的最优模型
评价方法MSE:(假设x到y的映射就是简单的y=x*w)
3.png

(模型预期值-真实值)的平方再平均,就是MSE(均方误差)
还是假设y=w*x,找出最佳权重:
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. x_data=[1.0,2.0,3.0]
  4. y_data=[3.0,6.0,9.0]
  5. def forward(x):
  6.     return x*w
  7. def loss(x,y):
  8.     y_pred=forward(x)
  9.     return (y_pred-y)*(y_pred-y)
  10. w_list=[]
  11. mse_list=[]
  12. for w in np.arange(0.0,4.1,0.1):
  13.     print("w=",w)
  14.     l_sum=0
  15.     for x_val,y_val in zip(x_data,y_data):
  16.         y_pred_val=forward(x_val)
  17.         loss_val=loss(x_val,y_val)
  18.         l_sum+=loss_val
  19.         print('\t',x_val,y_val,y_pred_val,loss_val)
  20.     print('MSE = ',l_sum/3)
  21.     w_list.append(w)
  22.     mse_list.append(l_sum/3)
  23. plt.plot(w_list,mse_list)
  24. plt.ylabel('Loss')
  25. plt.xlabel('w')
  26. plt.show()
复制代码
结果:
4.png

再试一个y=w*x+b的
  1. # import numpy as np
  2. # import matplotlib.pyplot as plt
  3. #
  4. # x_data=[1.0,2.0,3.0]
  5. # y_data=[3.0,6.0,9.0]
  6. #
  7. #
  8. # def forward(x):
  9. #     return x*w
  10. #
  11. # def loss(x,y):
  12. #     y_pred=forward(x)
  13. #     return (y_pred-y)*(y_pred-y)
  14. #
  15. # w_list=[]
  16. # mse_list=[]
  17. #
  18. # for w in np.arange(0.0,4.1,0.1):
  19. #     print("w=",w)
  20. #     l_sum=0
  21. #     for x_val,y_val in zip(x_data,y_data):
  22. #         y_pred_val=forward(x_val)
  23. #         loss_val=loss(x_val,y_val)
  24. #         l_sum+=loss_val
  25. #         print('\t',x_val,y_val,y_pred_val,loss_val)
  26. #     print('MSE = ',l_sum/3)
  27. #     w_list.append(w)
  28. #     mse_list.append(l_sum/3)
  29. # plt.plot(w_list,mse_list)
  30. # plt.ylabel('Loss')
  31. # plt.xlabel('w')
  32. # plt.show()
  33. import numpy as np
  34. import matplotlib.pyplot as plt
  35. from mpl_toolkits.mplot3d import Axes3D
  36. x_data=[1.0,2.0,3.0]
  37. y_data=[4.0,7.0,10.0]
  38. def forward(x):
  39.     return x*w+b
  40. def loss(x,y):
  41.     y_pred=forward(x)
  42.     return (y_pred-y)*(y_pred-y)
  43. w_list=[]
  44. b_list=[]
  45. mse_list=[]
  46. for w in np.arange(0.0,4.1,0.1):
  47.     for b in np.arange(0.0,4.1,0.1):
  48.         l_sum=0
  49.         for x_val,y_val in zip(x_data,y_data):
  50.             y_pred_val=forward(x_val)
  51.             loss_val=loss(x_val,y_val)
  52.             l_sum+=loss_val
  53.         #     print('\t',x_val,y_val,y_pred_val,loss_val)
  54.         # print('MSE = ',l_sum/3)
  55.         w_list.append(w)
  56.         b_list.append(b)
  57.         mse_list.append(l_sum/3)
  58. # 转换为numpy数组并重塑为网格格式
  59. w_array = np.array(w_list)
  60. b_array = np.array(b_list)
  61. mse_array = np.array(mse_list)
  62. # 创建网格数据
  63. w_unique = np.unique(w_array)
  64. b_unique = np.unique(b_array)
  65. W, B = np.meshgrid(w_unique, b_unique)
  66. MSE = mse_array.reshape(len(b_unique), len(w_unique))
  67. # 绘图
  68. fig = plt.figure(figsize=(10, 8))
  69. ax = fig.add_subplot(111, projection='3d')
  70. # 使用plot_surface绘制曲面
  71. surf = ax.plot_surface(W, B, MSE, cmap='viridis', alpha=0.8)
  72. ax.set_xlabel('权重 w')
  73. ax.set_ylabel('偏置 b')
  74. ax.set_zlabel('MSE 损失')
  75. ax.set_title('损失函数曲面: y = w*x + b')
  76. # 添加颜色条
  77. fig.colorbar(surf, ax=ax, shrink=0.5, aspect=5)
  78. # 找到最小MSE的点
  79. min_idx = np.argmin(mse_array)
  80. best_w = w_array[min_idx]
  81. best_b = b_array[min_idx]
  82. best_mse = mse_array[min_idx]
  83. # 标记最优点
  84. ax.scatter([best_w], [best_b], [best_mse], color='red', s=100, label=f'最优: w={best_w:.1f}, b={best_b:.1f}')
  85. ax.legend()
  86. plt.show()
  87. print(f"最优参数: w = {best_w:.1f}, b = {best_b:.1f}")
  88. print(f"最小MSE: {best_mse:.4f}")
复制代码
5.png


  • 坐标网格: W 和 B
  • 值网格: MSE
最后的坐标网络,W和B也各自是二维数组,这样才能和MSE组成一个3维图
这段有点难理解,ai写了下
  1. # 转换为numpy数组并重塑为网格格式
  2. w_array = np.array(w_list)
  3. b_array = np.array(b_list)
  4. mse_array = np.array(mse_list)
  5. # 创建网格数据
  6. w_unique = np.unique(w_array)
  7. b_unique = np.unique(b_array)
  8. W, B = np.meshgrid(w_unique, b_unique)
  9. MSE = mse_array.reshape(len(b_unique), len(w_unique))
复制代码
最后几段分步详解

我们来一步步拆解每一行代码:
1. w_unique = np.unique(w_array)


  • w_array这是一个一维的 NumPy 数组,里面存储了一系列的权重(weight)值。这些值可能有重复。

    • 例如:w_array = [1, 2, 2, 3, 3, 3]

  • np.unique(): 这是 NumPy 的一个函数,它会返回输入数组中排序后唯一值(即去重后的值)。
  • 结果 w_unique它将是
    1. w_array
    复制代码
    中所有不重复的权重值,并按从小到大排列。

    • 例如:w_unique = [1, 2, 3]

这一步的目的是:找出所有不同的权重值,作为我们后续网格的 X 轴坐标。
2. b_unique = np.unique(b_array)


  • b_array这是一个一维的 NumPy 数组,里面存储了一系列的偏置(bias)值。这些值也可能有重复。

    • 例如:b_array = [4, 4, 5, 5, 6]

  • 结果 b_unique它将是
    1. b_array
    复制代码
    中所有不重复的偏置值,并按从小到大排列。

    • 例如:b_unique = [4, 5, 6]

这一步的目的是:找出所有不同的偏置值,作为我们后续网格的 Y 轴坐标。
3. W, B = np.meshgrid(w_unique, b_unique)


  • np.meshgrid(): 这是最关键的一步。它接收两个一维数组,并返回两个二维数组。这两个二维数组共同构成了一个网格的坐标。

    • 它会以第一个输入数组(w_unique)为列,以第二个输入数组(b_unique)为行,创建一个二维坐标网格。

  • 结果 W 和 B:

    • W 是一个二维数组,它的每一行都是 w_unique。
    • B 是一个二维数组,它的每一列都是 b_unique。

  • 举例说明

    • 输入: w_unique = [1, 2, 3], b_unique = [4, 5, 6]
    • 输出:
      1. W = [[1 2 3]
      2.      [1 2 3]
      3.      [1 2 3]]
      4. B = [[4 4 4]
      5.      [5 5 5]
      6.      [6 6 6]]
      复制代码
    • 这样,W 和 B 就共同定义了一个 3x3 的网格,每个网格点的坐标 (W[j], B[j]) 都对应一个 (权重, 偏置) 的组合。

这一步的目的是:创建一个完整的二维坐标网格,覆盖所有可能的(权重, 偏置)组合。
4. MSE = mse_array.reshape(len(b_unique), len(w_unique))


  • mse_array: 这是一个一维的 NumPy 数组,里面存储了与w_array和b_array中每一组(w, b)相对应的均方误差(Mean Squared Error)值。

    • 它的长度必须与w_array和b_array相同。
    • 例如,如果 w_array 和 b_array 都有 6 个元素,mse_array 也必须有 6 个元素。

  • len(b_unique) 和 len(w_unique): 它们分别是网格的行数和列数。在我们的例子中,行数是 3,列数是 3。
  • reshape(...): 这个函数将一维的mse_array转换成一个二维数组。

    • 非常重要:reshape 函数默认是 ** 按行优先(C-style)** 的顺序重新排列元素的。这意味着,mse_array 中的元素必须是按照与 np.meshgrid 生成网格时相同的顺序排列的。
    • 也就是说,mse_array 的元素顺序应该是先固定b,再遍历w。例如:[mse(w=1,b=4), mse(w=2,b=4), mse(w=3,b=4), mse(w=1,b=5), ...]

  • 结果 MSE: 一个二维的 MSE 数组,它的形状是 (网格行数, 网格列数),也就是 (len(b_unique), len(w_unique))。

    • 这个二维数组MSE中的每一个元素MSE[j],都对应于网格坐标(W[j], B[j])处的均方误差值。

这一步的目的是:将一维的 MSE 值数组,按照我们创建的网格形状,重新组织成一个二维的 MSE 矩阵。
总结:为什么要这么做?

假设你有一批数据点 (w, b, mse),它们可能是这样散落的:

  • (1, 4, 0.1)
  • (2, 4, 0.2)
  • (3, 4, 0.15)
  • (1, 5, 0.3)
  • ...
通过上述四行代码,你将这些散落的数据点,整理成了一个结构化的、可以直接用于绘图的二维数据结构:

  • 坐标网格: W 和 B
  • 值网格: MSE
这样,你就可以使用像 matplotlib 这样的库,轻松地绘制出一张关于 w 和 b 的 MSE 热力图(imshow(MSE)),或者一个 3D 曲面图(plot_surface(W, B, MSE)),从而直观地看到在不同的权重和偏置组合下,模型的误差是如何变化的。这对于寻找最优的模型参数非常有帮助。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册