我正在按照mnielsen的在线书籍进行学习。我尝试在他的代码中实现这里定义的动量权重更新。动量权重更新的总体思路是,不直接用负梯度改变权重向量。你需要一个参数velocity
,初始时设为零,然后设定超参数mu
通常为0.9
。
# 动量更新v = mu * v - learning_rate * dx # 整合速度x += v # 整合位置
所以我有权重w和权重变化nebla_w
,如下面的代码片段所示:
def update_mini_batch(self, mini_batch, eta): """通过对单个小批量应用反向传播的梯度下降法来更新网络的权重和偏置。 ``mini_batch``是一个元组列表``(x, y)``,``eta``是学习率。""" nabla_b = [np.zeros(b.shape) for b in self.biases] nabla_w = [np.zeros(w.shape) for w in self.weights] for x, y in mini_batch: delta_nabla_b, delta_nabla_w = self.backprop(x, y) nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)] nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] self.weights = [w-(eta/len(mini_batch))*nw for w, nw in zip(self.weights, nabla_w)] self.biases = [b-(eta/len(mini_batch))*nb for b, nb in zip(self.biases, nabla_b)]
所以在最后两行中,你更新self.weight
如下:
self.weights = [w-(eta/len(mini_batch))*nw for w, nw in zip(self.weights, nabla_w)]
对于动量权重更新,我做了如下操作:
self.momentum_v = [ (momentum_mu * self.momentum_v) - ( ( float(eta) / float(len(mini_batch)) )* nw) for nw in nebla_w ]self.weights = [ w + v for w, v in zip (self.weights, self.momentum_v)]
然而,我得到了以下错误:
TypeError: can't multiply sequence by non-int of type 'float'
在momentum_v
更新时。我的eta
超参数已经是浮点数,尽管我又用float函数包装了一次。我也用float包装了len(mini_batch)
。我还尝试了nw.astype(float)
,但仍然会得到这个错误。我不确定为什么。nabla_w
是一个浮点数的numpy数组。
回答:
如评论中所讨论,这里有些东西不是numpy数组。上面给出的错误
TypeError: can't multiply sequence by non-int of type 'float'
是Python对序列类型(列表、元组等)发出的错误。错误信息意味着序列不能乘以非整数。它们可以乘以整数,但这不会改变值——它只是重复序列,即,
>>> [1, 0] * 3[1, 0, 1, 0, 1, 0]
当然,在这种情况下,乘以浮点数是没有意义的:
>>> [1, 0] * 3.14Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: can't multiply sequence by non-int of type 'float'
你会看到和你这里相同的错误信息。所以你乘的某个变量确实不是numpy数组,而是通用的序列类型。简单地在有问题的变量周围加上np.array()
的转换可以解决这个问题,或者你当然可以将其定义改为数组。