1、什么是神经元网络
神经元网络(Neural Network),也称人工神经元网络(Artificial Neural Network,简称ANN),是一种模仿生物大脑神经元之间相互连接和传递信息的计算模型。它由大量的神经元组成,这些神经元通过连接权重相互连接,形成一个复杂的网络结构。
神经元网络通常由以下几个元素组成:
- 神经元(Neuron):神经元是网络的基本单元,它接收输入信号并产生输出信号。
- 连接(Connection):连接是神经元之间的路径,通过连接传递信号。
- 权重(Weight):权重是连接的强度,它决定了信号在神经元之间的传递效果。
- 偏置(Bias):偏置是神经元的额外输入,用于调整神经元的激活水平。
- 激活函数(Activation Function):激活函数用于对神经元的输入进行非线性变换,常见的激活函数包括 sigmoid、ReLU 等。
- 输入层(Input Layer):输入层接收输入数据,并将其传递给后续的神经元。
- 隐藏层(Hidden Layer):隐藏层位于输入层和输出层之间,用于处理和抽象输入数据。
- 输出层(Output Layer):输出层产生最终的输出结果。
神经元是神经网络中的基本单元,它接收多个输入信号,通过一定的计算产生输出信号,并将输出信号传递给下一层神经元。神经元的数学模型可以这样来理解:多个输入信号线性加权相加,与b(阈值)相比较,所得结果由激活函数处理,最终产生输出信号。
h=g(∑i=1nθixi−b)
激活函数是用来标准化神经元的兴奋度,最简单的模型是0,1模型,即当总输入大于等于0时输出1,小于0时输出0。常用的激活函数有Sigmoid、ReLU等,Sigmoid函数的作用是把输入信号映射到(0,1)之间,且当输入信号为0时,映射值为0.5,非常适合评估神经元的兴奋度。
Sigmoid函数表达式及曲线图如下:
y=11+e−x
按上述神经元模型,我们将多个神经元,按一定层次连接到一起,就可以得到一个神经元网络。简单来说,神经元网络就是一个分层的有向图。
ANN神经网络总体来说应该算是一个概念,虽然一些主流框架都有ANN神经网络的实现,但是很少有人直接使用ANN神经网络,而是使用ANN网络的变体或扩张。ANN神经网络目前主要被用来实现教学和学习的目的。
2、如何训练神经元网络
上一节我们介绍了神经元网络的基本原理,下面我们来介绍一下一个完整的神经元网络是如何训练的。神经元网络的训练过程大概可以分为以下四个步骤:
2.1、定义网络结构
训练神经元网络之前,我们需要先确定神经元网络的层数、每层的神经元数量以及连接方式。输入层和输出层的节点数量都是确定的。通常情况下,输入层的神经元数量等于数据集特征的数量,输出层的神经元的数量等于数据集标签的数量。但是,隐藏层及其神经元的数量是无法简单确定的。
如何确定隐藏层数?
下面是人们常用的隐藏层确定规则:
- 没有隐藏层:仅能够表示线性可分函数或决策。
- 隐藏层数=1:可以拟合任何“包含从一个有限空间到另一个有限空间的连续映射”的函数。
- 隐藏层数=2:搭配适当的激活函数可以表示任意精度的任意决策边界,并且可以拟合任何精度的任何平滑映射。
- 隐藏层数>2:多出来的隐藏层可以学习复杂的描述(某种自动特征工程)。
在一些规模比较大的深度学习模型中,隐藏层数量可能会达到几十或上百。
如何确定隐藏层节点数?
隐藏层节点数的选择对网络性能影响很大,若节点数太少,网络获取的有用信息就少,容错性差,可能出现欠拟合(underfitting)问题;若节点数过多,不仅训练时间和训练难度增加,还可能会出现过拟合(overfitting)问题。
下面是一个国外论文给出的隐藏节点确定规则:
Nh=Ns(α×(Ni+No))
其中, Ni 表示输入层神经元个数, No 表示输出层神经元个数, Ns 表示训练集的样本数, α 是一个变量,取值范围2-10。
除此以外,还有一些经验方法可以参考,具体情况还得具体分析。
- 隐藏神经元的数量应在输入层的大小和输出层的大小之间。
- 隐藏神经元的数量应为输入层大小的2/3加上输出层大小的2/3。
- 隐藏神经元的数量应小于输入层大小的两倍。
2.2、前向传播
确定了神经元网络结构,我们就可以计算前向传播系数了。在神经元网络中,前向传播是指信息从输入层开始,依次通过隐藏层和输出层,最终得到输出结果的过程。在这个过程中,每个神经元都会对输入信息进行处理,并将处理结果传递给下一个神经元,直到到达输出层。
我们看一个例子:下图为一个简单的三层神经元网络。在输入层中, ,,x1,x2,x3 为输入值, x0 为偏置, θ1i(1),i=0,1,2,3 为权重。在隐藏层中, a1(2),a2(2) 为当前神经元输出的激活值, a0(2) 为偏置, θ1j(2),j=0,1,2 为权重。在输出层中, a1(3) 为最终输出的激活值。
首次迭代时,权重 θ1i(1),i=0,1,2,3 和 θ1j(2),j=0,1,2 的初始值通常会设置为随机数。
我们先来计算隐藏层激活值: a1(2)=g(θ10(1)x0+θ11(1)x1+θ12(1)x2+θ13(1)x3)a2(2)=g(θ20(1)x0+θ21(1)x1+θ22(1)x2+θ23(1)x3)
我们再来计算输出层激活值:
a1(3)=g(θ10(2)a0(2)+θ11(2)a1(2)+θ12(2)a2(2))
这样我们就完成了前向传播需要计算的所有激活值。
2.3、反向传播
前向传播完成后,我们首次计算出了网络中的所有激活值。但是这个激活值不一定能满足要求,毕竟我们的初始权重和偏置用的都是随机值。所以,我们要衡量一下输出误差的大小。衡量误差的方法是将输出结果与真实值进行比较,计算输出误差。
δi(3)=ai(3)−yi
其中 ai(3) 为第三层第i个神经元的预测值, yi 为真实值, δi(3) 表示第三层第i个神经元的误差。
运用反向传播,计算出除输入层外所有层的误差项为(推导过程略):
δi(l−1)=∑k=1nlθjk(l)g′(zj(l))δk(l)
从上式可以看出上一层的误差 δi(l−1) 需要依赖下一层的误差 δk(l) 。以此类推,最终算出 δi(1) 。
2.4、更新权重,重复训练
计算出每一个神经元的误差后,我们用梯度下降算法使整个神经元网络的总误差值最小或达到最大训练次数。这个过程会不断更新每一层神经元网络的权重和偏置值。当训练过程结束时,此时网络中的权重和偏置值就是最优值。
常用的梯度下降损失函数包括均方误差(MSE)和交叉熵(Cross-entropy)等。
MSE=1n∑i=1n(yi−yi~)2Cross−entropy=−1n∑i=1n(yilog(yi~)+(1−yi)log(1−yi~))
n 为样本数, yi 为真实值, yi~ 为预测值。
3、几种经典神经元网络模型
3.1、BP神经网络
BP(Backpropagation)神经网络是ANN神经网络的一种,是一种常用的前馈神经网络,由一个输入层、一个或多个隐含层和一个输出层组成。BP神经网络的核心思想是利用梯度下降法,通过反向传播不断调整网络的权值和阈值,使得网络的实际输出与期望输出之间的误差均方差达到最小。BP神经网络是目前应用最广泛的神经网络模型之一。
BP 神经网络的训练过程包括正向传播和反向传播两个阶段。在正向传播中,输入数据通过网络传播,计算输出值。在反向传播中,根据输出值与期望值之间的误差,通过链式法则计算每个神经元的误差信号,并根据误差信号调整网络的权重。
BP神经网络的主要应用领域包括:
BP神经网络的结构
BP神经网络的结构和ANN神经网络的结构完全一致,由一个输入层,多个隐藏层(>=1)和一个输出层组成。
每一层的计算公式为: y=f(WX−b)
其中,f代表的是激活函数,b代表偏置(激活阈值),W代表权重矩阵。
BP神经网络常用的激活函数包括:Sigmoid 函数,ReLU 函数,Tanh函数等。
BP神经网络的误差函数通常是均方误差(Mean Squared Error,MSE),表达式如下:
MSE=1N∑i=1N(yi−yi~)2
其中 yi 为真实值, yi~ 为BP神经网络预测值,N为样本数。
BP神经网络训练过程
- 初始化权重和阈值
- 前馈计算:将输入数据通过网络进行前馈计算,得到输出值。
- 误差反向传播:根据输出值和目标值之间的误差,计算每个神经元的误差梯度,并将其反向传播到网络的每个层。
- 权重更新:根据误差梯度,对网络的权重进行更新,以减少误差。
- 重复训练:重复2,3,4步骤,直到误差达到一定的精度或达到指定的训练次数。
举例
用BP神经网络对莺尾花数据集进行分类预测。网络模型使用scikit-learn库的MLPClassifier模型,该模型使用简单,无需关心底层的实现细节。
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPClassifier
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
# 将数据集分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 数据标准化
scaler = StandardScaler()
X_train_std = scaler.fit_transform(X_train)
X_test_std = scaler.transform(X_test)
# 创建 BP 神经网络模型,2个隐藏层,每一层50个神经元
mlp = MLPClassifier(hidden_layer_sizes=(50, 50), activation='relu', solver='adam', alpha=0.001, learning_rate='invscaling')
# 在训练集上训练模型
mlp.fit(X_train_std, y_train)
# 在测试集上评估模型
y_pred = mlp.predict(X_test_std)
predicted_classes = np.round(y_pred) # 将概率值四舍五入为0或1
print("Predicted Classes:", predicted_classes.flatten())
print("Actual Classes:", y_test)
accuracy = mlp.score(X_test_std, y_test)
print(f"模型的准确率为: {accuracy:.4f}")
输出结果:预测准确率高达100%,效果还是非常好的。
Predicted Classes: [1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0]
Actual Classes: [1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0]
模型的准确率为: 1.0000
3.2、卷积神经网络(CNN)
CNN(Convolutional Neural Networks)是一种专门用于处理具有类似网格结构数据的神经网络。CNN由多个卷积层和池化层组成,卷积层能够自动提取输入数据中的局部特征,而池化层则能够降低数据的维度,减少参数数量和计算复杂度。
CNN 卷积神经网络是一种特殊的神经元网络结构,它是神经元网络的一种应用和扩展,专门用于处理图像和视频等多维数据。它在神经元网络的基础上引入了卷积操作和池化操作,以提取图像中的特征并进行分类或识别等任务。
CNN神经网络的主要应用领域包括:
- 计算机视觉:图像识别、物体检测、人脸识别、图像分割等。
- 视频处理:动作识别、目标追踪等。
- 自然语言处理:文本分类、情感分析等。
- 医学成像:疾病诊断、病变检测等。
CNN的基本结构包括输入层、卷积层、池化层、全连接层和输出层。
- 输入层:输入层用于接收输入数据,通常是二维的图像或一维的序列数据。
- 卷积层:卷积层是 CNN 的核心部分,它由一系列的卷积核对输入数据进行卷积操作。每个卷积核在输入数据上滑动,并与相应位置的像素进行元素级乘法和求和,得到一个输出特征图。
- 池化层:池化层用于对卷积层的输出进行下采样,减少特征图的大小,同时保留重要的信息。常见的池化操作包括最大池化和平均池化。
- 全连接层:全连接层通常位于 CNN 的最后部分,它将前面的卷积层和池化层的输出转换为一维向量,并通过全连接神经网络进行分类或回归任务。全连接层有时候会直接作为输出层,且可以有多个全连接层并存。
- 输出层:输出层根据具体任务的需求,产生相应的输出结果,如分类标签或预测值。输出层是一个概念,它不一定独立存在,有时候全连接层就是输出层,也可以出现多个输出层。
卷积层
虽然CNN网络被称作卷积神经元网络,但是这里的卷积并非数学意义上的卷积运算,而是数学意义上的互相关(Cross-Correlation)运算。这两种运算的计算公式是比较相似的。
对于输入图像I和卷积核K,卷积运算公式为:
一维卷积: O(i)=∑mK(m)I(i+m)
二维卷积: O(i,j)=∑m∑nK(m,n)I(i+m,j+n)
卷积运算过程如下图所示。
卷积操作在CNN中能够有效地提取特征,主要是通过局部感知、参数共享、特征迁移和空间信息利用等方式实现的。
- 局部感知:卷积操作对输入数据进行局部区域的加权求和,能捕捉到数据中的局部特征。
- 参数共享:同一卷积核在卷积过程中被反复使用,这种参数共享的方式能够提高模型的泛化能力,使得模型能够更好地适应不同的数据分布。
- 特征迁移:通过前向传播和反向传播的过程,卷积操作能够将学到的特征从底层到高层进行迁移,使得高层能够获得更加抽象和高级的特征表示。
- 空间信息利用:卷积操作通过对输入数据进行滑动窗口的操作,能够有效地利用图像中的空间信息,从而更好地提取出图像中的结构信息和模式。
池化层
池化层也叫汇聚层,主要作用是对卷积层的输出进行下采样和降维。池化操作通过对特征图的局部区域进行聚合,减少特征图的大小和维度。常见的池化操作包括最大池化(Max Pooling)、平均池化(Average Pooling)和求和池化(Sum Pooling)。池化层有助于减少特征的数量和计算量,同时提高模型的泛化能力。
在CNN网络中,卷积层和池化层可以是多个,且通常成对出现。卷积层负责提取特征,而池化层则用于降低数据的维度,同时保留重要特征。通过多个卷积层和池化层的堆叠,网络能够逐步抽象出更高层次的特征表示。具体卷积层和池化层的数量,取决于任务和数据集的复杂度。
全连接层
全连接层的作用是将卷积层和池化层提取的特征进行整合,并生成最终的输出。全连接层也可以是多个。可以将全连接层看作是一个"分类器"或"决策器"。它接收来自卷积层和池化层的特征图,并将这些特征图转换为一维向量。然后,全连接层通过对这些一维向量进行加权求和和激活函数的应用,来生成最终的预测结果。
简单来说,全连接层将卷积层和池化层提取的特征进行综合,并根据这些特征做出最终的决策或预测。它在 CNN 中起到了将特征转化为输出的关键作用。
输出层
cnn网络的输出层不一定明确存在。输出层的设计取决于网络的应用和任务。对于分类任务,输出层通常使用 Softmax 函数将每个类别表示为一个概率分布。对于回归任务,输出层可能是一个全连接层,用于生成连续的输出值。对于生成任务,输出层可能是一个生成模型。
举例
我们使用手写数字的MNIST数据集来训练一个分类模型,再用模型评估测试集数据的准确性。
MNIST数据集包含60,000个用于训练的示例和10,000个用于测试的示例。这些数字已经过尺寸标准化并位于图像中心,图像是固定大小(28x28像素),其值为0到1。
# 导入所需的库
import numpy as np
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
import keras.utils
# 加载MNIST数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 将数据集转换为4D张量
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
# 数据归一化
x_train = x_train / 255.0
x_test = x_test / 255.0
# 将标签转换为独热编码
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)
# 定义模型
model = Sequential()
# 添加卷积层,用于提取特征
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
# 添加池化层,降低特征图的维度并减少计算量
model.add(MaxPooling2D(pool_size=(2, 2)))
# 添加卷积层,进一步提取特征
model.add(Conv2D(64, (3, 3), activation='relu'))
# 添加池化层,降低特征图的维度并减少计算量
model.add(MaxPooling2D(pool_size=(2, 2)))
# 添加Dropout层,防止过拟合
model.add(Dropout(0.25))
# 将特征图展平,为全连接层做准备
model.add(Flatten())
# 添加全连接层,对特征进行分类或回归任务
model.add(Dense(128, activation='relu'))
# 再添加一个Dropout层,进一步防止过拟合
model.add(Dropout(0.5))
# 输出层,对分类任务进行最后的输出,使用softmax激活函数得到每个类别的概率分布
model.add(Dense(10, activation='softmax'))
# 编译模型,选择优化器和损失函数等参数
model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy'])
# 训练模型
model.fit(x_train, y_train, batch_size=128, epochs=10, validation_data=(x_test, y_test))
prediction = model.predict(x_test)
print(prediction[0])
print(prediction[1])
print(prediction[2])
print(prediction[3])
print(prediction[4])
输出结果:输出结果每一行表示对一个数字从0-9预测的概率,第一行等于7的概率最大=0.6542437,第二行等于2的概率最大=0.38312846,第三行等于1的概率最大=0.5554214,第四行等于0的概率最大=0.61562777,第五行等于4的概率最大=0.37787333
[0.02346205 0.01705782 0.01757975 0.05409588 0.03439587 0.01591918
0.00883989 0.6542437 0.08179341 0.09261246]
[0.05002937 0.10302236 0.38312846 0.1215608 0.0156013 0.12997957
0.12326405 0.00494462 0.06291166 0.00555777]
[0.02301073 0.5554214 0.064373 0.06319463 0.0306963 0.04776492
0.05218607 0.04433963 0.08174606 0.03726724]
[0.61562777 0.00459658 0.02890156 0.03330857 0.02806828 0.05280998
0.1095016 0.05044021 0.04801216 0.0287333 ]
[0.04292481 0.0077546 0.07826033 0.02820184 0.37787333 0.04119621
0.06344225 0.12711853 0.10382561 0.12940244]
3.3、循环神经网络(RNN)
RNN(Recurrent Neural Network)是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递归神经网络(recursive neural network)。
RNN神经网络与BP神经网、CNN神经网络的核心差异在于:网络会对前面的信息进行记忆并应用于当前输出的计算中。隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。因此,RNN的输出不仅取决于当前的输入,还取决于之前的输入,这使得RNN能够处理具有时序依赖性的问题。
RNN神经网络的主要应用领域包括:
- 自然语言处理:文本生成、机器翻译、情感分析、语言模型等。
- 语音识别:语音到文本的转换等。
- 时间序列分析:股票价格预测、传感器数据分析等。
上图中,我们假设:X为输入层向量,O为输出层向量;U为输入层到隐藏层的权重矩阵,V为隐藏层到输出层的权重矩阵,W为隐藏层上一次的值作为这一次输入的权重矩阵;f为隐藏层激活函数,g为输出层激活函数。
将RNN神经网络模型展开可得下图。从图中我们可以看出,时刻t的隐藏层输出 St 值取决于当前时刻的输入值 Xt 以及上一时刻t-1的隐藏层输出 St−1 。
根据上图逻辑关系,我们可以得出: Ot=g(VSt)St=f(UXt+WSt−1)
将上式反复代入可得:
Ot=g(VSt)=g(Vf(UXt+WSt−1))=g(Vf(UXt+Wf(UXt−1+WSt−2)))=g(Vf(UXt+Wf(UXt−1+Wf(UXt−2+WSt−3))))
由上式可以看出,RNN神经网络的输出值与前面多个时刻的历史输入值有关,这就是为何循环神经网络能够往前看任意多个输入值的原因,也就是为何循环神经网络能够对序列数据建模的原因。
举例
为了充分展示RNN的记忆性特点,我们构建一个正弦曲线序列。在这个任务中,模型需要学习预测一个序列的下一个元素,该元素依赖于前面的几个元素。我们使用Keras构建的简单RNN模型的示例,用于预测正弦波序列中的下一个点。本例中,RNN模型将会学习识别正弦波的模式,并使用它的“记忆”来预测序列的下一个点。
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import SimpleRNN, Dense
# 生成正弦波数据
def generate_sine_wave(batch_size, n_steps):
freq1, freq2, offsets1, offsets2 = np.random.rand(4, batch_size, 1)
time = np.linspace(0, 1, n_steps)
series = 0.5 * np.sin((time - offsets1) * (freq1 * 10 + 10))
series += 0.2 * np.sin((time - offsets2) * (freq2 * 20 + 20))
series += 0.1 * (np.random.rand(batch_size, n_steps) - 0.5)
return series[..., np.newaxis].astype(np.float32)
# 超参数
batch_size = 10000
n_steps = 50
n_features = 1
# 生成训练数据
X_train, y_train = [], []
for _ in range(batch_size):
x = generate_sine_wave(1, n_steps + 1)[0]
X_train.append(x[:n_steps, :])
y_train.append(x[n_steps, :])
X_train, y_train = np.array(X_train), np.array(y_train)
print(X_train.shape)
# 构建RNN模型
model = Sequential([
SimpleRNN(50, return_sequences=True, input_shape=[X_train.shape[1], X_train.shape[2]]),
SimpleRNN(50),
Dense(n_features)
])
# 编译模型
model.compile(optimizer='adam', loss='mse')
# 训练模型
history = model.fit(X_train, y_train, epochs=100, verbose=1, validation_split=0.2)
# 评估模型
loss = model.evaluate(X_train, y_train, verbose=0)
print('Train loss:', loss)
# 使用模型进行预测
def predict_sequence(model, seed_sequence):
n_predict = 10 # 预测接下来的10个点
x = seed_sequence
for _ in range(n_predict):
x_pred = model.predict(x.reshape((1, x.shape[0], x.shape[1])))
x = np.concatenate([x, x_pred], axis=0)
return x
# 可视化预测结果
seed_sequence = generate_sine_wave(1, n_steps)[0]
predicted_sequence = predict_sequence(model, seed_sequence)
plt.figure(figsize=(12, 6))
plt.plot(np.linspace(0, 1 - 1/6, n_steps), seed_sequence.flatten(), label='Seed Sequence', linewidth=3)
plt.plot(np.linspace(0, 1, n_steps + 10), predicted_sequence.flatten(), label='Predicted Sequence', linewidth=2)
plt.legend()
plt.show()
从输出结果可见,右侧橙色曲线基本符合正确的走势。注:本例图形和正弦曲线稍微有些差距,但我们的目的不是为了完全拟合正弦曲线。
3.4、LSTM神经网络
LSTM神经元网络,即长短期记忆网络(Long Short-Term Memory Networks),是一种特殊的循环神经网络(RNN)。RNN在处理长序列时会遇到梯度消失和梯度爆炸问题,这些问题限制了RNN捕捉长距离依赖关系的能力。LSTM网络能够避免RNN网络的缺陷,主要是因为它通过引入门控机制和细胞状态的设计,从而解决了原始RNN的长期依赖性问题。
LSTM神经网络的主要应用领域包括:
- 自然语言处理:文本生成、机器翻译、语音识别等任务。
- 时间序列预测:股票价格预测、天气预报、交通流量预测等。
- 音频处理:语音合成、音乐生成等
- 图像处理:视频分析、图像标注等。
- 生物信息学:基因序列分析、蛋白质结构预测等。
- 推荐系统:处理用户的历史行为数据,提供更精准的推荐。
LSTM中的关键部分
- 细胞状态(Cell State):这是LSTM的核心,类似于传送带,直接在整个链上运行。细胞状态贯穿了整个“循环网络”,将历史的信息顺畅地向后传递。由于信息在细胞状态中流动时使用的是“+”而不是“×”,这使得链式求导时避免了连乘的出现,从而解决了梯度爆炸和梯度消失的问题。
- 门控机制:LSTM通过引入三种门(遗忘门、输入门和输出门)来控制信息的流动。这些门使用sigmoid函数和逐点相乘的操作来实现选择性地让信息通过。
- 遗忘门:决定是否忘记细胞状态中的某些信息。
- 输入门:决定是否将新的信息添加到细胞状态中。
- 输出门:控制细胞状态中的信息如何输出到LSTM的当前输出。
- 隐藏状态(Hidden State):LSTM还有一个隐藏状态,通常被称为短期记忆。它在每个时间步都会被更新,并用于计算输出和下一个时间步的细胞状态。
LSTM网络结构
在LSTM网络中,每个网络单元内部包含四个网络层:遗忘门、输入门、细胞状态、输出门。这些网络层通过不同的门控机制和激活函数,使得LSTM网络能够在处理长序列数据时有效地捕捉和记忆重要的信息,同时忽略不重要的信息。这也是LSTM网络在各种序列预测任务中取得显著成功的关键所在。
LSTM网络结构
细胞状态
LSTM网络中的细胞状态的信息变化不大,只在某些位置进行少量的线性交互。这种设计使得信息可以在序列中流动而不易丢失,从而避免了梯度爆炸和梯度消失问题。
遗忘门及其计算公式
遗忘门的工作原理是通过将输入数据和隐藏状态进行加权求和,并经过一个Sigmoid激活函数,输出一个0到1之间的值。这个值表示细胞状态中每个元素应该被保留的程度。如果输出值接近0,意味着对应的元素应该被遗忘,即丢弃旧的信息;如果输出值接近1,则意味着对应的元素应该被保留,即保留旧的信息。
输入门及其计算公式
输入门的工作原理是首先接收当前时间步的输入和前一个时间步的隐藏状态作为输入。然后,它将这些输入通过一个Sigmoid激活函数,得到一个介于0和1之间的值。数值的意义就不在重复了。接下来,输入门还会将当前输入和前一个时间步的隐藏状态通过另一个tanh激活函数,得到一个新的候选值向量。这个向量包含了可能被添加到细胞状态中的新信息。最后,输入门将Sigmoid函数的输出与tanh函数的输出相乘,得到一个新的信息向量。这个向量中的每个元素都表示了对应位置上新信息的权重,即哪些新信息应该被添加到细胞状态中。
输出门及其计算公式
输出门的工作原理在于它接收当前时间步的输入、前一个时间步的隐藏状态以及当前时间步的细胞状态作为输入。这些输入经过线性变换后,通过一个Sigmoid激活函数,产生一个介于0和1之间的数值。数值的意义就不在重复了。输出门的输出与当前细胞状态经过Tanh激活函数处理后的值相乘。Tanh激活函数将细胞状态的值映射到-1到1的范围内,这有助于调整输出的范围。相乘的结果就是最终从LSTM单元输出的值,它包含了细胞状态中被选择输出的重要信息。
3.5、Transformer神经网络
Transformer模型是一种基于注意力机制(Attention Mechanism)的深度学习模型,它主要用于处理自然语言处理(NLP)中的序列数据。Transformer是Google的团队在2017年提出的一种NLP经典模型,模型使用了Self-Attention机制,使得模型可以并行化训练,而且能够拥有全局信息。
注意力机制能够直接对输入序列的不同位置进行关注和处理。这使得模型能够更好地处理长距离依赖关系,捕捉句子中不同词语之间的关联,从而提升对语义的理解。因此Transformer模型处理NLP问题具有一定的优势。
Transformer神经网络的主要应用领域包括:
- 自然语言处理:机器翻译、文本摘要、问答系统、对话生成等。
- 计算机视觉:图像识别、目标检测等。
- 语音识别:语音到文本的转换等。
Transformer模型的核心组成部分包括编码器(Encoder)和解码器(Decoder),它们都是由多层的自注意力(Self-Attention)和前馈神经网络(Feed-Forward Neural Network)组成的。编码器负责将输入序列转换为一个高维的表示向量,而解码器则基于这个表示向量来生成输出序列。
上图中包含6个Encoder和6个Decoder,Encoder和Decoder的数量根据模型的复杂度来定。理论上数量越多,模型的表达能力就越强,类似于ANN神经网络的隐藏层。
Transformer模型
上图是一个Transformer模型的完整结构,其中左侧为Encoder,右侧为Decoder。模型内部包括很多算法子模块。图中橙色部分为 Multi-Head Attention,是由多个 Self-Attention组成的。Encoder包含一个 Multi-Head Attention,Decoder包含两个 Multi-Head Attention。下面我们分别介绍每一个模块。
Self-Attention模块
自注意力机制(Self-Attention Mechanism),也称为注意力机制(Attention Mechanism),是一种用于深度学习和自然语言处理中的关键技术。自注意力机制的基本思想是对输入序列中的每个元素(例如句子中的每个单词)分配一个权重,以表示该元素与其他元素的关联性。
Self-Attention机制主要包含以下步骤:
- 构建查询(Query)、键(Key)和值(Value):对于输入序列中的每个元素,生成三个向量,分别用于查询、键和值。这些向量通常是通过线性变换从输入数据中获得的。
- Query向量:代表了当前输入向量对其他输入向量的关注程度。在Self-Attention中,每个输入向量都会有一个对应的Query向量,用于与其他输入向量的Key向量进行匹配,从而确定注意力权重。
- Key向量:用于与Query向量进行匹配,以计算注意力权重。Key向量的作用是让模型能够知道哪些位置的信息对当前输入向量是重要的。
- Value向量:包含了实际的值信息,这些值信息会根据注意力权重被加权求和,以得到最终的输出向量。Value向量的作用是提供具体的输入信息,用于生成最终的输出。
- 计算注意力分数:对于每个查询向量,计算与所有键向量之间的相似性得分,通常使用点积或其他方法(如缩放点积注意力)。这些得分衡量了查询与每个键的关联程度。
- 计算注意力权重:将相似性得分通过softmax函数进行归一化,以得到权重向量,其中每个权重表示查询与对应键的关联强度。
- 计算输出:将权重向量与值向量进行加权和,得到最终的输出向量。这个输出向量包含了关联性信息,可以用于后续任务,如分类或生成。
Self-Attention计算过程可以用下图来表示:
上图的数学计算过程可以表示为:
Attention(Q,K,V)=softmax(QKTdk)V
多头注意力机制(Multi-head Attention)模块
从上图可以看到 Multi-Head Attention 包含多个 Self-Attention 层组成。首先,通过h个不同的线性变换对 Query、Key 和 Value 进行映射;然后,将不同的 Attention 拼接起来;最后,再进行一次线性变换。
Add & Norm模块
Add 和 Norm 是两个操作,Add指的是X+MultiHeadAttention(X),是一种残差连接,Norm表示归一化操作。
LayerNorm(X+MultiHeadAttention(X))LayerNorm(X+FeedForward(X))
Feed Forward模块
Feed Forward 层比较简单,是一个两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数,对应的公式如下。X是输入,Feed Forward 最终得到的输出矩阵的维度与X一致。
FFN(x)=max(0,xW1+b1)W2+b2
总的来说,Transformer模型通过其自注意力机制、多头注意力机制和优化的训练技术,实现了对序列数据的高效处理,并在自然语言处理任务中取得了显著的性能提升。这使得Transformer模型成为了当前自然语言处理领域的主流模型之一。
百度的文心一言就是基于Transformer模型训练出来的。
4、常用神经元网络框架
常用的神经元网络框架有很多,以下是一些比较知名的框架,尤其是前三个用处最多。
- TensorFlow:由Google开发的开源机器学习框架,支持分布式训练,能够在不同硬件上高效运行,并且有一个庞大的社区和丰富的生态系统,提供了许多高级的工具和库。
- Keras:是一个高层神经网络API,由Python编写,能够以TensorFlow、CNTK或者Theano作为后端运行。它支持快速实验,具有用户友好的API,使得构建和训练神经网络模型变得简单。
- PyTorch:由Facebook人工智能研究院研发的开源机器学习框架,支持动态图计算,具有高效的GPU加速功能,并且支持多种应用场景,包括自然语言处理、语音识别、图像处理等。
- Caffe:由Berkeley Vision and Learning Center(BVLC)研发的深度学习框架,以速度和可扩展性著称,支持多种数据格式和接口,并且有一个活跃的社区和丰富的预训练模型库。
- MXNet:由亚马逊人工智能研究院研发的深度学习框架,支持多种编程语言和平台,包括Python、C++、R、Scala等,具有高效的内存管理和分布式训练能力。
5、总结
本文简单介绍了神经元网络的基础知识。我们并没有详细介绍每一种神经元网络,因为每种神经元网络的模型都非常复杂,需要有长篇大论来描述。作者自己也是在学习神经元网络的过程中,后续会详细介绍每一种模型,并给出实战代码。
目前成熟的神经元网络有很多种,不同的神经元网络有自己独特的应用领域。因此, 要掌握不同领域的人工智能技术,就必须掌握好多种神经元网络。虽然不同神经元网络的框架有所差异,但是本质还是相同的,有触类旁通的效果。本文选择了几种较为常用的模型进行了介绍,但是整体来说介绍的还不够深入。每一种神经元网络都有很强的数学理论依据,后续我们会详细单独介绍。
总的来说,神经元网络是一种强大的机器学习工具,在许多领域都取得了显著的成果。它们的应用范围广泛,从图像和语音识别到预测和分类问题。随着技术的不断发展,神经元网络的研究和应用仍在不断前进,为解决各种复杂问题提供了有前途的方法。但在实际应用中,需要根据具体问题和数据特点选择合适的网络架构和训练方法,并进行适当的调优和评估。