当前位置: 首页 > news >正文

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

在「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 多平台发布

相关文章:

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

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

JVM-11-运行时栈帧结构

“栈帧”(Stack Frame)则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈(Virtual MachineStack)的栈元素。 栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回…...

【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! X的平方根 class Soluti…...

【大麦小米学量化】使用xtquant调用迅投MiniQMT客户端定时操作逆回购,再也不担心忘了赚零花钱了(含完整源代码)

文章目录 前言一、逆回购是什么?1. 什么是逆回购?2. 最低参与金额是多少?3. 逆回购交易是否安全?4. 逆回购交易适合什么类型的客户? 二、讯投XtQuant是什么?1. XtQuant运行依赖环境2. XtQuant运行逻辑 三、…...

php hyperf 读取redis,存储到数据库

背景说明 小白:伟哥,java中的set是无序的,Redis中可以带顺序吗? 伟哥:可以, 不过不叫set了,叫zset。 概述 SortedSet又叫zset,它是Redis提供的特殊数据类型,是一种特殊…...

云原生之深入解析K8S 1.27新特性如何简化状态服务跨集群平滑迁移

一、背景 Kubernetes v1.26 为 StatefulSet 引入了一个新的 Alpha 级别特性,可以控制 Pod 副本的序号。从 Kubernetes v1.27 开始,此特性进级到 Beta 阶段。序数可以从任意非负数开始, 那么该如何使用此功能呢?StatefulSet 序号为…...

鸿蒙OS:打破界限的操作系统新星

导言 鸿蒙OS(HarmonyOS)是华为公司为应对技术封锁而推出的分布式操作系统,其背后蕴含着华为构建全球数字生活愿景的雄心。本文将深入剖析鸿蒙OS的起源、核心特性,并展望其未来在数字生态中的角色。 1. 背景与起源 华为的…...

预测性维护在汽车制造行业中的应用

汽车制造行业是一个高度复杂和精细化的领域,依赖于各种设备来完成生产流程。这些设备包括机械装配线、焊接机器人、喷涂设备、传送带等。然而,这些设备在长时间运行中不可避免地会遇到各种故障,给生产进程带来延误和成本增加。为了应对这一挑…...

分布式链路追踪 —— 基于Dubbo的traceId追踪传递

文章目录 原文链接RpcContext 上下文对象Dubbo 过滤器(Filter)对象基于Dubbo的traceId追踪传递实现 原文链接 RpcContext 上下文对象 在实现 Dubbo 调用之间的链路跟踪之前,先简单了解 RpcContext 上下文对象和 Filter 过滤器对象&#xff…...

【uniapp小程序-上拉加载】

在需要上拉加载的页面的page.json上添加红框框里面的 onReachBottom() {if(this.commentCurrent<this.commentTotal){this.commentCurrent 1; this.commentList();this.status loading;}else{this.status ;} }, methods:{commentList(){let params {courseid:this.cour…...

ubuntu添加路由

ip route show 查看当前路由表 sudo ip route add /mask via 添加一条路由 目标ip 1.1.1.1/100 下一跳 2.2.2.2 sudo ip route add 1.1.1.1/100 via 2.2.2.2 dev ens160 proto static metric 100这是一条Linux命令&#xff0c;用于添加一个静态路由。具体含义如下&#xff1…...

python图像二值化处理

目录 1、双峰法 2、P参数法 3、迭代法 4、OTSU法 图像的二值化处理是将图像上的像素点的灰度值设置为0或255&#xff0c;也就是将整个图像呈现出明显的只有黑和白的视觉效果。二值化是图像分割的一种最简单的方法&#xff0c;可以把灰度图像转换成二值图像。具体实现是将大…...

4.配置系统时钟思路及方法

前言&#xff1a; 比起之前用过的三星的猎户座4412芯片&#xff0c;STM32F4的系统时钟可以说是小巫见大巫&#xff0c;首先我们需要清晰时钟产生的原理&#xff1a;几乎大多数的芯片都是由晶振产生一个比较低频的频率&#xff0c;然后通过若干个PLL得到单片机能承受的频率&…...

使用openMVS库,在VS2022中启用c++17标准编译仍然报错

使用openMVS库&#xff0c;在VS2022中启用c17标准编译仍然报错 现象 项目中引用了某些开源库&#xff08;例如openmvs2.1.0&#xff09;&#xff0c;编译时要求启用编译器对c17的支持。 没问题&#xff01;大家都知道在下图所示的位置调整C语言标准&#xff1a; 但是&#…...

uniGUI之上传文件UniFileUploadButton

TUniFileUploadButton主要属性&#xff1a; Filter: 文件类型过滤&#xff0c;有图片image/* audio/* video/*三种过滤 MaxAllowedSize: 设置文件最大上传尺寸&#xff1b; Message&#xff1a;标题以及消息文本&#xff0c;可翻译成中文 TUniFileUploadButton控件 支持多…...

福德植保无人机工厂:创新科技与绿色农业的完美结合

亲爱的读者们&#xff0c;欢迎来到福德植保无人机工厂的世界。这里&#xff0c;科技与农业的完美结合为我们描绘出一幅未来农业的新篇章。福德植保无人机工厂作为行业的领军者&#xff0c;以其领先的无人机技术&#xff0c;创新的理念&#xff0c;为我们展示了一种全新的农业服…...

JsRpc技术服务搭建,最简单的JSRPC,Flask+undetected-chromedriver

只需10来行代码快速实现JSRpc&#xff0c;最简单的JSRPC 使用Flask和undetected-chromedriver快速实现JsRpc 推荐Python版本3.7.x及以上&#xff0c;需要pip安装 pip install Flask pip install undetected-chromedriver __author__ jiuLiang __email__ "jiuliangef…...

<优化接口设计的思路>:接口安全

前言 一、接口安全的方式   1. 身份认证&#xff0c;鉴别客户端   2. 请求过程鉴权&#xff0c;防止请求被篡改   3. 访问控制&#xff0c;即控制客户端对API的访问权限 前言 某家电商平台上&#xff0c;用户可以通过客户端发起购物请求&#xff0c;并对所选商品进行下…...

Gitee基础知识

目录 1-gitee 1.1gitee介绍 1.2git与gitee的关系 1.3在国内为什么选择Gitee 2-注册与创建远程仓库 2.1注册 2.2创建远程仓库 2.3配置ssh公钥 2.3.1公钥的生成方法&#xff1a; 2.3.2 在gitee中配置公钥 2.3.4验证公钥 3-添加与推送远程仓库master 3.1基本命令…...

网络空间搜索引擎- FOFA的使用技巧总结

简介 FOFA是一款网络空间测绘的搜索引擎&#xff0c;旨在帮助用户以搜索的方式查找公网上的互联网资产。 FOFA的查询方式类似于谷歌或百度&#xff0c;用户可以输入关键词来匹配包含该关键词的数据。不同的是&#xff0c;这些数据不仅包括像谷歌或百度一样的网页&#xff0c;还…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...