pythonneural-networkshapesactivationmulti-layer

Neural Networks Value Errors: Shapes not alligned


I am trying to apply neural network (Multi layer perceptron) to my data. I get this error: ValueError: shapes (3,) and (4,99) not aligned: 3 (dim 0) != 4 (dim 0)

I have error on this line: a = self.activation(np.dot(a, self.weights[l]))

If somebody could help me, I would be happy.Thanks.

nn_inputs: [[15, 0, 2.48489062802], [-35, 29, 1.15616438943], [-5, -1, 2.32958496377], [-48, 33, 0.706488511889], [-10, 2, 2.09510386284], [-3, 11, 1.8423515073]]

nn_labels: [0, 1, 0, 1, 0, 1]

def tanh(x):
    return np.tanh(x)

def tanh_deriv(x):
    return 1.0 - np.tanh(x)**2

def logistic(x):
    return 1/(1 + np.exp(-x))

def logistic_derivative(x):
    return logistic(x)*(1-logistic(x))


class NeuralNetwork:
    def __init__(self, layers, activation='tanh'):
    """
    :param layers: A list containing the number of units in each layer.
    Should be at least two values
    :param activation: The activation function to be used. Can be
    "logistic" or "tanh"
    """
    if activation == 'logistic':
        self.activation = logistic
        self.activation_deriv = logistic_derivative
    elif activation == 'tanh':
        self.activation = tanh
        self.activation_deriv = tanh_deriv

    self.weights = []
    for i in range(1, len(layers) - 1):
        self.weights.append((2*np.random.random((layers[i - 1] + 1, layers[i]+ 1))-1)*0.25)
    self.weights.append((2*np.random.random((layers[i] + 1, layers[i +
                        1]))-1)*0.25)



    def fit(self, X, y, learning_rate=0.2, epochs=10000):
        X = np.atleast_2d(X)
        temp = np.ones([X.shape[0], X.shape[1]+1])
        temp[:, 0:-1] = X  # adding the bias unit to the input layer
        X = temp
        y = np.array(y)

        for k in range(epochs):
            i = np.random.randint(X.shape[0])
            a = [X[i]]


            for l in range(len(self.weights)):
                a.append(self.activation(np.dot(a[l], self.weights[l])))
            error = y[i] - a[-1]
            deltas = [error * self.activation_deriv(a[-1])]

            for l in range(len(a) - 2, 0, -1): # we need to begin at the second to last layer
              deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_deriv(a[l]))


        deltas.reverse()
        for i in range(len(self.weights)):
            layer = np.atleast_2d(a[i])
            delta = np.atleast_2d(deltas[i])
            self.weights[i] += learning_rate * layer.T.dot(delta)

    def predict(self, x):
        x = np.array(x)
        temp = np.ones(x.shape[0]+1)
        temp[0:-1] = x
        a = temp
        for l in range(0, len(self.weights)):
            a = self.activation(np.dot(a, self.weights[l]))
        return a


nn_inputs = map(list, zip(speed, occupancy, capacity))
nn_labels = labels

nn = NeuralNetwork([3,len(nn_inputs),1], 'tanh')


nn.fit(nn_inputs, nn_labels)
for i in [[0, 0], [0, 1], [1, 0], [1,1]]:
    print(i,nn.predict(i))

Solution

  • I have get the same error code and it seem this is due to the use of data shape which is different from the first element of vector in NN initialisation you must have: nn = NeuralNetwork([2,len(nn_inputs),1], 'tanh') instead of nn = NeuralNetwork([3,len(nn_inputs),1], 'tanh') as in class NeuralNetwork, the bias is added when processing

    i give you below the whole code that works fine for me:

    def linear(x): return 2*x+3 def linear_deriv(x): return 2 def tanh(x): return np.tanh(x)

    def tanh_deriv(x): return 1.0 - np.tanh(x)**2

    def logistic(x): return 1/(1 + np.exp(-x))

    def logistic_derivative(x): return logistic(x)*(1-logistic(x))

    class NeuralNetwork: def init(self, layers, activation='tanh'): """ :param layers: Une liste contenant le nombre d'unités de chaque couche (la couche d'entrée, les couches cachées et la couche de sortie Doit avoir au moins 2 valeurs (nombre de neurones de la couche d'entrée et celle de la couche de sortie :param activation: la fonction d'activation à utiliser. peut-être "logistic" or "tanh" """ self.layers=layers if activation == 'logistic': self.activation = logistic self.activation_deriv = logistic_derivative elif activation == 'tanh': self.activation = tanh self.activation_deriv = tanh_deriv elif activation == 'lineaire': self.activation = linear self.activation_deriv = linear_deriv

        #self.weights est une liste de matrice de poids. chaque matrice représente
        #l'ensemble des poids qui lient une couche et celle qui la suit
        #la première lie la couche des données à la première couche cachée
        #la seconde lie la première couche cachée à la seconde. Ainsi de suite
        #jusqu'à la dernière qui lie la dernière couche cachée et la couche de sortie
        self.weights = []
        """ Initialisation des poids.
        On initialise les poids que portent les liens entre les neurones des couches
        qui se suivent. Pour chaque couche exceptée la dernière, on ajoute le biais
        qui correspond à la valeur seuil de l'activation"""
        for i in range(1, len(layers) - 1):
            self.weights.append((2*np.random.random((layers[i - 1] + 1, layers[i]
                                + 1))-1)*0.25)
        #initialisation des poids des connexions entre la dernière couche cachée et
        #la couche de sortie
        self.weights.append((2*np.random.random((layers[i] + 1, layers[i +
                            1]))-1)*0.25)
    """la fonction d'apprentissage au taux d'apprentissage 0.2 avec un certain nombre d'itérations"""
    def fit(self, X, y, taux_apprentissage=0.2,  iterations=10000 ):
            X = np.atleast_2d(X)#Transformation de l'entrée (les données) en une matrice de deux dimension
                                 #Si on n'a pas déjà une matrice
            temp = np.ones([X.shape[0], X.shape[1]+1])
            temp[:, 0:-1] = X  # Ajout du biais à la couche d'éntrée
            X = temp
            y = np.array(y)
            for k in range(iterations):
                #choix d'un index au hasard
                i = np.random.randint(X.shape[0])
                #recupération de la donnée qui se trouve à cet index dans la matrice des données X
                a = [X[i]]
    
                for l in range(len(self.weights)):
                #calcul et propagation de l'activation de couche en couche de la première
                #à la dernière
    
                    a.append(self.activation(np.dot(a[l], self.weights[l])))
                #estimation de l'erreur entre la sortie obtenue et la sortie désirée
    
                error = y[i] - a[-1]
                #calcul du signal de l'erreur pour la couche de sortie
                deltas = [error * self.activation_deriv(a[-1])]
                #calcul du signal d'erreur pour les autres couches
                for l in range(len(a) - 2, 0, -1):
                    # On doit commencer le calcul
                    # de l'avant dernière couche d'ou le "len(a)-2" à la première
                    #on multiplie la derniere valeur du signal d'erreur par
                    deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_deriv(a[l]))
                deltas.reverse()
                #Mise à jour des poids par retropropagation du gradient
                for i in range(len(self.weights)):
                    layer = np.atleast_2d(a[i])
                    delta = np.atleast_2d(deltas[i])
                    self.weights[i] += taux_apprentissage * layer.T.dot(delta)
                if k==iterations-1:
                    for u in range (X.shape[0]):
                        a = [X[u]]
                        error=0.0
    
                        for l in range(len(self.weights)):
                        #calcul et propagation de l'activation de couche en couche de la première
                        #à la dernière
    
                            a.append(self.activation(np.dot(a[l], self.weights[l])))
                        #estimation de l'erreur entre la sortie obtenue et la sortie désirée
                        e=(y[u] - a[-1])
                        #calcul de l'erreur quadratique moyenne
                        error =error + e[0]**2
                    if error/X.shape[0]> -0.000001 and error/X.shape[0]> 0.000001  :
                        print("erreur globale: ")
                        print(error/X.shape[0])
                        break
                    else:
                        k=0
    
    
    def predict(self, x):
                x = np.array(x)
    
                temp = np.ones(x.shape[0]+1)
                temp[0:-1] = x
    
                a = temp
                for l in range(0, len(self.weights)):
                    a=self.activation(np.dot(a[l], self.weights[l]))
    
                return a
    

    hope this will be helpful