30、自然语言理解与生成中的深度学习技术

自然语言理解与生成中的深度学习技术

1. 激活函数

1.1 Sigmoid函数

Sigmoid函数存在一些局限性:
- 梯度消失问题 :可参考 此链接 详细了解。由于该问题,使用Sigmoid激活函数的人工神经网络(ANN)有时收敛速度非常慢。若想深入探究,可查看 这个链接
- 非零中心函数 :Sigmoid函数的输出范围是[0, 1],这意味着函数输出值始终为正,使得权重的梯度要么全为正,要么全为负。这会导致梯度更新在不同方向上走得太远,增加优化难度。

由于这些局限性,Sigmoid函数在深度神经网络(DNN)中近来已较少使用。不过,你可以在ANN的最后一层使用Sigmoid激活函数。

1.2 TanH函数

为克服Sigmoid函数的问题,引入了双曲正切函数(TanH)。它将输入区域压缩在[-1, 1]范围内,输出以零为中心,便于优化。但它同样存在梯度消失问题,因此还需考虑其他激活函数。

1.3 ReLu及其变体

  • ReLu函数 :修正线性单元(ReLu)是行业中最流行的函数,其公式为max(0, x),即当x小于0时,值为0;当x大于或等于0时,呈斜率为1的线性关系。研究人员Krizhevsky在图像分类的论文中指出,使用ReLu作为激活函数可使收敛速度提高六倍,可点击 此处 阅读该论文。ReLu函数简单,计算不复杂,相比Sigmoid和TanH成本更低,学习速度更快,且不存在梯度消失问题。如今,大多数DNN在隐藏层使用ReLu函数。对于分类问题,输出层应使用Softmax函数,因为它能给出每个类别的概率,如在word2vec算法中就使用了Softmax激活函数;对于回归问题,输出层应使用线性函数,因为信号可直接通过。
  • Leaky ReLu函数 :ReLu存在一个问题,即神经网络的某些单元在训练过程中可能变得脆弱并“死亡”,也就是大梯度流经ReLu神经元可能导致权重更新,使其在任何数据点上都不再激活,此后流经它的梯度将始终为0。为克服这一局限,引入了Leaky ReLu函数,当x小于0时,它有一个小的负斜率。
  • Maxout函数 :是ReLu和Leaky ReLu的广义形式,但会使每个神经元的参数翻倍,这是其缺点。

选择激活函数时,通常优先选择ReLu;若有太多神经元“死亡”,则使用Leaky ReLu或Maxout。激活函数应用于隐藏层,对于输出层,分类问题使用Softmax函数,回归问题使用线性激活函数。Sigmoid和TanH不应在DNN中使用。此外,还有其他激活函数,如恒等函数、二元阶跃函数、ArcTan等。

激活函数对比表格

激活函数 优点 缺点 适用场景
Sigmoid 输出范围在[0, 1],可用于表示概率 梯度消失,非零中心 ANN最后一层
TanH 输出以零为中心,便于优化 梯度消失 较少使用
ReLu 简单,学习速度快,无梯度消失问题 神经元可能“死亡” DNN隐藏层
Leaky ReLu 解决了ReLu神经元“死亡”问题 当ReLu神经元“死亡”过多时使用
Maxout 广义形式,可适应多种情况 参数翻倍 特定复杂场景

2. 损失函数

损失函数有时也被称为成本函数或误差函数,它能让我们了解ANN在给定训练示例上的表现。训练ANN时,先定义误差函数,训练得到输出后,将生成的输出与训练数据中的预期输出进行比较,计算误差函数的梯度值,然后在网络中反向传播误差梯度,更新现有权重和偏置值,以优化生成的输出。误差函数是训练的核心部分。

常见的误差函数有:
- 二次成本函数(也称为均方误差或平方和误差)
- 交叉熵成本函数(也称为伯努利负对数似然或二元交叉熵)
- 库尔贝克 - 莱布勒散度(也称为信息散度、信息增益、相对熵或KLIC)

此外,还有指数成本、海林格距离、广义库尔贝克 - 莱布勒散度和板仓 - 斋藤距离等损失函数。一般来说,回归问题使用平方和误差,分类任务和处理分类数据使用交叉熵。

3. ANN的实现

3.1 单层神经网络与反向传播

3.1.1 反向传播概念

在单层神经网络中,将输入馈送到第一层,层连接有一些权重。将输入、权重和偏置相加,其和通过激活函数生成输出。将生成的输出与实际预期输出进行比较,根据误差函数计算误差,再使用误差函数的梯度计算误差梯度。误差梯度指示如何优化生成的输出,它在ANN中反向流动,开始更新权重,以在下次迭代中获得更好的输出。这个过程称为反向传播,它是通过梯度下降更新权重来训练神经网络的流行技术。

3.1.2 代码实现步骤
  1. 定义主函数和抽象步骤,给出输入和输出值。由于数据有标签,这是一个监督学习示例。
  2. 进行训练,重复训练10,000次。首先使用随机权重,然后根据激活函数和误差函数调整权重。
  3. 使用Sigmoid作为激活函数,用Sigmoid导数计算Sigmoid曲线的梯度。误差函数是生成的输出与实际输出的简单相减。将误差值与梯度相乘得到误差梯度,用于调整NN的权重。
  4. 新更新的权重和输入再次通过ANN,计算Sigmoid曲线的梯度下降和误差梯度,调整权重直到误差最小。

3.2 代码示例

虽然文档中未给出完整代码,但给出了相关代码片段的引用:
- 图9.37:单层ANN主函数的代码片段
- 图9.38:单层ANN的代码片段
- 图9.39:ANN的代码片段

运行代码后,可得到图9.40所示的输出片段。

3.3 练习

使用numpy构建一个三层深度ANN。提示:单层ANN只使用一层,而这里要使用三层。反向传播通常使用递归求导,在单层演示中没有递归,因此需要应用递归导数。

4. 深度学习与深度神经网络

4.1 深度学习回顾

具有许多层的ANN称为DNN。当使用大量计算能力在大量数据上使用多层深度神经网络时,这个过程称为深度学习。

4.2 DNN的基本架构

DNN的架构用激活函数、隐藏层激活函数、损失函数等数学公式定义。使用多层深度神经网络的原因如下:
- 模拟人类大脑工作方式 :DNN基于人类大脑工作的抽象概念推导而来。
- 改变编码方式 :最初向机器提供颜色、形状等特征来识别图像中的水果名称,而使用DNN和深度学习,向机器提供大量示例,机器会自行学习特征,之后提供新的水果图像时,机器就能预测水果名称。

DNN能够自行学习特征的原因如下:
- 特征提取和转换 :DNN使用一系列多层非线性处理单元进行特征提取和转换,每层使用前一层的输出作为输入,类似于人类大脑神经元之间传递信息。
- 分层学习特征 :深度学习中,通过DNN使用多层次表示来学习特征,高层特征从低层特征推导而来,这种特征推导概念是分层的,类似于人类大脑推导概念的方式。

多层DNN有助于机器推导分层表示,这就是架构中使用多层的意义。借助DNN和数学概念,机器能够模拟人类大脑的一些过程。深度学习可应用于有监督和无监督数据集,开发自然语言处理(NLP)应用,如机器翻译、文本摘要、问答系统、文章生成、图像字幕标注等。

多层DNN优势的mermaid流程图

graph LR
    A[复杂图像识别问题] --> B[传统编码困难]
    B --> C[使用DNN]
    C --> D[模拟人类大脑]
    C --> E[机器自行学习特征]
    D --> F[分层处理信息]
    E --> F
    F --> G[准确识别图像]

5. NLP中的深度学习

5.1 NLP早期与现状

NLP早期基于规则系统,许多应用的早期原型也基于此,因为当时没有大量数据。现在,应用机器学习技术处理自然语言,使用统计和基于概率的方法,将单词表示为独热编码格式或共现矩阵。但这种方法大多只能得到句法表示,而非语义表示,在尝试基于词汇的方法(如词袋模型、n - 元语法等)时,无法区分某些上下文。

5.2 深度学习解决NLP问题的优势

如今有大量数据可供使用,并且已经开发出word2vec、GloVe等算法来捕捉自然语言的语义方面。DNN和深度学习提供了以下能力:
- 可表达性 :表示机器对通用函数的近似能力。
- 可训练性 :对NLP应用非常重要,指示深度学习系统学习给定问题并开始生成有意义输出的能力和速度。
- 泛化性 :表示机器对给定任务的泛化能力,以便对未见数据进行准确预测或生成结果。

此外,深度学习还提供了可解释性、模块化、可迁移性、低延迟、对抗稳定性和安全性等能力。由于语言复杂,不同语言有不同的句法结构、单词用法和含义,难以用其他语言准确表达,因此需要一些技术来泛化问题并获得良好结果,这些因素促使我们在NLP应用中使用DNN和深度学习。

5.3 经典NLP技术与深度学习NLP技术的区别

技术类型 处理步骤
经典NLP技术 1. 早期对数据进行预处理
2. 使用命名实体识别(NER)工具、词性标注器和解析器生成手工特征
3. 将这些特征作为输入馈送到机器学习算法中训练模型
4. 检查准确性,若不准确则优化算法参数以生成更准确的结果
5. 根据NLP应用,可包含语言检测模块并生成特征
深度学习NLP技术 1. 对数据进行一些基本预处理
2. 使用词嵌入技术(如word2vec、GloVe、doc2vec等)将文本输入数据转换为密集向量
3. 将密集向量嵌入馈送到DNN中
4. 根据NLP应用使用不同类型的DNN,如机器翻译使用序列到序列模型,文本摘要使用长短期记忆单元(LSTMs)
5. 多层DNN泛化目标,学习实现目标的步骤,机器学习分层表示并给出结果,根据需要验证和调整模型

若想查看不同DNN变体的代码,可使用 这个GitHub链接

6. 深度学习技术与NLU应用

6.1 机器翻译应用开发

开发机器翻译应用使用深度学习技术,但深度学习需要大量计算能力,因此不实际训练模型,而是使用训练好的模型来复制结果。例如,谷歌使用100个GPU连续训练一周来训练语言翻译模型。

6.2 TensorFlow安装

  • 若要安装TensorFlow 0.12版本,可使用以下命令:
$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.12.1-cp27-none-linux_x86_64.whl
$ sudo pip install --upgrade $TF_BINARY_URL
  • 若要使用CPU版本的TensorFlow,可使用以下简单命令安装:
$ pip install tensorflow
  • 若要在GPU上运行,可使用谷歌云、AWS等云平台,或使用支持GPU的计算机。安装GPU版本的TensorFlow可参考 此链接

接下来将构建两个主要应用:一个用于自然语言理解(NLU),一个用于自然语言生成(NLG)。使用TensorFlow和Keras作为主要依赖进行编码示例,在编码过程中会深入理解序列到序列和LSTM等DNN变体。具体来说,将构建一个机器翻译器作为NLP应用,并从食谱中生成摘要。

7. 构建 NLU 和 NLG 应用

7.1 自然语言理解(NLU)应用 - 机器翻译器

在前面提到了开发机器翻译应用使用深度学习技术且不实际训练模型,而是使用训练好的模型。下面详细介绍构建机器翻译器的步骤:

  1. 数据准备

    • 收集大量的平行语料库,即源语言和目标语言的对应句子对。例如,对于中英翻译,需要大量的中文句子及其对应的英文翻译。
    • 对数据进行预处理,包括分词、去除特殊字符、转换为小写等操作。
  2. 模型选择

    • 选择适合机器翻译的 DNN 变体,如序列到序列(Sequence-to-Sequence)模型。该模型由编码器和解码器组成,编码器将输入的源语言句子编码为一个固定长度的向量,解码器根据这个向量生成目标语言的句子。
  3. 使用训练好的模型

    • 从可靠的来源获取训练好的机器翻译模型。
    • 将预处理后的输入句子输入到模型中,得到翻译结果。

7.2 自然语言生成(NLG)应用 - 食谱摘要生成

构建食谱摘要生成应用的步骤如下:

  1. 数据收集与预处理

    • 收集大量的食谱数据,包括食材、步骤、描述等信息。
    • 对食谱数据进行清洗,去除无用的信息,如广告、重复内容等。
    • 将食谱文本进行分词处理,以便后续处理。
  2. 模型选择

    • 可以选择长短期记忆单元(LSTMs)模型。LSTMs 能够处理序列数据,并且可以捕捉长距离的依赖关系,适合用于文本摘要生成任务。
  3. 训练与生成摘要

    • 使用预处理后的食谱数据对 LSTM 模型进行训练。
    • 输入新的食谱文本,模型会根据训练学到的模式生成食谱的摘要。

7.3 代码示例(概念性)

虽然文档未给出完整代码,但以下是使用 TensorFlow 和 Keras 构建简单序列到序列模型的概念性代码示例:

import tensorflow as tf
from tensorflow.keras.layers import Input, LSTM, Dense
from tensorflow.keras.models import Model

# 定义编码器
encoder_inputs = Input(shape=(None, num_encoder_tokens))
encoder = LSTM(latent_dim, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
encoder_states = [state_h, state_c]

# 定义解码器
decoder_inputs = Input(shape=(None, num_decoder_tokens))
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)

# 定义模型
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)

# 编译模型
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

# 训练模型
model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
          batch_size=batch_size,
          epochs=epochs,
          validation_split=0.2)

构建应用步骤的 mermaid 流程图

graph LR
    A[数据准备] --> B[模型选择]
    B --> C[训练或使用预训练模型]
    C --> D[应用测试与优化]
    D --> E[得到最终应用]

8. 总结与建议

8.1 激活函数选择总结

场景 推荐激活函数
一般隐藏层 ReLu
ReLu 神经元大量死亡 Leaky ReLu 或 Maxout
分类问题输出层 Softmax
回归问题输出层 线性激活函数

8.2 损失函数选择建议

问题类型 推荐损失函数
回归问题 二次成本函数(均方误差)
分类问题 交叉熵成本函数

8.3 构建应用建议

  • 在构建 ANN 或 DNN 应用时,根据问题的复杂程度和数据特点选择合适的架构和模型。
  • 对于计算资源有限的情况,可以使用预训练模型,避免从头开始训练。
  • 不断优化模型的参数和超参数,以提高模型的性能。

未来展望

深度学习在自然语言理解和生成领域已经取得了显著的成果,但仍有许多挑战和改进的空间。例如,如何提高模型的可解释性、如何更好地处理多语言和跨语言问题等。未来的研究可能会集中在开发更高效、更强大的模型架构,以及探索新的应用场景。

通过本文的介绍,你对自然语言理解与生成中的深度学习技术有了更深入的了解,包括激活函数、损失函数、ANN 和 DNN 的实现、以及如何构建 NLU 和 NLG 应用。希望这些知识能帮助你在相关领域取得更好的成果。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值