代码实现三层神经网络的手写字训练及测试
- 2019 年 10 月 5 日
- 筆記
本篇使用的原理和计算公式是来自于上一篇:神经元矩阵计算示例
废话不说直接上代码:
import numpy import scipy.special import matplotlib.pyplot class network: def __init__(self , inputnodes, hiddennodes, outputnodes,learningrate ): self.inputnodes=inputnodes self.hiddennodes=hiddennodes self.outputnodes=outputnodes self.lr=learningrate # 计算输入层隐藏层的权重系数 self.wih = numpy.random.normal(0.0, pow(self.hiddennodes, -0.5),(self.hiddennodes, self.inputnodes)) # 计算隐藏层输出层的权重系数 self.who = numpy.random.normal(0.0, pow(self.outputnodes, -0.5),(self.outputnodes, self.hiddennodes)) # 定义激活函数,使用scipy中的expit函数 self.activation_function = lambda x:scipy.special.expit(x) # 训练神经网络 def train(self, inputs_list, targets_list): # 将输入转化为2维矩阵 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) # 计算输出层的输入 final_inputs = numpy.dot(self.who, hidden_outputs) #计算激活函数处理后输出层的输入变成输出 final_outputs = self.activation_function(final_inputs) 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 # query the neural network 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 #加载数据进行训练 def train_datas(output_nodes,network): with open('/home/opprash/Desktop/mnist_train_100.csv', 'r') as f: data_list = f.readlines() f.close() #可视化csv中的数字的意义 # all_values = data_list[1].split(',') # image_array = numpy.asfarray(all_values[1:]).reshape((28, 28)) # matplotlib.pyplot.imshow(image_array, cmap='Greys', interpolation='None') # matplotlib.pyplot.show() # scaled_input = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # print(scaled_input) # 训练神经网络 # 遍历训练集的所有数据 for record in data_list: # 以逗号分割 all_values = record.split(',') # 将数据压缩到0到1之间,原始数据是在0-255之间 inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # 创建目标输出值(全部0.01,除了所需的值标签是0.99) targets = numpy.zeros(output_nodes) + 0.01 # all_values[0] 是此记录的目标标签 targets[int(all_values[0])] = 0.99 network.train(inputs, targets) pass #加载数据进行测试 def test_data(network): with open('/home/opprash/Desktop/mnist_test_10.csv', 'r') as f: data_list = f.readlines() f.close() scorecard = [] for record in data_list: # 以逗号分割 all_values = record.split(',') # 正确答案是第一个值 correct_label = int(all_values[0]) print( "真实的标签",correct_label) # 将数据压缩到0到1之间,原始数据是在0-255之间 inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01 # 使用网络进行查询 outputs = network.query(inputs) # 最高值的索引就是对应的标签 label = numpy.argmax(outputs) print("神经网络预测的答案:",label) # 追加正确或者不正确的list 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) if __name__ == '__main__': # 定义输入,隐藏层,输出层节点个数 input_nodes = 784 hidden_nodes = 100 output_nodes = 10 # 学习率 0.3 learning_rate = 0.3 # 实例化神经网络 n = network(input_nodes,hidden_nodes,output_nodes,learning_rate) train_datas(output_nodes,n) test_data(n)
运行结果:
