自然语言处理: 第三章NPLM(Neural Probabilistic Language Mode)

news2024/11/25 3:00:40

理论基础

NPLM的全称是"Neural Probabilistic Language Model",即神经概率语言模型。这是一种基于神经网络的语言模型,用于生成自然语言文本。最早是由Bengio 在2003年的A Neural Probabilistic Language Model一文中提出来的, NPLM通过学习文本数据的概率分布,能够预测下一个单词或字符的概率,从而生成连贯的语句或段落。这种模型在机器翻译、文本生成和自然语言处理等任务中被广泛应用。



其中NPLM主要由三部分组成:

  • 输入层将单词映射到连续的词向量空间(根据上下文信息可动态调整) , 实际就是又文本的index 转换成为embedding的过程
  • 隐藏层通过非线性激活函数学习单词间的复杂关系,其中隐藏层可以自行调整
  • 输出层通过Softmax层产生下一个单词的概率分布

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WFR9aguy-1687143723638)(image/NPLM/1686883737846.png)]



代码实现

下面是一个构建最简单的NPLM的代码实现,其流程如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nqUr6GTy-1687143723640)(image/NPLM/1686884050025.png)]

  1. 构建语料库,其实就是分词之后利用字典得到对应的index

    class Corpus():
        def __init__(self , sentences) -> None:
            self.sentences = sentences
            # 将所有句子连接在一起,用空格分隔成词汇,再将重复的词去除,构建词汇表
            self.word_list = list(set(" ".join(sentences).split()))  
            # 创建一个字典,将每个词汇映射到一个唯一的索引
            self.word_to_idx = {word: idx for idx, word in enumerate(self.word_list)} 
            # 创建一个字典,将每个索引映射到对应的词汇
            self.idx_to_word = {idx: word for idx, word in enumerate(self.word_list)}  
            self.voc_size = len(self.word_list)  # 计算词汇表的大小
            print('字典:', self.word_to_idx)  # 打印词汇到索引的映射字典
            print('字典大小:', self.voc_size)  # 打印词汇表大小 
    
  2. 生成训练数据 , 这里实现比较简单,每个句子去预测最后一个词,前面的词则都作为content

    class Corpus():
        def __init__(self , sentences) -> None:
            self.sentences = sentences
            # 将所有句子连接在一起,用空格分隔成词汇,再将重复的词去除,构建词汇表
            self.word_list = list(set(" ".join(sentences).split()))  
            # 创建一个字典,将每个词汇映射到一个唯一的索引
            self.word_to_idx = {word: idx for idx, word in enumerate(self.word_list)} 
            # 创建一个字典,将每个索引映射到对应的词汇
            self.idx_to_word = {idx: word for idx, word in enumerate(self.word_list)}  
            self.voc_size = len(self.word_list)  # 计算词汇表的大小
            print('字典:', self.word_to_idx)  # 打印词汇到索引的映射字典
            print('字典大小:', self.voc_size)  # 打印词汇表大小 
    
    
        def make_batch(self , batch_size = 3):
            input_batch = []  # 定义输入批处理列表
            target_batch = []  # 定义目标批处理列表
            selected_sentences = random.sample(self.sentences, batch_size) # 随机选择句子
            for sen in selected_sentences:  # 遍历每个句子
                word = sen.split()  # 用空格将句子分隔成词汇
                # 将除最后一个词以外的所有词的索引作为输入
                input = [self.word_to_idx[n] for n in word[:-1]]  # 创建输入数据
                # 将最后一个词的索引作为目标
                target = self.word_to_idx[word[-1]]  # 创建目标数据
                input_batch.append(input)  # 将输入添加到输入批处理列表
                target_batch.append(target)  # 将目标添加到目标批处理列表
            input_batch = torch.LongTensor(input_batch) # 将输入数据转换为张量
            target_batch = torch.LongTensor(target_batch) # 将目标数据转换为张量
            return input_batch, target_batch  # 返回输入批处理和目标批处理数据
    
  3. 定义NPLM模型, 这里定义了一个比较简单的隐藏层为N层的LSTM 以及 GRU 网络 , 其中batch_first 设置为true的话,输出的tensor的格式为(batch , seq , feature) 反之则为输出的tensor的格式为(seq, batch , feature) 。 其次, voc_size的意思是词表大小, embedding_size是嵌入层的大小 , n_hidden 代表的是隐藏层的大小 , num_layers 代表的是RNN网络的层数。

    class Lstm(nn.Module):
        def __init__(self , voc_size , embedding_size , n_hidden , num_layers):
            super(Lstm, self).__init__()
            self.embedding = nn.Embedding(voc_size, embedding_size)
            self.lstm = nn.LSTM(embedding_size, n_hidden, num_layers ,  batch_first=True)
            self.linear = nn.Linear(n_hidden, voc_size)
    
        def forward(self, X):
            X = self.embedding(X)
            lstm_out, _ = self.lstm(X)
            output = self.linear(lstm_out[:, -1, :])  # 只选择最后一个时间步的输出作为全连接层的输入
            return output
    
    class Gru(nn.Module):
        def __init__(self , voc_size , embedding_size , n_hidden , num_layers):
            super(Gru, self).__init__()
            self.embedding = nn.Embedding(voc_size, embedding_size)
            self.gru = nn.GRU(embedding_size, n_hidden, num_layers , batch_first=True)
            self.linear = nn.Linear(n_hidden, voc_size)
    
        def forward(self, X):
            X = self.embedding(X)
            lstm_out, _ = self.gru(X)
            output = self.linear(lstm_out[:, -1, :])  # 只选择最后一个时间步的输出作为全连接层的输入
            return output
    
  4. 实例化模型, 这里因为涉及两个隐层模式(lstm 以及gru), 如果需要哪个注释掉就行。

        # model = Lstm( voc_size ,  embedding_size, n_hidden , num_layers) # 创建神经概率语言模型实例
        model = Gru(voc_size ,  embedding_size, n_hidden , num_layers)
        print('RNN模型结构:', model)  # 打印模型的结构
    
  5. 训练

    def train(model , corpus , lr):
        criterion = nn.CrossEntropyLoss() # 定义损失函数为交叉熵损失
        optimizer = optim.Adam(model.parameters(), lr= lr) # 定义优化器为Adam,学习率为0.1
        # 训练模型
        for epoch in range(5000): # 设置训练迭代次数
            optimizer.zero_grad() # 清除优化器的梯度
            input_batch, target_batch = corpus.make_batch() # 创建输入和目标批处理数据
            output = model(input_batch) # 将输入数据传入模型,得到输出结果
            # output的形状为 [batch_size, n_class],target_batch的形状为 [batch_size]
            loss = criterion(output, target_batch) #计算损失值
            if (epoch + 1) % 1000 == 0: # 每1000次迭代,打印损失值
                print(f"Epoch: {epoch + 1:04d} cost = {loss:.6f}") 
            loss.backward() # 反向传播计算梯度
            optimizer.step() # 更新模型参数
    
        return model
    
  6. 做inference

def test(input , corpus , model):
    # 将输入序列转换为对应的索引
    input_indices = [[corpus.word_to_idx[word] for word in seq] for seq in input]  
    input_tensor = torch.LongTensor(input_indices)  # 将输入序列的索引转换为张量
    # 对输入序列进行预测,取输出中概率最大的类别
    predict = model(input_tensor).data.max(1)[1]  
    # 将预测结果的索引转换为对应的词汇
    predict_strs = [corpus.idx_to_word[n.item()] for n in predict.squeeze()]  
    for input_seq, pred in zip(input, predict_strs):
        print(input_seq, '->', pred)  # 打印输入序列和预测结果



结果

整体实验结果如下:

在这里插入图片描述

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

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

相关文章

卖家必读,深入了解亚马逊,速卖通,temu测评补单方式的各种利弊

大部分人对补单的认识还停留在刷好评、信誉上,事实上,信誉等级和好评仅是补单的目标之一,不是目标的全部。 对于一个真正的老手来说,补单真正的目的是提升自己宝贝的权重和搜索排名。因为信誉等级和好评相对来说比较简单。 我们试…

从零开始 Spring Boot 43:DI 注解

从零开始 Spring Boot 43:DI 注解 图源:简书 (jianshu.com) Spring 通过注解实现 DI(依赖注入),本文详细讨论这些注解。 Autowired Autowired是 Spring 定义的注解,属于包org.springframework.beans.fac…

【无标题】AI+电力、大模型主题人工智能师资培训班重磅招募中

大语言模型热度空前,诸如文心一言、ChatGPT 等已经能够与人对话互动、回答问题、协助创作,逐渐应用于人们的工作和生活,也引发了社会热议。人工智能赋能新型电力系统下新能源发电、变电、调度、配网、安监、营销、基建以及企业经营管理等领域…

强化学习从基础到进阶-案例与实践[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验

【强化学习原理项目专栏】必看系列:单智能体、多智能体算法原理项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍:【强化学习原理项目专栏】必看系列:单智能体、多智能体算法原理项目实战、相关技巧…

MySQL数据库的高级操作

数据表高级操作 一、克隆表,将数据表的数据记录生成到新的表中方法一方法二 二、清空表,删除表内的所有数据方法一方法二 三、创建临时表四、创建外键约束,保证数据的完整性和一致性。1、外键的定义2、主键表和外键表的理解3、MySQL中6种常见…

盘点一个Python自动化办公案例分享

背景:某公司需要对某一款产品的销售情况进行跟踪和分析,分析需求包括必要的统计图表生成,数据分析,生成报告等操作。 解决方案:利用 Python 编写自动化程序,实现对该产品的销售数据自动抓取,数据…

【python+Coppeliasim】仓储机器人

一、仓储机器人介绍 仓储机器人(也称为自动导航AGV,Automated Guided Vehicle)是一种智能机器人系统,专门设计用于在仓库、物流中心和制造业等环境中执行货物搬运和物流任务。它们被广泛应用于自动化仓储和物流管理系统中&#xf…

详解HTTP协议和HTTPS协议

目录 一.HTTP协议 1.什么是HTTP 2.HTTP发展历史 3.HTTP请求和响应 4. 抓包的方式和工具Fiddler 1.开发者工具 2.Fiddler 二.请求和响应 1.请求和响应报文 2.URL结构 3.常见的方法 1.GET方法 2.POST方法 3.其他方法 三.请求报头(header) 1.Host 2.Content-Length 3.Co…

Objective-C 混用UITabBar与UINavigation

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 混用UITabBar与UINavigation做app,tab和nav,有时候显示有时候…

有关浪涌保护器参数科普

浪涌保护器(SPD)或简称电涌保护器是一种用于确保防止瞬态浪涌的设备。它用于保护家庭和商业应用免受电压瞬变的影响。它与必须保护的负载并联连接。 什么是瞬态浪涌? 瞬态浪涌是持续几微秒的功率(电压和电流)的突然增…

CleanMyMac X4.13.6电脑清理垃圾最干净的软件

CleanMyMac是一款Mac清理工具,MacOSX系统下知名系统清理软件,它可以流畅地与系统性能相结合,只需简单的步骤就可以节省硬盘空间,提高电脑的运行速度,时刻保持电脑的清洁和健康,监视和优化Mac的性能。 现在…

高可用数据库集群mariadb(mysql)

一、概述 是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件 二、端口号 22 三、高可用MHA简述 目前在mysql高可用方面是一个成熟的方案,是一套优秀的高可用环境下故障切…

在用户界面线程上等待的危险性

我们做这么一个假设哈。 如果有一个线程,它拥有一个窗口,则在这个线程的整个运行过程中,我们都不应该调用 Sleep 函数。为什么? 因为 Sleep 调用会导致线程在睡眠等待期停止处理窗口消息。即使对于持续时间较短的睡眠也是如此&a…

【正点原子STM32连载】 第三十三章 DAC实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1)实验平台:正点原子stm32f103战舰开发板V4 2)平台购买地址:https://detail.tmall.com/item.htm?id609294757420 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html# 第三…

亚马逊云服务器EC2开通Windows系统实例和远程RDP连接远程桌面

在这篇文章中,我们准备详细的亲测记录开通亚马逊云服务器EC2开通Windows系统。这里需要提醒的是,如果我们是初次免费体验亚马逊云服务器账户的话,是有支持单个云服务器750小时免费,如果我们超过部分是需要支付的,所以如…

探究贴纸滤镜和美颜SDK的技术实现原理

在移动应用高需求的背景下,贴纸滤镜和美颜SDK成为了移动应用中不可或缺的功能之一。那么,这些功能是如何实现的呢?本文将探究贴纸滤镜和美颜SDK的技术实现原理。 一、贴纸滤镜的技术实现原理 贴纸滤镜是一种可以在图片或视频上添加贴纸、滤镜…

1、DuiLib的编译和运行

文章目录 1、原生DuiLib的编译和运行1.1、下载并解压成这个样子1.2、打开.sln解决方案文件1.3、编译成功 2、网易DuiLib编译和运行2.1、下载并解压成这个样子2.2、打开.sln解决方案文件2.3、编译成功 3、腾讯DuiLib编译和运行vs 20173.1、下载并解压成这个样子3.2、打开.sln解决…

个人IP打造全过程:如何打造出属于自己的个人IP?

随着互联网的快速发展,个人IP已经逐渐成为一个热门话题。拥有自己的个人IP可以为你带来更多的机会和收益,让你在竞争激烈的市场中脱颖而出。但是,要想打造自己的个人IP并不是一件容易的事情。本文将为你介绍如何打造属于自己的个人IP。#IP# 一…

Burp Suite 功能详解(渗透测试工具)

一、抓包。 找到 代理--拦截--打开自带浏览器(这里也可以自己找扩展设置代理,但还要添加安全证书等等,我觉得太麻烦了,还不如直接使用Burp Suite自带的浏览器抓包)。 这是Burp Suite自带网页的页面。 点击开启拦截。 …