本篇是神经网络体系搭建的第一篇,解决体系搭建的前四个问题,详见神经网络体系搭建(序)
神经网络
最简单的神经网络
神经网络的定义就不再赘述,直接从最简单的神经网络说起。
将一系列输入数据,通过训练好的网络模型处理,得到输出结果,这是神经网络决策的步骤。那么我们的重点就是通过训练得到网络模型。
从上图可以看出,模型的关键其实是寻找合适的权重矩阵。
那么如何寻找呢,是一个暴力过程。
给一个初始权重矩阵,用这个矩阵进行预测,看预测结果和实际结果相差多远(损失函数的作用),根据这个相差多远的情况,来更新权重矩阵,直到预测结果和实际结果相差最小(其实就是求损失函数的最小值)的时候为止,带有这个能使预测值与实际结果相差最小的权重矩阵的模型就是我们训练好的网络模型了。
求损失函数最小值的方法通常为梯度下降。
已经知道了权重矩阵、损失函数的位置和作用,还有一个概念没有解释——激活函数。
激活函数的作用是给神经元添加非线性因素,说白了就是如果不通过激活函数,输出就是线性函数,y=wx+b,但是wx+b通过激活函数,得到的y就可以是非线性的了。
思维导图中罗列了常用激活函数,优点和使用情况不属于体系的主干系列,因此不再这里赘述,可以参考常用激活函数比较。
解决问题的步骤
数学部分
损失函数通常有误差平方和(SSE)、误差平方的均值(MSE)等,也不属于主干,具体的可以参考深度学习中的损失函数总结以及Center Loss函数笔记。找到合适的损失函数是一个可优化点。
梯度下降
有了损失函数,我们的重点是如何找到损失函数的最小值。采用的算法是梯度下降。梯度下降最常见的例子就是下山,从山顶每次找最陡的一条路,达到最快下山的目的,陷阱也就是可能还没有到山脚却以为到了山脚(陷入局部最优而非全局最优)。
那么梯度下降说白了就是找斜率,找斜率就是求导。
以单行数据通过单层网络为例:
如果有多个输出单元:
代码部分
单条数据
import numpy as np
# 定义激活函数
def sigmoid(x):
return 1/(1+np.exp(-x))
# 计算激活函数导数
def sigmoid_prime(x):
return sigmoid(x) * (1 - sigmoid(x))
# 设置输入数据x
x = np.array([x1, x2, x3, x4, x5]) # xi为用来举例的假数据,替换即可
# 设置标签y
y = np.array(y) # y为用来举例的假数据,替换即可
# 设置学习率
learn_rate = 0.5
# 初始化权重矩阵
w = np.array([w1, w2, w3, w4, w5]) #wi为用来举例的假数据,替换即可
# 计算h
h = np.dot(x, w)
# 计算预测值
y_predict = sigmoid(h)
# 计算误差
error = y - y_predict
# 计算误差项
error_term = error * sigmoid_prime(h)
# 计算权重变化量delta_w
delta_w= learn_rate * error_term * x
# 更新权重矩阵
w += delta_w
多条数据
其实将单条数据的delta_w通过循环更新,最后在累加到权重矩阵中,更新e代就是多条数据的训练。
for e in range(epochs):
del_w = np.zeros(w.shape)
for x, y in zip(features.values, targets):
h = np.dot(x, w)
y_predict= sigmoid(h)
error = y - y_predict
error_term = error * sigmoid_prime(h)
del_w += error_term * x
weights += learnrate * del_w / len(x)
问题回答
至此,序中的四个问题已有了答案:
-
神经网络是什么?解决问题的步骤(算法)是什么?
见思维导图。 -
梯度下降用在神经网络的哪一步?
梯度下降用来找损失函数的最小值,数学原理和代码见上。 -
损失函数是干什么用的?
损失函数用来衡量预测值与真实值的差距,有了损失函数,才能指导权重矩阵的更新。 -
神经网络模型有哪些参数可以调整(优化)?
选择合适的迭代次数、找合适的学习率、找合适的初始权重矩阵、找合适的激活函数、找合适的损失函数。
以上内容来自822实验室神经网络知识分享
我们的822,我们的青春
欢迎所有热爱知识热爱生活的朋友和822思享实验室一起成长,吃喝玩乐,享受知识。