【Pytorch神经网络实战案例】30 jieba库分词+训练中文词向量

1 安装jieba

1.1 安装

pip install jieba

1.2 测试

import jieba
seg_list = jieba.cut("谭家和谭家和")
for i in seg_list:printf(i);

1.3 词向量

在NLP中,一般都会将该任务中涉及的词训练成词向量,然后让每个词以词向量的形式型的输入,进行一些指定任务的训练。对于一个完整的训练任务,词向量的练大多发生在预训练环节。

除了从头训练词向量,还可以使用已经训练好的词向量。尤其在样本不充足的情况下,可以增加模型的泛化性。

通用的词嵌入模型常以key-vaue的格式保存,即把词对应的向量一一列出来。这种方式具有更好的通用性,它可以不依赖任何框架。

2 代码实现:训练中文词向量

2.1 样本预处理并生成字典---skip_gram.py(第一部分)

# 1.1 样本预处理并生成字典
# 使用get_ch lable函数将所有文字读入raining_data,然后在fenci函数里使用jeba库对ci放入buld_dataset里并生成指定长度(350)的字典。# 指定设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
training_file = './data/一大段文本.txt'# 中文字
def get_ch_lable(txt_file): # 获取文件内的文本信息labels= ""with open(txt_file, 'rb') as f:for label in f:labels =labels+label.decode('gb2312')return  labels# 分词
def fenci(training_data):seg_list = jieba.cut(training_data)  # 默认是精确模式training_ci = " ".join(seg_list)training_ci = training_ci.split()# 以空格将字符串分开training_ci = np.array(training_ci)training_ci = np.reshape(training_ci, [-1, ])return training_ci# build dataset()函数实现了对样本文字的处理。
# 在该函数中,对样本文字的词频进行统计,将照频次由高到低排序。同时,将排序后的列表中第0个索引设置成unknown(用“UNK”表示),
# 这个unknown字符可用于对词频低的词语进行填充。如果设置字典为350,则频次排序在350的词都会被当作unknown字符进行处理。
def build_dataset(words,n_words): #count = [['UNK', -1]]count.extend(collections.Counter(words).most_common(n_words - 1))dictionary = dict()for word, _ in count:dictionary[word] = len(dictionary)data = list()unk_count = 0for word in words:if word in dictionary:index = dictionary[word]else:index = 0  # dictionary['UNK']unk_count += 1data.append(index)count[0][1] = unk_countreversed_dictionary = dict(zip(dictionary.values(), dictionary.keys()))return data, count, dictionary, reversed_dictionarytraining_data = get_ch_lable(training_file)
print("总字数",len(training_data)) # 1567
training_ci =fenci(training_data)
print("总词数",len(training_ci)) #
training_label, count, dictionary, words = build_dataset(training_ci, 350)#计算词频
word_count = np.array([freq for _,freq in count], dtype=np.float32)
word_freq = word_count / np.sum(word_count)#计算每个词的词频
word_freq = word_freq ** (3. / 4.)#词频变换
words_size = len(dictionary)
print("字典词数",words_size) # 350
print('Sample data', training_label[:10], [words[i] for i in training_label[:10]]) # # 显示的是样本文字里前10个词的词频。

2.2 代码实现:按照skip-Gram模型的规则制作数据集---skip_gram.py(第二部分)

# 1.2 按照skip-Gram模型的规则制作数据集
# 使用Dataset与Dataloader接口制作数据集。
# 在自定义Dataset类中,按照Skip-Gram模型的规则对样本及其对应的标签进行组合。
# 每批次取12个,每个词向量的维度为128,中心词前后的取词个数为3,负采样的个数为64。具体代码如下。C = 3   # 定义中心词前后的取词个数
num_sampled = 64 # 负采样个数
BATCH_SIZE = 12
EMBEDDING_SIZE = 128class SkipGramDataset(Dataset): # 自定义数据集# 样本中的每个词都被当作一个中心词,对于任意一个样本中心词,都会生成两组标签:正向标签与负向标签。# 正向标签来自中心词的前后位置,负向标签主要来自词频的多项式来样。def __init__(self,training_label,word_to_idx,idx_to_word,word_freqs):super(SkipGramDataset, self).__init__()self.text_encode = torch.Tensor(training_label).long()self.word_to_idx = word_to_idxself.idx_to_word = idx_to_wordself.word_freqs = torch.Tensor(word_freqs)def __len__(self):return len(self.text_encode)def __getitem__(self, idx):idx = min(max(idx,C),len(self.text_encode)-2-C) # 防止越界:对组合标签过程中的越界问题做了处理,使提取样本的索引为3~(总长度-5)。center_word = self.text_encode[idx]pos_indices = list(range(idx-C,idx)) + list(range(idx+1,idx+1+C))pos_words = self.text_encode[pos_indices]# ---start---对负向标签进行采样。在使用多项式分布采样之后,还要从中去掉与正向标签相同的索引。其中np.setdiff1d()函数用于对两个数组做差集。# 多项式分布采样,取出指定个数的高频词neg_words = torch.multinomial(self.word_freqs, num_sampled + 2 * C, False)  # True)# 去掉正向标签neg_words = torch.Tensor(np.setdiff1d(neg_words.numpy(), pos_words.numpy())[:num_sampled]).long()# ---end---对负向标签进行采样。在使用多项式分布采样之后,还要从中去掉与正向标签相同的索引。其中np.setdiff1d()函数用于对两个数组做差集。return center_word, pos_words,neg_wordsprint("制作数据集...")
train_dataset = SkipGramDataset(training_label,dictionary,words,word_freq)
dataloader = torch.utils.data.DataLoader(train_dataset,batch_size=BATCH_SIZE,drop_last=True,shuffle=True)
sample = iter(dataloader)					#将数据集转化成迭代器
center_word, pos_words, neg_words = sample.next()				#从迭代器中取出一批次样本
print(center_word[0],words[np.long(center_word[0])],[words[i] for i in pos_words[0].numpy()])

2.3 搭建模型并进行训练

2.3.1 余弦定理

2.3.2 代码片段

 2.3.3 词嵌入夹角余弦结构

 2.3.4 代码实现:搭建模型并进行训练---skip_gram.py(第三部分)

# 1.3 搭建模型并进行训练
# 首先定义一个词嵌入层用手训练,将输入的样本和标签分别用词嵌入层进行转化。
# 在训练过程中,将输入与标签的词嵌入当作两个向量,将二者的矩阵相乘当作两个向量间的夹角余弦值,并用该夹角余弦值作为被优化的损失函数。
# 在训练模型时,定义了验证模型的相关参数,其中valid_size表示在0~words_size/2中随机取不能重复的16个字来验证模型。
class Model(nn.Module):def __init__(self,vocab_size,embed_size):super(Model, self).__init__()self.vocab_size = vocab_sizeself.embed_size = embed_sizeinitrange = 0.5 / self.embed_sizeself.in_embed = nn.Embedding(self.vocab_size, self.embed_size, sparse=False)self.in_embed.weight.data.uniform_(-initrange, initrange)def forward(self,input_lables,pos_labels,neg_labels):# LogSigmoid激活函数,该激活函数的值域是(-inf,0](inf是无穷值的意思),即当输入值越大,输出值越接近于0。# 如果将输入样本的词嵌入和目标标签的词嵌入分别当作两个向量,则可以用这两个向量间的夹角余弦值来当作二者的相似度。# 为了规范计算,先通过LogSigmoid激活函数中的Sigmoid函数将参与运算的向量控制为0~1,再从正 / 负标签两个方向进行相似度计算:# ① 对于正向标签,可以直接进行计算:# ② 对于负向标签,可以先用1减去输入样本的词嵌入,得到输入样本对应的负向量,再将该结果与负向标签的词向量一起计算相似度。#       根据Sigmoid函数的对称特性1 - Sigmoid(x) = Sigmoid(-x),可以直接对输入样本词向量的符号取负来实现向量的转化。input_embedding = self.in_embed(input_lables)pos_embedding = self.in_embed(pos_labels)neg_embedding = self.in_embed(neg_labels)# 计算输入与正向标签间的夹角余弦值:用bmm函数完成两个带批次数据的矩阵相乘【bmm函数处理的必须是批次数据,即形状为{b,m,n]与[b,n,m]矩阵相乘;】log_pos = torch.bmm(pos_embedding, input_embedding.unsqueeze(2)).squeeze()# 计算输入与负向标签间的夹角余弦值:用bmm函数完成两个带批次数据的矩阵相乘【bmm函数处理的必须是批次数据,即形状为{b,m,n]与[b,n,m]矩阵相乘;】log_neg = torch.bmm(neg_embedding, -input_embedding.unsqueeze(2)).squeeze() # 在计算输入与负向标签间的夹角余弦值时,使用样本词嵌入的赋值。这样做与使用LogSigmoid激活函数有关。# 使用LogSigmoid激活函数log_pos = F.logsigmoid(log_pos).sum(1)log_neg = F.logsigmoid(log_neg).sum(1)loss = log_pos + log_negreturn -loss # 对最终的损失值取负,将损失函数的值域由(-inf,0]变为(0,inf]。这种变换有利于使用优化器在迭代训练中进行优化(因为优化器只能使损失值沿着最小化的方向优化)。
# 实例化模型
model = Model(words_size,EMBEDDING_SIZE).to(device)
model.eval()
# 定义测试样本
valid_size = 16
valid_window = words_size/2 # 取样数据的分布范围
valid_examples = np.random.choice(int(valid_window),valid_size,replace=True) #0- words_size/2,中的数取16个。不能重复。optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)NUM_EPOCHS = 200for e in range(NUM_EPOCHS): # 训练模型for ei, (input_labels, pos_labels, neg_labels) in enumerate(dataloader):input_labels = input_labels.to(device)pos_labels = pos_labels.to(device)neg_labels = neg_labels.to(device)optimizer.zero_grad()loss = model(input_labels, pos_labels, neg_labels).mean()loss.backward()optimizer.step()if ei % 20 == 0: # 显示训练结果print("epoch: {}, iter: {}, loss: {}".format(e, ei, loss.item()))if e % 40 == 0: # 测试模型# ---start---实现对现有模型的能力测试。该代码会从验证样本中取出指定的个数的词,通过词嵌入的转化,在已有的训练样本中找到与其语义相近的词,并显示出来。# 计算测试样本词嵌入和所有样本词嵌入间的余弦相似度norm = torch.sum(model.in_embed.weight.data.pow(2), -1).sqrt().unsqueeze(1) # norm代表每一个词对应向量的长度矩阵,见式(3-5)。normalized_embeddings = model.in_embed.weight.data / norm # normalized_embeddings表示向量除以自己的模,即单位向量。它可以确定向量的方向。valid_embeddings = normalized_embeddings[valid_examples]# 计算余弦相似度:用mm函数完成矩阵相乘【mm函数处理的是普通矩阵数据,即形状为[m,n]与[n,m]矩阵相乘】similarity = torch.mm(valid_embeddings, normalized_embeddings.T) # similanity就是valid_dataset中对应的单位向量vald_embeddings与整个词嵌入字典中单位向量的夹角余弦。for i in range(valid_size):valid_word = words[valid_examples[i]]top_k = 8  # 取最近的排名前8的词# similarity就是当前词与整个词典中每个词的夹角余弦,夹角余弦值越大,就代表相似度越高。nearest = (-similarity[i, :]).argsort()[1:top_k + 1]  # argsort()用于将数组中的值按从小到大的顺序排列后,返回每个值对应的索引。在使用argsort函数之前,将similarity取负,得到的就是从小到大的排列。log_str = 'Nearest to %s:' % valid_word # 格式化输出日志for k in range(top_k):close_word = words[nearest[k].cpu().item()]log_str = '%s,%s' % (log_str, close_word)print(log_str)# ---end---实现对现有模型的能力测试。该代码会从验证样本中取出指定的个数的词,通过词嵌入的转化,在已有的训练样本中找到与其语义相近的词,并显示出来。

2.4 代码实现:实现词向量可视化---skip_gram.py(第四部分)

# 1.4 实现词向量可视化
# 对与可视化相关的引入库做了初始化,具体说明如下:
# ①通过设置mpl的值让p|ot能够显示中文信息。
# ②Scikit-learn(也称为sklearn)库的t-SNE算法模块,作用是非对称降维。
#       t-SNE算法结合t分布,将高维空间的数据点映射到低维空间的距离,主要用于可视化和理解高维数据。
#
# 将词典中的词嵌入向量转成单位向量(只有方向),然后将它们通过t-SNE算法降维映射到二维平面中进行显示。
def plot_with_labels(low_dim_embs, labels, filename='./data/tsne.png'):assert low_dim_embs.shape[0] >= len(labels), 'More labels than embeddings'plt.figure(figsize=(18, 18))  # in inchesfor i, label in enumerate(labels):x, y = low_dim_embs[i, :]plt.scatter(x, y)plt.annotate(label, xy=(x, y), xytext=(5, 2), textcoords='offset points',ha='right', va='bottom')plt.savefig(filename)final_embeddings = model.in_embed.weight.data.cpu().numpy()
tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000)
plot_only = 200  # 输出100个词
low_dim_embs = tsne.fit_transform(final_embeddings[:plot_only, :])
labels = [words[i] for i in range(plot_only)]
plot_with_labels(low_dim_embs, labels)

3 skip_gram.py(代码总览)

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader, Dataset
import collections
from collections import Counter
import numpy as np
import random
import jieba
from sklearn.manifold import TSNE
import matplotlib as mpl
import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False# 1.1 样本预处理并生成字典
# 使用get_ch lable函数将所有文字读入raining_data,然后在fenci函数里使用jeba库对ci放入buld_dataset里并生成指定长度(350)的字典。# 指定设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
training_file = './data/一大段文本.txt'# 中文字
def get_ch_lable(txt_file): # 获取文件内的文本信息labels= ""with open(txt_file, 'rb') as f:for label in f:labels =labels+label.decode('gb2312')return  labels# 分词
def fenci(training_data):seg_list = jieba.cut(training_data)  # 默认是精确模式training_ci = " ".join(seg_list)training_ci = training_ci.split()# 以空格将字符串分开training_ci = np.array(training_ci)training_ci = np.reshape(training_ci, [-1, ])return training_ci# build dataset()函数实现了对样本文字的处理。
# 在该函数中,对样本文字的词频进行统计,将照频次由高到低排序。同时,将排序后的列表中第0个索引设置成unknown(用“UNK”表示),
# 这个unknown字符可用于对词频低的词语进行填充。如果设置字典为350,则频次排序在350的词都会被当作unknown字符进行处理。
def build_dataset(words,n_words): #count = [['UNK', -1]]count.extend(collections.Counter(words).most_common(n_words - 1))dictionary = dict()for word, _ in count:dictionary[word] = len(dictionary)data = list()unk_count = 0for word in words:if word in dictionary:index = dictionary[word]else:index = 0  # dictionary['UNK']unk_count += 1data.append(index)count[0][1] = unk_countreversed_dictionary = dict(zip(dictionary.values(), dictionary.keys()))return data, count, dictionary, reversed_dictionarytraining_data = get_ch_lable(training_file)
print("总字数",len(training_data)) # 1567
training_ci =fenci(training_data)
print("总词数",len(training_ci)) #
training_label, count, dictionary, words = build_dataset(training_ci, 350)#计算词频
word_count = np.array([freq for _,freq in count], dtype=np.float32)
word_freq = word_count / np.sum(word_count)#计算每个词的词频
word_freq = word_freq ** (3. / 4.)#词频变换
words_size = len(dictionary)
print("字典词数",words_size) # 350
print('Sample data', training_label[:10], [words[i] for i in training_label[:10]]) # # 显示的是样本文字里前10个词的词频。# 1.2 按照skip-Gram模型的规则制作数据集
# 使用Dataset与Dataloader接口制作数据集。
# 在自定义Dataset类中,按照Skip-Gram模型的规则对样本及其对应的标签进行组合。
# 每批次取12个,每个词向量的维度为128,中心词前后的取词个数为3,负采样的个数为64。具体代码如下。C = 3   # 定义中心词前后的取词个数
num_sampled = 64 # 负采样个数
BATCH_SIZE = 12
EMBEDDING_SIZE = 128class SkipGramDataset(Dataset): # 自定义数据集# 样本中的每个词都被当作一个中心词,对于任意一个样本中心词,都会生成两组标签:正向标签与负向标签。# 正向标签来自中心词的前后位置,负向标签主要来自词频的多项式来样。def __init__(self,training_label,word_to_idx,idx_to_word,word_freqs):super(SkipGramDataset, self).__init__()self.text_encode = torch.Tensor(training_label).long()self.word_to_idx = word_to_idxself.idx_to_word = idx_to_wordself.word_freqs = torch.Tensor(word_freqs)def __len__(self):return len(self.text_encode)def __getitem__(self, idx):idx = min(max(idx,C),len(self.text_encode)-2-C) # 防止越界:对组合标签过程中的越界问题做了处理,使提取样本的索引为3~(总长度-5)。center_word = self.text_encode[idx]pos_indices = list(range(idx-C,idx)) + list(range(idx+1,idx+1+C))pos_words = self.text_encode[pos_indices]# ---start---对负向标签进行采样。在使用多项式分布采样之后,还要从中去掉与正向标签相同的索引。其中np.setdiff1d()函数用于对两个数组做差集。# 多项式分布采样,取出指定个数的高频词neg_words = torch.multinomial(self.word_freqs, num_sampled + 2 * C, False)  # True)# 去掉正向标签neg_words = torch.Tensor(np.setdiff1d(neg_words.numpy(), pos_words.numpy())[:num_sampled]).long()# ---end---对负向标签进行采样。在使用多项式分布采样之后,还要从中去掉与正向标签相同的索引。其中np.setdiff1d()函数用于对两个数组做差集。return center_word, pos_words,neg_wordsprint("制作数据集...")
train_dataset = SkipGramDataset(training_label,dictionary,words,word_freq)
dataloader = torch.utils.data.DataLoader(train_dataset,batch_size=BATCH_SIZE,drop_last=True,shuffle=True)
sample = iter(dataloader)					#将数据集转化成迭代器
center_word, pos_words, neg_words = sample.next()				#从迭代器中取出一批次样本
print(center_word[0],words[np.long(center_word[0])],[words[i] for i in pos_words[0].numpy()])# 1.3 搭建模型并进行训练
# 首先定义一个词嵌入层用手训练,将输入的样本和标签分别用词嵌入层进行转化。
# 在训练过程中,将输入与标签的词嵌入当作两个向量,将二者的矩阵相乘当作两个向量间的夹角余弦值,并用该夹角余弦值作为被优化的损失函数。
# 在训练模型时,定义了验证模型的相关参数,其中valid_size表示在0~words_size/2中随机取不能重复的16个字来验证模型。
class Model(nn.Module):def __init__(self,vocab_size,embed_size):super(Model, self).__init__()self.vocab_size = vocab_sizeself.embed_size = embed_sizeinitrange = 0.5 / self.embed_sizeself.in_embed = nn.Embedding(self.vocab_size, self.embed_size, sparse=False)self.in_embed.weight.data.uniform_(-initrange, initrange)def forward(self,input_lables,pos_labels,neg_labels):# LogSigmoid激活函数,该激活函数的值域是(-inf,0](inf是无穷值的意思),即当输入值越大,输出值越接近于0。# 如果将输入样本的词嵌入和目标标签的词嵌入分别当作两个向量,则可以用这两个向量间的夹角余弦值来当作二者的相似度。# 为了规范计算,先通过LogSigmoid激活函数中的Sigmoid函数将参与运算的向量控制为0~1,再从正 / 负标签两个方向进行相似度计算:# ① 对于正向标签,可以直接进行计算:# ② 对于负向标签,可以先用1减去输入样本的词嵌入,得到输入样本对应的负向量,再将该结果与负向标签的词向量一起计算相似度。#       根据Sigmoid函数的对称特性1 - Sigmoid(x) = Sigmoid(-x),可以直接对输入样本词向量的符号取负来实现向量的转化。input_embedding = self.in_embed(input_lables)pos_embedding = self.in_embed(pos_labels)neg_embedding = self.in_embed(neg_labels)# 计算输入与正向标签间的夹角余弦值:用bmm函数完成两个带批次数据的矩阵相乘【bmm函数处理的必须是批次数据,即形状为{b,m,n]与[b,n,m]矩阵相乘;】log_pos = torch.bmm(pos_embedding, input_embedding.unsqueeze(2)).squeeze()# 计算输入与负向标签间的夹角余弦值:用bmm函数完成两个带批次数据的矩阵相乘【bmm函数处理的必须是批次数据,即形状为{b,m,n]与[b,n,m]矩阵相乘;】log_neg = torch.bmm(neg_embedding, -input_embedding.unsqueeze(2)).squeeze() # 在计算输入与负向标签间的夹角余弦值时,使用样本词嵌入的赋值。这样做与使用LogSigmoid激活函数有关。# 使用LogSigmoid激活函数log_pos = F.logsigmoid(log_pos).sum(1)log_neg = F.logsigmoid(log_neg).sum(1)loss = log_pos + log_negreturn -loss # 对最终的损失值取负,将损失函数的值域由(-inf,0]变为(0,inf]。这种变换有利于使用优化器在迭代训练中进行优化(因为优化器只能使损失值沿着最小化的方向优化)。
# 实例化模型
model = Model(words_size,EMBEDDING_SIZE).to(device)
model.eval()
# 定义测试样本
valid_size = 16
valid_window = words_size/2 # 取样数据的分布范围
valid_examples = np.random.choice(int(valid_window),valid_size,replace=True) #0- words_size/2,中的数取16个。不能重复。optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)NUM_EPOCHS = 200for e in range(NUM_EPOCHS): # 训练模型for ei, (input_labels, pos_labels, neg_labels) in enumerate(dataloader):input_labels = input_labels.to(device)pos_labels = pos_labels.to(device)neg_labels = neg_labels.to(device)optimizer.zero_grad()loss = model(input_labels, pos_labels, neg_labels).mean()loss.backward()optimizer.step()if ei % 20 == 0: # 显示训练结果print("epoch: {}, iter: {}, loss: {}".format(e, ei, loss.item()))if e % 40 == 0: # 测试模型# ---start---实现对现有模型的能力测试。该代码会从验证样本中取出指定的个数的词,通过词嵌入的转化,在已有的训练样本中找到与其语义相近的词,并显示出来。# 计算测试样本词嵌入和所有样本词嵌入间的余弦相似度norm = torch.sum(model.in_embed.weight.data.pow(2), -1).sqrt().unsqueeze(1) # norm代表每一个词对应向量的长度矩阵,见式(3-5)。normalized_embeddings = model.in_embed.weight.data / norm # normalized_embeddings表示向量除以自己的模,即单位向量。它可以确定向量的方向。valid_embeddings = normalized_embeddings[valid_examples]# 计算余弦相似度:用mm函数完成矩阵相乘【mm函数处理的是普通矩阵数据,即形状为[m,n]与[n,m]矩阵相乘】similarity = torch.mm(valid_embeddings, normalized_embeddings.T) # similanity就是valid_dataset中对应的单位向量vald_embeddings与整个词嵌入字典中单位向量的夹角余弦。for i in range(valid_size):valid_word = words[valid_examples[i]]top_k = 8  # 取最近的排名前8的词# similarity就是当前词与整个词典中每个词的夹角余弦,夹角余弦值越大,就代表相似度越高。nearest = (-similarity[i, :]).argsort()[1:top_k + 1]  # argsort()用于将数组中的值按从小到大的顺序排列后,返回每个值对应的索引。在使用argsort函数之前,将similarity取负,得到的就是从小到大的排列。log_str = 'Nearest to %s:' % valid_word # 格式化输出日志for k in range(top_k):close_word = words[nearest[k].cpu().item()]log_str = '%s,%s' % (log_str, close_word)print(log_str)# ---end---实现对现有模型的能力测试。该代码会从验证样本中取出指定的个数的词,通过词嵌入的转化,在已有的训练样本中找到与其语义相近的词,并显示出来。# 1.4 实现词向量可视化
# 对与可视化相关的引入库做了初始化,具体说明如下:
# ①通过设置mpl的值让p|ot能够显示中文信息。
# ②Scikit-learn(也称为sklearn)库的t-SNE算法模块,作用是非对称降维。
#       t-SNE算法结合t分布,将高维空间的数据点映射到低维空间的距离,主要用于可视化和理解高维数据。
#
# 将词典中的词嵌入向量转成单位向量(只有方向),然后将它们通过t-SNE算法降维映射到二维平面中进行显示。
def plot_with_labels(low_dim_embs, labels, filename='./data/tsne.png'):assert low_dim_embs.shape[0] >= len(labels), 'More labels than embeddings'plt.figure(figsize=(18, 18))  # in inchesfor i, label in enumerate(labels):x, y = low_dim_embs[i, :]plt.scatter(x, y)plt.annotate(label, xy=(x, y), xytext=(5, 2), textcoords='offset points',ha='right', va='bottom')plt.savefig(filename)final_embeddings = model.in_embed.weight.data.cpu().numpy()
tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000)
plot_only = 200  # 输出100个词
low_dim_embs = tsne.fit_transform(final_embeddings[:plot_only, :])
labels = [words[i] for i in range(plot_only)]
plot_with_labels(low_dim_embs, labels)

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

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

相关文章

javascript option 菜单图标_苹果电脑上神奇的Option键 巧用option键提升效率

Option键 是苹果电脑一个非常有用的键option键主要的用途,是绕过一些你不想要的对话框。巧用option键可以提升效率,喜欢的朋友收藏起来吧!Option键神奇功能拖拽粘贴Mac电脑上拖拽文件默认是剪切功能按住Option键拖拽文件就能快速达到复制粘贴…

核酸结果统计难?130行代码实现基于ocr的核酸截图识别存储Excel(复现代码核查核酸报告)

来源: 核酸结果统计难?复旦博士生的操作火了https://m.gmw.cn/baijia/2022-04/08/35644611.html 1 程序背景 学校要收核酸截图,汇总太麻烦了,故将OCR整合到数据中。 1.1 命名规范 20200250202003曹文举4.12阴性.jpg 1.2 Eas…

ubuntu下面的git服务器搭建

1、安装相应的软件和依赖 ubuntu:~$ sudo apt-get install git-core openssh-server openssh-client git-core是git版本控制核心软件安装openssh-server和openssh-client是由于git需要通过ssh协议来在服务器与客户端之间传输文件然后中间有个确认操作,输…

实验四:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

王康 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 系统调用:操作系统中,程序员通过封装好的库函数来实现系统调用 前提 1,用户态内核态中断: 1,用户态内核…

【Pytorch神经网络理论篇】 37 常用文本处理工具:spaCy库+torchtext库

同学你好!本文章于2021年末编写,获得广泛的好评! 故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现, Pytorch深度学习理论篇(2023版)目录地址…

海龟画图 python太阳花_python 简单的绘图工具turtle使用详解

目录 1. 画布(canvas) 1.1 设置画布大小 2. 画笔 2.1 画笔的状态 2.2 画笔的属性 2.3 绘图命令 3. 命令详解 4. 绘图举例 4.1 太阳花 4.2 绘制小蟒蛇 4.3 绘制五角星 python2.6版本中后引入的一个简单的绘图工具,叫做海龟绘图(Turtle Graphics),turtle库是python的内…

【Pytorch神经网络实战案例】31 TextCNN模型分析IMDB数据集评论的积极与消极

卷积神经网络不仅在图像视觉领域有很好的效果,而且在基于文本的NLP领域也有很好的效果。TextCN如模型是卷积神经网络用于文本处理方面的一个模型。 在TextCNN模型中,通过多分支卷积技术实现对文本的分类功能。 1 TextCNN 1.1 TextCNN模型结构 TexCNN…

python怎么画出好看的统计图_用最简单的 Python ,画最好看的图 [简单数据可视化]...

可以直接修改参数使用,非常的方便。import numpy as np import pandas as pd import holoviews as hv hv.extension(bokeh) macro_df pd.read_csv(http://assets.holoviews.org/macro.csv, \t) key_dimensions [(year, Year), (country, Country)] value_dimensio…

combobox之下拉宽度自适应

效果对比 先看下优化前后的效果,再看实现过程. 优化前 优化后 从上图中可看到,combobox优化后可以自适应不同长度的字符串,保证每个字符串都能够显示完整。 实现过程 当我们触发CBN_DROPDOWN事件时,不再使用默认的实现&#xff0c…

Python工具:将文件夹下的视频按照帧数输出图片文件(含代码)

1、描述 将一个视频流按帧数截取大量的图片 2、用途 AI的数据集制作,得到大量的图片,之后将其打标签 3、案例文件截图 4、代码实现: import cv2 import argparse import os# 边里该文件夹下的文件名称 def read_directory(directory_nam…

用Python语言对任意图像进行m*n的均匀分块(思路非常清晰,步骤简单)

主要用途:处理图片数据集 1 对单个图片进行分块 import numpy as np import matplotlib.pyplot as plt import cv2def divide_method1(img,m,n):#分割成m行n列print(img.shape)h, w img.shape[0],img.shape[1]gx np.round(h).astype(np.int)gy np.round(w).asty…

python爬虫用什么软件写_python爬虫怎么写

如今很多有编程能力的小伙伴已经不满足手动搜索内容了,都希望通过编写爬虫软件来快速获取需要的内容,那么如何使用python制作爬虫呢?下面小编给大家讲解一下思路 工具/原料 python 方法/步骤 1 首先我们需要确定要爬取的目标页面内容&#xf…

花书《深度学习》代码实现:01 线性代数:基本概念+代码实现基本运算

1 标量、向量、矩阵和张量 2 矩阵和向量相乘 3 单位矩阵和逆矩阵 3.0 单位矩阵 a np.identity(3) # 三行三列单位矩阵 3.1 矩阵的逆 A [[1.0,2.0],[3.0,4.0]] A_inv np.linalg.inv(A) print("A 的逆矩阵", A_inv) 3.1 转置 A np.array([[1.0,2.0],[1.0,0…

【Pytorch神经网络理论篇】 38 Transformers:安装说明+应用结构+AutoModel类

同学你好!本文章于2021年末编写,获得广泛的好评! 故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现, Pytorch深度学习理论篇(2023版)目录地址…

clone是深拷贝还是浅拷贝_Python中的浅拷贝和深拷贝

本文翻译自copy in Python (Deep Copy and Shallow Copy),讲述了在Python语言中浅拷贝与深拷贝的不同用法。全文系作者原创,仅供学习参考使用,转载授权请私信联系,否则将视为侵权行为。码字不易,感谢支持。以下为全文内…

【Pytorch神经网络实战案例】32 使用Transformers库的管道方式实现:加载指定模型+文本分类+掩码语言建模+摘要生成+特征提取+阅读理解+实体词识别

管道方式是Transformers库中高度集成的极简使用方式。使用这种方式来处理NLP任务,只需要编写几行代码就能实现。通过本例的练习可以使读者对Transformers库的使用快速上手。 1 在管道方式中指定NLP任务 Transfomers库的管道方式使用起来非常简单,核心步…

jqprint获取打印页数_如何将每张打印多页PPT的PDF变成常规课件

在工作和学习中,经常会收到各种 PDF 文件,尤其是老师的课件。为了防止学生大量上传到各种文库网站赚积分,或者为了方便学生打印出来预习复习。通常,会在每页 PDF 里面,打印多张 PPT 内容。一般是 6 张或 9 张&#xff…

vba 判断文本框内容是否为空_【VBA】 数据输入 Inputbox 基本语法

在使用Excel 的过程中,如果需要用户输入简单的数据,作为“已知数”,那么可以使用inputbox 函数显示一个对话框,供用户在对话框中输入数据。 Inputbox 函数语法在一对话框来中显示提示,等待用户输入正文或按下按钮&…

无向图的深度优先遍历非递归_LeetCode0429: N叉树的层序遍历

题目介绍描述:给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。例如,给定一个 3叉树 :返回其层序遍历:[[1],[3,2,4],[5,6] ]说明:树的深度不会超过 1000。 树的节点总数不会超过 5000。解题思路:★ …

一条龙操作有效解决PermissionError: [WinError 5] 拒绝访问的问题

1 问题描述 当在使用pip install 安装包时,如:pip install scrapy scrapyd scrapyd-client spiderkeeper出现报错:PermissionError: [WinError 5] 拒绝访问。: ‘c:\programdata\anaconda3\lib\site-packages\dateutil\easter.py’ 2 解决办…