本帖最后由 cc1989summer 于 2024-9-2 22:32 编辑
《人工智能实践教程——从Python入门到机器学习》
第五篇阅读分享,也就是本书的第三部分,神经网络
神经网络的定义:神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器学习技术。
我们常规来说,需要借助机器实现的功能,大致分为三类:判断、识别、预测。(个人理解)
1. 判断,比较好理解,给定几个参数(两个或更多),给出判断,比如:胖瘦,好坏等等。
就像前面我们做过的回归分析,建立曲线,通过明确的计算,给出判断。
比如,输入体重、身高两个参数,用BMI公司计算出对应BMI,再跟标准进行比对,就可以对胖瘦做出判断。
2. 识别,给定几个参数(两个或更多),识别出深层含义(如:文字、感情等)。
这个不能通过明确的计算给出判断,比如手写输入的文字,他是一堆点阵数据,没有确切的公式可以套进去进行计算。
需要基于已有的学习数据,建立模型,进而给出识别结果(具体的文字)。
3. 预测,给定几个参数(两个或更多),预测未来走势(如天气预报、股票涨跌,五子棋对方可能的走棋战术等等)。
是在前几种基础申请网络的基础上,基于已有数据、现有模型、模糊算法,给出对于未来的预测值,是比较高级的人工智能。
比如GraphCast天气预报系统。
GraphCast 是一种基于机器学习和图神经网络 (GNN) 的天气预报系统,就能耗而言,它可能要比传统方法便宜 1000 倍。
GraphCast 以 0.25 度经度/纬度(赤道处 28 公里 x 28 公里)的高分辨率进行预测,超过一百万个网格点覆盖了整个地球表面。在每个网格点,该模型预测 5 个地球表面变量(包括温度、风速和风向以及平均海平面压力)以及 37 个海拔高度的每个高度的 6 个大气变量(包括比湿度、风速和风向以及温度)。
虽然 GraphCast 的训练计算量很大,但生成的预测模型非常高效。在一台谷歌 TPU v4 机器上使用 GraphCast 进行 10 天预测只需要不到一分钟时间。相比之下,使用传统方法(例如 HRES)进行 10 天的预测可能需要在超级计算机中进行数小时的计算。
而所有这些都基于神经网络。
而最基础的神经网络就是感知机。
感知机是由美国学者FrankRosenblatt在1957年提出来的。感知机是作为神经网络(深度学习)的起源的算法。因此,学习感知机的构造也就是学习通向神经网络和深度学习的一种重要思想。
感知机接收多个输入信号,输出一个信号。这里所说的“信号”可以想象成电流或河流那样具备“流动性”的东西。像电流流过导线,向前方输送电子一样,感知机的信号也会形成流,向前方输送信息。但是,和实际的电流不同的是,感知机的信号只有“流/不流”(1/0)两种取值。这里我们认为0对应“不传递信号”, 1对应“传递信号”。
下图就是一个接收两个输入信号的感知机的例子。
x1、 x2是输入信号,y是输出信号, w1、 w2是权重(w是weight的首字母)。图中的○称为“神经元”或者“节点”。输入信号被送往神经元时,会被分别乘以固定的权重(w1x1、 w2x2)。神经元会计算传送过来的信号的总和,只有当这个总和超过了某个界限值时,才会输出1。这也称为“神经元被激活” 。这里将这个界限值称为阈值,用符号θ表示。
感知机的运行原理只有这些!把上述内容用数学式来表示,就是下面这个式子。
感知机的多个输入信号都有各自固有的权重,这些权重发挥着控制各个信号的重要性的作用。也就是说,权重越大,对应该权重的信号的重要性就越高。
感知器的缺点是:只能做简单的线性分类任务。
于是神经网络登场了,神经网络的基础神经元模型是一个包含输入,输出与计算功能的模型。输入可以类比为神经元的树突,而输出可以类比为神经元的轴突,计算则可以类比为细胞核。
下图是一个典型的神经元模型:包含有3个输入,1个输出,以及2个计算功能。
注意中间的箭头线。这些线称为“连接”。每个上有一个“权值”。
一个神经网络的训练算法就是让权重的值调整到最佳,以使得整个网络的预测效果最好。
我们使用a来表示输入,用w来表示权值。一个表示连接的有向箭头可以这样理解:在初端,传递的信号大小仍然是a,端中间有加权参数w,经过这个加权后的信号会变成a*w,因此在连接的末端,信号的大小就变成了a*w。
如果我们将神经元图中的所有变量用符号表示,并且写出输出的计算公式的话,就是下图。
以下是个单层简单的示例:
import numpy as np
def sigmoid(x):
# 我们的激活函数: f(x) = 1 / (1 + e^(-x))
return 1 / (1 + np.exp(-x))
class Neuron:
def __init__(self, weights, bias):
self.weights = weights
self.bias = bias
def feedforward(self, inputs):
# 权重乘以输入,与偏移量相加,然后通过激活函数
total = np.dot(self.weights, inputs) + self.bias
return sigmoid(total)
weights = np.array([0, 1]) # w1 = 0, w2 = 1
bias = 4 # b = 4
n = Neuron(weights, bias)
x = np.array([2, 3]) # x1 = 2, x2 = 3
print(n.feedforward(x)) # 0.9990889488055994
运行结果:
两层神经网络除了包含一个输入层,一个输出层以外,还增加了一个中间层。此时,中间层和输出层都是计算层。我们扩展上节的单层神经网络,在右边新加一个层次(只含有一个节点)。
import numpy as np
# ... code from previous section here
class OurNeuralNetwork:
'''
神经网络:
- 2 个输入
- 1 个隐藏层,2 个神经元 (h1, h2)
- 1 个输出层,1 个神经元 (o1)
所有神经元有同样的权重和偏移量:
- w = [0, 1]
- b = 0
'''
def __init__(self):
weights = np.array([0, 1])
bias = 0
# 这里的 Neuron 类是上一节的代码里定义的
self.h1 = Neuron(weights, bias)
self.h2 = Neuron(weights, bias)
self.o1 = Neuron(weights, bias)
def feedforward(self, x):
out_h1 = self.h1.feedforward(x)
out_h2 = self.h2.feedforward(x)
# o1 的输入就是 h1 和 h2 的输出
out_o1 = self.o1.feedforward(np.array([out_h1, out_h2]))
return out_o1
network = OurNeuralNetwork()
x = np.array([2, 3])
print(network.feedforward(x)) # 0.7216325609518421
多层神经网络在两层神经网络的输出层后面,继续添加层次。原来的输出层变成中间层,新加的层次成为新的输出层。所以可以得到下图。
多层神经网络中,输出也是按照一层一层的方式来计算。从最外面的层开始,算出所有单元的值以后,再继续计算更深一层。只有当前层所有单元的值都计算完毕以后,才会算下一层。有点像计算向前不断推进的感觉。所以这个过程叫做“正向传播”。
与两层层神经网络不同。多层神经网络中的层数增加了很多。
增加更多的层次有什么好处?更深入的表示特征,以及更强的函数模拟能力。
更深入的表示特征可以这样理解,随着网络的层数增加,每一层对于前一层次的抽象表示更深入。在神经网络中,每一层神经元学习到的是前一层神经元值的更抽象的表示。例如第一个隐藏层学习到的是“边缘”的特征,第二个隐藏层学习到的是由“边缘”组成的“形状”的特征,第三个隐藏层学习到的是由“形状”组成的“图案”的特征,最后的隐藏层学习到的是由“图案”组成的“目标”的特征。通过抽取更抽象的特征来对事物进行区分,从而获得更好的区分与分类能力。
从单层神经网络(感知器)开始,到包含一个隐藏层的两层神经网络,再到多层的深度神经网络,一共有三次兴起过程。详见下图。
从单层神经网络,到两层神经网络,再到多层神经网络,下图说明了,随着网络层数的增加,以及激活函数的调整,神经网络所能拟合的决策分界平面的能力。
神经网络的发展背后的外在原因可以被总结为:更强的计算性能,更多的数据,以及更好的训练方法。只有满足这些条件时,神经网络的函数拟合能力才能得已体现,见下图。
今天的学习分享就到这里(部分基于自己的理解,部分来源于本书及互联网资料整理,以便更好理解从单层神经网络到多层神经网络的进化)。