《动手学深度学习 Pytorch版》 9.5 机器翻译与数据集

机器翻译(machine translation)指的是将序列从一种语言自动翻译成另一种语言,基于神经网络的方法通常被称为神经机器翻译(neural machine translation)。

import os
import torch
from d2l import torch as d2l

9.5.1 下载和预处理数据集

“Tab-delimited Bilingual Sentence Pairs”数据集是由双语句子对组成的“英-法”数据集,数据集中的每一行都是制表符分隔的文本序列对,序列对由英文文本序列和翻译后的法语文本序列组成。请注意,每个文本序列可以是一个句子,也可以是包含多个句子的一个段落。在这个将英语翻译成法语的机器翻译问题中,英语是源语言(source language), 法语是目标语言(target language)。

#@save
d2l.DATA_HUB['fra-eng'] = (d2l.DATA_URL + 'fra-eng.zip','94646ad1522d915e7b0f9296181140edcf86a4f5')#@save
def read_data_nmt():"""载入“英语-法语”数据集"""data_dir = d2l.download_extract('fra-eng')with open(os.path.join(data_dir, 'fra.txt'), 'r',encoding='utf-8') as f:return f.read()raw_text = read_data_nmt()
print(raw_text[:75])
Downloading ..\data\fra-eng.zip from http://d2l-data.s3-accelerate.amazonaws.com/fra-eng.zip...
Go.	Va !
Hi.	Salut !
Run!	Cours !
Run!	Courez !
Who?	Qui ?
Wow!	Ça alors !

原始文本数据需要经过几个预处理步骤,例如:

  • 用空格代替不间断空格(non-breaking space)

  • 使用小写字母替换大写字母

  • 在单词和标点符号之间插入空格。

#@save
def preprocess_nmt(text):"""预处理“英语-法语”数据集"""def no_space(char, prev_char):return char in set(',.!?') and prev_char != ' '# 使用空格替换不间断空格# 使用小写字母替换大写字母text = text.replace('\u202f', ' ').replace('\xa0', ' ').lower()# 在单词和标点符号之间插入空格out = [' ' + char if i > 0 and no_space(char, text[i - 1]) else charfor i, char in enumerate(text)]return ''.join(out)text = preprocess_nmt(raw_text)
print(text[:80])
go .	va !
hi .	salut !
run !	cours !
run !	courez !
who ?	qui ?
wow !	ça alors !

9.5.2 词元化

在机器翻译中更喜欢单词级词元化(最先进的模型可能使用更高级的词元化技术)。

#@save
def tokenize_nmt(text, num_examples=None):"""词元化“英语-法语”数据数据集"""source, target = [], []  # source 是源语言  target 是目标语言for i, line in enumerate(text.split('\n')):  # 按行遍历if num_examples and i > num_examples:  # 限制句子数breakparts = line.split('\t')if len(parts) == 2:source.append(parts[0].split(' '))  # 分割成词元列表target.append(parts[1].split(' '))return source, targetsource, target = tokenize_nmt(text)
source[:6], target[:6]
([['go', '.'],['hi', '.'],['run', '!'],['run', '!'],['who', '?'],['wow', '!']],[['va', '!'],['salut', '!'],['cours', '!'],['courez', '!'],['qui', '?'],['ça', 'alors', '!']])
#@save
def show_list_len_pair_hist(legend, xlabel, ylabel, xlist, ylist):"""绘制列表长度对的直方图"""d2l.set_figsize()_, _, patches = d2l.plt.hist([[len(l) for l in xlist], [len(l) for l in ylist]])d2l.plt.xlabel(xlabel)d2l.plt.ylabel(ylabel)for patch in patches[1].patches:patch.set_hatch('/')d2l.plt.legend(legend)show_list_len_pair_hist(['source', 'target'], '# tokens per sequence','count', source, target);


在这里插入图片描述

9.5.3 词表

使用单词级词元化时,词表大小将明显大于使用字符级词元化时的词表大小。为了缓解这一问题,将出现次数少于2次的低频率词元视为相同的未知(“<unk>”)词元。 除此之外还指定了额外的特定词元,例如在小批量时用于将序列填充到相同长度的填充词元(“<pad>”),以及序列的开始词元(“<bos>”)和结束词元(“<eos>”)。这些特殊词元在自然语言处理任务中比较常用。

src_vocab = d2l.Vocab(source, min_freq=2,reserved_tokens=['<pad>', '<bos>', '<eos>'])
len(src_vocab)
10012

9.5.4 加载数据集

在机器翻译中,每个样本都是由源和目标组成的文本序列对,其中的每个文本序列可能具有不同的长度,因此需要通过截断(truncation)和填充(padding)方式实现一次只处理一个小批量的文本序列。简言之就是多了截断,短了补齐。

#@save
def truncate_pad(line, num_steps, padding_token):"""截断或填充文本序列"""if len(line) > num_steps:return line[:num_steps]  # 长了截断return line + [padding_token] * (num_steps - len(line))  # 短了填充truncate_pad(src_vocab[source[0]], 10, src_vocab['<pad>'])
[47, 4, 1, 1, 1, 1, 1, 1, 1, 1]

定义 build_array_nmt 函数将文本序列转换成小批量数据集用于训练。将特定的“<eos>”词元添加到所有序列的末尾,用于表示序列的结束。

此外,还记录了每个文本序列的长度,统计长度时排除了填充词元。

#@save
def build_array_nmt(lines, vocab, num_steps):"""将机器翻译的文本序列转换成小批量"""lines = [vocab[l] for l in lines]  # 将句子中的各词元转换为下标lines = [l + [vocab['<eos>']] for l in lines]  # 添加结束符array = torch.tensor([truncate_pad(  # 分成小批量l, num_steps, vocab['<pad>']) for l in lines])valid_len = (array != vocab['<pad>']).type(torch.int32).sum(1)  # 计算长度return array, valid_len

9.5.5 整合

#@save
def load_data_nmt(batch_size, num_steps, num_examples=600):"""返回翻译数据集的迭代器和词表"""text = preprocess_nmt(read_data_nmt())  # 预处理source, target = tokenize_nmt(text, num_examples)  # 词元化src_vocab = d2l.Vocab(source, min_freq=2,  # 源语言词表reserved_tokens=['<pad>', '<bos>', '<eos>'])tgt_vocab = d2l.Vocab(target, min_freq=2,  # 目标语言词表reserved_tokens=['<pad>', '<bos>', '<eos>'])src_array, src_valid_len = build_array_nmt(source, src_vocab, num_steps)  # 源语言小批量化tgt_array, tgt_valid_len = build_array_nmt(target, tgt_vocab, num_steps)  # 目标语言小批量化data_arrays = (src_array, src_valid_len, tgt_array, tgt_valid_len)data_iter = d2l.load_array(data_arrays, batch_size)return data_iter, src_vocab, tgt_vocab
train_iter, src_vocab, tgt_vocab = load_data_nmt(batch_size=2, num_steps=8)
for X, X_valid_len, Y, Y_valid_len in train_iter:print('X:', X.type(torch.int32))print('X的有效长度:', X_valid_len)print('Y:', Y.type(torch.int32))print('Y的有效长度:', Y_valid_len)break
X: tensor([[ 39,  91,   4,   3,   1,   1,   1,   1],[139,  12,   4,   3,   1,   1,   1,   1]], dtype=torch.int32)
X的有效长度: tensor([4, 4])
Y: tensor([[ 92,  12,   5,   3,   1,   1,   1,   1],[111,   0,   4,   3,   1,   1,   1,   1]], dtype=torch.int32)
Y的有效长度: tensor([4, 4])

练习

(1)在 load_data_nmt 函数中尝试不同的 num_examples 参数值。这对源语言和目标语言的词表大小有何影响?

for num_examples in range(100, 1201, 100):train_iter, src_vocab, tgt_vocab = load_data_nmt(batch_size=2, num_steps=8, num_examples=num_examples)print(f"num_examples = {'%4d'%num_examples}      len(src_vocab) = {len(src_vocab)}      len(tgt_vocab) = {len(tgt_vocab)}")
num_examples =  100      len(src_vocab) = 40      len(tgt_vocab) = 40
num_examples =  200      len(src_vocab) = 69      len(tgt_vocab) = 67
num_examples =  300      len(src_vocab) = 102      len(tgt_vocab) = 107
num_examples =  400      len(src_vocab) = 130      len(tgt_vocab) = 125
num_examples =  500      len(src_vocab) = 159      len(tgt_vocab) = 163
num_examples =  600      len(src_vocab) = 184      len(tgt_vocab) = 201
num_examples =  700      len(src_vocab) = 208      len(tgt_vocab) = 224
num_examples =  800      len(src_vocab) = 229      len(tgt_vocab) = 250
num_examples =  900      len(src_vocab) = 249      len(tgt_vocab) = 286
num_examples = 1000      len(src_vocab) = 266      len(tgt_vocab) = 321
num_examples = 1100      len(src_vocab) = 293      len(tgt_vocab) = 359
num_examples = 1200      len(src_vocab) = 314      len(tgt_vocab) = 384

(2)某些语言(例如中文和日语)的文本没有单词边界指示符(例如空格)。对于这种情况,单词级词元化仍然是个好主意吗?为什么?

没有边界指示符不意味着没有单词,仍然是需要分词的,只是麻烦些。

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

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

相关文章

云表|低代码开发崛起:重新定义企业级应用开发

低代码开发这个概念在近年来越来越受到人们的关注&#xff0c;市场对于低代码的需求也日益增长。据Gartner预测&#xff0c;到2025年&#xff0c;75&#xff05;的大型企业将使用至少四种低代码/无代码开发工具&#xff0c;用于IT应用开发和公民开发计划。 那么&#xff0c;为什…

黑豹程序员-架构师学习路线图-百科:MVC的演变终点SpringMVC

MVC发展史 在我们开发小型项目时&#xff0c;我们代码是混杂在一起的&#xff0c;术语称为紧耦合。 如最终写ASP、PHP。里面既包括服务器端代码&#xff0c;数据库操作的代码&#xff0c;又包括前端页面代码、HTML展现的代码、CSS美化的代码、JS交互的代码。可以看到早期编程就…

【C语言】#define宏与函数的优劣对比

本篇文章目录 1. 预处理指令#define宏2. #define定义标识符或宏&#xff0c;要不要最后加上分号&#xff1f;3.宏的参数替换后产生的运算符优先级问题3.1 问题产生3.2 不太完美的解决办法3.3 完美的解决办法 4.#define的替换规则5. 有副作用的宏参数6. 宏与函数的优劣对比6.1 宏…

向量数据库Transwarp Hippo1.1多个新特性升级,帮助用户实现降本增效

例如,当查询“A公司业务发展情况”时,通过向量检索可以检索出A公司“主要业务”、“经营模式”、“财务情况”、“市场地位”等信息,通过全文检索可以检索出知识库中和关键字“业务”、“发展”相关的结果作为补充,通过将两者检索的结果进行结合,可以使得大模型回答的结果…

438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 输入: s "cbaebabacd", p "…

分类预测 | Matlab实现WOA-GRU鲸鱼算法优化门控循环单元的数据多输入分类预测

分类预测 | Matlab实现WOA-GRU鲸鱼算法优化门控循环单元的数据多输入分类预测 目录 分类预测 | Matlab实现WOA-GRU鲸鱼算法优化门控循环单元的数据多输入分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现WOA-GRU鲸鱼算法优化门控循环单元的数据多输入…

【Qt】常见控件

文章目录 按钮组QListWidget列表容器TreeWidget树控件TableWidget 表格控件其它控件介绍下拉框QLabel显示图片和动图 自定义控件封装 按钮组 QPushButton 常用按钮 QToolButton 工具按钮&#xff1a; 用于显示图片 如果想显示文字&#xff1a;修改风格&#xff1a;toolButto…

文档外发控制与安全:实现高效协作与数据安全的关键

随着企业数据量的不断增加&#xff0c;文档外发成为了一个不可避免的需求。然而&#xff0c;很多企业在文档外发过程中存在着很多问题&#xff0c;如数据泄露、信息误用等。因此&#xff0c;如何保证文档外发的安全性和高效性成为了企业亟待解决的问题。飞驰云联Ftrans的文件收…

Kafka Tool(Kafka 可视化工具)安装及使用教程

Kafka Tool&#xff08;Kafka 可视化工具&#xff09;安装及使用教程 Kafka Tool 工具下载 下载地址 http://www.kafkatool.com/download.html 下载界面 不同版本的Kafka对应不同版本的工具&#xff0c;个人使用的是2.11&#xff0c;所以下载的是最新的2.0.8版本&#xff…

C++初阶--C++入门(2)

C入门&#xff08;1&#xff09;链接入口 文章目录 内联函数auto关键字注意事项 基于范围的for循环(C11)nullptr 内联函数 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调用建立栈帧的开销&#xff0c;内联函数提…

Spring学习笔记(2)

Spring学习笔记&#xff08;2&#xff09; 一、Spring配置非定义Bean1.1 DruidDataSource1.2、Connection1.3、Date1.4、SqlSessionFactory 二、Bean实例化的基本流程2.1 BeanDefinition2.2 单例池和流程总结 三、Spring的bean工厂后处理器3.1 bean工厂后处理器入门3.2、注册Be…

Flutter的Invalid use of a private type in a public API警告

文章目录 问题描述有问题的源码 问题原因解决方法 问题描述 自己在写Flutter 应用时发现了一个Invalid use of a private type in a public API警告。 发现很多官方的例子也有这个问题。 有问题的源码 有问题的源码如下&#xff1a; class MyTabPage extends StatefulWid…

【Linux学习笔记】代码编辑工具vim

1. vim工具基本模式的转换2. vim命令模式下的各种编辑命令2.1. 光标行定位2.2. 光标自由定位2.3. 复制粘贴2.4. 删除2.5. 文本的大小写替换2.6. 文本的替换2.7. 文本的前删后删2.8. 撤销操作 3. vim底行模式下的命令3.1. 设置行号与取消设置行号3.2. 分屏操作3.3. 在不退出vim的…

【Mac使用技巧】Mac和iPhone间接力功能失效解决总结

问题 Mac OS升级到Monterey版本后&#xff0c;遇到iPhone复制内容后&#xff0c;在Mac无法接力粘贴&#xff0c;此时“接力”功能失效了。 解决过程 参考官网接力功能配置说明 1、重启Mac和iPhone&#xff0c;仍无法接力粘贴 2、重新登录2台设备的iCloud&#xff0c;仍无法…

01、Python 安装 ,Pycharm 安装

目录 安装安装 Python安装 Pycharm 创建项目简单添加文件运行 简单爬取下载小视频 安装 python-3.8.10-amd64.exe – 先安装这个 pycharm-community-2022.2.exe 再安装这个 安装 Python python-3.8.10-amd64.exe 安装&#xff08;这个是其他版本的安装&#xff0c;步骤一样…

ZXing.Net 的Core平台生成二维码

一、引用 二、代码 帮助类 /// <summary>/// ZXing.NET 二维码帮助类/// </summary>public class ZXingHelper{/// <summary>/// 站点二维码的目录/// </summary>private static string QRCodeDirectory "QRCode";/// <summary>/// 使…

MySQL数据库——视图-介绍及基本语法(创建、查询、修改、删除、演示示例)

目录 介绍 语法 创建 查询 修改 删除 演示示例 介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff08;称为基表&#xff09;&#xff0c;并且是在使用视图时动…

爬虫基础 JS逆向

爬虫核心 1. HTTP协议与WEB开发 1. 什么是请求头请求体&#xff0c;响应头响应体 2. URL地址包括什么 3. get请求和post请求到底是什么 4. Content-Type是什么 &#xff08;1&#xff09;简介 HTTP协议是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;…

SpringBoot+Mybatis实现多数据源+分页

1 主要依赖版本 &#xff08;1&#xff09;SpringBoot 2.7.8 &#xff08;2&#xff09;Mybatis 2.2.2 &#xff08;3&#xff09;Pagehelper 1.3.0 &#xff08;4&#xff09;MySQL 8.0.26 &#xff08;5&#xff09;Oracle 11.2.0.3 2 概述 &#xff08;1&#xff09;…

List集合拆分为多个List

list 拆分 目录概述需求&#xff1a; 设计思路实现思路分析1.list 拆分是2.用stream的parallel实现list的分批处理3.使用stream的parallel实现list的分批处理 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full bus…