Моя нейронная сеть может предсказать только один класс

#python #neural-network

#python #нейронная сеть

Вопрос:

Я создал NeuralNetwork класс следующим образом

 import numpy as np
import matplotlib.pyplot as plt

class NeuralNetwork():
    
    def __init__(self, alpha, layer_dims):
        self.alpha = alpha
        self.L = len(layers_dims) - 1
        self.n = {}
        self.W = {}
        self.b = {}
        for l in range(1, len(layer_dims)):
            self.n['n'   str(l)] = layer_dims[l]
            self.W['W'   str(l)] = np.random.randn(layer_dims[l], layer_dims[l-1]) / np.sqrt(layer_dims[l-1])
            self.b['b'   str(l)] = np.zeros((layer_dims[l], 1))
    
    @staticmethod
    def sigmoid(z):
        return 1 / (1   np.exp(-z))
    
    def sigmoid_derivative(self, z):
        return self.sigmoid(z) * (1 - self.sigmoid(z))
    
    @staticmethod
    def relu(z):
        return np.maximum(0, z)
    
    @staticmethod
    # NOT SURE WITH THIS SO JUST CHANGE LATER
    def relu_derivative(z):
        dadz = np.zeros(z.shape)
        dadz[z > 0] = 1
        return dadz
        
    def get_cost(self, Y):
        logprobs = Y * np.log(self.A['A'   str(self.L)])   (1 - Y) * np.log(1 - self.A['A'   str(self.L)])
        return -1/self.m * np.sum(logprobs)
    
    def forward_propagation(self, X):
        self.Z = {}
        self.A = {}
        self.A['A0'] = X
        for l in range(1, self.L):
            self.Z['Z'   str(l)] = np.dot(self.W['W'   str(l)], self.A['A'   str(l-1)])   self.b['b'   str(l)]
            self.A['A'   str(l)] = self.relu(self.Z['Z'   str(l)])
        self.Z['Z'   str(self.L)] = np.dot(self.W['W'   str(self.L)], self.A['A'   str(self.L-1)])   self.b['b'   str(self.L)]
        self.A['A'   str(self.L)] = self.sigmoid(self.Z['Z'   str(self.L)])
    
    def backward_propagation(self, Y):
        self.dZ = {}
        self.dA = {}
        self.dW = {}
        self.db = {}
        self.dA['dA'   str(self.L)] = -Y/self.A['A'   str(self.L)]   (1-Y)/(1-self.A['A'   str(self.L)])
        self.dZ['dZ'   str(self.L)] = self.dA['dA'   str(self.L)] * self.sigmoid_derivative(self.Z['Z'   str(self.L)])
        self.dW['dW'   str(self.L)] = 1/self.m * np.dot(self.dZ['dZ'   str(self.L)], self.A['A'   str(self.L-1)].T)
        self.db['db'   str(self.L)] = 1/self.m * np.sum(self.dZ['dZ'   str(self.L)], axis=1, keepdims=True)
        for l in reversed(range(1, self.L)):
            self.dA['dA'   str(l)] = np.dot(self.W['W'   str(l   1)].T, self.dZ['dZ'   str(l   1)])
            self.dZ['dZ'   str(l)] = self.dA['dA'   str(l)] * self.relu_derivative(self.Z['Z'   str(l)])
            self.dW['dW'   str(l)] = 1/self.m * np.dot(self.dZ['dZ'   str(l)], self.A['A'   str(l-1)].T)
            self.db['db'   str(l)] = 1/self.m * np.sum(self.dZ['dZ'   str(l)], axis=1, keepdims=True)
    
    def update_parameters(self):
        for l in range(1, self.L 1):
            self.W['W'   str(l)] = self.W['W'   str(l)] - self.alpha * self.dW['dW'   str(l)]
            self.b['b'   str(l)] = self.b['b'   str(l)] - self.alpha * self.db['db'   str(l)]
            
    def train(self, X_train, y_train, max_iters):
        self.m = X_train.shape[-1]
        self.costs = []
        for _ in range(max_iters):
            self.forward_propagation(X_train)
            self.backward_propagation(y_train)
            self.update_parameters()
            self.costs.append(self.get_cost(y_train))
        print(f'Training done! Loss after {max_iters} iterations: {self.costs[-1]}')
        
    def predict(self, X_test):
        self.forward_propagation(X_test)
        y_pred = self.sigmoid(self.A['A'   str(self.L)])
        y_pred[y_pred >= 0.5] = 1
        y_pred[y_pred < 0.5] = 0
        return y_pred
    
    def plot_cost(self):
        plt.figure(dpi=100)
        plt.plot(self.costs)
        plt.show()
  

где layer_dims [n_x, n_h1, n_h2, ..., n_y] . Я пробовал тестирование forward_propagation backward_propagation , и они работают нормально. Я также пробовал разные типы инициализации параметров, но безрезультатно. Всякий раз, когда я предсказываю новые результаты, все они получают одинаковые вероятности. Что не так с моим кодом? Что я пропустил?

Форма X_train есть (n_x, m) , тогда как форма y_train есть (n_y, m) .

Комментарии:

1. Возможно, ваш обучающий набор имеет только один класс.

2. Я протестировал его на задаче двоичной классификации.

Ответ №1:

Обратите внимание, что вы применили сигмовидную активацию как для прямого распространения, так и для прогнозирования. Это было бы проблематично, потому что выходные данные 2 вложенных сигмоидов всегда будут не менее 0,5.

Комментарии:

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