我的反向传播计算有问题吗?

时间:2018-07-04 17:42:33

标签: python algorithm neural-network backpropagation

在过去的三天里,我一直试图建立我的第一个神经网络无济于事。我在这里问这个问题是因为我无法想到其他任何地方来获得质量反馈,并且到目前为止我还没有找到任何解决方案。

该网络需要784个输入(像素),并且有9个输出(数字0-9),我正在尝试在mnist手写数字数据集上进行训练。

问题在于,经过几次迭代后,输出会爆炸到随机的+1和-1列表,例如。

[-1。,1.,1.,1.,-1。,-1。,1.,1.,1。]

我将包括ANNs init (),f_pass()和backpropagate()的代码片段,因为我认为如果有错误,可能会出现在包含矩阵的代码中。如果需要,我可以根据要求上传更多代码。

 class Feedforward:


    def __init__(self, size_vector):

        self.nLayers = len(size_vector)
        self.size_vector = size_vector
        weight_matrix = lambda x: np.random.random((x[0],x[1]))
        self.weights = {}
        self.b = {}
        self.z = {}
        self.a = {}

        for i in range(0,self.nLayers,1):
            z = size_vector[i:i+2]
            try:
                self.b[i] = np.random.random((1,size_vector[i+1]))
            except IndexError:
                pass
            if len(z) == 2:
                self.weights[i] = weight_matrix(z)

f_pass():

def f_pass(self, data):
        for layer in range(self.nLayers-1):
            if layer == 0:
                self.z[layer] = data.dot(self.weights[0])+self.b[layer].reshape((1,self.size_vector[layer+1]))
                self.a[layer] = self.activation(self.z[layer]).reshape((1,self.size_vector[layer+1]))
            else:
                self.z[layer] = self.a[layer-1].dot(self.weights[layer])+self.b[layer]
                self.a[layer] = self.activation(self.z[layer]).reshape((1,self.size_vector[layer+1]))

Backprop():

def backporpagate(self, data):
        lr = .01
        expected, inputs = data
        cost = np.square(expected-self.a[self.nLayers-2])
        partial_layer_error = {}
        partial_weight_error = {}
        partial_bias_error = {}
        for i in range(self.nLayers-1):
            layer = self.nLayers-2-i
            if i == 0:
                partial_layer_error[layer] = 2*(expected-self.a[self.nLayers-2])*self.activation_prime(self.z[layer]).reshape(1,self.size_vector[layer+1])
                partial_weight_error[layer] = self.a[layer-1].transpose().dot(partial_layer_error[layer])
                partial_bias_error[layer] = partial_layer_error[layer].reshape(1,self.size_vector[layer+1])
            elif layer == 0:
                partial_layer_error[layer] = partial_layer_error[layer+1].dot(self.weights[layer+1].transpose())
                partial_weight_error[layer] = inputs.transpose().dot(partial_layer_error[layer])
                partial_bias_error[layer] = partial_layer_error[layer].reshape(1,self.size_vector[layer+1])
            else:
                partial_layer_error[layer] = self.weights[layer+1].transpose().dot(partial_layer_error[layer+1])*self.activation_prime(self.z[layer])
                partial_weight_error[layer] = self.a[layer-1].transpose().dot(partial_layer_error[layer])
                partial_bias_error[layer] = partial_layer_error[layer].reshape(1,self.size_vector[layer+1])


        for i in range(len(self.size_vector)-1):
            self.weights[i] -= lr*partial_weight_error[i]
            self.b[i] -= lr*partial_bias_error[i]
        print(self.a[len(self.size_vector)-2])
        print(expected)

完整的代码(如果有人想查看)是:

import numpy as np
import random
import pandas as pd
import scipy

class Feedforward:


    def __init__(self, size_vector):

        self.nLayers = len(size_vector)
        self.size_vector = size_vector
        weight_matrix = lambda x: np.random.random((x[0],x[1]))
        self.weights = {}
        self.b = {}
        self.z = {}
        self.a = {}

        for i in range(0,self.nLayers,1):
            z = size_vector[i:i+2]
            try:
                self.b[i] = np.random.random((1,size_vector[i+1]))
            except IndexError:
                pass
            if len(z) == 2:
                self.weights[i] = weight_matrix(z)


    def activation(self, matrix):
        #print(matrix)
        matrix = np.clip( matrix, -300, 300 )
        return (np.exp(2*matrix)-1)/(np.exp(2*matrix)+1)

    def activation_prime(self, matrix):
        return 1/(1-np.square(matrix))


    def f_pass(self, data):
        for layer in range(self.nLayers-1):
            if layer == 0:
                self.z[layer] = data.dot(self.weights[0])+self.b[layer].reshape((1,self.size_vector[layer+1]))
                self.a[layer] = self.activation(self.z[layer]).reshape((1,self.size_vector[layer+1]))
            else:
                self.z[layer] = self.a[layer-1].dot(self.weights[layer])+self.b[layer]
                self.a[layer] = self.activation(self.z[layer]).reshape((1,self.size_vector[layer+1]))

    def backporpagate(self, data):
        lr = .01
        expected, inputs = data
        cost = np.square(expected-self.a[self.nLayers-2])
        partial_layer_error = {}
        partial_weight_error = {}
        partial_bias_error = {}
        for i in range(self.nLayers-1):
            layer = self.nLayers-2-i
            if i == 0:
                partial_layer_error[layer] = 2*(expected-self.a[self.nLayers-2])*self.activation_prime(self.z[layer]).reshape(1,self.size_vector[layer+1])
                partial_weight_error[layer] = self.a[layer-1].transpose().dot(partial_layer_error[layer])
                partial_bias_error[layer] = partial_layer_error[layer].reshape(1,self.size_vector[layer+1])
            elif layer == 0:
                partial_layer_error[layer] = partial_layer_error[layer+1].dot(self.weights[layer+1].transpose())
                partial_weight_error[layer] = inputs.transpose().dot(partial_layer_error[layer])
                partial_bias_error[layer] = partial_layer_error[layer].reshape(1,self.size_vector[layer+1])
            else:
                partial_layer_error[layer] = self.weights[layer+1].transpose().dot(partial_layer_error[layer+1])*self.activation_prime(self.z[layer])
                partial_weight_error[layer] = self.a[layer-1].transpose().dot(partial_layer_error[layer])
                partial_bias_error[layer] = partial_layer_error[layer].reshape(1,self.size_vector[layer+1])


        for i in range(len(self.size_vector)-1):
            self.weights[i] -= lr*partial_weight_error[i]
            self.b[i] -= lr*partial_bias_error[i]
        print(self.a[len(self.size_vector)-2])
        print(expected)

    def train(self, data):
        batch = data.sample(2000)
        pairs = [batch.iloc[:,0],batch.iloc[:,1]]
        avg_I = np.zeros(9)
        avg_O = np.zeros(784)
        for index, (label, img) in batch.iterrows():
            label = np.array(label)
            img = np.array(img)[:,np.newaxis].transpose()/255
            self.f_pass(img)
            self.backporpagate((label, img))

def prepare_mnist():
    print('preparing MNIST: please wait' + '\n')
    with open('mnist_test.csv') as f:
        data = f.readlines()
    mnist = []
    print('Reading Data: \n')
    for i in data:
        key = []
        for j in range(9):
            if j == int(i[0])-1:
                key.append(1)
            else:
                key.append(0)

        value = i[1:]
        value = value.replace('\n','')
        value = value.split(',')
        value.pop(0)
        value = [int(x) for x in value]
        mnist.append((key,value))
    print("Converting to DataFrame \n")
    df = pd.DataFrame(mnist)
    return df

N = Feedforward([784,50,9])
N.train(prepare_mnist())

如果有人可以帮助我,我将非常感激。这困扰了我好几天,我真的很想开始实践这些东西。

0 个答案:

没有答案