0

現在、私はNeural Networks and Deep Learningを読んでおり、問題が残っています。問題は、彼がL2正則化の代わりにL1正則化を使用するために与えたコードを更新することです。ミニバッチ更新でL1正規化を実行する

L2正則化を使用するコードの元の部分である:

self.weightsをL2正則用語を使用して更新されることが分かる
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)] 
    self.weights = [(1-eta*(lmbda/n))*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)] 

。 L1正則化のために、私はちょうどそれは、私たちはミニを使用して

enter image description here

用語を推定することができる本に記載されている

weight update for l1 regularization

を反映するために、その同じ行を更新する必要があることと考えています - バッチ平均。これは私にとっては紛らわしい声明でしたが、各ミニバッチで各レイヤーの平均値をnabla_wとすることが考えられました。

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)] 

が、私は約10%の精度で、かなりノイズだけです取得結果:これは、コードを次のように編集を行うために私を導きました。私は文を間違って解釈しているのですか、またはコードが間違っていますか?どんなヒントもありがとう。

答えて

1

これは間違っています。

は、概念的には L2正則たちは各トレーニング反復の後、いくつかの崩壊によって 幾何学的に規模Wダウンしようとしていると言っています。そうすれば、Wが本当に大きくなると、それはもっと小さくなるでしょう。これにより、W内の個々の値が大きくなりすぎることがなくなります。

概念的L1正則は(ゼロを交差しない、我々は各トレーニング反復の後、いくつかの定数でダウンW 直線減少しようとしていると言っている。正の数がゼロになるではなく、以下にされている。負の数はに増加していますゼロ以上ではありません)。これは、Wの非常に小さな値をゼロにして、重要な貢献をする値だけを残します。

あなたの第2式

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

は、生の減算を実装していないが、それでも wは* (1-エータ*(lmbda/N))で乗算(幾何学的なスケーリングを)持っています。 ( - ETA *(lmbda/n))は、0 wはABS()*(1.0場合> = 0他ワット

は、MAXを*(lmbda/n)のワットとイータを取り、返すいくつかの機能reduceLinearlyToZeroを実装します - 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)] 
+0

これは非常に非常に役に立ちました。私は、L1とL2の正則化の概念的な記述が目の開きであることを発見しました。ありがとうございました! –

関連する問題