当前位置: 首页 > 科技观察

实现手写识别的单层基础神经网络

时间:2023-03-20 00:19:23 科技观察

先上传代码importtensorflowfromtensorflow.examples.tutorials.mnistimportinput_dataimportmatplotlib.pyplotasplt#GeneralNeuralNetworkLearning#LearningandtrainingclassNormal:weight=[]biases=[]def__init__(self):self.times=1000self.mnist=[]self.session=tensorflow.Session()self.xs=tensorflow.placeholder(tensorflow.float32,[None,784])self.ys=tensorflow.placeholder(tensorflow.float32,[无,10])self.save_path='learn/result/normal.ckpt'defrun(self):self.import_data()self.train()self.save()def_setWeight(self,weight):self.weight=weightdef_setBiases(self,biases):self.biases=biasesdef_getWeight(self):returnsself.weightdef_getBiases(self):returnsself.biases#trainingdeftrain(self):prediction=self.add_layer(self.xs,784,10,activation_function=tensorflow.nn.softmax)cross_entropy=tensorflow.reduce_mean(-tensorflow.reduce_sum(self.ys*tensorflow.log(预测),reduction_indices=[1]))train_step=tensorflow.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)self.session.run(tensorflow.global_variables_initializer())foriinrange(self.times):batch_xs,batch_ys=self.mnist.train.next_batch(100)self.session.run(train_step,feed_dict={self.xs:batch_xs,self.ys:batch_ys})ifi%50==0:#images变换为labels,images相对于x,labels相对于yaccurary=self.computer_accurary(self.mnist.test.images,self.mnist.test.labels,prediction)#数据导入defimport_data(self):self.mnist=input_data.read_data_sets('MNIST_data',one_hot=True)#数据保存defsave(self):saver=tensorflow.train.Saver()path=saver.save(self.session,self.save_path)#添加隐藏层defadd_layer(self,inputs,input_size,output_size,activation_function=None):weight=tensorflow.Variable(tensorflow.random_normal([input_size,output_size]),dtype=tensorflow.float32,name='weight')biases=tensorflow.Variable(tensorflow.zeros([1,output_size])+0.1,dtype=tensorflow.float32,name='biases')Wx_plus_b=tensorflow.matmul(inputs,weight)+biasesself._setBiases(biases)self._setWeight(weight))ifactivation_functionisNone:outputs=Wx_plus_belse:outputs=activation_function(Wx_plus_b,)returnoutputs#计算结果数据和实际数据的正确率defcomputer_accurary(self,x_data,y_data,tf_prediction):prediction=self.session.run(tf_prediction,feed_dict={self.xs:x_data,self.ys:y_data})#返回***值在两个矩阵中的索引号位置,然后比较对应位置的值,设置为True/Falsecorrect_predition=tensorflow.equal(tensorflow.argmax(prediction,1),tensorflow.argmax(y_data,1))#转换数据格式,然后进行降维和平均={self.xs:x_data,self.ys:y_data})returnresult#识别类classNormalRead(Normal):input_size=784output_size=10defrun(self):self.import_data()self.getSaver()origin_input=self._getInput()output=self.recognize(origin_input)self._showImage(origin_input)self._showOutput(output)pass#显示识别结果def_showOutput(self,output):number=output.index(1)print('recognizednumber:',number)#显示识别图像def_showImage(self,origin_input):data=[]tmp=[]i=1#原始数据被转换为可显示矩阵forvinorigin_input[0]:ifi%28==0:tmp.append(v)data.append(tmp)tmp=[]else:tmp.append(v)i+=1plt.figure()plt.imshow(data,cmap='binary')#黑白显示plt.show()def_setBiases(self,biases):self.biases=biasespassdef_setWeight(self,weight):self.weight=weightpassdef_getBiases(self):returnsself.biasesdef_getWeight(self):returnsself.weight#获取训练模型defgetSaver(self):weight=tensorflow.Variable(tensorflow.random_normal([self.input_size,self.output_size]),dtype=tensorflow.float32,name='weight')biases=tensorflow.Variable(tensorflow.zeros([1,self.output_size])+0.1,dtype=tensorflow.float32,name='偏见')saver=tensorflow.train.Saver()saver.restore(self.session,self.save_path)self._setWeight(weight)self._setBiases(biases)defrecognize(self,origin_input):input=tensorflow.placeholder(tensorflow.float32,[None,784])weight=self._getWeight()biases=self._getBiases()result=tensorflow.matmul(input,weight)+biasesresultSof=tensorflow.nn.softmax(result,)#使用结果setwithsoftmaxIncentiveresultSig=tensorflow.nn.sigmoid(resultSof,)#激发result设置了sigmoid函数用于后续分类output=self。session.run(resultSig,{input:origin_input})output=output[0]#对识别结果进行分类output_tmp=[]foriteminoutput:ifitem<0.6:output_tmp.append(0)else:output_tmp.append(1)returnoutput_tmpdef_getInput(self):inputs,y=self.mnist.train.next_batch(100);return[inputs[50]]以上是程序,整个程序是基于TensorFlow实现的,整个训练过程我就不说了具体的TensorFlow安装废话不多说,我发现网上关于训练的教程很多,但是关于训练结果的教程却很少。整个程序中,通过tensorflow.train.Saver()的save来存储训练结果模型,然后通过tensorflow.train.Saver()的restore来恢复模型,得到训练好的weight和baises。这里要注意一点,就是一次性随机取出100张手写图片进行批量训练。我拍的时候其实是批量随机拍了100张,但是我传入识别的是一张,通过下面的程序:def_getInput(self):inputs,y=self.mnist.train.next_batch(100);return[inputs[50]]注意这里的数据结构,其实就是这个batch的第50张。其实这个程序写成:def_getInput(self):inputs,y=self.mnist.train.next_batch(1);return[inputs[0]]会更好。因为识别需要用到训练的隐藏层,所以我这里虽然识别一张图片,但是必须传入这样一个batchdata的结构。然后为了识别,我用了两个激活函数:resultSof=tensorflow.nn.softmax(result,)#使用softmax来刺激结果集resultSig=tensorflow.nn.sigmoid(resultSof,)#使用结果集作为sigmoid函数是用于激励,用于后续分类。在这里,我发现第一次softmax激发后的数据是以e为基数的索引形式。它被转换成普通的浮点数。不是很清楚是什么,那我认数判断不方便,于是又通过了sigmoid激励。以后我会通过循环判断来进行实际的分类。之所以这样,首先要说说识别结果的形式:[0,0,0,0,0,0,0,0,0,1,0]像上面的数据,表示的是个数为8,也就是说数组下面的表格中的位数为1,表示数,比如0的表示:[1,0,0,0,0,0,0,0,0,0,0]和sigmoid函数在这个地方,其实是对每个位置的数据进行了分类。我发现如果分类值小于0.52,数据其实代表的是不是,也就是说这个位置的值对应0,大于0.52的值应该对应true。即1;而我在程序中以0.6为界限来判断。其实这个极限值应该是在神经网络训练的时候取的,而不是看识别结果凭感觉取的(虽然训练时的参数也是凭感觉取的)。这篇文章是基于我的个人经验。我是根据自己的理解写的。如果以后发现有什么错误,我会在新的文章中告诉他们,但这篇文章不保留,以便我以后查看和思考记录时知道如何踩坑。下面是我上次写的关于sigmoid函数的文章:https://segmentfault.com/a/11...关于其他的激励函数,大家可以在网上找资料看懂,放很多基础数学知识转化为一些更具体的知识。应用程序将非常有趣。