Python 神经网络MNIST
我已经研究了一段时间的神经网络,并用python和numpy实现了它。我用XOR做了一个非常简单的例子,效果很好。所以我想我可以更进一步,尝试MNIST数据库 这是我的问题。我使用的神经网络有784个输入,30个隐藏和10个输出神经元。 隐藏层的激活功能只吐出一个,因此网络基本停止学习。我所做的数学是正确的,同样的实现在XOR示例中运行良好,我正确地读取了MNIST集。所以我不明白问题从何而来Python 神经网络MNIST,python,numpy,machine-learning,neural-network,mnist,Python,Numpy,Machine Learning,Neural Network,Mnist,我已经研究了一段时间的神经网络,并用python和numpy实现了它。我用XOR做了一个非常简单的例子,效果很好。所以我想我可以更进一步,尝试MNIST数据库 这是我的问题。我使用的神经网络有784个输入,30个隐藏和10个输出神经元。 隐藏层的激活功能只吐出一个,因此网络基本停止学习。我所做的数学是正确的,同样的实现在XOR示例中运行良好,我正确地读取了MNIST集。所以我不明白问题从何而来 import pickle import gzip import numpy as np def
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个时间段对其进行训练没有帮助。XOR和MNIST问题之间的区别在于类的数量:XOR是一种二元分类,在MNIST中有10个类
您计算的错误
E
适用于XOR,因为sigmoid函数可以在二进制情况下使用。当有2个以上的类时,必须使用扩展版的sigmoid和。看看有什么不同。您已经正确地将y
转换为一个热编码,但是输出
不包含预测的概率分布,实际上包含10个值的向量,每个值都非常接近1.0
。这就是网络无法学习的原因。感谢您的快速回答。我一直在使用下面的教程,他使用了和我类似的网络,有10个输出神经元,还有像我一样的乙状结肠,在第一个历元后获得了95%左右的成功率。我会检查他的代码和我的代码并进行比较。魔鬼在细节中。但是,是的,一旦我有了这个工作,我肯定会进入softmax、dropout和relus等领域。我实际上有点怀疑所描述的网络是否能达到95%的准确率。他的下一个例子是使用逻辑回归(我所建议的),然后是卷积神经网络(更可能显示这样的结果),可能就是这个模型在起作用。但如果你能证明我错了,并且达到90%的准确率,让我知道,我很想亲自尝试一下这个网络。我运行了他的代码,在第一个历元之后,我得到了90%。到目前为止,我所看到的区别是,他根据批次大小划分学习率,并对批次进行随机化,而我没有这样做。但这并不能解释我的问题。我什么也没得到,所有的神经元激活都是1在隐藏和输出层我更新了代码。我有两个整数常量,我做了浮点运算。现在我可以看到权重更新,但问题仍然非常相似。