目录
[1. 文本张量表示](#1. 文本张量表示)
[2. 0ne-Hot词向量表示](#2. 0ne-Hot词向量表示)
[3. Word2Vec模型](#3. Word2Vec模型)
[3.1 Word2Vec模型介绍](#3.1 Word2Vec模型介绍)
[3.2 word2vec的训练和使用](#3.2 word2vec的训练和使用)
[3.2.1 获取训练数据](#3.2.1 获取训练数据)
[3.2.2 词向量的训练保存加载](#3.2.2 词向量的训练保存加载)
[3.2.3 查看单词对应的词向量](#3.2.3 查看单词对应的词向量)
[3.2.4 模型效果检验](#3.2.4 模型效果检验)
[3.2.5 模型超参数设定](#3.2.5 模型超参数设定)
[4. 词嵌入Word Embedding介绍](#4. 词嵌入Word Embedding介绍)
1. 文本张量表示
-
概念
将一段文本使用张量进行表示,其中一般将词汇表示成向量,称作词向量,再由各个词向量按顺序组成矩阵形成文本表示。
例如:
["人生", "该", "如何", "起头"] ==> # 每个词对应矩阵中的一个向量 [[1.32, 4,32, 0,32, 5.2], [3.1, 5.43, 0.34, 3.2], [3.21, 5.32, 2, 4.32], [2.54, 7.32, 5.12, 9.54]]Copy
-
作用
将文本表示成张量(矩阵)形式,能够使语言文本可以作为计算机处理程序的输入,进行接下来一系列的解析工作。
- 连接文本与计算机
- **机器可读性:**计算机无法直接理解人类语言,文本张量表示是将文本转换为数值形式(通常是多维数组),使其能够被计算机处理和理解。
- **模型输入:**大多数机器学习和深度学习模型(包括 NLP 模型)都需要数值输入,文本张量表示是文本数据进入这些模型的桥梁。
- 表达语义信息:
- **捕捉词语关系:**好的文本张量表示方法,例如词嵌入,可以将词语映射到高维空间中,使得语义相似的词语在向量空间中也彼此接近。例如,"king" 和 "queen" 的向量在空间中会比 "king" 和 "apple" 更接近。
- **保留上下文信息:**对于句子和文档的表示方法,例如句嵌入和文档嵌入,能够保留文本的上下文信息,例如词语之间的顺序和依赖关系。
- **理解文本含义:**通过将文本映射到向量空间,模型可以学习到文本的深层语义含义,而不仅仅是表面上的字面意思。
- 提升模型性能:
- **特征提取:**文本张量表示可以看作是对文本进行特征提取的过程,将文本转换为计算机可以理解的特征。
- **降维:**一些文本张量表示方法,例如词嵌入,可以将文本的维度降低,减少模型的计算量,并避免维度灾难。
- **减少噪声:**一些文本张量表示方法,例如 TF-IDF,可以对文本中的噪声进行过滤,突出重要信息。
- ...
- 连接文本与计算机
-
文本张量表示的方法
- one-hot编码
- Word2vec
- Word Embedding
- ...
2. 0ne-Hot词向量表示
-
概念
one-hot编码是一种将离散的分类变量转化为二进制向量的方法。在自然语言处理中,one-hot编码常用于表示单词。每个单词都被表示为一个稀疏向量,该向量的长度等于词汇表的大小,其中只有一个位置为1,其他位置为0。
例如:
假设有一个简单的词汇表:["cat", "dog", "fish"]。我们将每个单词用一个固定长度的向量表示: "cat" → [1, 0, 0] "dog" → [0, 1, 0] "fish" → [0, 0, 1]Copy
-
特点
- 稀疏性:one-hot编码通常会产生非常稀疏的向量,尤其是词汇表很大时。大部分元素为零,只有一个位置是1。
- 维度较高:词汇表的大小决定了one-hot向量的维度。如果词汇表包含10000个单词,那么每个单词的表示将是一个长度为10000的向量。
- 信息丢失:one-hot编码无法表达词与词之间的语义关系。例如,"cat" 和 "dog" 的表示完全不同,尽管它们在语义上很接近。
-
优缺点
- 优点:实现简单,容易理解。
- 缺点:高维稀疏向量,计算效率低,无法捕捉词之间的语义相似性。而且在大语料集下,每个向量的长度过大,占据大量内存。
-
one-hot编码器代码实现
# 导入keras中的词汇映射器Tokenizer from tensorflow.keras.preprocessing.text import Tokenizer # pip install tensorflow==2.12.1 -i https://mirrors.aliyun.com/pypi/simple/ # 导入用于对象保存与加载的joblib import joblib # 思路分析 生成onehot # 1 准备语料 vocabs # 2 实例化词汇映射器Tokenizer, 使用映射器拟合现有文本数据 (内部生成 index_word word_index) # 2-1 注意idx序号-1 # 3 查询单词idx 赋值 zero_list,生成onehot # 4 使用joblib工具保存映射器 joblib.dump() def dm_onehot_gen(): # 1 准备语料 vocabs vocabs = {"周杰伦", "陈奕迅", "王力宏", "李宗盛", "吴亦凡", "鹿晗"} # 2 实例化词汇映射器Tokenizer, 使用映射器拟合现有文本数据 (内部生成index_word word_index) # 2-1 注意idx序号-1 mytokenizer = Tokenizer() mytokenizer.fit_on_texts(texts=vocabs) # 3 查询单词idx 赋值 zero_list,生成onehot for vocab in vocabs: zero_list = [0] * len(vocabs) idx = mytokenizer.word_index[vocab] - 1 zero_list[idx] = 1 print(vocab, '的onehot编码是', zero_list) # 4 使用joblib工具保存映射器 joblib.dump() mypath = './mytokenizer' joblib.dump(mytokenizer, mypath) print('保存mytokenizer End') # 注意5-1 字典没有顺序 onehot编码没有顺序 []-有序 {}-无序 区别 # 注意5-2 字典有的单词才有idx idx从1开始 # 注意5-3 查询没有注册的词会有异常 eg: 狗蛋 print(mytokenizer.word_index) print(mytokenizer.index_word)Copy
输出结果:
陈奕迅 的onehot编码是 [1, 0, 0, 0, 0, 0]
王力宏 的onehot编码是 [0, 1, 0, 0, 0, 0]
鹿晗 的onehot编码是 [0, 0, 1, 0, 0, 0]
周杰伦 的onehot编码是 [0, 0, 0, 1, 0, 0]
李宗盛 的onehot编码是 [0, 0, 0, 0, 1, 0]
吴亦凡 的onehot编码是 [0, 0, 0, 0, 0, 1]
保存mytokenizer End
{'陈奕迅': 1, '王力宏': 2, '鹿晗': 3, '周杰伦': 4, '李宗盛': 5, '吴亦凡': 6}
{1: '陈奕迅', 2: '王力宏', 3: '鹿晗', 4: '周杰伦', 5: '李宗盛', 6: '吴亦凡'}Copy
-
one-hot编码器使用
# 思路分析 # 1 加载已保存的词汇映射器Tokenizer joblib.load(mypath) # 2 查询单词idx 赋值zero_list,生成onehot 以token为'李宗盛' # 3 token = "狗蛋" 会出现异常 def dm_onehot_use(): vocabs = {"周杰伦", "陈奕迅", "王力宏", "李宗盛", "吴亦凡", "鹿晗"} # 1 加载已保存的词汇映射器Tokenizer joblib.load(mypath) mypath = './mytokenizer' mytokenizer = joblib.load(mypath) # 2 编码token为"李宗盛" 查询单词idx 赋值 zero_list,生成onehot token = "李宗盛" zero_list = [0] * len(vocabs) idx = mytokenizer.word_index[token] - 1 zero_list[idx] = 1 print(token, '的onehot编码是', zero_list)Copy
输出结果:
李宗盛 的onehot编码是 [0, 0, 0, 0, 1, 0] Copy
3. Word2Vec模型
3.1 Word2Vec模型介绍
- Word2Vec概念
- Word2Vec是一种流行的将词汇表示成向量的无监督训练方法 ,该过程将构建神经网络模型 ,将网络参数作为词汇的向量表示,通过上下文信息来学习词语的分布式表示(即词向量)。它包含CBOW 和skipgram两种训练模式。
- Word2Vec实际上利用了文本本身的信息来构建 "伪标签"。模型不是被人为地告知某个词语的正确词向量,而是通过上下文词语来预测中心词(CBOW)或者通过中心词来预测上下文词语(Skip-gram)。
- Word2Vec的目标是将每个词转换为一个固定长度的向量,这些向量能够捕捉词与词之间的语义关系。
- Word2Vec特点
- 密集表示:Word2Vec通过训练得到的词向量通常是稠密的,即大部分值不为零,每个向量的维度较小(通常几十到几百维)。
- 捕捉语义关系:Word2Vec可以通过词向量捕捉到词之间的语义相似性,例如通过向量运算可以发现"king"-"man"+"woman"≈"queen"。
- Word2Vec优缺点
- 优点:能够生成稠密的词向量,捕捉词与词之间的语义关系,计算效率高。
- 缺点:需要大量的语料来训练,且可能不适用于某些特定任务(例如:词语的多义性)。
-
CBOW(Continuous bag of words)模式
-
概念
给定一段用于训练的上下文词汇(周围词汇),预测目标词汇。
例如,在句子"the quick brown fox jumps over the lazy dog"中,如果目标词是"jumps",则CBOW模型使用"the","quick","brown","fox","over","the","lazy","dog"这些上下文词来预测"jumps"。
图中窗口大小为9, 使用前后4个词汇对目标词汇进行预测。
-
CBOW模式下的word2vec过程说明
-
假设我们给定的训练语料只有一句话: Hope can set you free (愿你自由成长),窗口大小为3,因此模型的第一个训练样本来自Hope can set,因为是CBOW模式,所以将使用Hope和set作为输入,can作为输出,在模型训练时,Hope,can,set等词汇都使用它们的one-hot编码。如图所示: 每个one-hot编码的单词与各自的变换矩阵(即参数矩阵3x5->随机初始化,这里的3是指最后得到的词向量维度)相乘,得到上下文表示矩阵(3x1),也就是词向量 。将所有上下文词语的词向量按元素平均,得到平均词向量。
-
接着, 将上下文表示矩阵(平均词向量)与变换矩阵(参数矩阵5x3->随机初始化,所有的变换矩阵共享参数)相乘,得到5x1的结果矩阵,使用softmax函数将得分向量转换为概率分布,它将与我们真正的目标矩阵即can的one-hot编码矩阵(5x1)进行损失的计算,然后更新网络参数完成一次模型迭代。
-
最后窗口按顺序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示。
-
-
-
Skip-gram模式
-
概念
给定一个目标词,预测其上下文词汇。
例如,在句子"the quick brown fox jumps over the lazy dog"中,如果目标词是"jumps",skip-gram模型尝试预测它周围的词,如"the","quick","brown","fox","over","the","lazy","dog"。
图中窗口大小为9,使用目标词汇对前后四个词汇进行预测。
-
Skip-gram模式下的word2vec过程说明
-
假设我们给定的训练语料只有一句话: Hope can set you free (愿你自由成长),窗口大小为3,因此模型的第一个训练样本来自Hope can set,因为是skip-gram模式,所以将使用can作为输入,Hope和set作为输出,在模型训练时,Hope、can、set等词汇都使用它们的one-hot编码。如图所示: 将can的one-hot编码与变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘, 得到目标词汇表示矩阵(3x1)。
-
接着, 将目标词汇表示矩阵与多个变换矩阵(参数矩阵5x3)相乘 , 得到多个5x1的结果矩阵,使用softmax函数将得分向量转换为概率分布,它将与我们Hope和set对应的one-hot编码矩阵(5x1)进行损失的计算, 然后更新网络参数完成一次模 型迭代。
-
最后窗口按序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵即参数矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示。
-
-
-
词向量的检索获取
-
神经网络训练完毕后,神经网络的参数矩阵w就我们的想要词向量。如何检索某1个单词的向量呢?以CBOW方式举例说明如何检索a单词的词向量。
-
如下图所示:a的onehot编码[10000],用参数矩阵[3,5] * a的onehot编码[10000],可以把参数矩阵的第1列参数给取出来,这个[3,1]的值就是a的词向量。
-
3.2 word2vec的训练和使用
- 第一步: 获取训练数据
- 第二步: 训练词向量
- 第三步: 模型超参数设定
- 第四步: 模型效果检验
- 第五步: 模型的保存与重加载
3.2.1 获取训练数据
数据来源:http://mattmahoney.net/dc/enwik9.zip
在这里, 我们将研究英语维基百科的部分网页信息, 它的大小在300M左右。这些语料已经被准备好, 我们可以通过Matt Mahoney的网站下载。
注意:原始数据集已经放在data/enwik9.zip,解压后数据为data/enwik9,预处理后的数据为data/fil9
-
查看原始数据:
# 原始数据将输出很多包含XML/HTML格式的内容, 这些内容并不是我们需要的 <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.3/ http://www.mediawiki.org/xml/export-0.3.xsd" version="0.3" xml:lang="en"> <siteinfo> <sitename>Wikipedia</sitename> <base>http://en.wikipedia.org/wiki/Main_Page</base> <generator>MediaWiki 1.6alpha</generator> <case>first-letter</case> <namespaces> <namespace key="-2">Media</namespace> <namespace key="-1">Special</namespace> <namespace key="0" />Copy
-
原始数据处理
# 使用wikifil.pl文件处理脚本来清除XML/HTML格式的内容 perl wikifil.pl data/enwik9 > data/fil9 # 该命令已经执行Copy
-
查看预处理后的数据
# 查看前80个字符 head -c 80 data/fil9 # 输出结果为由空格分割的单词 anarchism originated as a term of abuse first used against early working classCopy
3.2.2 词向量的训练保存加载
fasttext是facebook开源的一个词向量与文本分类工具。下面是该工具包的安装方法:
官网(fasttext-wheel)下载对应操作系统对应python解析器版本的fasttext模块的whl文件
进入到base虚拟环境,然后在whl文件目录下通过以下命令安装
当前目录下要有whl文件名称
pip install asttext_wheel-0.9.2-cp311-cp311-win_amd64.whlCopy
# 导入fasttext
import fasttext
def dm_fasttext_train_save_load():
# 1 使用train_unsupervised(无监督训练方法) 训练词向量
mymodel = fasttext.train_unsupervised(input='data/fil9', model='skipgram', dim=300, epoch=1)
print('训练词向量 ok')
# 2 save_model()保存已经训练好词向量
# 注意,该行代码执行耗时很长
mymodel.save_model(path="./data/fil9.bin")
print('保存词向量 ok')
# 3 模型加载
mymodel = fasttext.load_model(path='./data/fil9.bin')
print('加载词向量 ok')Copy
输出结果:
# 步骤1运行效果如下:
有效训练词汇量为124M, 共218316个单词
Read 124M words
Number of words: 218316
Number of labels: 0
Progress: 100.0% words/sec/thread: 53996 lr: 0.000000 loss: 0.734999 ETA: 0h 0mCopy
3.2.3 查看单词对应的词向量
# 通过get_word_vector方法来获得指定词汇的词向量, 默认词向量训练出来是1个单词100特征
def dm_fasttext_get_word_vector():
mymodel = fasttext.load_model(path='./data/fil9.bin')
myvector = mymodel.get_word_vector(word='the')
print('myvector->', type(myvector), myvector.shape, myvector)Copy
myvector-> <class 'numpy.ndarray'> (100,) [-0.03087516, 0.09221972, 0.17660329, 0.17308897, 0.12863874,
0.13912526, -0.09851588, 0.00739991, 0.37038437, -0.00845221,
...
-0.21184735, -0.05048715, -0.34571868, 0.23765688, 0.23726143]Copy
3.2.4 模型效果检验
# 检查单词向量质量的一种简单方法就是查看其邻近单词, 通过我们主观来判断这些邻近单词是否与目标单词相关来粗略评定模型效果好坏.
# 查找"运动"的邻近单词, 我们可以发现"体育网", "运动汽车", "运动服"等.
# k:邻近单词的数量
print(mymodel.get_nearest_neighbors(word='sports', k=10))
# 0.8414610624313354:目标词与其最相似的邻居之间的相似度 余弦相似度 值越接近 1 表示相似度越高
[(0.8414610624313354, 'sportsnet'), (0.8134572505950928, 'sport'), (0.8100415468215942, 'sportscars'), (0.8021156787872314, 'sportsground'), (0.7889881134033203, 'sportswomen'), (0.7863013744354248, 'sportsplex'), (0.7786710262298584, 'sporty'), (0.7696356177330017, 'sportscar'), (0.7619683146476746, 'sportswear'), (0.7600985765457153, 'sportin')]
# 查找"音乐"的邻近单词, 我们可以发现与音乐有关的词汇.
print(mymodel.get_nearest_neighbors(word='music'))
[(0.8908010125160217, 'emusic'), (0.8464668393135071, 'musicmoz'), (0.8444250822067261, 'musics'), (0.8113634586334229, 'allmusic'), (0.8106718063354492, 'musices'), (0.8049437999725342, 'musicam'), (0.8004694581031799, 'musicom'), (0.7952923774719238, 'muchmusic'), (0.7852965593338013, 'musicweb'), (0.7767147421836853, 'musico')]
# 查找"小狗"的邻近单词, 我们可以发现与小狗有关的词汇.
print(mymodel.get_nearest_neighbors(word='dog'))
[(0.8456876873970032, 'catdog'), (0.7480780482292175, 'dogcow'), (0.7289096117019653, 'sleddog'), (0.7269964218139648, 'hotdog'), (0.7114801406860352, 'sheepdog'), (0.6947550773620605, 'dogo'), (0.6897546648979187, 'bodog'), (0.6621081829071045, 'maddog'), (0.6605004072189331, 'dogs'), (0.6398137211799622, 'dogpile')]Copy
3.2.5 模型超参数设定
# 在训练词向量过程中, 我们可以设定很多常用超参数来调节我们的模型效果, 如:
# 无监督训练模式: 'skipgram' 或者 'cbow', 默认为'skipgram', 在实践中,skipgram模式在利用子词方面比cbow更好.
# 词嵌入维度dim: 默认为100, 但随着语料库的增大, 词嵌入的维度往往也要更大.
# 数据循环次数epoch: 默认为5, 但当你的数据集足够大, 可能不需要那么多次.
# 学习率lr: 默认为0.05, 根据经验, 建议选择[0.01,1]范围内.
# 使用的线程数thread: 默认为12个线程, 一般建议和你的cpu核数相同.
model = fasttext.train_unsupervised(input='data/fil9', model="cbow", dim=300, epoch=1, lr=0.1, thread=4)Copy
输出结果:
Read 124M words
Number of words: 218316
Number of labels: 0
Progress: 100.0% words/sec/thread: 49523 lr: 0.000000 avg.loss: 1.777205 ETA: 0h 0m 0sCopy
4. 词嵌入Word Embedding介绍
Word Embedding 与 Word2Vec 的关系
- Word2Vec 是一种Word Embedding方法,专门用于生成词的稠密向量表示。Word2Vec通过神经网络训练,利用上下文信息将每个词表示为一个低维稠密向量。
- Word Embedding是一个更广泛的概念,指任何将词汇映射到低维空间的表示方法,不仅限于Word2Vec。GloVe和FastText等方法同样属于词嵌入。
-
概念
- 一种通过一定的方式将单词映射到指定维度的空间技术,目的是将单词的语义信息编码进低维向量空间。
- 广义的word embedding包括所有密集词汇向量的表示方法,如之前学习的word2vec, 即可认为是word embedding的一种。
- 狭义的word embedding是指在神经网络中加入的embedding层, 对整个网络进行训练的同时产生的embedding矩阵(embedding层的参数), 这个embedding矩阵就是训练过程中所有输入词汇的向量表示组成的矩阵。
-
特点
- 低维稠密向量:词嵌入将每个词映射为低维稠密的向量,通常维度为50、100、200或300。
- 捕捉语义和句法信息:词嵌入能够捕捉词语之间的关系,例如语法上的相似性(如复数形式)和语义上的相似性(如"man"与"woman")。
- 迁移学习:词嵌入能够在不同任务之间共享词向量,提高模型的泛化能力。
-
优缺点
- 优点:能够有效捕捉词的语义和句法信息,且训练出来的词向量可以在多个任务中使用。
- 缺点:对于一些低频词和未见过的词处理可能较差。
-
Word Embedding的可视化分析
通过使用tensorboard可视化嵌入的词向量
import torch from tensorflow.keras.preprocessing.text import Tokenizer from torch.utils.tensorboard import SummaryWriter import jieba import torch.nn as nn # 注意: # fs = tf.io.gfile.get_filesystem(save_path) # AttributeError: module 'tensorflow._api.v2.io.gfile' has no attribute 'get_filesystem' # 错误原因分析: # from tensorboard.compat import tf 使用了tf 如果安装tensorflow,默认会调用它tf的api函数 # import tensorflow as tf # import tensorboard as tb # tf.io.gfile = tb.compat.tensorflow_stub.io.gfile # 实验:nn.Embedding层词向量可视化分析 # 1 对句子分词 word_list # 2 对句子word2id求my_token_list,对句子文本数值化sentence2id # 3 创建nn.Embedding层,查看每个token的词向量数据 # 4 创建SummaryWriter对象, 可视化词向量 # 词向量矩阵embd.weight.data 和 词向量单词列表my_token_list添加到SummaryWriter对象中 # summarywriter.add_embedding(embd.weight.data, my_token_list) # 5 通过tensorboard观察词向量相似性 # 6 也可通过程序,从nn.Embedding层中根据idx拿词向量 def dm02_nnembeding_show(): # 1 对句子分词 word_list sentence1 = '传智教育是一家上市公司,旗下有黑马程序员品牌。我是在黑马这里学习人工智能' sentence2 = "我爱自然语言处理" sentences = [sentence1, sentence2] word_list = [] for s in sentences: word_list.append(jieba.lcut(s)) # print('word_list--->', word_list) # 2 对句子word2id求my_token_list,对句子文本数值化sentence2id mytokenizer = Tokenizer() mytokenizer.fit_on_texts(texts=word_list) # print(mytokenizer.index_word, mytokenizer.word_index) # 打印my_token_list my_token_list = mytokenizer.index_word.values() print('my_token_list-->', my_token_list) # 打印文本数值化以后的句子 sentence2id = mytokenizer.texts_to_sequences(texts=word_list) print('sentence2id--->', sentence2id, len(sentence2id)) # 3 创建nn.Embedding层 embd = nn.Embedding(num_embeddings=len(my_token_list), embedding_dim=8) # print("embd--->", embd) # print('nn.Embedding层词向量矩阵-->', embd.weight.data, embd.weight.data.shape, type(embd.weight.data)) # 4 创建SummaryWriter对象 词向量矩阵embd.weight.data 和 词向量单词列表my_token_list # 词向量保存到runs目录中,不要出现中文路径,否则报错 # log_dir: 默认None, 保存到当前目录下的runs/xxx目录(自动创建)中 summarywriter = SummaryWriter(log_dir='D:/code/PycharmProjects/runs') # mat:词向量表示 张量或numpy数组 # metadata:词标签 summarywriter.add_embedding(mat=embd.weight.data, metadata=my_token_list) summarywriter.close() # 5 通过tensorboard观察词向量相似性 # cd 程序的当前目录下执行下面的命令 # 启动tensorboard服务 tensorboard --logdir=runs --host 0.0.0.0 # 通过浏览器,查看词向量可视化效果 http://127.0.0.1:6006 print('从nn.Embedding层中根据idx拿词向量') # # 6 从nn.Embedding层中根据idx拿词向量 for idx in range(len(mytokenizer.index_word)): tmpvec = embd(torch.tensor(idx)) print('%4s' % (mytokenizer.index_word[idx + 1]), tmpvec.detach().numpy())
输出结果:
my_token_list--> dict_values(['是', '黑马', '我', '传智', '教育', '一家', '上市公司', ',', '旗下', '有', '程序员', '品牌', '。', '在', '这里', '学习', '人工智能', '爱', '自然语言', '处理'])
sentence2id---> [[4, 5, 1, 6, 7, 8, 9, 10, 2, 11, 12, 13, 3, 1, 14, 2, 15, 16, 17], [3, 18, 19, 20]] 2
从nn.Embedding层中根据idx拿词向量
是 [ 0.46067393 -0.9049023 -0.03143226 -0.32443136 0.03115687 -1.3352231
-0.08336695 -2.4732168 ]
黑马 [ 0.66760564 0.08703537 0.23735243 1.5896837 -1.8869231 0.22520915
-1.0676078 -0.7654686 ]
我 [-0.9093167 -0.6114051 -0.6825029 0.9269122 0.5208822 2.294128
-0.11160549 -0.34862307]
传智 [-1.1552105 -0.4274638 -0.8121502 -1.4969801 -1.3328248 -1.0934378
0.6707438 -1.1796173]
教育 [ 0.01580311 -1.1884228 0.59364647 1.5387698 -1.0822943 0.36760855
-0.4652998 -0.57378227]
一家 [-1.1898873 -0.42482868 -1.9391155 -1.5678993 -1.6960118 0.22525501
-1.0754168 0.41797593]
上市公司 [ 0.590556 2.4274144 1.6698223 -0.9776848 -0.6119061 0.4434897
-2.3726876 -0.2607738]
, [-0.17568143 1.0074369 0.2571488 1.8940887 -0.5383494 0.65416646
0.63454026 0.6235991 ]
旗下 [ 2.8400452 -1.0096515 2.247107 0.30006626 -1.2687006 0.05855403
0.01199368 -0.6156502 ]
有 [ 0.89320636 -0.43819678 1.0345292 1.3546743 -1.4238662 -1.6994532
0.30445674 2.673923 ]
程序员 [ 1.2147354 0.24878891 0.36161897 0.37458655 -0.48264053 -0.0141514
1.2033817 0.7899459 ]
品牌 [ 0.59799325 -0.01371854 0.0628166 -1.4829391 0.39795023 -0.39259398
-0.60923046 0.54170054]
。 [ 0.59599686 1.6038656 -0.10832139 0.25223547 0.37193906 1.1944667
-0.91253406 0.6869221 ]
在 [-1.161504 2.6963246 -0.6087775 0.9399654 0.8480068 0.684357
0.96156543 -0.3541162 ]
这里 [ 0.1034054 -0.01949253 0.8989019 1.61057 -1.5983531 0.17945968
-0.17572908 -0.9724814 ]
学习 [-1.3899843 -1.0846052 -1.1301199 -0.4078141 0.40511298 0.6562911
0.9231357 -0.34704337]
人工智能 [-1.4966388 -1.0905199 1.001238 -0.75254333 -1.4210068 -1.854177
1.0471514 -0.27140012]
爱 [-1.5254552 0.6189947 1.2703396 -0.4826037 -1.4928672 0.8320283
1.7333516 0.16908517]
自然语言 [-0.3856235 -1.2193452 0.9991112 -1.5821775 0.45017946 -0.66064674
0.08045111 0.62901515]
处理 [ 1.5062869 1.3156213 -0.21295634 0.47610474 0.08946162 0.57107806
-1.0727187 0.16396333]
词向量和词显示标签 写入磁盘ok 在当前目录下查看 ./runs 目录