当前位置:   article > 正文

大模型系统和应用——神经网络基础_大模型原理 神经网络

大模型原理 神经网络

引言

最近在公众号中了解到了刘知远团队退出的视频课程《大模型交叉研讨课》,看了目录觉得不错,因此拜读一下。
观看地址: https://www.bilibili.com/video/BV1UG411p7zv

目录:

  1. 自然语言处理&大模型基础
  2. 神经网络基础
  3. Transformer&PLM
  4. Prompt Tuning & Delta Tuning
  5. 高效训练&模型压缩
  6. 基于大模型的文本理解与生成
  7. 大模型与生物医学
  8. 大模型与法律智能
  9. 大模型与脑科学

神经网络基本组成元素

人工神经网络(Artificial Neural Network)受到生物中的神经网络所启发。
在这里插入图片描述

神经元

受到生物里面的神经网络和生物神经元的启发,人们设计出由计算机能够计算的人工神经元,这里简称为神经元(Neuron)。
在这里插入图片描述
一个神经元可以有 n n n个输入和一个输出,同时包含了参数 w w w b b b
经过线性运算 w T x w^Tx wTx加上偏置 b b b后经过激活函数,得到神经元的输出。

多层网络

我们上面看到的是单个神经元,我们利用很多单个的神经元就可以构成一个只有一层的神经网络。

在这里插入图片描述
上图中有3个神经元,它们经过矩阵运算并行计算,可以一次计算出这三个神经元的输出。

我们得到了单层神经网络之后,就可以在后面继续叠加类似的层,形成多层神经网络(Multilayer Neural Network)。

在这里插入图片描述
通常我们从输入开始依次计算每层的结果,这就是所谓的前向计算(Feedforward Computation)。

在这里插入图片描述
我们通常将输入层之上添加的多层网络称之为隐藏层(Hidden Layer)。

这里有三个隐藏层,每层的输入由上层的输入经由线性变换和激活函数得到的。

非线性

这里的激活函数一般都是非线性的,那么为什么要使用非线性的激活函数?

如果没有非线性激活函数,那么每层相当于对上一层的输出进行了一次线性变换,
在这里插入图片描述
这里假设有两层没有线性激活函数的网络,把第一层的计算结果 h 1 h_1 h1代入到 h 2 h_2 h2的计算公式中之后,我们可以发现,实际上就可以转换为单层神经网络的线性变换。

同时,有了非线性激活函数,可以大大增强网络的表达能力,可以拟合更复杂的函数。

常用的激活函数有:
在这里插入图片描述

输出层

我们知道,可以通过叠加更多的隐藏层来提升网络的表达能力,那我们如何得到想要的输出结果呢?
此时,我们就需要增加网络的输出层。

在这里插入图片描述
输出层根据需要,它也有不同的形态。

在这里插入图片描述
对于这种只有一个输出的输出层,对应了两种情况。

  • 一是线性输出: y = w T h + b y=w^Th + b y=wTh+b,它会得到一个取值范围在 ( − ∞ , + ∞ ) (-\infty,+\infty) (,+)的标量,通常用来解决回归问题。
  • 二是经过激活函数Sigmoid后的输出: y = σ ( w T h + b ) y=\sigma(w^Th + b) y=σ(wTh+b),它会得到一个取值范围在 [ 0 , 1 ] [0,1] [0,1]之间的实数,通常我们可以理解为属于某一类别的概率。那么不属于该类别的概率,就是 1 − y 1-y 1y

在这里插入图片描述
如果有多个输出,那么可以看成是多分类问题,每个输出值代表对应类别的得分,那么经过Softmax函数后,就可以转换为概率:
y i = softmax ( z i ) = exp ⁡ ( z i ) ∑ j exp ⁡ ( z j ) z = W h + b y_i = \text{softmax}(z_i) = \frac{\exp (z_i)}{\sum_j \exp (z_j)} \\ z = Wh + b yi=softmax(zi)=jexp(zj)exp(zi)z=Wh+b
这里 z i z_i zi对应其中第 i i i个输出。

如何训练神经网络

训练目标

想要训练一个神经网络,我们首先需要设定一个训练目标(Objective)。
然后根据该训练目标对网络进行调整。

均方误差

这里举个例子,假设有 N N N条训练数据,它的输入是某个电脑 x i x_i xi的一些属性,希望模型能预测出电脑的假设 y i y_i yi。这显然是一个回归问题。
我们希望训练一个神经网络 F θ F_\theta Fθ,根据输入样本的属性来预测电脑价格。此时,合理的训练目标就是均方误差(Mean Squared Error)
min ⁡ θ J ( θ ) = min ⁡ θ 1 N ∑ i = 1 N ( y i − F θ ( x i ) ) 2 \min_\theta J(\theta) = \min_\theta \frac{1}{N} \sum_{i=1}^N \left(y_i - F_\theta(x_i) \right)^2 θminJ(θ)=θminN1i=1N(yiFθ(xi))2
其中 θ \theta θ是神经网络 F θ F_\theta Fθ的参数。

这里误差(loss)越小,说明模型预测的越准确,因此我们要最小化这个目标函数。

交叉熵

我们来看另外一种情况。
给定 N N N段文本,我们希望模型去预测情感标签:正面、中性、负面。此时,合理的训练目标是交叉熵(Cross Entropy)
min ⁡ θ J ( θ ) = min ⁡ θ − 1 N ∑ i = 1 N log ⁡ P m o d e l ( F θ ( x i ) = y i ) \min_\theta J(\theta) = \min_\theta - \frac{1}{N} \sum_{i=1}^N \log P_{model}(F_\theta(x_i) = y_i) θminJ(θ)=θminN1i=1NlogPmodel(Fθ(xi)=yi)

随机梯度下降

我们知道为了达到训练目标,我们需要最小化某一个损失函数。
那么如何最小化一个损失函数呢?
在神经网络中我们通常会采用随机梯度下降法(Stochastic Gradient Descent)。
我们希望把整个优化步骤拆分成若干个子步骤,在每个子步骤中我们缩小一点损失函数。那么要如何调整参数,才能做到每一步能缩小一点损失函数呢。
首先要计算损失函数对于模型参数的梯度,这个梯度代表了对这个参数进行单位大小的改动下,损失函数它变化最快的一个方向。顺着这个方向向前走一步,就可以降低一点点损失函数值。
在这里插入图片描述
在这里插入图片描述
给定一个有 n n n个输入 1 1 1个输出的函数 F F F,我们可以通过偏导数来计算对向量 x x x的梯度。

在这里插入图片描述
给定一个有 n n n个输入 m m m个输出的函数 F F F,我们可以把它拆分成具有 m m m个单个输出的函数 [ F 1 , F 2 , ⋯   , F m ] [F_1,F_2,\cdots,F_m] [F1,F2,,Fm]
然后让这 m m m个函数对这 n n n个输入去求偏导数,得到一个 m × n m \times n m×n的矩阵,称为Jacobian矩阵。
如果我们按行来看这个矩阵的话,就是一个函数对应每个输入的偏导数。

链式法则

在这里插入图片描述
在求微分时会用到链式法则,这里所有的函数都是一元函数,要求 z z z x x x的导数,我们先求 z z z y y y的导数,乘以 y y y x x x的导数即可。

推广到多输入多输出的函数情形。

在这里插入图片描述
假设我们要计算 h h h x x x的微分,那么我们也可以先计算 h h h z z z的微分,然后计算 z z z x x x的矩阵。这里这两者都可以表示成Jacobian矩阵,然后把这两个矩阵进行相乘,就得到了我们想要的结果。

如果回到神经网络,假设 s = u T h s=u^Th s=uTh是损失函数得到的结果, h = f ( z ) , z = W x + b h=f(z), z=Wx+b h=f(z),z=Wx+b z z z是线性变换, f f f是非线性激活函数。那么如果计算 s s s对参数 b b b的导数?

在这里插入图片描述
利用链式法则,我们可以列出需要计算的微分式子。然后分别求解即可。

反向传播

在实际深度学习中,是通过反向传播算法去计算对每个参数的梯度。

在这里插入图片描述
这里不得不提到计算图这个工具,在计算图中第一个节点代表网络的输入 x x x,其他的节点代表计算操作。图中的有向边代表操作的操作数,同时也可以表示传递计算值的过程。

这里由于在博主的另外一篇博客自动求导神器计算图中有详细的探讨,因此就跳过了。

词表示:Word2Vec

这里介绍一个简单的神经网络的例子,Word2Vec,它利用非常简单的神经网络进行训练,就可以得到词向量,即词的低维表示。

Word2Vec利用两类架构来产生分布式的词表示:

  • CBOW
  • Skip-gram
    在这里插入图片描述
    Word2vec使用固定大小的滑动窗口框住文本中连续出现的单词来构造训练数据。

在每个窗口中,中间的单词是目标词,其他的单词是上下文词。

  • 给定上下文词,CBOW预测目标词的概率
  • 而给定目标词,Skip-gram预测上下文词的概率

一个滑动窗口的例子:
在这里插入图片描述
这里窗口大小为5,蓝色背景的单词代表目标词,注意边界情况。

CBOW

在CBOW架构中,模型给定周围的上下文词来预测目标词。
根据词袋假设:上下文词的顺序不影响预测。

在这里插入图片描述
假设窗口大小为5,我们要预测never too __ to learn中间的词。

在这里插入图片描述
这里只画出了两个上下文词,首先将上下文词表示为one-hot向量,然后在要训练的词向量矩阵中得到这两个词的词向量,然后取这两个词向量的均值,得到一个向量。为了能计算词表中每个单词作为目标词的概率,我们需要输出层的大小和词表大小一致。那么,经过Softmax就可以得到词表中单词的概率分布。因此,经过求均值得到的向量需要进行一个线性变换,转换为词表大小的维度。

Skip-Gram

而在Skip-Gram中,通过目标词来预测上下文词。

在这里插入图片描述
同样,假设窗口大小为5,如果Never是目标词,那么模型需要预测too和late是上下文词;如果too是目标词,那么模型需要预测Never,late和to是上下文词。

但让神经网络来预测出多个输出是不容易的,所以我们把这个任务进行分解,让它分别预测每个上下文词的概率:
在这里插入图片描述
如果Never是目标词,那么先让模型学习输出too,再让模型学习去输出late。

在这里插入图片描述
在预测是,看起来和CBOW很类似,除了这里的输入只有一个目标词,输出一次只是一个上下文词。

在这两种架构中,我们都默认去对整个词表进行Softmax,这里可能出现性能问题。
如果词表非常大,那么对它进行Softmax需要非常大的计算量。
因此我们需要提升计算效率。

这里有两种提升Word2vec计算效率的技术:

  • 负采样
  • 分层Softmax

这里只介绍负采样。

负采样

在这种技术中,我们不对整个词表进行Softmax。简单来说是把多分类问题变成二分类问题。
即将上下文词作为正例,同时采样一小部分非上下文词作为负例。现在只需要判断某个词是正例还是负例即可。

这里在进行负采样时也有要注意的地方,即为了让稀有词被采样的概率增大,通过下面的公式来计算最终单词被采样的概率:

在这里插入图片描述
f ( w i ) f(w_i) f(wi)是单词 w i w_i wi的频次。

在这里插入图片描述
有了负采样之后,我们不需要再计算整个词表的Softmax概率。这里假设只采样了4个负例,那么现在只需要拿出4个负例和1个正例对应的得分计算Softmax。

这样计算量会大大降低,假设词向量维度是300,词表中词个数为10000。那么原本要对这10000个词进行Softmax,然后在反向传播时,需要对整个 300 × 10000 300 \times 10000 300×10000的矩阵进行梯度计算。那么计算量非常大。
我们使用负采样之后,假设只采4个负例,那么在Softmax的时候只有5个值,我们只需要更新 300 × 5 300 \times 5 300×5的权重矩阵,计算量只有原来的 0.05 % 0.05\% 0.05%

其他技巧

Word2vec还有其他学习技巧,一个是Sub-Sampling。它为了平滑常见词和罕见次。罕见词出现的概率虽然较低,但可能包含丰富的语义信息。而常见词(像“的”、“呢”)出现的概率较高,可能含有的意义就没那么重要。

在这里插入图片描述
Sub-Sampling的方法是在训练过程中去掉一些词,具体去掉的概率是根据上面的公式进行计算。

还有一种方法是非固定的滑动窗口,称为软滑动窗口。它认为离目标词越近的上下文词越重要(或者说相关)。
它不对窗口大小进行固定,窗口大小是通过这样一种方法来采样得到的。
首先定义滑动窗口大小的最大值 S m a x S_{max} Smax,在生成训练数据时从 1 1 1 S m a x S_{max} Smax之间去采样一个值。让这个采样的值作为这一次训练的滑动窗口大小。
这样,通过变化的滑动窗口大小,离目标词更近的上下文词,有更大的机会被采样成上下文词。

常见神经网络

循环神经网络

循环神经网络(RNN)的关键点在于处理序列数据时会有一个顺序的记忆。所谓顺序记忆就是我们看到熟悉顺序的内容时能更顺畅的阅读,比较浅显的例子是阅读中文文章和英文文章的体验。虽然有时你发现英文单词都认识,但是读起来就是很吃力。

RNN通过递归更新顺序记忆来为序列数据建模。

RNN

在这里插入图片描述
这是一个典型的RNN例子。

这里画出了输入序列长度为3,对应会生成三个隐藏状态,和三个输出。

在这里插入图片描述
那给定某时刻的输入和上一时刻的隐藏状态,它是如何计算隐藏状态和输出的呢?

根据上图中的公式。

RNN能处理时间序列的这种性质,特别适用于NLP任务,尤其是作为语言模型。

在这里插入图片描述
上图是一个例子,首先在时刻1有输入 w 1 w_1 w1,它是一个one-hot向量,那么经过词嵌入矩阵得到对应的词嵌入向量 x 1 x_1 x1,作为RNN的输入。
然后根据 x 1 x_1 x1和上一时刻的隐藏状态 h 0 h_0 h0来计算当前时刻的隐藏状态,由于这里是第一个时刻,因此 h 0 h_0 h0需要我们自己先初始化,一般初始化为零向量。

在这里插入图片描述
以此类推,将"never too late to"依次输入到RNN网络中,我们知道语言模型需要预测下一个单词是什么。

在这里插入图片描述
这时候,我们需要用到最后时刻"to"计算出来的隐藏状态 h 4 h_4 h4,因为该隐藏状态包含了前面四个词的所有信息。同理,我们这里也会经过线性层,把它的维度转换为词表大小,然后经过Softmax计算词表中每个单词作为下一个词的概率。

从图中也可以发现,每个时刻的 W x W_x Wx W h W_h Wh都是一样的,因为每个时刻其实都是同一个RNN单元的不断复制,可以很好地实现参数共享,这样有助于模型处理不同长度的样本,也助于模型更好地学习,节省参数量。

RNN的应用场景也很多:

  • 序列标注
  • 序列预测
  • 图片描述
  • 文本分类

综上RNN的优点如下:

  • 能处理任意长度的输入
  • 模型大小不随输入长度增加
  • 权重在每个时间步共享
  • 计算当前时间步信息理论上会用到前面很多时间步的信息

但也有一些缺点:

  • 循环计算缓慢
  • 实际上,很难获得过远的历史时间步信息。
  • 梯度消失/梯度爆炸

在这里插入图片描述
随着序列的变长,根据链式法则,在求解某个权重时会产生很长的计算公式。
具体是梯度消失还是梯度爆炸会处决于每个式子中的 ∂ h n ∂ h n − 1 \frac{ \partial h_n}{\partial h_{n-1}} hn1hn的结果。如果该结果每次都大于1,会导致梯度呈指数型增大,从而形成梯度爆炸;反之若小于1,那么也会导致梯度呈指数型衰减,从而形成梯度消失。

有几个RNN的变体专门来解决这个问题,比较有名的变体是GRU和LSTM。

GRU

普通的RNN在计算下一时刻隐藏状态时,通过
h i = tanh ⁡ ( W x x i + W h h i − 1 + b ) h_i = \tanh(W_xx_i + W_hh_{i-1}+ b) hi=tanh(Wxxi+Whhi1+b)
GRU在此基础上引入了门控机制,来控制哪些信息可以传到下一时刻。
GRU有两个门,分别是更新门
z i = σ ( W x ( z ) x i + W h ( z ) h i − 1 + b ( z ) ) z_i = \sigma(W_x^{(z)} x_i + W_h^{(z)} h_{i-1} + b^{(z)}) zi=σ(Wx(z)xi+Wh(z)hi1+b(z))
和重置门
r i = σ ( W x ( r ) x i + W h ( r ) h i − 1 + b ( r ) ) r_i = \sigma(W_x^{(r)}x_i + W_h^{(r)}h_{i-1} + b^{(r)}) ri=σ(Wx(r)xi+Wh(r)hi1+b(r))

它们的作用就是权衡过去的信息和当前输入信息在计算新的隐藏状态上的比重。

新隐藏状态 h i h_i hi计算为:
h i = z i ⊙ h i − 1 + ( 1 − z i ) ⊙ h ~ i h_i = z_i \odot h_{i-1} + (1-z_i) \odot \tilde h_i hi=zihi1+(1zi)h~i
这里 ⊙ \odot 代表按元素相乘, h ~ i \tilde h_i h~i是候选隐藏状态,它的计算公式类似于RNN中的隐藏状态,代表当前时刻的信息。
可以看到,这里更新门控制了当前隐藏状态 h i h_i hi中有多少来自前一隐藏状态 h i − 1 h_{i-1} hi1,如果来自前一隐藏状态的信息越多,那么来自候选隐藏状态的信息就越少。

我们来看下候选隐藏状态是如何计算的:
h ~ i = tanh ⁡ ( W x x i + r i ⊙ W h h i − 1 + b ) \tilde h_i = \tanh(W_x x_i + r_i \odot W_h h_{i-1} + b) h~i=tanh(Wxxi+riWhhi1+b)
如果上式中没有 r i r_i ri,那么就完全等同于普通RNN中隐藏状态的计算,那么这里的 r i r_i ri是控制是否会遗忘过去的隐藏状态(历史信息)。

对于重置门来说。

如果过重置门 r i r_i ri接近于0,那么相当于 h ~ i = tanh ⁡ ( W x x i + b ) \tilde h_i = \tanh(W_x x_i + b) h~i=tanh(Wxxi+b)
即忽略了前一时刻隐藏状态,表示当前激活值与过去无关。

对于更新门来说,它控制了过去的状态与当前激活相比之下有多大的关系。
z i z_i zi接近于1时,那么 h i = h i − 1 h_i=h_{i-1} hi=hi1,即完全保留了上一时刻的信息。

z i z_i zi接近于0时,那么 h i = h ~ i h_i = \tilde h_i hi=h~i,即完全丢弃了上一时刻的信息。

LSTM

相比于GRU只有两个门,LSTM有三个门,它更加复杂一点。

在这里插入图片描述
LSTM也是RNN的变体,它比GRU多了一个门。LSTM关键之处在于它增加了一个新的状态 C t C_t Ct(单元状态)。

在这里插入图片描述
它的作用有:

  • 能够捕获长期依赖
  • C t C_t Ct的更新只有微小的线性变换
  • 易于移除或增加信息到 C t C_t Ct

具体地,LSTM也是通过一系列门进行操作的。我们分别来看下。

在这里插入图片描述
首先是遗忘门,决定上一个状态有哪些信息可以从单元状态中移除。
这里 [ h t − 1 , x t ] [h_{t-1},x_t] [ht1,xt]是上一时刻隐藏状态和当前时刻输入的拼接,代表同时考虑了这两者。

如果 f t = 0 f_t=0 ft=0,则表示直接丢弃信息。
下面来看输入门。
在这里插入图片描述
以及候选单元状态 C ~ t \tilde C_t C~t
输入门决定哪些候选单元状态信息可以存储到单元状态。

在这里插入图片描述
有了上面计算的结果,就可以来更新单元状态。计算公式如上图。
它通过遗忘门来控制遗忘多少旧(上一时刻)单元状态信息,以及保留多少新的候选单元状态信息。

有了当前时刻的单元状态,就可以来计算新的隐藏状态。

在这里插入图片描述
在计算隐藏状态时,有一个输出门,它控制单元状态中的哪些信息可以输出到隐藏状态。

双向RNN

在这里插入图片描述
前面我们介绍的RNN(包括简单RNN、GRU和LSTM)中,只能沿着一个方向从左到右读取输入。但有时候,如果能双向地读取输入,那么问题就解决得更好。比如在命名实体识别任务中。

卷积神经网络

卷积神经网络(CNN)通常应用于图像中,但也可以应用到NLP领域内。比如ELMo中就应用到了CNN。

CNN擅长于提取局部和位置不变的模式。在NLP中,可能是一些短语或局部语法结构。

在这里插入图片描述
CNN提取模式通过:

  • 计算句子中所有可能的n-gram短语表示(如上图红,以讲过相邻的词作为短语)
  • 无需额外的语言学数据(比如依赖解析)

在这里插入图片描述
CNN在处理NLP时,往往包含了输入层、卷积层、池化层和非线性层。

输入层对输入进行处理,只有也会有一个词向量矩阵,每个单词都能获取一个维度固定的表示。
然后经过不同大小的卷积层对词向量进行卷积。
接着进入池化层,对特征进一步提取,一般选择最大池化。
最后进入非线性层得到非线性输出,根据任务不同。会进一步对得到的特征向量进行处理,可能经过全连接层进行维度缩放。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/102274
推荐阅读
相关标签
  

闽ICP备14008679号