「X」Embedding in NLP|神经网络和语言模型 Embedding 向量入门

news2024/11/19 3:30:56

在「X」Embedding in NLP 进阶系列中,我们介绍了自然语言处理的基础知识——自然语言中的 Token、N-gram 和词袋语言模型。今天,我们将继续和大家一起“修炼”,深入探讨神经网络语言模型,特别是循环神经网络,并简要了解如何生成 Embedding 向量。

01.深入了解神经网络

首先,简要回顾一下神经网络的构成,即神经元、多层网络和反向传播算法。如果还想更详细深入了解这些基本概念可以参考其他资源,如 CS231n 课程笔记。

在机器学习中,神经元是构成所有神经网络的基本单元。本质上,神经元是神经网络中的一个单元,它对其所有输入进行加权求和,并加上一个可选的偏置项。方程式表示如下所示:

在这里, x 0 , x 1 , . . . , x n − 1 代表上一层神经元的输出, w 0 , w 1 , . . . , w n − 1 代表这个神经元用来综合输出值的权重。

如果一个多层神经网络仅由上述方程中的加权和组成,我们可以将所有项合并为一个单一的线性层——这对于建模 Token 之间的关系或编码复杂文本并不是很理想。这就是为什么所有神经元在加权和之后都包含一个非线性激活函数,其中我们最熟知的例子就是修正线性单元(ReLU)函数:

对于大多数现代神经网络语言模型来说,高斯误差线性单元(GELU)激活函数更常见:

在这里, Φ q 代表高斯累积分布函数,可以用 G E L U ( q ) ≈ q 1 + e − 1.702 q 来表示。这个激活函数在上述的加权求和之后被应用。总而言之,一个单一的神经元看起来像这样:

alt

为了学习更复杂的函数,我们可以将神经元堆叠起来——一个接一个地形成一个层。同一层中的所有神经元接收相同的输入;它们之间唯一的区别是权重 w 和偏置 b 。我们可以用矩阵符号将上述方程表示一个单层:

在这里, w 是一个二维矩阵,包含应用于输入 x 的所有权重;矩阵的每一行对应一个神经元的权重。这种类型的层通常被称为密集层或全连接层,因为所有输入 x 都连接到所有输出 y

我们可以将这两个层串联起来,创建一个基本的前馈网络:

alt
h 1 = G E L U ( W 1 x + b 1 ) y = G E L U ( W 2 h 1 + b 2 )

这里我们引入了一个新的隐藏层 h1,它既没有直接连接到输入 x ,也没有直接连接到输出 y 。这一层有效地增加了网络的深度,增加了总的参数数量(多个权重矩阵 w )。此时,需要注意:随着添加的隐藏层增多,靠近输入层的隐藏值(激活值)与 x 更“相似”,而靠近输出的激活值则与 y 更相似。

我们在后续的文章中将基于这个原则探讨 Embedding 向量。隐藏层的概念对理解向量搜索至关重要。

前馈网络中单个神经元的参数可以通过一个称为反向传播的过程进行更新,本质上就是微积分中链式法则的重复应用。大家可以搜索一些专门讲解反向传播的课程,这些课程会介绍反向传播为什么对训练神经网络如此有效。这里我们不多做赘述,其基本过程如下所示:

  1. 通过神经网络输入一批数据。

  2. 计算损失。这通常是回归的 L2 损失(平方差)和分类的交叉熵损失。

  3. 使用这个损失来计算与最后一个隐藏层权重的损失梯度 ∂ Λ ∂ W n 。

  4. 计算通过最后一个隐藏层的损失,即 ∂ Λ ∂ h n − 1 。

  5. 将这个损失反向传播到倒数第二个隐藏层的权重 ∂ Λ ∂ W n − 1 。

  6. 重复步骤 4 和 5,直到计算出所有权重的偏导数。

在计算出与网络中所有权重相关的损失的偏导数后,可以根据优化器和学习率进行一次大规模的权重更新。这个过程会重复进行,直到模型达到收敛或所有轮次都完成。

02.循环神经网络

所有形式的文本和自然语言本质上都是顺序性的,也就是说单词 /Token 是一个接一个地处理的。看似简单的变化,比如增加一个单词、颠倒两个连续的 Token,或增加标点符号,都可能导致解释上的巨大差异。例如,“let's eat, Charles”和“let's eat Charles”两个短语完全是两回事。由于自然语言具备顺序性这一特性,因此循环神经网络(RNNs)是自然而然成为了语言建模的不二之选。

递归是一种独特的递归形式,其中函数是神经网络而不是代码。RNN 还有着生物学起源——人类大脑可以类比为一个(人工)神经网络,我们输入的单词或说出的话语都是生物学处理的结果。

RNN 由两个组成部分:1)一个标准的前馈网络和2)一个递归组件。前馈网络与我们在前一节中讨论的相同。对于递归组件,最后一个隐藏状态被反馈到输入中,以便网络可以保持先前的上下文。因此,先前的知识(以前一个时间步的隐藏层的形式)在每一个新的时间步被注入网络。

alt

基于上述对 RNN 的宏观定义和解释,我们可以大致了解其实现方式以及为什么 RNN 在语义建模时表现良好。

首先,RNN 的循环结构使它们能够根据顺序捕捉和处理数据,其数据处理方式类似于人类说话、阅读和写作方式。此外,RNN 还可以有效访问来自较早时间的“信息”,比 n-gram 模型和纯前馈网络更能理解自然语言。

大家可以试试用 PyTorch 来实现一个 RNN。注意,这需要对 PyTorch 基础有深入的理解;如果对 PyTorch 还不太熟悉 ,建议大家先阅读该链接。

首先定义一个简单的前馈网络,然后将其扩展为一个简单的 RNN,先定义层:

from torch import Tensor
import torch.nn as nn
class BasicNN(nn.Module):    
   def __init__(self, in_dims: int, hidden_dims: int, out_dims: int):        
       super(BasicNN, self).__init__()        
       self.w0 = nn.Linear(in_dims, hidden_dims)
       self.w1 = nn.Linear(hidden_dims, out_dims)

注意,由于我们仅仅输出原始的逻辑值,我们还没有定义损失的样式。在训练时,可以根据实际情况加上某种标准,比如 nn.CrossEntropyLoss

现在,我们可以实现前向传递:

    def forward(self, x: Tensor):
        h = self.w0(x)
        y = self.w1(h)
        return y

这两段代码片段结合在一起形成了一个非常基础的前馈神经网络。为了将其变成 RNN,我们需要从最后一个隐藏状态添加一个反馈回路回到输入:

    def forward(self, x: Tensor, h_p: Tensor):
        h = self.w0(torch.cat(x, h_p))        
        y = self.w1(h)        
        return (y, h)

上述基本上就是全部步骤。由于我们现在增加了由 w0 定义的神经元层的输入数量,我们需要在 __init__中更新它的定义。现在让我们来完成这个操作,并将所有内容整合到一个代码片段中:

import torch.nn as nn
from torch import Tensor

class SimpleRNN(nn.Module):
    def __init__(self, in_dims: int, hidden_dims: int, out_dims: int):
        super(RNN, self).__init__()
        self.w0 = nn.Linear(in_dims + hidden_dims, hidden_dims)
        self.w1 = nn.Linear(hidden_dims, out_dims)
        
    def forward(self, x: Tensor, h_p: Tensor):
        h = self.w0(torch.cat(x, h_p))
        y = self.w1(h)
        return (y, h)

在每次前向传递中,隐藏层h的激活值与输出一起返回。这些激活值随后可以与序列中的每个新 Token一起再次传回模型中。这样一个过程如下所示(以下代码仅作示意):

model = SimpleRNN(n_in, n_hidden, n_out)

...

h = torch.zeros(1, n_hidden)
for token in range(seq):
    (out, h) = model(token, )

至此,我们成功定义了一个简单的前馈网络,并将其扩展为一个简单的 RNN。

03.语言模型 Embedding

我们在上面例子中看到的隐藏层有效地将已经输入到 RNN 的所有内容(所有 Token)进行编码。更具体而言,所有解析 RNN 已看到的文本所需的信息应包含在激活值 h 中。换句话说,h 编码了输入序列的语义,而由 h 定义的有序浮点值集合就是 Embedding 向量,简称为 Embedding。

这些向量表示广泛构成了向量搜索和向量数据库的基础。尽管当今自然语言的 Embedding 是由另一类称为 Transformer 的机器学习模型生成的,而不是 RNN,但本质概念基本相同:将文本内容编码为计算机可理解的 Embedding 向量。我们将在下一篇博客文章中详细讨论如何使用 Embedding 向量。

04.总结

我们在 PyTorch 中实现了一个简单的循环神经网络,并简要介绍了语言模型Embedding。虽然循环神经网络是理解语言的强大工具,并且可以广泛应用于各种应用中(机器翻译、分类、问答等),但它们仍然不是用于生成 Embedding 向量的 ML 模型类型。

在接下来的教程中,我们将使用开源的 Transformer 模型来生成 Embedding 向量,并通过对它们进行向量搜索和运算来展示向量的强大功能。此外,我们也将回到词袋模型的概念,看看这两者如何一起用于编码词汇和语义。敬请期待!

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1313691.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【postgresql】ERROR: INSERT has more expressions than target columns

执行下面sql insert into apply_account_cancellation3 select * from pply_account_cancellation; 返回下面错误信息 insert into apply_account_cancellation3 select * from apply_account_cancellation > ERROR: INSERT has more expressions than target colu…

ShardingSphereJDBC简单入门

ShardingSphere 介绍ShardingSphere-JDBCSharding-Sphere-ProxyShardingSphere-Sidecar混合架构运行模式DistSQL可拔插架构ShardingSphere的发展路线 主从复制ShardingSphere-JDBC功能SQL解析SQL支持程度SQL稳定支持SQL实验性支持 MySQL不支持SQL清单分页 数据分片垂直分片水平…

世界5G大会

会议名称:世界 5G 大会 时间:2023 年 12 月 5 日-12 月 8 日 地点:河南郑州 一、会议简介 世界 5G 大会,是由国务院批准,国家发展改革委、科技部、工 信部与地方政府共同主办,未来移动通信论坛联合属地主管厅局联合 承办,邀请全球友好伙伴共同打造的全球首个 5G 领域…

KITTI数据集处理为COCO数据集格式

KITTI作为自动驾驶常用数据集,被广泛的应用于自动驾驶目标检测等过程中。 首先是数据集类别合并,原始的KITTI数据集有九个类别,分别是: Car Van Truck Pedestrian Person_sitting Cyclist Tram Misc而我们在使用过程中&#xff0…

使用@ApiModel和@ApiModelProperty的技巧

在现代软件开发中,提供清晰全面的 API 文档 至关重要。ApiModel 和 ApiModelProperty 这样的代码注解在此方面表现出色,通过增强模型及其属性的元数据来丰富文档内容。它们的主要功能是为这些元素命名和描述,使生成的 API 文档更加明确。 Api…

Python Flask-Admin: 构建强大的 Flask 后台管理

概要 Flask-Admin 是一个基于 Flask 的后台管理框架,它提供了丰富的功能和灵活性,使得开发者能够轻松构建功能强大的后台管理系统。在本文中,我们将详细介绍 Flask-Admin 的安装、配置和使用,通过深入的示例代码演示其主要特性。…

【改进YOLOv8】生猪胖瘦评价分级系统:可重参化EfficientRepBiPAN优化Neck

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义: 随着计算机视觉和深度学习的快速发展,目标检测成为了计算机视觉领域的一个重要研究方向。目标检测的目标是在图像或视频中准确地识别和定…

LiteClient工具箱:降低成本,减少监管风险

​​发表时间:2023年9月14日 BSV区块链协会的工程团队一直在为即将推出的LiteClient而努力工作,这是一套模块化的组件,可使简易支付验证(SPV)变得更加便利。 借助LiteClient工具箱,交易所可以通过区块头中…

【学习笔记】JavaScript中的GC算法

1、内存管理 内存:由可读写单元组成,标识一片可操作的空间 管理: 认为的去操作一篇空间的申请、使用和释放 内存管理:开发者主动申请空间、使用空间、释放空间 管理流程: 申请-使用-释放 // 申请 let obj {} //使…

【电路笔记】-电容器

电容器 文章目录 电容器1、概述2、电容器的电容单位3、电容4、电容器示例15、电介质6、额定电压7、总结 电容器是简单的无源器件,当连接到电压源时,可以在极板上存储电荷。 1、概述 在本电容器简介文章中,我们将看到电容器是无源电子元件&am…

采埃孚4D成像雷达拆解

1 基本信息 品牌:海外Tier1采埃孚 • 应用:上汽飞凡中高端纯电平台 • 数量:单车2个,安装在前后保内部 • 最远探测距离:350米 拆解来看,4D雷达主要可以分为4个部分,分别为数字接口板及结构件…

从Aspera到这些替代方案,下载大文件再也不用等待了

在过去,下载大文件往往需要漫长的等待时间,甚至可能会超过数小时或数天。为了解决这个问题,IT行业一直在努力研发新的下载技术和工具,以提高下载速度和效率。本文将深入探讨Aspera替代方案,如何让用户在下载大文件时不…

C# WPF上位机开发(网络程序界面开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 之前我们讨论过,设备之间通讯的方式很多。但是,不知道大家有没有注意,前面谈到的这些通讯方式都需要上位机电脑…

4.electron之create-react-app的桌面应用程序

如果可以实现记得点赞分享,谢谢老铁~ Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 将 Chromium 和 Node.js 嵌入到了一个二进制文件中,因此它允许你仅需一个代码仓库,就可以撰写支持 Windows、…

typescript个人学习笔记

https://ts.xcatliu.com/basics/primitive-data-types.html 深受启发 1.剑谱第一页,初始化ts outDir表示把ts编译成js文件,文件编译后存放的位置 2.类型声明 基础数据五种 undefined可以赋值给其他类型引用类型数组对象 //定义数组一 let arr:[][]…

基于SSM的实践项目管理系统设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

电商控制台前台整合优化

前台逻辑 显示商品菜单输入id,进入某个商品检测登录和注册 根据登录和注册的状态,订单或者是购物车都需要登录。 登录:生成订单(先生成订单表,再生成订单详情表) 开发直接购买,加入购物车, …

基于SSM的志愿者管理系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

多用户商城系统哪种好用

多用户商城系统是一种能快速打造类似京东、天猫的商户入驻型平台系统,它一般有三种模式: 1、招商模式 商户入驻,平台收取入驻费及年费,平台做中介的模式,成交抽取服务佣金,这是一般的多用户商城的模式&…

web微服务规划

一、背景 通过微服务来搭建web系统,就要对微服务进行规划,包括服务的划分,每个服务和数据库的命名规则,服务用到的端口等。 二、微服务划分 1、根据业务进行拆分 如: 一个购物系统可以将微服务拆分为基础中心、会员…