网站版面布局结构图,做h5免费的网站有,购物网站排名 2019,交互式网站定义目录 一、《python神经网络编程》
二、一些粗浅的认识
1#xff09; 神经网络也是一种拟合
2#xff09;神经网络不是真的大脑
3#xff09;网络构建需要反复迭代
三、数字图像识别的实现思路
1#xff09;建立一个神经网络类 2#xff09;权重更新的具体实现
3 神经网络也是一种拟合
2神经网络不是真的大脑
3网络构建需要反复迭代
三、数字图像识别的实现思路
1建立一个神经网络类 2权重更新的具体实现
3网络测试
四、总结 一、《python神经网络编程》
最近学习了一本书《python神经网络编程》该书通过对一个数字识别案例的深入详细讲解可以让读者对神经网络的思想有更加清晰的理解明白计算机神经网络是如何工作的。在没有真正接触神经网络之前总以为这是非常深奥的理论也不明白神经网络是如何模拟人的大脑进行学习和判断的难以理解计算机能够模拟人的大脑。《python神经网络编程》确实是一本很好的入门教材它让读者能够真正踏入人工智能的门槛奠定深入研究的基础。
二、一些粗浅的认识
1 神经网络也是一种拟合
在数学中有很多拟合方法比如线性拟合、多项式拟合等等。在这些拟合中我们同样需要有确定的已知数据然后通过这些拟合方法我们可以得到一个确定的数学解析表达式并通过这个表达式来预测未知的结果。而神经网络的核心思想我想也是一样的只是这个实现过程相对复杂。我们最终能得到的是一个预测网络也称模型而不是一个精确的数学方程表达式。我们使用已知输入和输出的大量数据来训练神经网络就是在让这个网络的输出结果逐渐逼近已知的输出结果。这个网络在训练的过程中最终建立起了输入与输出之间的对应关系。但是这个对应关系我们无法用一个清晰的数学表达式来描述可是我们可以使用这个网络来进行预测。正如对于图片中的数字而言我们人看到图片中的数字就可以知道图中的数字是多少因为在我们认识数字之前经过了学习很多次有人告诉我们这个图形对应的数字就是这个数字。就像神经网络不能用一个准确的数学公式来描述输入与输出之间的关系一样我们人类其实至今也还是不知道我们大脑学习的本质是什么。所以神经网络得到的拟合结果是一个黑盒子我们针对特定的问题建立了一个黑盒子然后训练了这个黑盒子我们只知道给这个黑盒子一个输入他能给出一个可信的结果。
2神经网络不是真的大脑
神经网络只是借用了人类大脑神经元的形式。计算机神经网络是否真的能实现动物大脑的能力我想还是难以断定。我们以前总是认为计算机的工作都是确定的给它一个输入我们必然能够准确预测它的输出结果。其实现在的神经网络也是一样的虽然它是个黑盒子但是给它相同的输入它必然能够得到相同的结果即使我们不知道它具体的计算逻辑因为在这个网络中所有的参数经过训练后已经确定计算机计算的每一步都是确定的。但计算机神经网络这种模糊拟合的实现让我们认识到当大量简单计算累计到一定数量时在庞大的信息传递中是否就存在不可预测性。我们不理解自己为什么会思考或许在不久的将来我们也无法确信庞大计算机系统的运行的真是我们人类设计的程序。
3网络构建需要反复迭代
在构建神经网络过程中输入与输出的节点数量需要根据实际问题进行分析。我们需要根据解决的实际问题分析如何将问题的输入数字化并设计相应的输入节点。而对于输出也是一样我们需要分析如何用输出的数字信息来表达我们想要的结果形式并设计相应的输出节点。我们常见的简单的神经网络通常是3层包括输入、输出和中间的隐藏层而隐藏层的层数以及每层的节点数该如何设计这需要通过不断的尝试。较少的层数和节点数能够获得较高的计算效率但是性能较低误差较大较多的层数和节点数能够获得较高的精度但是计算效率低。因此针对具体的问题需要综合考虑反复迭代后确定网络构建形式。
三、数字图像识别的实现思路
1建立一个神经网络类
《python神经网络编程》书中给出了一个实现数字识别的例子。在Python中首先定义一个3层神经网络类neuralNetwork。在类的初始化函数中确定网络的输入层节点数、隐藏层节点数、输出层节点数和学习率4个参数。并确定使用的激活函数。输入层与隐藏层、隐藏层和输出层之间的初始权重矩阵随机生成。
训练神经网络时先根据训练数据的输入正向逐层计算最后得到网络的输出结果。然后计算网络输出结果与实际结果的误差值然后再将误差进行反向传播更新权重矩阵。这样一组数据的训练就完成。
网络输出就是利用测试数据对网络进行一次正向输出的过程最后根据输出数据给出网络的图像识别结果具体实现后面再叙述。
class neuralNetwork:# 初始化函数def __int__(self, inputnodes, hiddennodes, outputnodes, learningrate):self.inodes inputnodes # 输入节点数self.hnodes hiddennodes # 隐藏节点数self.onodes outputnodes # 输出节点数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.hnodes, -0.5), (self.onodes, self.hnodes)) # 随机生成初始的隐藏层到输出层的权重矩阵self.learn learningrate # 权重更新率self.active_function lambda x: scipy.special.expit(x) # 选择需要使用的激活函数pass# 定义训练函数def train(self, input_list, target_list): # 提供已知的输入和输出结果inputs numpy.array(input_list, ndmin2).T # 将输入转换为二维矩阵形式targets numpy.array(target_list, ndmin2).Thidden_inputs numpy.dot(self.wih, inputs) # 计算隐藏层的输入值输入层到隐藏层的权重矩阵乘以输入hidden_outputs self.active_function(hidden_inputs) # 计算隐藏层的输出值将隐藏层的输入值带入激活函数final_inputs numpy.dot(self.who, hidden_outputs) # 计算输出层的输入值隐藏层到输出层的权重矩阵乘以隐藏层的输出值final_outputs self.active_function(final_inputs) # 计算输出层的输出结果将输出层的输入值带入激活函数output_errors targets - final_outputs # 计算误差值已知的输出结果-输出层的输出值hidden_errors numpy.dot(self.who.T, output_errors) # 传递误差# 更新权重矩阵self.who self.learn * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)),numpy.transpose(hidden_outputs))self.wih self.learn * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)),numpy.transpose(inputs))pass# 定义输出函数def query(self, input_list):inputs numpy.array(input_list, ndmin2).Thidden_inputs numpy.dot(self.wih, inputs)hidden_outputs self.active_function(hidden_inputs)final_inputs numpy.dot(self.who, hidden_outputs)final_outputs self.active_function(final_inputs)return final_outputs2权重更新的具体实现
权重矩阵反复更新就是神经网络不断学习获得正确拟合结果的过程。权重更新根据严格的数学推导公式程序实现过程不能直观反映具体的实现思想。它的核心就是利用每次训练的计算误差来修正权重矩阵。
(1)误差计算
在训练神经网络过程中计算误差时程序中我们直接将实际结果与计算结果相减output_errors targets - final_outputs得到一个误差向量。但是理论分析时直接相减计算误差的方法并不合适我们通常使用差的平方来表示所有节点的总误差如下 2误差传递
我们可以直接计算出输出层的误差但是最终的误差是由前面的计算逐层、逐节点计算累计得到的该如何将最终的误差反向分配到每个节点上呢通常我们认为节点之间连接权重越大的链路计算引入的误差也越大因此我们也同样通过权重来分配误差。针对本例而言我们已经得到了输出层的误差还需要计算隐藏层的误差。输入层不需要计算因为默认输入层输入与输出是相同的不需要使用激活函数。那么隐藏层的输出误差计算如下 此处需要注意的是误差反向传播计算的矩阵正好是正向计算时隐藏层到输出层权重矩阵的转置至于为什么是转置我们手动简单计算一下就知道了。同时需要注意的是通过上式计算得到的总误差并不是输出层的总误差 。因为更新权重矩阵时我们其实并不关心过程中的误差大小而是更关心是哪个链路导致的误差更大只要能体现出各链路误差的相对大小就可以。
3更新权重
在此例中使用跟新权重的方法是梯度下降法这也是使用非常广泛的一种方法。我们需要建立起权重与误差之间的关系。我们以最后的输出层为例输出层的输入是隐藏层的输出乘以隐藏层和输出层之间的权重矩阵 将此结果代入激活函数则输出层的结果为 sigmoid函数为激活函数形式为 则每个节点的输出误差为 将上述公式联合然后对权重w求导就可以得到误差相对于权重的导数斜率 权重更新公式为 上述公式中我们实际使用时并不关心常系数2因此在代码实现时省略了。
3网络测试
网络测试的具体实现可参见代码。
# 测试网络
scorecard []
i 0
for record in test_data_list:i 1if(i ! 10): # 可调整数字逐张识别continuepassall_values record.split(,)correct_label int(all_values[0])inputs (numpy.asarray(all_values[1:], numpy.float32) / 255.0 * 0.99) 0.01image_array numpy.asarray(all_values[1:], numpy.int32).reshape((28, 28))fig matplotlib.pyplot.figure(figsize(5, 5))matplotlib.pyplot.imshow(image_array, cmapGreys, interpolationNone)matplotlib.pyplot.show()outputs n.query(inputs) # 网络识别的结果label numpy.argmax(outputs) # 输出结果中的最大值print(输入数字, all_values[0], 识别结果, label) # 打印出实际值if(label correct_label):scorecard.append(1)else:scorecard.append(0)passpassscorecard_array numpy.asarray(scorecard)
print(performance , scorecard_array.sum() / scorecard_array.size)
四、总结
《python神经网络编程》与书中的示例简明阐述了神经网络的核心思想和基本架构任何复杂的神经网络均可基于此构建。我们可以通过使用不同的网络层数、节点数、激活函数以及链路连接方式等构建不同的适用于各种应用的神经网络模型。或许正式因为神经网络内部的不可描述性对网络结构的各种优化为研究神经网络开辟了广阔空间。