手搓一个用于MNIST深度学习网络
目标
实现一个建议的可改进的神经网络
让我们来用python和numpy来实现一个可以将minst分类的神经网络
理解深度学习原理
简单来说深度学习就是输入一个对象的多个特征数据,列如:我们所用的minst数据集的每一张图片像素为28x28,但我们输入时会将其展开为784,(28x28=784),所以在这里我们输入的每一个对象的多个数据特征就是这展开的784个像素点,将其写成一个向量的形式(一个1行784列的向量),让其乘以一个矩阵(784x50),这里的50可以小幅调整,并且50是数据经过第一个隐藏层的神经元数量,第二步用一个50x100的矩阵与上一步结果相乘
现在,我们将输入进来的1x784的向量变成了1x100的向量
但是我们最终需要的是1x10的向量
所以,还要在乘以一个100x10的矩阵
现在,我们得到了一个1x10的向量,这10个数值取最大值的索引就是识别的结果
好了,以上就是大致步骤,现在让我们来python实现
第一步 获取MNIST数据
from mnist import load_mnist
def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
#load_mnist函数返回两对元组,每对元祖包含x为图像,t为相同索引下的图像的正确标签
return x_test, t_test
第二步 进行矩阵乘法
首先来读取矩阵的参数
def init_network():
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)
return network
#矩阵被保存在sample_weight.pkl文件中
#我们使用pickle.load读取
下面来定义一个矩阵计算的函数
def predict(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = softmax(a3)
return y
在上面的函数中,我们进行了三次矩阵乘法,最后得到了一个1x10的列向量
第三步 RUN!
x, t = get_data()
network = init_network()
test = x[8]
y = predict(network, test)
index = np.argmax(y)
print("The results is ", index)
运行便会打印出识别的结果
下面是完整代码
import numpy as np
import pickle
from mnist import load_mnist
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def softmax(x):
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T
x = x - np.max(x) # 溢出对策
return np.exp(x) / np.sum(np.exp(x))
#以上的两个函数并非重点
def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
return x_test, t_test
def init_network():
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)
return network
def predict(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = softmax(a3)
return y
x, t = get_data()
while True:
#随便输入一个数字即可
i = int(input('start >>>'))
network = init_network()
y = predict(network, x[i])
p= np.argmax(y)
print('The result is ',p)
#将以下代码注释解除即可显示图片,但是要先安装PLI库
# from PIL import Image
# def img_show_plus(img):
# img = img * 255
# img = img.reshape(28, 28)
# pil_img = Image.fromarray(np.uint8(img))
# pil_img.show()
# img_show_plus(x[i])
相关代码以及数据
链接:https://pan.baidu.com/s/182VW1T2ai5o-5H3hFB7UTw?pwd=x4aw
提取码:x4aw
本文参考《深度学习入门》一书