NN реализация - обновление после обратного распространения изменяет размеры - PullRequest
1 голос
/ 08 апреля 2019

как часть задания, нам нужно реализовать NN.

Я вычисляю прямой результат, затем запускаю обратное распространение, а затем обновляю веса (все для одного и того же экземпляра).

Когда я пытаюсь вычислить прямое значение для того же экземпляра, я получаю сообщение об ошибке, что размеры неверны.

class MyNN:
     def __init__(self, learning_rate, layer_sizes):
        self.learning_rate = learning_rate
        self.layer_sizes = layer_sizes
        self.model_params = {}
        self.memory = {}
        self.grads = {}

        # Initializing weights
        for layer_index in range(len(layer_sizes) - 1):
            W_input = layer_sizes[layer_index + 1]
            W_output = layer_sizes[layer_index]
            self.model_params['W_' + str(layer_index + 1)] = np.random.randn(W_input, W_output) * 0.1
            self.model_params['b_' + str(layer_index + 1)] = np.random.randn(W_input) * 0.1


    def forward_single_instance(self, x):    
        a_i_1 = x
        self.memory['a_0'] = x
        for layer_index in range(len(self.layer_sizes) - 1):
            W_i = self.model_params['W_' + str(layer_index + 1)]
            b_i = self.model_params['b_' + str(layer_index + 1)]
            z_i = np.dot(W_i, a_i_1) + b_i
            a_i = 1/(1+np.exp(-z_i))
            self.memory['a_' + str(layer_index + 1)] = a_i
            a_i_1 = a_i
        return a_i_1


    def log_loss(self, y_hat, y):
        '''
        Logistic loss, assuming a single value in y_hat and y.
        '''
        m = y_hat[0]
        cost = -y[0]*np.log(y_hat[0]) - (1 - y[0])*np.log(1 - y_hat[0])
        return cost


    def backward_single_instance(self, y):

        a_output = self.memory['a_' + str(len(self.layer_sizes) - 1)]
        dz = a_output - y

        for layer_index in range(len(self.layer_sizes) - 1, 0, -1):   
            a_l_1 = self.memory['a_' + str(layer_index - 1)]
            dW = np.dot(dz.reshape(-1, 1), a_l_1.reshape(1, -1))
            db = dz.transpose()
            self.grads['dW_' + str(layer_index)] = dW
            self.grads['db_' + str(layer_index)] = db
            W_l = self.model_params['W_' + str(layer_index)]
            dz = (a_l_1 * (1 - a_l_1)).reshape(-1, 1) * np.dot(W_l.T, dz.reshape(-1, 1))


    def update(self):
        for layer_index in range(len(self.layer_sizes) - 1):
            Wi = 'W_' + str(layer_index + 1)
            bi = 'b_' + str(layer_index + 1)
            dWi = 'dW_' + str(layer_index + 1)        
            dbi = 'db_' + str(layer_index + 1)
            W_i = self.model_params[Wi]
            b_i = self.model_params[bi]
            dW_i = self.grads[dWi]
            db_i = self.grads[dbi]
            self.model_params[Wi] = W_i - self.learning_rate * dW_i
            self.model_params[bi] = b_i - self.learning_rate * db_i

тогда для тестирования я написал этот код:

 nn = MyNN(0.01, [3, 2, 1])

    x = np.random.randn(3)
    y = np.random.randn(1)

    y_hat = nn.forward_single_instance(x)
    print(y_hat)

    nn.backward_single_instance(y)

    nn.update()

    y_hat = nn.forward_single_instance(x)

Это ошибка, которая печатается:

x  
[ 0.57072262  1.8578982  -1.48560691]
x  
[[0.53932246 0.57051188]]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-99-d8d9152fef18> in <module>()
----> 1 y_hat = nn.forward_single_instance(x)
      2 print(y_hat)
      3 
      4 
      5 l = nn.log_loss(y_hat, y)

<ipython-input-89-f354993c95f9> in forward_single_instance(self, x)
     24       W_i = self.model_params['W_' + str(layer_index + 1)]
     25       b_i = self.model_params['b_' + str(layer_index + 1)]
---> 26       z_i = np.dot(W_i, a_i_1) + b_i
     27       a_i = 1/(1+np.exp(-z_i))
     28       self.memory['a_' + str(layer_index + 1)] = a_i



ValueError: shapes (1,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)

проблема в размерах b_i, и я не могу понять, почему. Я попробовал варианты формы b_i (вектор строки, вектор столбца), и все они выдают одно и то же исключение.

...