使用python制作神经网络——搭建框架
一.神经网络的大体结构可分为三个函数,分别如下:
1.初始化函数
设定输入层节点,隐藏层节点和输出层节点的数量。
2.训练
学习给定训练集样本后,优化权重。
3.查询
给定输入,从输出节点给出答案
所编写的代码框架可如下所示:
1 #神经网络类定义 2 class NeuralNetwork(): 3 #初始化神经网络 4 def _init_(): 5 pass 6 7 #训练神经网络 8 def train(): 9 pass 10 11 #查询神经网络 12 def query(): 13 pass
二.初始化网络
需要设置输入层节点,隐藏层节点和输出层节点的数量,同时不要忘记设置学习率。
1 def _init_(self,inputnodes,hiddennodes,outputnodes,learningrate): 2 #设置输入层节点,隐藏层节点和输出层节点的数量 3 self.inodes = inputnodes 4 self.hnodes = hiddennodes 5 self.onodes = outputnodes 6 #学习率设置 7 self.lr = learningrate 8 pass
如果每层创建三个节点,学习率为0.5的小型神经网络对象则如下所示:
1 #设置每层节点个数为3个 2 input_nodes = 3 3 hidden_nodes = 3 4 output_nodes = 3 5 #设置学习率为0.5 6 learning_rate =0.5 7 #创建神经网络 8 n = NeuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)
三. 权重-网络的核心
简单而又比较流行的优化初始权重的方式是:使用正态概率分布采样权重,其中平均值为0,标准方差为节点传入链接数目的开方。
python中可用numpy.random.normal()函数来以正态分布的方式采样,其中初始化权重的代码如下所示:
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))
我将正态分布的中心设置为0.0,与下一层中节点相关的标准方差为节点数目的-0.5次方,最后一个参数,是numpy数组的形状大小。
因为权重是神经网络的固有部分,与神经网络共存亡,它不是一个临时的数据集,不会随着函数调用结束而消失,因此,权重必须也是初始化的一部分,并且可以使用其他函数(如训练函数和查询函数)来访问。
四.查询网络
query()函数接受神经网络的输入,返回网络的输出,它需要来自输入层节点的输入信号,通过隐藏层,最后从输出层输出。
(1)第一步需要做的是输入的数据和输入层与隐藏层之间的权重矩阵相乘,得到传输到隐藏层的输入信号,可表示如下:
Xhidden = Winput_hidden * I
用python可表示为:
hidden_inputs= numpy.dot(self.wih,inputs)
(2)为了获得从隐藏层节点处出现的信号,需要增加激活函数sigmod()
Ohidden = sigmod(Xhidden)
python中的Scripy库中有此函数,可表示为:
import scripy.special self.activation_function = lambda x:scripy.special.expit(x)
(3)隐藏层的输入输出呢?和上面的思路一样,可定义如下:
1 #计算到输出层的信号 2 final_inputs= numpy.dot(self.who,hidden_outputs) 3 final_outputs = self.activation_function(final_inputs)
至此,训练函数还没有完成,以上部分的完整代码如下:
import numpy import scripy.special #神经网络类定义 class NeuralNetwork(): #初始化神经网络 def _init_(self,inputnodes,hiddennodes,outputnodes,learningrate): #设置输入层节点,隐藏层节点和输出层节点的数量 self.inodes = inputnodes self.hnodes = hiddennodes self.onodes = outputnodes #学习率设置 self.lr = learningrate #权重矩阵设置 正态分布 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)) #激活函数设置,sigmod()函数 self.activation_function = lambda x:scripy.special.expit(x) pass #训练神经网络 def train(): pass #查询神经网络 def query(self,input_list): #转换输入列表到二维数组 inputs = numpy.array(input_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 #设置每层节点个数为3个 input_nodes = 3 hidden_nodes = 3 output_nodes = 3 #设置学习率为0.5 learning_rate =0.5 #创建神经网络 n = NeuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)
下面定义一个输入为:
print(n.query([1.0,0.5,-1.5]))
可看到程序的实际运行效果为:
[[0.65948789] [0.4672955 ] [0.66051158]]
输入是列表,输出也是一个列表。正确,但是这个输出没有实际意义,因为我们还没有训练网络。