最新在朋友的推荐下看了《python神经网络编程》,深有启发,本文以深入浅出的道理,简单明了的介绍了一种神经网络的原理及python实现过程及全部代码,通过学习,至少基本掌握了相关知识,为后面学习打下基础,有几点心得分享如下:
1、大学阶段学好数学很重要
在《python神经网络编程》一书中,里面核心的算法思维方式就是线性代数和微积分,尤其是线性代数矩阵的乘法,是神经网络计算的核心内容,幸好大学时这块基础很好,所里整本书看起来不费力气。
2、尝试一步一步实现所有功能
在《python神经网络编程》一书中,作者手把手教你如何用python实现神经网络的过程,并用图片识别来叫我们进行训练和应用,从而较好的掌握其中的应用场景。建议读者应该逐步实现相关功能,并了解去原理,适当进行代码的优化和展示。由于不同的应用环境、编程环境,实际上展示回有一些区别,需要自己反复琢磨和百度查询。没有没有python经验,直接入手有可能比较麻烦,建议可以找一本python书籍看看,我看的是刘瑜老师的《Python编程从零基础到项目实战》,该书深入浅出的介绍了python基础语法,并就实际各种应用场景进行了基础的普及和尝试,是初学者的福音。
3、优化并提出自己的想法
在数字识别过程中,《python神经网络编程》一书只提供了单一的代码执行方法,这样没有办法系统的进行数据测试和数据分析,我就尝试用多重循环的方式进行改进,从而达到任意隐藏节点层数、任意世代次数,任意学习效率的组合测试和输出,并加入每一次的运行时间,输出每一次的运行结果,从而试图寻找其中的规律,找到最优值。并对每次运行结果进行记录,以便以后学习和分析。
4、分享自己的代码
以下是完整的实现代码,欢迎大家留言,讨论,共同学习,共同进步,后续继续分享自己的心得。现在最大的问题就是笔记本计算机计算不过来了,需要更大、更好的运行环境,也希望如果有人测试完成了能够分享出来。
import numpy
# scipy.special for the sigmoid function expit
import scipy.special
# neural network class definition
import matplotlib.pyplot
import time
import datetime
# 2018年12月16日对《python神经网络编程》一书代码进行优化,并进行测试,lucoaixi
class neuralNetwork:
#initialise the neural network
def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
#set number if nodes in each input,hidden,output layer
self.inodes = inputnodes
self.hnodes = hiddennodes
self.onodes = outputnodes
# link weight matrices,wih and who
# weight insides the arrays are w_i_j,where link is fron node i to node j in the next layer
# w11 w21
#w12 w22 etc
self.wih = 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))
# learning rate
self.lr = learningrate
#activation funtion is the sigmoid function
self.activation_function =lambda x:scipy.special.expit(x)
pass
#train the neural network
def train(self,inputs_list,targets_list):
# convet inputs list to 2d array
inputs = numpy.array(inputs_list,ndmin=2).T
targets = numpy.array(targets_list,ndmin=2).T
#calculate signals into hidden layer
hidden_inputs = numpy.dot(self.wih,inputs)
#calculate the signals emerging from hidden layer
hidden_outputs =self.activation_function(hidden_inputs)
#calculate signals into final output layer
final_inputs = numpy.dot(self.who,hidden_outputs)
#calculate the signals emerging from final output layer
final_outputs =self.activation_function(final_inputs)
# putput layer error is the (target-actual)
output_errors = targets - final_outputs
#output layer error is the output_errors,split by weights,recombined at hidden nodes
hidden_errors = numpy.dot(self.who.T,output_errors)
#update the weights for the links between the hidden and output layers
self.who +=self.lr * numpy.dot((output_errors*final_outputs*(1.0-final_outputs)),numpy.transpose(hidden_outputs))
#update the weights for the links between the input and hidden layers
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):
#convet inputs list to 2d array
inputs = numpy.array(inputs_list,ndmin=2).T
#calculate signals into hidden layer
hidden_inputs = numpy.dot(self.wih,inputs)
#calculate the signals emerging from hidden layer
hidden_outputs =self.activation_function(hidden_inputs)
#calculate signals into final output layer
final_inputs = numpy.dot(self.who,hidden_outputs)
#calculate the signals emerging from final output layer
final_outputs =self.activation_function(final_inputs)
return final_outputs
#begin process 进程开始
#初始化训练数据和测试数据
#load the mnist training data CSV file into a list
training_data_file =open("C:/test/mnist_train.csv",'r')
training_data_list = training_data_file.readlines()
training_data_file.close()
#load the mnist test data CSV file into a list
#test_data_file = open("C:/test/mnist_train_100.csv",'r')
test_data_file =open("C:/test/mnist_test.csv",'r')
test_data_list = test_data_file.readlines()
test_data_file.close()
#初始化 输入点数、隐藏层节点数、输出节点数
#number of input,hidden and output nodes
input_nodes =784
hidden_nodes1= ['10','20','40','80','100','200','300','400','500','600','700','800','900','1000']
#hidden_nodes2= ['10','20','40','80','100','120','150','200']
hidden_nodes2= ['200','300','400','500','600','700','800','900','1000' ]#测试200-1000个隐藏节点
hidden_nodes =100
output_nodes =10
# 初始化学习率 is 0.3
#learning_rate = ['0.1','0.2','0.3','0.4', '0.5', '0.6','0.7','0.8','0.9']
learning_rate = ['0.1','0.2','0.3']#测试学习率0.1、0.2、0.3
#dataSet = dataSet.astype('float64')
#初始化世代次数
epochs =10
#程序开始
start = time.time()
print('begin:',time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
print('世代次数cs,','学习率lr,','隐藏层节点数hn,','执行时长tm,',"执行结果out")
for iin range(len(hidden_nodes2)):
for ein range(epochs):
for lrin range(len(learning_rate)):
start = time.time()
n = neuralNetwork(input_nodes,int(hidden_nodes2[i]), output_nodes,float(learning_rate[lr]))
# go through all records in the training data set
for recordin training_data_list:
# split the record by the ',' connas
all_values = record.split(',')
# scale and shift the inputs
inputs = (numpy.asfarray(all_values[1:]) /255.0 *0.99) +0.01
# create the target output values(all 0.01,except the desired label which is 0.99)
targets = numpy.zeros(output_nodes) +0.01
# all_values[0] is the target lable for this record
targets[int(all_values[0])] =0.99
n.train(inputs, targets)
pass
pass
# 测试这个神经网络
# 计分卡记录网络运行情况,初始值为空
scorecard = []
# 在测试数据集中计算所有的记录值
for recordin test_data_list:
all_values = record.split(',')
correct_lable =int(all_values[0])
# print(correct_lable,'correct_lable')
inputs = (numpy.asfarray(all_values[1:]) /255.0 *0.99) +0.01
outputs = n.query(inputs)
lable = numpy.argmax(outputs)
# print(lable,"networks's answer")
if (lable == correct_lable):
scorecard.append(1)
else:
scorecard.append(0)
pass
pass
end = time.time()
seconds = end - start
# print(scorecard)
scorecard_array = numpy.asarray(scorecard)
print('cs=',e+1,',lr=',learning_rate[lr],',hn=',hidden_nodes2[i],',tm=',int(seconds),",out=",
scorecard_array.sum() / scorecard_array.size)
pass
#结束
end = time.time()
seconds = end - start
print(seconds)
print('end:',time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
以下是未运行完的数据:
begin: 2018-12-16 13:36:10
世代次数cs, 学习率lr, 隐藏层节点数hn, 执行时长tm, 执行结果out
cs= 1 ,lr= 0.1 ,hn= 200 ,tm= 154 ,out= 0.9593
cs= 1 ,lr= 0.2 ,hn= 200 ,tm= 152 ,out= 0.9568
cs= 1 ,lr= 0.3 ,hn= 200 ,tm= 148 ,out= 0.9519
cs= 2 ,lr= 0.1 ,hn= 200 ,tm= 147 ,out= 0.9582
cs= 2 ,lr= 0.2 ,hn= 200 ,tm= 145 ,out= 0.9581
cs= 2 ,lr= 0.3 ,hn= 200 ,tm= 144 ,out= 0.9541
cs= 3 ,lr= 0.1 ,hn= 200 ,tm= 144 ,out= 0.9583
cs= 3 ,lr= 0.2 ,hn= 200 ,tm= 144 ,out= 0.9573
cs= 3 ,lr= 0.3 ,hn= 200 ,tm= 144 ,out= 0.9507
cs= 4 ,lr= 0.1 ,hn= 200 ,tm= 145 ,out= 0.9595
cs= 4 ,lr= 0.2 ,hn= 200 ,tm= 145 ,out= 0.9554
cs= 4 ,lr= 0.3 ,hn= 200 ,tm= 144 ,out= 0.9513
cs= 5 ,lr= 0.1 ,hn= 200 ,tm= 144 ,out= 0.9599
cs= 5 ,lr= 0.2 ,hn= 200 ,tm= 144 ,out= 0.9562
cs= 5 ,lr= 0.3 ,hn= 200 ,tm= 146 ,out= 0.9421
cs= 6 ,lr= 0.1 ,hn= 200 ,tm= 147 ,out= 0.9556
cs= 6 ,lr= 0.2 ,hn= 200 ,tm= 147 ,out= 0.9591
cs= 6 ,lr= 0.3 ,hn= 200 ,tm= 147 ,out= 0.9552
cs= 7 ,lr= 0.1 ,hn= 200 ,tm= 192 ,out= 0.959
cs= 7 ,lr= 0.2 ,hn= 200 ,tm= 202 ,out= 0.9577
cs= 7 ,lr= 0.3 ,hn= 200 ,tm= 198 ,out= 0.9506
cs= 8 ,lr= 0.1 ,hn= 200 ,tm= 192 ,out= 0.9601
cs= 8 ,lr= 0.2 ,hn= 200 ,tm= 195 ,out= 0.9534
cs= 8 ,lr= 0.3 ,hn= 200 ,tm= 192 ,out= 0.9583
cs= 9 ,lr= 0.1 ,hn= 200 ,tm= 1010 ,out= 0.9571
cs= 9 ,lr= 0.2 ,hn= 200 ,tm= 185 ,out= 0.9558
cs= 9 ,lr= 0.3 ,hn= 200 ,tm= 186 ,out= 0.9522
cs= 10 ,lr= 0.1 ,hn= 200 ,tm= 190 ,out= 0.9586
cs= 10 ,lr= 0.2 ,hn= 200 ,tm= 191 ,out= 0.9594
cs= 10 ,lr= 0.3 ,hn= 200 ,tm= 189 ,out= 0.9467
cs= 1 ,lr= 0.1 ,hn= 300 ,tm= 264 ,out= 0.9613
cs= 1 ,lr= 0.2 ,hn= 300 ,tm= 260 ,out= 0.9607
cs= 1 ,lr= 0.3 ,hn= 300 ,tm= 261 ,out= 0.9561
cs= 2 ,lr= 0.1 ,hn= 300 ,tm= 264 ,out= 0.9602
cs= 2 ,lr= 0.2 ,hn= 300 ,tm= 277 ,out= 0.9587
cs= 2 ,lr= 0.3 ,hn= 300 ,tm= 282 ,out= 0.9498
cs= 3 ,lr= 0.1 ,hn= 300 ,tm= 281 ,out= 0.9608
cs= 3 ,lr= 0.2 ,hn= 300 ,tm= 2198 ,out= 0.9569
cs= 3 ,lr= 0.3 ,hn= 300 ,tm= 248 ,out= 0.9446
cs= 4 ,lr= 0.1 ,hn= 300 ,tm= 256 ,out= 0.9601
cs= 4 ,lr= 0.2 ,hn= 300 ,tm= 256 ,out= 0.9599
cs= 4 ,lr= 0.3 ,hn= 300 ,tm= 293 ,out= 0.956
cs= 5 ,lr= 0.1 ,hn= 300 ,tm= 308 ,out= 0.9586
cs= 5 ,lr= 0.2 ,hn= 300 ,tm= 220 ,out= 0.9566
cs= 5 ,lr= 0.3 ,hn= 300 ,tm= 220 ,out= 0.9559
cs= 6 ,lr= 0.1 ,hn= 300 ,tm= 218 ,out= 0.9586
cs= 6 ,lr= 0.2 ,hn= 300 ,tm= 217 ,out= 0.9576
cs= 6 ,lr= 0.3 ,hn= 300 ,tm= 217 ,out= 0.9551
cs= 7 ,lr= 0.1 ,hn= 300 ,tm= 205 ,out= 0.9594
cs= 7 ,lr= 0.2 ,hn= 300 ,tm= 207 ,out= 0.96
cs= 7 ,lr= 0.3 ,hn= 300 ,tm= 232 ,out= 0.9581
cs= 8 ,lr= 0.1 ,hn= 300 ,tm= 223 ,out= 0.958
cs= 8 ,lr= 0.2 ,hn= 300 ,tm= 221 ,out= 0.9528
cs= 8 ,lr= 0.3 ,hn= 300 ,tm= 222 ,out= 0.9537
cs= 9 ,lr= 0.1 ,hn= 300 ,tm= 222 ,out= 0.9589
cs= 9 ,lr= 0.2 ,hn= 300 ,tm= 219 ,out= 0.9574
cs= 9 ,lr= 0.3 ,hn= 300 ,tm= 219 ,out= 0.9563
cs= 10 ,lr= 0.1 ,hn= 300 ,tm= 218 ,out= 0.9598
cs= 10 ,lr= 0.2 ,hn= 300 ,tm= 217 ,out= 0.9558
cs= 10 ,lr= 0.3 ,hn= 300 ,tm= 218 ,out= 0.956
cs= 1 ,lr= 0.1 ,hn= 400 ,tm= 288 ,out= 0.9609
cs= 1 ,lr= 0.2 ,hn= 400 ,tm= 297 ,out= 0.9598
cs= 1 ,lr= 0.3 ,hn= 400 ,tm= 298 ,out= 0.9562
cs= 2 ,lr= 0.1 ,hn= 400 ,tm= 294 ,out= 0.9597
cs= 2 ,lr= 0.2 ,hn= 400 ,tm= 281 ,out= 0.959
cs= 2 ,lr= 0.3 ,hn= 400 ,tm= 312 ,out= 0.9561
cs= 3 ,lr= 0.1 ,hn= 400 ,tm= 300 ,out= 0.9598
cs= 3 ,lr= 0.2 ,hn= 400 ,tm= 304 ,out= 0.9603
cs= 3 ,lr= 0.3 ,hn= 400 ,tm= 292 ,out= 0.9507
cs= 4 ,lr= 0.1 ,hn= 400 ,tm= 290 ,out= 0.9603
cs= 4 ,lr= 0.2 ,hn= 400 ,tm= 307 ,out= 0.9619
cs= 4 ,lr= 0.3 ,hn= 400 ,tm= 302 ,out= 0.9498
cs= 5 ,lr= 0.1 ,hn= 400 ,tm= 292 ,out= 0.9599
cs= 5 ,lr= 0.2 ,hn= 400 ,tm= 297 ,out= 0.9588
cs= 5 ,lr= 0.3 ,hn= 400 ,tm= 285 ,out= 0.9544
cs= 6 ,lr= 0.1 ,hn= 400 ,tm= 296 ,out= 0.9608
cs= 6 ,lr= 0.2 ,hn= 400 ,tm= 277 ,out= 0.9608
cs= 6 ,lr= 0.3 ,hn= 400 ,tm= 281 ,out= 0.9466
cs= 7 ,lr= 0.1 ,hn= 400 ,tm= 272 ,out= 0.9579
cs= 7 ,lr= 0.2 ,hn= 400 ,tm= 325 ,out= 0.9622
cs= 7 ,lr= 0.3 ,hn= 400 ,tm= 288 ,out= 0.9515
cs= 8 ,lr= 0.1 ,hn= 400 ,tm= 289 ,out= 0.96
cs= 8 ,lr= 0.2 ,hn= 400 ,tm= 288 ,out= 0.9607
cs= 8 ,lr= 0.3 ,hn= 400 ,tm= 287 ,out= 0.9556