【问题标题】:Neural Network MNIST神经网络 MNIST
【发布时间】:2018-03-21 01:21:29
【问题描述】:

我研究神经网络已经有一段时间了,用 python 和 numpy 做了一个实现。我用 XOR 做了一个非常简单的例子,效果很好。所以我想我更进一步,尝试 MNIST 数据库。

这是我的问题。我正在使用具有 784 个输入、30 个隐藏和 10 个输出神经元的 NN。 隐藏层的激活函数只吐出一个,让网络基本停止学习。我所做的数学是正确的,并且相同的实现适用于 XOR 示例,并且我正在正确读取 MNIST 集。所以我看不出问题出在哪里。

import pickle
import gzip

import numpy as np

def load_data():
    f = gzip.open('mnist.pkl.gz', 'rb')
    training_data, validation_data, test_data = pickle.load(f, encoding="latin1")
    f.close()
    return (training_data, validation_data, test_data)

def transform_output(num):
    arr = np.zeros(10)
    arr[num] = 1.0
    return arr

def out2(arr):
    return arr.argmax()


data = load_data()
training_data = data[0]
training_input = np.array(training_data[0])
training_output = [transform_output(y) for y in training_data[1]]

batch_size = 10

batch_count = int(np.ceil(len(training_input) / batch_size))

input_batches = np.array_split(training_input, batch_count)
output_batches = np.array_split(training_output, batch_count)

#Sigmoid Function
def sigmoid (x):
    return 1.0/(1.0 + np.exp(-x))

#Derivative of Sigmoid Function
def derivatives_sigmoid(x):
    return x * (1.0 - x)

#Variable initialization
epoch=1 #Setting training iterations
lr=2.0 #Setting learning rate
inputlayer_neurons = len(training_input[0]) #number of features in data set
hiddenlayer_neurons = 30 #number of hidden layers neurons

output_neurons = len(training_output[0]) #number of neurons at output layer

#weight and bias initialization
wh=np.random.uniform(size=(inputlayer_neurons,hiddenlayer_neurons))
bh=np.random.uniform(size=(1,hiddenlayer_neurons))
wout=np.random.uniform(size=(hiddenlayer_neurons,output_neurons))
bout=np.random.uniform(size=(1,output_neurons))

for i in range(epoch):
    for batch in range(batch_count):

        X = input_batches[batch]
        y = output_batches[batch]

        zh1 = np.dot(X, wh)
        zh = zh1 + bh

        # data -> hidden neurons -> activations
        ah = sigmoid(zh)

        zo1 = np.dot(ah, wout)
        zo = zo1 + bout

        output = sigmoid(zo)

        # data -> output neurons -> error
        E = y - output

        print("debugging")
        print("X")
        print(X)
        print("WH")
        print(wh)
        print("zh1")
        print(zh1)
        print("bh")
        print(bh)
        print("zh")
        print(zh)
        print("ah")
        print(ah)
        print("wout")
        print(wout)
        print("zo1")
        print(zo1)
        print("bout")
        print(bout)
        print("zo")
        print(zo)
        print("out")
        print(output)
        print("y")
        print(y)
        print("error")
        print(E)
        # data -> output neurons -> slope
        slope_out = derivatives_sigmoid(output)

        # data -> output neurons -> change of error
        d_out = E * slope_out

        # data -> hidden neurons -> error = data -> output neurons -> change of error DOT output neurons -> output inputs (equal to hidden neurons) -> weights
        error_hidden = d_out.dot(wout.T)

        # data -> hidden neurons -> slope
        slope_h = derivatives_sigmoid(ah)

        # data -> hidden neurons -> change of error
        d_hidden = error_hidden * slope_h

        # hidden neurons -> output neurons -> weights = "" + hidden neurons -> data -> activations DOT data -> output neurons -> change of error
        wout = wout + ah.T.dot(d_out) * lr
        bout = bout + np.sum(d_out, axis=0, keepdims=True) * lr

        wh = wh + X.T.dot(d_hidden) * lr
        bh = bh + np.sum(d_hidden, axis=0, keepdims=True) * lr
    # testing results
    X = np.array(data[1][0][0:10])
    zh1 = np.dot(X, wh)
    zh = zh1 + bh

    # data -> hidden neurons -> activations
    ah = sigmoid(zh)

    zo1 = np.dot(ah, wout)
    zo = zo1 + bout

    output = sigmoid(zo)
    print([out2(y) for y in output])
    print(data[1][1][0:10])

所以总体而言,神经网络的输出对于每个输入都是相同的,并且使用不同的批量大小、学习率和 100 个 epoch 对其进行训练并没有帮助。

【问题讨论】:

    标签: python numpy machine-learning neural-network mnist


    【解决方案1】:

    XOR 和 MNIST 问题的区别在于类的数量:XOR 是二元分类,在 MNIST 中有 10 个类。

    您计算为错误E 的内容适用于 XOR,因为 sigmoid 函数可以在二进制情况下使用。当有 2 个以上的类时,您必须使用 softmax function,这是 sigmoid 的扩展版本,以及 cross entropy loss。看看this question 看看有什么不同。您已正确地将y 转换为单热编码,但output 不包含预测概率分布,实际上包含一个由10 个值组成的向量,每个值都非常接近1.0。这就是网络无法学习的原因。

    【讨论】:

    • 感谢您的快速回答。我一直在使用以下教程 neuralnetworksanddeeplearning.com/chap1.html 他使用与我类似的网络,有 10 个输出神经元和 sigmoid,并且在第一个 epoch 后获得了大约 95% 的成功率。我将通过他的代码和我的代码进行比较。魔鬼在细节中。但是,是的,一旦我有这个工作,我肯定会进入 softmax、dropout 和 relus 等。
    • 我实际上有点怀疑所描述的网络能否达到 95% 的准确率。他的下一个示例使用逻辑回归(我所建议的),然后使用卷积神经网络(更可能显示这样的结果),可能是这个模型在起作用。但如果你能证明我错了并达到 90% 的准确率,请告诉我,我很想亲自尝试这个网络。
    • 我运行了他的代码,在第一个 epoch 之后我得到了 90%。到目前为止,我看到的不同之处在于,他根据批次大小划分学习率并随机化批次,而我没有这样做。但这并不能解释我的问题。我什么也没得到,所有神经元激活在隐藏层和输出层都是 1
    • 我更新了代码。我有几个整数常量,我制作了浮点数。现在我可以看到权重在更新,但问题仍然非常相似。
    猜你喜欢
    • 2019-08-29
    • 1970-01-01
    • 2020-04-29
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 2015-04-29
    • 2021-03-25
    • 1970-01-01
    相关资源
    最近更新 更多