从零开始深度学习搭建神经网络(一)

来源:互联网 发布:云计算应用 编辑:程序博客网 时间:2024/05/18 00:07

人工智能不神秘,会一点加减乘除就够了。

对于神经元来说,当神经受到刺激的时候,会释放神经递质传给下一个神经元,不同程度的刺激对下一个神经元释放的神经递质的量也不同,所以模仿这个过程建立神经网络:

当输入一个数据x的时候,模拟输入一个外界刺激,经过处理后,输出的结果为f(x),把这个f(x)传给下一个神经元,逐步求解,最终输出一个值z,与给定的值进行对比(有监督学习),根据结果调整每个的神经元内部函数的参数,称为反向扩散,然后在下一轮来重复这个过程,直到达到指定迭代次数,通过不断调整参数以接近损失(lost)最小的点。

 

可以看出,输出的值z应该具有一个范围,比如识别一组图片是否为猫,则在训练样例中,结果应该是0或者1,那么输出也应该对应为0或1,所以需要映射到0/1上。而如果分类数增加,那么范围也应该相应扩大。

 

所以,举例进行学习:

输入为x,例如一张图片,像素为34*34pixels,那么根据RGB成色原理,共有34*34*3个数据,所以将x映射为一个(34*34*3, 1)的矩阵(一般采用w的转置矩阵,即wT),按照R(34*34),G(34*34),B(34*34)进行排列。

下一步需要确定f(x)函数,先采取比较简单的线性(一次)神经网络,比较常见的一元一次方程形式为f(x)= ax+b,所以采用类似的形式:

       f(x) = W*x + b

其中,W为weight权重,b为bias偏差,即学习调整参数,也就是调整W和b的值。

注意:

       矩阵相乘对矩阵的大小是有要求的,在这里x的规格为(34*34*3, 1),所以W的列数也应该为34*34*3,如果我们只有一层神经元,那么f(x)就是一个数,即(1, 1)的矩阵,所以此处W的大小应为(1, 34*34*3),b仅仅是一个常数。


 

线性方程的范围大家都知道,是(-∞,+∞),所以我们需要映射到 [0,1] 的区间,也需要一个方程:

       sigmoid(z) = 1 / (1 + e^(-z))

将变量映射到0,1之间,选择这个方程的原因是求导容易, s’(x) = s(x) / (1 – s(x)).



评价参数是否合理也需要一个方程,即损失方程(Loss),表示的含义为预测值与标准(监督)值之间的偏差,尽量减小这个偏差来达到更好的预测(分类)效果,比较常用的损失方程为:

定义,a为预测值,y为准确值。

L(a, y)= -y * log(a)- (1 - y) * log (1 - a)

如果有m个训练样例的话,平均损失函数为值加起来后除以m,即

       L = sum(Li) / m

 

计算完cost后需要调整W和b的值,因为我们需要cost的值减小,所以需要对L方程求导获取梯度值(gradient),逐步朝着最小值前进,此处’dw’、’db’均为方便在python代码中进行表示,实际含义为右侧等式(求的是微分):

       ‘dw’ = dJ/dw = (dj/dz)*(dz/dw)= X*(A-Y)T / m

       ‘db’ = dj/db = sum(a-y) / m

所以新的值为:

       w = w – α * dw

       b = b – α * db,其中 α 为学习速率,在下一轮迭代中采用新的w、b。

设定迭代次数,迭代完毕后,就是最终得到的参数w, b,用测试用例来验证识别准确率,一般应该在70%以上。

在我的博文“知乎爬虫”中,会有关于爬取数据进行训练的代码编写过程,目前仅需要明白神经网络流程即可。

具体的代码在https://github.com/Lee-Jiazheng/My_neural_network.git中的base_func.py,实现了简单的神经网络,后续会增加更多神经元和优化速度。

 

原创粉丝点击