来自deeplearning.ai :
构建神经网络的一般方法是:
- 定义神经网络结构(输入单元数、隐藏单元数等)。
- 初始化模型参数
- 循环:
- 实现前向传播
- 计算损失
- 实现反向传播以获取梯度
- 更新参数(梯度下降)
损失函数如何影响网络的学习方式?
例如,这是我实现的前向和反向传播的代码,我认为是正确的,因为我可以使用下面的代码训练模型以达到可接受的结果:
for i in range(number_iterations): # 前向传播 Z1 = np.dot(weight_layer_1, xtrain) + bias_1 a_1 = sigmoid(Z1) Z2 = np.dot(weight_layer_2, a_1) + bias_2 a_2 = sigmoid(Z2) mse_cost = np.sum(cost_all_examples) cost_cross_entropy = -(1.0/len(X_train) * (np.dot(np.log(a_2), Y_train.T) + np.dot(np.log(1-a_2), (1-Y_train).T)))# 反向传播和梯度下降 d_Z2 = np.multiply((a_2 - xtrain), d_sigmoid(a_2)) d_weight_2 = np.dot(d_Z2, a_1.T) d_bias_2 = np.asarray(list(map(lambda x : [sum(x)] , d_Z2))) # 在负梯度方向上进行参数更新以减少损失 weight_layer_2 = weight_layer_2 + np.multiply(- learning_rate , d_weight_2) bias_2 = bias_2 + np.multiply(- learning_rate , d_bias_2) d_a_1 = np.dot(weight_layer_2.T, d_Z2) d_Z1 = np.multiply(d_a_1, d_sigmoid(a_1)) d_weight_1 = np.dot(d_Z1, xtrain.T) d_bias_1 = np.asarray(list(map(lambda x : [sum(x)] , d_Z1))) weight_layer_1 = weight_layer_1 + np.multiply(- learning_rate , d_weight_1) bias_1 = bias_1 + np.multiply(- learning_rate , d_bias_1)
请注意以下几行:
mse_cost = np.sum(cost_all_examples)cost_cross_entropy = -(1.0/len(X_train) * (np.dot(np.log(a_2), Y_train.T) + np.dot(np.log(1-a_2), (1-Y_train).T)))
我可以使用均方误差损失或交叉熵损失来告知系统的学习情况。但这只是为了提供信息,损失函数的选择并不影响网络的学习方式。我认为我没有理解一些基本的东西,因为在深度学习文献中经常提到选择损失函数是深度学习的一个重要步骤?但如上面的代码所示,我可以选择交叉熵或均方误差损失,并且不影响网络的学习方式,交叉熵或均方误差损失仅用于信息目的?
更新:
例如,这里是来自deeplearning.ai的计算成本的代码片段:
# GRADED FUNCTION: compute_costdef compute_cost(A2, Y, parameters): """ 计算方程(13)中的交叉熵成本 参数: A2 -- 第二个激活的Sigmoid输出,形状为(1, 示例数量) Y -- 形状为(1, 示例数量)的“真实”标签向量 parameters -- 包含您的参数W1, b1, W2和b2的python字典 返回: cost -- 方程(13)中的交叉熵成本 """ m = Y.shape[1] # 示例数量 # 从parameters中检索W1和W2 ### START CODE HERE ### (≈ 2 lines of code) W1 = parameters['W1'] W2 = parameters['W2'] ### END CODE HERE ### # 计算交叉熵成本 ### START CODE HERE ### (≈ 2 lines of code) logprobs = np.multiply(np.log(A2), Y) + np.multiply((1 - Y), np.log(1 - A2)) cost = - np.sum(logprobs) / m ### END CODE HERE ### cost = np.squeeze(cost) # 确保成本的维度是我们期望的。 # 例如,将[[17]]转换为17 assert(isinstance(cost, float)) return cost
这段代码按预期运行并实现了高准确度/低成本。成本的值在这段实现中除了向机器学习工程师提供网络学习情况的信息外,没有其他用途。这让我质疑选择成本函数如何影响神经网络的学习?
回答:
嗯,这只是一个粗略的高层次尝试,回答可能不适合SO的问题(正如我理解你原则上的困惑)。
成本的值在这段实现中除了向机器学习工程师提供网络学习情况的信息外,没有其他用途。
实际上,这是正确的;仔细阅读Andrew Ng的Jupyter笔记本中你发布的compute_cost
函数,你会看到:
5 – 成本函数
现在你将实现前向和反向传播。你需要计算成本,因为你想检查你的模型是否真的在学习。
字面上,这是在你的代码中明确计算成本函数的实际值的唯一原因。
但这只是为了提供信息,损失函数的选择并不影响网络的学习方式。
别急!这里有一个(通常不可见的)陷阱:
选择成本函数决定了用于计算dw
和db
量的具体方程,因此决定了学习过程。
请注意,这里我讨论的是函数本身,而不是它的值。
换句话说,像你的
d_weight_2 = np.dot(d_Z2, a_1.T)
和
d_weight_1 = np.dot(d_Z1, xtrain.T)
这些计算不是凭空而来的,而是反向传播数学应用于特定成本函数的结果。
这里是Andrew在Coursera的入门课程中一些相关的高等级幻灯片:
希望这有帮助;关于我们如何从成本函数的导数开始到达dw
和db
计算的具体形式的细节超出了本文的范围,但你可以在线找到许多关于反向传播的好教程(这里是一个)。
最后,对于选择错误的成本函数(例如,将二元交叉熵用于多类分类,而不是正确的分类交叉熵)可能会发生什么的(非常)高级描述,你可以查看我在Keras binary_crossentropy vs categorical_crossentropy performance?上的回答。