保存一下我简短学习的神经网络(只是最最最基础的那种三层的神经网络而已)。
功能:训练、识别手写数字,统计正确率。
!里面用到的训练集和测试集是网上下载的,如果有需要可以私聊我。。。。因为我不知道怎么传文件????
# 神经网络构建 识别手写数字
import numpy
import scipy.special
import scipy.misc
import matplotlib.pyplot
# 神经网络定义
class neuralNetwork:
# 初始化神经网络参数
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
# 输入层、隐藏层、输出层的结点个数
self.inodes = inputnodes # 输入层节点个数
self.hnodes = hiddennodes # 隐藏层节点个数
self.onodes = outputnodes # 输出层节点个数
# 学习率
self.lr = learningrate
# 权值矩阵
self.wih = (numpy.random.rand(self.hnodes, self.inodes) - 0.5) # 输入层与隐藏层之间权值
self.who = (numpy.random.rand(self.onodes, self.hnodes) - 0.5) #隐藏层与输出层之间权值
'''正态分布采样权重
self.win = numpy.random.normal(0.0, pow(self.hnodes, -0.5),(self.hnodes, self.inodes))
self.who = numpy.random.normal(0.0, pow(self.onodes, -0.5),(self.onodes, self.hnodes))
'''
# S函数
self.activation_function = lambda x: scipy.special.expit(x) # lambda为快速创建函数,x为参数,返回scipy.special.expit(x)
pass
# 训练神经网络
def train(self, inputs_list, targets_list):
inputs = numpy.array(inputs_list, ndmin=2).T # 将输入数据转换为列矩阵
targets = numpy.array(targets_list, ndmin=2).T # 将正确答案转换为列矩阵
hidden_inputs = numpy.dot(self.wih, inputs) # 隐藏层输入为权值矩阵与输入矩阵的乘积
hidden_outputs = self.activation_function(hidden_inputs) # 隐藏层输出 经过S函数变换
final_inputs = numpy.dot(self.who, hidden_outputs) # 输出层输入为权值矩阵与隐藏层输出矩阵的乘积
final_outputs = self.activation_function(final_inputs) # 输出层输出 经过S函数变换
output_errors = targets - final_outputs # 输出结果与正确答案误差
hidden_errors = numpy.dot(self.who.T, output_errors) # 隐藏层误差为 权值矩阵的转职与输出误差矩阵的乘积
self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)), # 根据误差更新权值矩阵
numpy.transpose(hidden_outputs))
self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)),
numpy.transpose(inputs))
pass
# 查询
def query(self, inputs_list):
inputs = numpy.array(inputs_list, ndmin=2).T # 将输入数据转为输入矩阵
hidden_inputs = numpy.dot(self.wih, inputs)
hidden_outputs = self.activation_function(hidden_inputs)
final_inputs = numpy.dot(self.who, hidden_outputs)
final_outputs = self.activation_function(final_inputs)
return final_outputs # 返回最后结果
pass
# 神经网络初始化
input_nodes = 784
hidden_nodes = 100
output_nodes = 10
learning_rate = 0.2
n = neuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate) # 新建神经网络
#准备训练
training_data_file = open("mnist_train.csv", 'r') # 打开训练文件
training_data_list = training_data_file.readlines() # 存训练数据
training_data_file.close()
for record in training_data_list: # 遍历训练数据
all_values = record.split(',') # 以,分割数据
inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # 为保证输出在0-1,将输入数据范围优化在0.01-1之间
targets = numpy.zeros(output_nodes) + 0.01
targets[int(all_values[0])] = 0.99 # 将正确答案位置设为0.99,其他位置为0.01
n.train(inputs, targets) # 训练
pass
'''***********************************测试输出正确率******************************
# 输出正确数字
test_data_file = open("mnist_test.csv", 'r') # 打开测试数据文件
test_data_list = test_data_file.readlines()
test_data_file.close()
all_values = test_data_list[0].split(',')
print(all_values[0])
# 输出像素点组成的图片
image_array = numpy.asfarray(all_values[1:]).reshape((28,28))
#image_array = scipy.misc.imread("1.png", flatten=True)
#img_data = 255.0 - image_array.reshape(784)
#img_data = (img_data / 255.0 * 0.99) + 0.01
matplotlib.pyplot.imshow(image_array , cmap='Greys', interpolation='None')
matplotlib.pyplot.show()
# 查询结果
n.query((numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01) # 操作一波让输入在0—1之间
print(n.query((numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01)) # 输出神经网络判断结果
#记录正确率
scorecard = []
for record in test_data_list: # 循环测试数组
all_values = record.split(',') # 分割数据
correct_label = int(all_values[0]) # 记录正确数据,即第一个数字
# print(correct_label, "correct label")
inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # 输入数据
outputs = n.query(inputs) #输出查询结果
label = numpy.argmax(outputs) # 经过神经网络判断得到的数字
# print(label, "network's answer")
if(label == correct_label): # 如果判断结果与正确数据相同,记录1
scorecard.append(1)
else: # 如果判断错误,记录0
scorecard.append(0)
# 输出正确率
scorecard_array = numpy.asarray(scorecard)
print("正确率=", scorecard_array.sum() / scorecard_array.size)
'''