参考
Python神经网络编程(Tariq Rashid著)
菜鸟教程
神经网络类
我们需要利用Python面向对象的优势创建一个神经网络类,这样我们就可以轻松地利用这一个类生成很多个不同而又有相似性的神经网络。这一过程也称之为实例化。
为了尽可能地简单,我们设计这个神经网络是基于层次模型的,且只有三层,输入层,中间层(隐藏层),输出层。并且激活函数选择S。所以,用户只需要自定义这一个神经网络的输入层,隐层与输出层的节点数量即可。当然我们知道,很多时候,学习率地选择也很重要,所以我们希望,用户也可以自由地选择这一个网络的学习率。所以这一类的参数则包含了:输入输出与隐层各自的节点数量与学习率,一共四个参数是从外界接受过来的。
而我们知道,一个类最重要的就是它的属性与行为。从上面可以知道,神经网络类的属性已经包括了各层的节点数量与学习率。所以对于一个完整的神经网络来说,我们还需要在初始化函数内部定义其的激活函数(S函数,不由用户决定),并且初始化各个传递链的权重(即形成权重矩阵)。这些就是一个神经网络基本要具有的元素,因此我们称之为神经网络类的属性。
至于行为,则需要设计这个神经网络的功能或者说它是如何工作的。显然除了初始化函数以为,神经网络最重要的功能就是从输入中获得输出。即用户输入一组数据,神经网络返回输出结果。所以,这一个过程可以被称之为查询,参数除了Python类函数标准里面的self之外,我们只需要用户的输入数据input_list即可。
由了结果以后,我们当然还需要把结果与预期做对比,借此改善我们的神经网络。所以一个神经网络类还需要具有的行为便是学习或者称之为训练,即能够通过用户给的输入输出数据集训练权重矩阵。当然训练完毕以后,我们只需要用查询函数即可检验结果。所以,我们不再需要设计任何新的函数作为一类基本的神经网络的行为。
Python实现
Python是一种解释型脚本语言,是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。
可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发等
接下来,我们自然要关注于如何利用Python实现我们上面构筑的蓝图。Python基本语法与面向对象编程的基本思想,在这里不会过多的介绍。由于算法中牵涉许多矩阵运算,因此我们需要引用Python的Numpy库
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
此外,因为我们需要使用S函数,因此我们需要借助scipy库的帮助,其中的special库包含了大量的特殊函数。下面展示了一个3层神经网络的Python实现代码。
import numpy
import scipy.special#包含一系列特殊函数
class neuralNetwork:
def __init__(self, inputnodes,hiddennodes,ouputnodes,learningrate):#初始化函数
self.inodes=inputnodes#接受用户设置的输入节点,隐层节点和输出层节点数
self.hnodes=hiddennodes
self.onodes=ouputnodes
self.lr=learningrate#接受用户的设置的学习率
self.activation_function=lambda x: scipy.special.expit(x)#选择s函数用作激活函数
#https://github.com/makeyourownneuralnetwork/makyourownneuralnetwork/blob/master/part2_neural_network.ipynb
self.wih = numpy.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes))
#以服从正太分布的形式生成输入层与隐层之间各条链的初始权重,分布中心是0.0,标准差是pow函数,大小是hXi
self.who = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))
#以同样的方式生成隐层与输出层之间的权重矩阵
pass
def train(self, inputs_list, targets_list):#通过用户传入的输入输出数据集训练
#通常输入层的神经元不应用激活函数
inputs = numpy.array(inputs_list, ndmin=2).T
targets = numpy.array(targets_list, ndmin=2).T
#将输入转换为2维数组
hidden_inputs = numpy.dot(self.wih, inputs)
#用点乘的方式计算输入层传入的输入信号X=W.I
hidden_outputs = self.activation_function(hidden_inputs)
#对传入输入层的信号应用激活函数
final_inputs = numpy.dot(self.who, hidden_outputs)
#计算得到输出层得到的输入信号
final_outputs = self.activation_function(final_inputs)
#计算输出层误差
output_errors = targets - final_outputs
#反向传播法计算隐层误差E=W.E'
hidden_errors = numpy.dot(self.who.T, output_errors)
#利用梯度下降法更新隐层与输出层之间的权重
self.who += self.lr * numpy.dot((output_errors * final_outputs * (1.0 - final_outputs)), numpy.transpose(hidden_outputs))
#利用梯度下降法更新输出层与隐层之间的权重
self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), numpy.transpose(inputs))
pass
def query(self, inputs_list):#根据用户输入查询在当前权重下的输出值
inputs = numpy.array(inputs_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
input_nodes = 3
hidden_nodes = 3
output_nodes = 3
# 设置学习率为0.3
learning_rate = 0.3
# 将神经网络类实例化为n
n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, learning_rate)
由此我们已经利用Python实现了一个简单的3X3的神经网络。接下来,我们将主要期望使用神经网络来对数字进行图像识别,这将需要借助大量的数据的帮助。