学习词向量的概念
用Skip-thought模型训练词向量
学习使用PyTorch dataset 和 dataloader
学习定义PyTorch模型
学习torch.nn中常见的Module
学习常见的PyTorch operations
bmm
logsigmoid
保存和读取PyTorch模型
训练数据:
链接:https://pan.baidu.com/s/1tFeK3mXuVXEy3EMarfeWvg 密码:v2z5
在这一份notebook中,我们会(尽可能)尝试复现论文Distributed Representations of Words and Phrases and their Compositionality中训练词向量的方法.
我们会实现Skip-gram模型,并且使用论文中noice contrastive sampling的目标函数。
这篇论文有很多模型实现的细节,这些细节对于词向量的好坏至关重要。我们虽然无法完全复现论文中的实验结果,主要是由于计算资源等各种细节原因,但是我们还是可以大致展示如何训练词向量。
以下是一些我们没有实现的细节
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.data as tud
from torch.nn.parameter import Parameter
from collections import Counter
import numpy as np
import random
import math
import pandas as pd
import scipy
import sklearn
from sklearn.metrics.pairwise import cosine_similarity
USE_CUDA = torch.cuda.is_available()
# 为了保证实验结果可以复现,我们经常会把各种random seed固定在某一个值
random.seed(53113)
np.random.seed(53113)
torch.manual_seed(53113)
if USE_CUDA:
torch.cuda.manual_seed(53113)
# 设定一些超参数
K = 100 # number of negative samples
C = 3 # nearby words threshold
NUM_EPOCHS = 2 # The number of epochs of training
MAX_VOCAB_SIZE = 30000 # the vocabulary size
BATCH_SIZE = 128 # the batch size
LEARNING_RATE = 0.2 # the initial learning rate
EMBEDDING_SIZE = 100 # 词向量维度
LOG_FILE = "word-embedding.log"
# tokenize函数,把一篇文本转化成一个个单词
def word_tokenize(text):
return text.split()
从文本文件中读取所有的文字,通过这些文本创建一个vocabulary
由于单词数量可能太大,我们只选取最常见的MAX_VOCAB_SIZE个单词
我们添加一个UNK单词表示所有不常见的单词
我们需要记录单词到index的mapping,以及index到单词的mapping,单词的count,单词的(normalized) frequency,以及单词总数。
with open("./text8.train.txt", "r") as fin:
text = fin.read()
text = [w for w in word_tokenize(text.lower())]
vocab = dict(Counter(text).most_common(MAX_VOCAB_SIZE - 1)) # 29999,单词:词频,降序
vocab[‘<unk>‘] = len(text) - np.sum(list(vocab.values())) # print(vocab)
idx_to_word = [word for word in vocab.keys()]
word_to_idx = {word:i for i, word in enumerate(idx_to_word)}
word_counts = np.array([count for count in vocab.values()], dtype=np.float32) # 词频统计
word_freqs = word_counts / np.sum(word_counts)
word_freqs = word_freqs ** (3./4.)
word_freqs = word_freqs / np.sum(word_freqs) # 用来做 negative sampling
VOCAB_SIZE = len(idx_to_word)
VOCAB_SIZE # 3000
一个dataloader需要以下内容:
把所有text编码成数字,然后用subsampling预处理这些文字。
保存vocabulary,单词count,normalized word frequency
每个iteration sample一个中心词
根据当前的中心词,返回context单词
根据中心词sample一些negative单词,返回单词的counts
这里有一个好的tutorial介绍如何使用PyTorch dataloader.
为了使用dataloader,我们需要定义以下两个function:
__len__ function需要返回整个数据集中有多少个item__get__ 根据给定的index返回一个item有了dataloader之后,我们可以轻松随机打乱整个数据集,拿到一个batch的数据等等。
原文:https://www.cnblogs.com/douzujun/p/13429912.html