# 小废话
这段时间在实验室帮忙做下手,希望能够早日抓到离子完成毕设。但在前天,离子阱平台的 的声光晶体的放大器坏掉了,需要重新购买更换,这或许又要花费好几天的时间而进行实验。这就是做实验研究的一个十分痛苦的地方,也许某个器件坏了就得耽误很长一段时间。
回归正题,为什么我突然要做一个这样的神经网络呢?原因是这几天看了一篇文章 —— Minimization of the micromotion of trapped ions
with artificial neural networks。里面谈及了运用人工神经网络的机器学习方法来找到最佳的电极电压以此优化离子的微运动。看完之后,我认为在以后的研究生涯里,很可能会用到许多的神经网络来处理问题,于是趁今天没事干,也不想写毕业论文,所以弄了一个简单的神经网络来练练手。
上一次(也是第一次)写神经网络的代码是在大三上学期的计算物理期末作业中,写的是一个用 Unet 神经网络去除马赛克的代码。而这次我写的是更加简单的神经网络,而我设置要解决的问题也十分十分地简单。其实主要就是想回顾一下神经网络的 python 代码怎么写罢了。
# 正文
# 神经网络布局
假若我们有一组输入量 (当然可以不止只有两个),对应有一组输出量 (当然也可以不止只有两个),假若在现实中这一对输入与输出量的数学关系是复杂而不可知的,那么这是神经网络就可以发挥它的天然优势了。
我们可以利用如图一所示的神经网络,这是一种用于实现线性变换,即全连接层 (fully connected layer) 的神经网络,其原理是通过学习权重矩阵和偏置向量来实现线性变换。
图中每一个 就代表了第 层第 个神经元。我设置的神经网络一共有 个隐藏层,每层有 个神经元;假设输入层和输出层,则一共有 层。输入与输出之间的这 个神经元的原理公式如下:
输出量可表示为:
# 激活函数
式中的 是激活函数。激活函数在神经网络中起着至关重要的作用,主要有以下几个方面:
- 引入非线性:激活函数引入了非线性因素,使神经网络能够学习复杂的非线性关系。如果没有激活函数,多个线性层堆叠起来仍然只能表示线性关系,限制了神经网络的表达能力。
- 解决梯度消失问题:激活函数能够避免梯度消失或梯度爆炸的问题。在反向传播过程中,梯度需要通过激活函数进行反向传播,某些激活函数能够帮助梯度更好地传播,避免梯度消失或梯度爆炸。
- 增加网络的表达能力:通过引入非线性,激活函数使神经网络能够拟合更复杂的函数,提高了网络的表达能力,从而更好地学习数据的特征。
- 稀疏激活:某些激活函数如 ReLU 能够引入稀疏激活,即只有部分神经元被激活,从而促使网络学习到更加有用的特征,提高网络的泛化能力。
常见的激活函数有三种:
,全称为 Rectified Linear Unit,中文名称是线性整流函数。通常意义下,其指代数学汇总的斜坡函数,即 。其对应的函数图像为图 2。
,是常用的连续、平滑的 s 型激活函数,也被称为逻辑(Logistic)函数。可以将一个实数映射到 区间,经常用于做二分类问题。其函数定义为 ,函数图像如图 3 所示。
, 是双曲正切函数,函数定义为 ,值域为 ,图像如图 4 所示。
在这里我们采用的是 作为激活函数。
# 结果
我把问题设置得十分简单,输入量与输出量各一个。输入量 是一个 内的某个数,输出量 的函数关系我随便设置了一个非线性函数:
我们就用这个神经网络,看看它能不能找出这一个隐藏的函数关系。
我们随机生成了 组数据,其中 作为训练集, 作为测试集。采用了 函数,即均方误差 (Mean Squared Error) 函数,作为损失函数;也是采用了一种常见的优化算符 ——,即自适应随机梯度下降法。
最终的训练结果如下图所示: