在小批量更新上执行L1正则化

时间:2017-06-19 01:40:47

标签: python neural-network gradient-descent regularized mini-batch

我目前正在阅读Neural Networks and Deep Learning并且我遇到了问题。问题是更新他给出的​​代码以使用L1正则化而不是L2正则化。

使用L2正则化的原始代码是:

self.weights

可以看到使用L2正则化项更新nabla_w。对于L1正则化,我认为我只需要更新同一行以反映

weight update for l1 regularization

书中陈述我们可以估计

enter image description here

使用小批量平均值的术语。这对我来说是一个令人困惑的陈述,但我认为这意味着每个小批量使用每层的def update_mini_batch(self, mini_batch, eta, lmbda, n): """Update the network's weights and biases by applying gradient descent using backpropagation to a single mini batch. The ``mini_batch`` is a list of tuples ``(x, y)``, ``eta`` is the learning rate, ``lmbda`` is the regularization parameter, and ``n`` is the total size of the training data set. """ 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)] avg_nw = [np.array([[np.average(layer)] * len(layer[0])] * len(layer)) for layer in nabla_w] self.weights = [(1-eta*(lmbda/n))*w-(eta)*nw for w, nw in zip(self.weights, avg_nw)] self.biases = [b-(eta/len(mini_batch))*nb for b, nb in zip(self.biases, nabla_b)] 的平均值。这导致我对代码进行了以下编辑:

{{1}}

但我得到的结果几乎只是噪音,准确率约为10%。我是否解释了错误的陈述或我的代码是错的?任何提示都将不胜感激。

1 个答案:

答案 0 :(得分:1)

这不正确。

概念上 L2 正则化表示我们将在每次训练迭代后将几何缩小W下降一些衰减。这样,如果W变得非常大,它将缩小更多。这使得W中的各个值不会变得太大。

概念上 L1 正则化表示我们将在每次训练迭代之后<强>线性将W减少一些常数(不要越过零。正数减少到零但不是在下面。负数增加到零而不是在上面。)这会将非常小的W值归零,只留下值作出重大贡献的值。

你的第二个等式

self.weights = [(1-eta*(lmbda/n))*w-(eta)*nw
                for w, nw in zip(self.weights, avg_nw)]

没有实现原始减法,但仍然在(1-eta *(lmbda / n))* w 中进行乘法(几何缩放)。

实现一些函数 reduceLinearlyToZero ,它取w和eta *(lmbda / n)并返回max(abs(w-eta *(lmbda / n)),0)*(1.0如果w&gt; ; = =其他-1.0)

def reduceLinearlyToZero(w,eta,lmbda,n) :
    return max( abs( w - eta*(lmbda/n) ) , 0 ) * ( 1.0 if w >= 0 else -1.0 )


self.weights = [ reduceLinearlyToZero(w,eta,lmbda,n)-(eta/len(mini_batch))*nw
                for w, nw in zip(self.weights, avg_nw)]

或可能

self.weights = [ reduceLinearlyToZero(w-(eta/len(mini_batch))*nw,eta,lmbda,n)
                for w, nw in zip(self.weights, avg_nw)]