感知器算法的python实现,使用python实现深度神经网络
神经感知器
0x00概述功能强大的库已经有了,比如TensorFlow,PyTorch,Keras等等。
本文将介绍用Python创建MLP神经网络的基础知识。
感知器是神经网络的基本组成部分。感知器的输入函数是权重、偏差和输入数据的线性组合。具体来说:
In_j=权重输入偏差。(in_j=权重输入偏差)
在每个感知器上,我们可以指定一个激活函数g。
激活函数是一种数学方法,用于确保传感器仅在达到某个输入水平后“发射”或激活。常见的非线性激活函数有s型、softmax、整流线性单元(ReLU)或简单双曲正切函数。
激活函数有许多选项,但在本文中,我们只介绍Sigmoid和softmax。
图1:感知器
对于监督学习,我们稍后通过一系列隐藏层将输入数据转发到输出层。这称为正向传播。
在输出层,我们可以输出预测Y,通过我们对Y的预测,我们可以计算出误差 y*-y ,并使误差通过神经网络传播回来。这被称为反向传播。
通过随机梯度下降(SGD)过程,隐层中每个感知器的权重和偏差将被更新。
图2:神经网络的基本结构
现在我们已经介绍了基础知识,让我们实现一个神经网络。我们的神经网络的目标是对MNIST数据库中的手写数字进行分类。我将使用NumPy库进行基本的矩阵计算。
在我们的问题中,MNIST数据由[748,1]矩阵中的8位颜色通道表示。本质上,我们有一个[748,1]的数矩阵,从[0,1,255],其中0代表白色,255代表黑色。
结果
MNIST手写数字数据库包含60,000个用于训练目的的手写示例和10,000个用于测试目的的示例。在用30个历元训练了60,000个样本之后,我在测试数据集上运行了训练好的神经网络,并实现了93.2%的准确率。甚至可以通过调整超参数来进一步优化。
本文分为五个部分。这些部分是:
激活函数权重初始化偏差初始化训练算法进行预测。
0x01激活函数Sigmoid是由等式1 /(1 exp(-x))定义的激活函数,并且将用于隐藏层传感器中。
Soft是一个激活函数,当我们想把输入分成几类时,通常用在输出层。在我们的例子中,我们想把一个数分成10个桶[0,1,2,…,9]中的一个。它计算矩阵中每个条目的概率;概率总计为1。具有最高概率的条目将对应于其预测,即0,1,…,9。Max定义为exp(x)/sum(exp(x))。
图3:激活功能的实现
0x02权重初始化对于每个隐藏层,我们需要初始化权重矩阵。有几种不同的方法可以做到这一点,如图4所示。
#零初始化-初始化所有权重=0
初始化-使用随机数初始化权重,不是完全随机的。我们通常在标准正态分布中使用随机数(均值为0,方差为1)。
Xavier初始化-使用正态分布中的随机数和设定的方差初始化权重。我们将根据前一层的大小来设置方差。
如上所述,进入感知器的边缘乘以权重矩阵。关键的一点是,矩阵的大小取决于当前层和它之前的层的大小。显然,权重矩阵的大小是[当前层大小,先前层大小]。
如上所述,进入感知器的边缘乘以权重矩阵。关键的一点是,矩阵的大小取决于当前层和它之前的层的大小。显然,权重矩阵的大小是[当前层大小,先前层大小]。
假设我们有一个包含100个节点的隐藏层。我们的输入层的大小是[748,1],而我们需要的输出层的大小是[10,1]。输入层和第一个隐藏层之间的权重矩阵的大小是[100,748]。隐藏层之间的每个权重矩阵的大小为[100,100]。最后,最终隐藏层与输出层之间的权重矩阵为[10,100]。
出于教育目的,我们将坚持使用单一隐藏层;在最终的模型中,我们将使用多个层。
图4:权重初始化实现
0x03偏移初始化与权重初始化一样,偏移矩阵的大小取决于层大小,尤其是当前层大小。初始化偏移量的一种方法是将偏移量设置为零。
对于我们的实现,我们需要为每个隐藏层和输出层提供一个偏差。基于每个隐藏层中的100个节点,偏移矩阵的大小为[100,1],而输出层的大小为[10,1]。
图5:偏移初始化的实现
0x04训练算法如前所述,训练基于随机梯度下降(SGD)的概念。在SGD中,我们一次只考虑一个训练点。
在我们的例子中,我们将在输出层使用softmax激活。“交叉熵损失”公式将用于计算损失。对于SGD,我们将需要使用softmax来计算交叉熵损失的导数。也就是这个导数降为y -y,也就是预测的y减去期望的y。
图6:关于softmax激活的交叉熵损失及其导数
我们还需要写出S型激活函数的导数。在图7中,定义了S型函数及其导数。
图7: Sigmoid函数(上)及其导数(下)
通常,神经网络将允许用户指定几个“超级参数”。在我们的实现中,我们将着重于允许用户指定纪元、批量大小、学习速率和动量。还有其他优化技术:
学习率(LR):学习率是一个参数,用户可以通过它来指定网络允许我们学习和更新其参数的速度。选择一个好的学习率是一门艺术,如果LR太高,我们可能永远不会收敛到好的可以接受的训练误差。如果LR太低,我们可能会浪费很多计算时间。历元:历元是整个训练集的迭代。为了确保我们不会过度拟合早期样本中的数据,我们将在每个时期后随机对数据进行排序。批量大小:通过Epoc2h的每一次迭代,我们都会批量训练数据。对于批次中的每个训练点,我们将收集梯度,并在批次完成后更新权重/偏差。动量:这是一个参数,我们将通过收集过去梯度的移动平均值并允许在该方向上移动来加速学习。在大多数情况下,这将导致更快的收敛。典型值范围从0.5到0.9。下面,有一些通用的伪代码来模拟反向传播学习算法。
为了便于阅读,诸如计算输出和将训练数据分成批次之类的任务被写成了注释。
0x05现在进行预测,我们只缺少这个实现的一个关键方面。预测算法。在编写反向传播算法的过程中,我们已经完成了大部分工作。我们只需要使用相同的前向传播代码来进行预测。输出层的softmax激活函数将计算大小为[10,1]的矩阵中每个条目的概率。
我们的目标是从0到9对数字进行分类。因此,aj2矩阵的索引将对应于预测。概率最高的索引会被np.argmax()选中,成为我们的预测。
0x06结论我们已经用Python写好了神经网络的实现。
但是我们如何选择最佳参数呢?我们可以使用算法的一般知识来选择有意义的超参数。
我们需要选择能够汇总数据但又不能过度拟合的超级参数。我们可以调整动量、学习速率、周期数、批量大小和隐节点数来实现我们的目标。向前迈出一步,我们可以编写更多的算法来为我们做这件事!
遗传算法是一种人工智能算法,可以用来选择最佳参数。遗传算法的思想是创造一组不同参数的子代,使它们产生与参数相关的测试误差。我们可以用最好的超参数来繁殖和变异神经网络,以找到更好的参数。在花了很多时间之后,我们将能够了解很多关于超参数的情况,并找到新的最佳超参数值。
我们能采取其他措施来减少测试误差吗?是的,我们可以缩放输入数据。与许多算法一样,较大的数字会对算法的结果产生重大影响。在我们的例子中,数字范围是[0到255]。如果我们按比例缩放这些数字,使它们的范围从[0到1],我们可以减少这种偏差。
转载请联系作者取得转载授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。