我编写了一些代码,以通过逻辑激活函数和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/

10-12 23:09