Make your own Neural NetWork之代码详解上

本文基于《Make your own Neural NetWork》书籍,讲解如何构建一个简单的神经网络,包括初始化网络、设置网络形状和大小、权重的创建、训练网络等步骤。文中使用Python实现,介绍了神经网络的基本构造和工作原理。
摘要由CSDN通过智能技术生成

这篇博客接上一篇博客Make Your Own Neural Network简介。本文也是出自Make your own Neural NetWork这本书。上一篇博客讲了该书的行文结构,本文主要介绍如何构建自己的神经网络并附代码。
本文简单讲述了一本书Make your own Neural NetWork的主要内容。这本书一步一步教会我们搭建简单的单隐层神经网络,如果你对该书该兴趣,你可以先阅读一下这篇博客,看一下这本书的行文思路。
声明:

  1. 代码用的Python编写
  2. 红字为后面要讲的内容的中心句

骨干代码

  我们先想像一下神经网络类应该是什么样的。首先它有自己的参数,可以通过样本训练网络,训练好之后还可以获取未标定样本的标签,归结来看,至少有三个功能:

  1. 初始化:设置输入,隐藏和输出节点的数量
  2. 训练: 通过输入的训练样本调整权重
  3. 获取输出:在给出输入后,获得输出节点的结果

下面的这个神经网络类可能现在还没有完全定义,还需要更多详细的功能描述,但是现在让我们用这些来开始。要知道,从骨干到全貌是一种良好的编码习惯。

# 初始代码
# neural network class definition
class neuralNetwork :
    # initialise the neural network
    def _init__() :
        pass
    # train the neural network
    def train() :
        pass
    # query the neural network
    def query() :
        pass

初始化网络

网络形状和大小

  在初始化网络部分,首先,我们知道我们需要设置输入,隐藏的和输出层节点的数量,这样就定义了神经网络的形状和大小。当创建一个新的神经网络对象时,我们将用输入参数来创建不同形状和大小的神经网络,以满足不同类型的需要。此外,另一个超参数(需要外部输入的参数)是学习率。PS:网络的层数已经被固定为3层了,改变的知识每一层神经元的个数

# 修改后的初始化函数
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
        # learning rate
        self.lr = learningrate
        pass
    # train the neural network
    def train() :
        pass
    # query the neural network
    def query() :
        pass

到此,我们定义了一个包含4个超参数的神经网络类(虽然也只是包含,没有其他作用),初始化当前的mini神经网络测试一下:

# 创建一个神经网络
n = neuralNetwork(3, 3, 3, 0.1)
print '输入节点、隐层节点、输出节点的数量和学习率分别是:', n.inodes, n.hnodes, n.onodes, n.lr

怎么样,怎么样,如沐春风的感觉(回想起了以前写的Hello World)。

权重——网络的核心

  然后下一步是创建网络节点(神经元)之间的链接(网络链路)的权重,这也是最重要的部分,它们用于计算正向传递的信号和反向传递的误差,并通过不断的更新来提升网络学习能力。权重可以简洁地表示为一个矩阵,因为有两层网络,所以我们可以创建两个权重矩阵:

  1. 输入和隐藏层之间的链接的权重矩阵, Winputhidden W i n p u t h i d d e n ,大小为(隐层节点数,输入节点数
  2. 隐藏和输出层之间的链接的权重矩阵, Whiddenoutput W h i d d e n o u t p u t ,大小为(输出节点数,隐层节点数)。

为什么是隐层x输入层:原因如下图所示,自己动手算一下就知道了。
nn12.png

  链接权重的初始值应该是小的随机数,使用函数np.random.rand() 来创建。我们准备在我们的Python程序中创建初始权重矩阵,这些权重是一个神经网络的组成部分,应当作为神经网络类的属性。这意味着它需要成为初始化函数的一部分,这样就可以从其他功能(如训练和输出)中访问。

# 创建两个权重矩阵:输入层到隐层,隐层到输出层
# 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
import numpy
self.wih = (numpy.random.rand(self.hnodes, self.inodes) - 0.5)
self.who = (numpy.random.rand(self.onodes, self.hnodes) - 0.5)

可选:更复杂的权重

  这个章节是可选的,因为它只是初始化权重的简单但流行的例子。也就是说,这一部分并没有严谨的科学证明,但在很多时候确实会提升网络的性能。没错,其实就是有些人喜欢稍微更复杂的创建初始随机权重的方法:在期望为0、方差为下一层节点数的倒数的正态分布中,抽样得到初始值。由此:

  1. 输入层和隐层之间的权重矩阵为self.wih = numpy.random.normal (0.0, pow(self.hnodes, 0.5), (self.hnodes, self.inode))
  2. 隐层和输出之间的权重矩阵为self.who = numpy.random.normal (0.0, pow(self.onodes, 0.5), (self.onodes, self.hnodes))

带现在,网络的初始化部分已经完成了,总结一下,一个简单的神经网络类的属性包括:每个层的节点数、学习率、层与层之间的权重矩阵,最后还有后面要讲的激活函数

获取网络的输出

  讲道理现在考虑的应该是当前为空的train()函数,但是我们会拖延这样做,而是把目光放在更简单的query()函数,先易后难嘛~(其实是因为train()函数会在很大程度上借鉴query()),这也将给我们更多的时间逐渐建立信心并得到进一步的实践。query()函数获取网络的输入,返回网络的输出。通俗的说,它是为了检验神经网络的学习成果。输入数据需要经过各个层中,包含层与层之间的权值矩阵以及激活函数的计算,一步一步得到。如果我们有很多节点,计算量会相当可怕:需要用Python代码对于每个节点的输入乘以权重,然后求和,再应用激活函数,节点越多,代码越多。那会是一场恶梦!幸运的是,我们不必这样做,因为我们选择的计算方式是矩阵计算。接下来分为两步:

  1. 上一层的输出信号经过权值矩阵变成这一层的输入信号
  2. 这一层的输入信号经过该层的激活函数变成这一层的输出信号

  如何用输入层信号和权值矩阵获取隐层输入 Xhid

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值