显然是自编的反向传播神经网络的随机预测

时间:2018-02-01 22:39:01

标签: python neural-network gradient-descent

我正在尝试实现一个简单的神经网络进行自学,以识别手写数字(通过python-MNIST)。我正在Python 2.7中构建一个使用梯度下降的反向传播网络 - 下面的代码。

import numpy as np

from mnist import MNIST
mndata_training = MNIST('Training')
training_images, training_labels = mndata_training.load_training()

IMAGE_WIDTH = 28
IMAGE_HEIGHT = 28
NEURON_COUNT = 10
INPUT_COUNT = IMAGE_WIDTH * IMAGE_HEIGHT
OUTPUT_COUNT = 10 # There are ten different digits (0,1,2,3,4,5,6,7,8,9)

def sigmoid(z):
    # The sigmoid activation function
    return 1 / (1+ np.exp(-z))

def sigmoid_prime(z):
    # The derivative of the sigmoid activation function
    return np.multiply(sigmoid(z), np.ones(np.shape(z)) - sigmoid(z))

def mult(x, weights):
    # Take inputs and return the output activation for a matrix of weights
    return np.dot(x, weights)

def parse_label(numeral):
    training_vector = np.zeros(10)
    training_vector[numeral] = 1
    return training_vector



class neural_network:
    def __init__(self):
        self.weights_hidden_layer = np.asmatrix(np.random.rand(INPUT_COUNT,NEURON_COUNT))
        self.weights_outer_layer = np.asmatrix(np.random.rand(NEURON_COUNT, OUTPUT_COUNT))

    def propagate(self, input_data):
        self.X = np.asmatrix(input_data)
        self.input_hidden_layer = mult(input_data, self.weights_hidden_layer)
        self.activation_hidden_layer = sigmoid(self.input_hidden_layer)
        self.input_output_layer = mult(self.activation_hidden_layer, self.weights_outer_layer)
        self.activation_output_layer = sigmoid(self.input_output_layer)
        self.guess = np.argmax(self.activation_output_layer)

    def calc_error(self, expected_data):
        self.residual = self.activation_output_layer - expected_data
        return self.residual

    def gradient(self):
        self.delta_2 = np.multiply(self.residual, sigmoid_prime(self.input_output_layer))
        self.weights_outer_layer_grad = np.dot(self.activation_hidden_layer.T, self.delta_2)
        self.delta_1 = np.multiply(np.dot(self.delta_2, self.weights_outer_layer.T), sigmoid_prime(self.input_hidden_layer))
        self.weights_hidden_layer_grad = np.dot(self.X.T, self.delta_1)

    def improve(self):
        self.weights_hidden_layer = self.weights_hidden_layer - self.weights_hidden_layer_grad
        self.weights_outer_layer = self.weights_outer_layer - self.weights_outer_layer_grad

neural_net = neural_network()

image = training_images
label = training_labels

neural_net.propagate(image[0])
before = neural_net.activation_output_layer

for n in range(50000):
    neural_net.propagate(image[n])
    neural_net.calc_error(parse_label(label[n]))
    neural_net.gradient()
    # Output the network's guess, alongside the true numeral
    print(str(neural_net.guess) + "<" + str(label[n]) + ">")
    # Update the weights for each neuron
    neural_net.improve()

当看到程序的输出时,很明显神经网络无法预测手写数字。我检查了第一个数据样本和最后一个数据样本的神经元输出层的激活。奇怪的是,对于所有10个神经元,第一个样本的激活约为1,并且对于所有10个神经元,最后一个样本的激活几乎为0。

在这里没有正确使用反向传播的某些方面并且可能导致这些结果吗?

0 个答案:

没有答案