1

私は機械学習とニューラルネットワークの初心者です。最近、Andrew Ngの深い学習に関する講義を見てから、私は深い神経ネットワークを使ってバイナリ分類器を自分で実装しようとしました。
しかし、関数のコストは各反復後に減少すると予想されます。 私のプログラムでは、最初はわずかに減少しましたが、後で急激に増加します。学習率や反復回数を変更しようとしましたが、無駄にしました。私は非常に混乱しています。
は、ここに私のコード

ディープニューラルネットワークの実装でのコストは、何度か反復して増加するのはなぜですか?

1.ニューラルネットワーク分類器クラスです

class NeuralNetwork: 
    def __init__(self, X, Y, dimensions, alpha=1.2, iter=3000): 
     self.X = X 
     self.Y = Y 
     self.dimensions = dimensions # Including input layer and output layer. Let example be dimensions=4 
     self.alpha = alpha # Learning rate 
     self.iter = iter # Number of iterations 
     self.length = len(self.dimensions)-1 
     self.params = {} # To store parameters W and b for each layer 
     self.cache = {}  # To store cache Z and A for each layer 
     self.grads = {}  # To store dA, dZ, dW, db 
     self.cost = 1  # Initial value does not matter 

    def initialize(self): 
     np.random.seed(3) 
     # If dimensions is 4, then layer 0 and 3 are input and output layers 
     # So we only need to initialize w1, w2 and w3 
     # There is no need of w0 for input layer 
     for l in range(1, len(self.dimensions)): 
      self.params['W'+str(l)] = np.random.randn(self.dimensions[l], self.dimensions[l-1])*0.01 
      self.params['b'+str(l)] = np.zeros((self.dimensions[l], 1)) 

    def forward_propagation(self): 
     self.cache['A0'] = self.X 
     # For last layer, ie, the output layer 3, we need to activate using sigmoid 
     # For layer 1 and 2, we need to use relu 
     for l in range(1, len(self.dimensions)-1): 
      self.cache['Z'+str(l)] = np.dot(self.params['W'+str(l)], self.cache['A'+str(l-1)]) + self.params['b'+str(l)] 
      self.cache['A'+str(l)] = relu(self.cache['Z'+str(l)]) 
     l = len(self.dimensions)-1 
     self.cache['Z'+str(l)] = np.dot(self.params['W'+str(l)], self.cache['A'+str(l-1)]) + self.params['b'+str(l)] 
     self.cache['A'+str(l)] = sigmoid(self.cache['Z'+str(l)]) 

    def compute_cost(self): 
     m = self.Y.shape[1] 
     A = self.cache['A'+str(len(self.dimensions)-1)] 
     self.cost = -1/m*np.sum(np.multiply(self.Y, np.log(A)) + np.multiply(1-self.Y, np.log(1-A))) 
     self.cost = np.squeeze(self.cost) 

    def backward_propagation(self): 
     A = self.cache['A' + str(len(self.dimensions) - 1)] 
     m = self.X.shape[1] 
     self.grads['dA'+str(len(self.dimensions)-1)] = -(np.divide(self.Y, A) - np.divide(1-self.Y, 1-A)) 
     # Sigmoid derivative for final layer 
     l = len(self.dimensions)-1 
     self.grads['dZ' + str(l)] = self.grads['dA' + str(l)] * sigmoid_prime(self.cache['Z' + str(l)]) 
     self.grads['dW' + str(l)] = 1/m * np.dot(self.grads['dZ' + str(l)], self.cache['A' + str(l - 1)].T) 
     self.grads['db' + str(l)] = 1/m * np.sum(self.grads['dZ' + str(l)], axis=1, keepdims=True) 
     self.grads['dA' + str(l - 1)] = np.dot(self.params['W' + str(l)].T, self.grads['dZ' + str(l)]) 
     # Relu derivative for previous layers 
     for l in range(len(self.dimensions)-2, 0, -1): 
      self.grads['dZ'+str(l)] = self.grads['dA'+str(l)] * relu_prime(self.cache['Z'+str(l)]) 
      self.grads['dW'+str(l)] = 1/m*np.dot(self.grads['dZ'+str(l)], self.cache['A'+str(l-1)].T) 
      self.grads['db'+str(l)] = 1/m*np.sum(self.grads['dZ'+str(l)], axis=1, keepdims=True) 
      self.grads['dA'+str(l-1)] = np.dot(self.params['W'+str(l)].T, self.grads['dZ'+str(l)]) 

    def update_parameters(self): 
     for l in range(1, len(self.dimensions)): 
      self.params['W'+str(l)] = self.params['W'+str(l)] - self.alpha*self.grads['dW'+str(l)] 
      self.params['b'+str(l)] = self.params['b'+str(l)] - self.alpha*self.grads['db'+str(l)] 

    def train(self): 
     np.random.seed(1) 
     self.initialize() 
     for i in range(self.iter): 
      #print(self.params) 
      self.forward_propagation() 
      self.compute_cost() 
      self.backward_propagation() 
      self.update_parameters() 
      if i % 100 == 0: 
       print('Cost after {} iterations is {}'.format(i, self.cost)) 



奇数か偶数分類器2.テストコード

import numpy as np 
from main import NeuralNetwork 
X = np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]) 
Y = np.array([[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]) 
clf = NeuralNetwork(X, Y, [1, 1, 1], alpha=0.003, iter=7000) 
clf.train() 



3.ヘルパーコード

import math 
import numpy as np 

def sigmoid_scalar(x): 
    return 1/(1+math.exp(-x)) 
def sigmoid_prime_scalar(x): 
    return sigmoid_scalar(x)*(1-sigmoid_scalar(x)) 
def relu_scalar(x): 
    if x > 0: 
     return x 
    else: 
     return 0 
def relu_prime_scalar(x): 
    if x > 0: 
     return 1 
    else: 
     return 0 
sigmoid = np.vectorize(sigmoid_scalar) 
sigmoid_prime = np.vectorize(sigmoid_prime_scalar) 
relu = np.vectorize(relu_scalar) 
relu_prime = np.vectorize(relu_prime_scalar) 



出力

enter image description here

+0

2つのことが思い浮かぶ:1.低い学習率( '1E-5')を試したことがありますか?2.入力を拡大しようとしましたか?おそらく 'X = X/10'のような単純なもので十分でしょう。 –

+0

は、私がポイントに学習率 – Sahil

+0

コストの低下を低減しようとしたロドリゴ・シルベイラ@ – Sahil

答えて

1

私はあなたのクロスエントロピー誘導体は間違っていると信じています。この代わりに:

# WRONG! 
self.grads['dA'+str(len(self.dimensions)-1)] = -(np.divide(self.Y, A) - np.divide(1-self.Y, A)) 

が...次の操作を行います。

# CORRECT 
self.grads['dA'+str(len(self.dimensions)-1)] = np.divide(A - self.Y, (1 - A) * A) 

詳細はthese lecture notesを参照してください。私はあなたが式(5)を意味すると思うが、1-Aを忘れてしまった。とにかく、式(6)を使ってください。

+0

私はそれを修正しました。まだ動作していません。私は勾配降下が働いているが、結果は満足できるものではないことを意味する。エラーは最初は減少しますが、非常にゆっくりしてからかなり高い値で一定になります。私は、レートと反復回数を学習のさまざまな組み合わせを試してみましたが、NNは、特に各層の1個のニューロンで、学ぶことのために無駄に – Sahil

+0

のMod 2は容易ではありません。あなたの次のステップは、「深い」だけでなく「幅広く」することです。 – Maxim

+0

はい。それから私はアンドリュー・ウのコースの週2割り当てのデータセットだった別の例でそれを訓練しました。割り当てでは、0.69のコストで開始し、0に非常に近くに達した。しかし同じ例で、私は0.23件まで最大値を取得しています。私は4つのニューロンで1つの隠れたレイヤーを使用しました。 – Sahil

関連する問題