python - 修正线性单元的反向传播

标签 python numpy neural-network backpropagation

我已经编写了一些代码来在具有逻辑激活函数和 softmax 输出的深度神经网络中实现反向传播。

def backprop_deep(node_values, targets, weight_matrices):
    delta_nodes = node_values[-1] - targets
    delta_weights = delta_nodes.T.dot(node_values[-2])
    weight_updates = [delta_weights]
    for i in xrange(-2, -len(weight_matrices)- 1, -1):
        delta_nodes = dsigmoid(node_values[i][:,:-1]) * delta_nodes.dot(weight_matrices[i+1])[:,:-1]
        delta_weights = delta_nodes.T.dot(node_values[i-1])
        weight_updates.insert(0, delta_weights)
    return weight_updates

代码运行良好,但当我切换到 ReLU 作为激活函数时,它停止工作了。在 backprop 例程中,我只更改了激活函数的导数:

def backprop_relu(node_values, targets, weight_matrices):
    delta_nodes = node_values[-1] - targets
    delta_weights = delta_nodes.T.dot(node_values[-2])
    weight_updates = [delta_weights]
    for i in xrange(-2, -len(weight_matrices)- 1, -1):
        delta_nodes = (node_values[i]>0)[:,:-1] * delta_nodes.dot(weight_matrices[i+1])[:,:-1]
        delta_weights = delta_nodes.T.dot(node_values[i-1])
        weight_updates.insert(0, delta_weights)
    return weight_updates

但是,网络不再学习,权重很快变为零并保持不变。我完全被难住了。

最佳答案

虽然我已经确定了问题的根源,但我将保留它以防其他人受益。

问题是我在更改激活函数时没有调整初始权重的比例。当节点输入接近于零且逻辑函数近似线性时,逻辑网络学习得很好,而 ReLU 网络在节点输入适度大时学习得很好。因此,逻辑网络中使用的小权重初始化是不必要的,实际上是有害的。我看到的行为是 ReLU 网络忽略了特征并试图专门学习训练集的偏差。

我目前在 MNIST 数据集上使用从 -.5 到 .5 均匀分布的初始权重,它学习得非常快。

关于python - 修正线性单元的反向传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29451165/

相关文章:

python - 在 tensorflow.data.Dataset.map() 函数中完成的操作梯度

python - ZMQ 上下文套接字创建在新计算机上慢得多

python - 如何在python中将4维数组转换为2维并另存为csv

python - 有效地查找 numpy 数组中二进制字符串中的位位置

python - 为 Pandas 数据框中的每一行运行一次函数

python - 如何将密集层转换为 Keras 中的等效卷积层?

machine-learning - 强化学习和POMDP

python - 以人类可读的格式保存 numpy 数组的字典

python - 从html代码中提取数据

python - 使用 numpy 将非常小的值取为实际的 0 时,如何优雅地设置精度/容差?