注意,反向传播算法会重复利用前向传播中存储的中间值,以避免重复计算,因此,需要保留前向传播的中间结果,这也会导致模型训练比单纯的预测需要更多的内存(显存)。同时这些中间结果占用内存(显存)大小与网络层的数量和批量(batch_size)大小成正比,因此使用大 batch_size 训练更深层次的网络更容易导致内存不足(out of memory)的错误!
1.4,总结
前向传播在神经网络定义的计算图中按顺序计算和存储中间变量,它的顺序是从输入层到输出层。
反向传播按相反的顺序(从输出层到输入层)计算和存储神经网络的中间变量和参数的梯度。
在训练神经网络时,在初始化模型参数后,我们交替使用前向传播和反向传播,基于反向传播计算得到的梯度,结合随机梯度下降优化算法(或者 Adam 等其他优化算法)来更新模型参数。
def derivative_function(theta): x = theta[0] y = theta[1] return np.array([2*x, 4*y])
def show_3d_surface(x, y, z): fig = plt.figure() ax = Axes3D(fig) u = np.linspace(-3, 3, 100) v = np.linspace(-3, 3, 100) X, Y = np.meshgrid(u, v) R = np.zeros((len(u), len(v))) for i in range(len(u)): for j in range(len(v)): R[i, j] = pow(X[i, j], 2)+ 4*pow(Y[i, j], 2)
ax.plot_surface(X, Y, R, cmap='rainbow') plt.plot(x, y, z, c='black', linewidth=1.5, marker='o', linestyle='solid') plt.show()
if __name__ == '__main__': theta = np.array([-3, -3]) # 输入为双变量 eta = 0.1# 学习率 error = 5e-3# 迭代终止条件,目标函数值 < error X = [] Y = [] Z = [] for i in range(50): print(theta) x = theta[0] y = theta[1] z = target_function(x,y) X.append(x) Y.append(y) Z.append(z) print("%d: x=%f, y=%f, z=%f" % (i,x,y,z)) d_theta = derivative_function(theta) print(" ", d_theta) theta = theta - eta * d_theta if z < error: break show_3d_surface(X,Y,Z)