前言 前面我们简单讲解了神经网络的基本概念和工作原理,接下来,将通过具体的python代码来完成基于神经网络的图形识别。这里使用手写的数字图像作为输入,神经网络将输出图像所对应的数字。
获取神经网络源码首先访问github获取 神经网络源码。
这里通过ssh登录开发板,执行git clone克隆整个项目,如图所示:
图1
进入项目目录,通过ls命令查看内容,如下图:
图2
接下来,通过浏览器访问开发板。可以看到文件列表中多了一个我们刚刚克隆的项目。如下图:
图3
神经网络源码分析在运行代码之前,我们先来了解一下神经网络代码的构成。代码至少包含三个函数。 - 初始化函数--设定输入层节点、隐藏层 节点和输出层节点的数量。
- 训练函数--学习给定的训练样本,然后优化权重
- 查询函数--输入测试数据,输出答案
接下来看代码。我这里在part2_neural_network_mnist_data.ipynb代码的基础上,做了一些修改,方便接下来的演示。
具体代码如下:
- # neural network class definition
- class neuralNetwork:
- # initialise the neural network
- def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
- # set number of nodes in each input, hidden, output layer
- self.inodes = inputnodes
- self.hnodes = hiddennodes
- self.onodes = outputnodes
- # link weight matrices, wih and who
- # weights inside the arrays are w_i_j, where link is from node i to node j in the next layer
- # w11 w21
- # w12 w22 etc
- self.wih = numpy.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes))
- self.who = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))
- # learning rate
- self.lr = learningrate
- # activation function 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):
- # convert 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)
- # output layer error is the (target - actual)
- output_errors = targets - final_outputs
- # hidden 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):
- # convert 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
复制代码
在初始化函数中,需要设置输入层节点、隐藏层节点、输出层节点的数量。这些节点定义了神经网络的形状和尺寸。接下来需要初始化权重矩阵。这里创建了两个链接权重矩阵,并使用self.inodes,self.hnodes,self.onodes为两个链接权重矩阵设置了合适的大小。最后是设定学习率和设置激活函数。 在查询函数中,由输入节点和链接权重进行矩阵的点乘,其结果作为隐藏层节点的输入。然后应用激活函数,得到隐藏节点的输出。再由隐藏节点输出与链接权重做矩阵的点乘,得到最终的输入,最后应用激活函数计算出最终的输出。 在训练函数中,由输入计算输出的方式与查询函数中的一样。不过这里多了一个很重要的步骤,即将实际输出与期望值做比较,使用差值来指导网络的权重更新。
测试在浏览器中运行python代码,由于训练样本较大,运行需要一定时间。待程序运行结束,输出结果如下图:
图4
首先读取测试数据,使用imshow()函数,绘制出我们待测试的数据,从图中可以看出,我们待识别的数字为7。接下来调用查询函数query(),将图像数据作为输入参数。最终的输出为7,与期望一致,表明我们的神经网络图形识别成功了。
总结本文讲解了基于python代码的神经网络图形识别。这里使用了一个较小的样本数据来训练神经网络,即完成了手写图形的识别。训练样本及测试数据均来自于网络,感兴趣的朋友可以自己手写数字来进行测试。 由于整个代码使用python语言编写,只使用了芯片的ARM处理器部分。虽然训练样本较小,但在执行训练函数的时候,也花费了不少时间。如果能利用FPGA部分进行神经网络的硬件加速,应该可缩短整个运行时间,这里留给后面慢慢研究。 最后感谢电子发烧友论坛和xilinx提供本次试用机会。由于时间关系,仅对自己感兴趣的部分做了简单的体验,希望有机会继续深入研究这种ARM+FPGA的二合一芯片。
|