[PYTHON] J'ai créé Word2Vec avec Pytorch

Cet article est le 11ème jour du Calendrier de l'Avent Ibaraki 2019.

Implémentez Word2Vec avec Pytorch. Word2Vec Quand j'ai pensé à construire Word2Vec, de nombreux articles de gensim ont été touchés, mais comme il y avait peu d'articles qui implémentaient Word2Vec en utilisant Pytorch, j'ai décidé de le publier. Puisqu'il existe de nombreux articles qui expliquent Word2Vec, je vais l'expliquer brièvement.

Skip-gram

Screen Shot 2019-12-01 at 14.25.48.png

skip-gram maximise la probabilité de sortie de la séquence de mots environnante $ {, w (t-1), w (t + 1)} $ lorsque le mot d'entrée $ w (t) $ est donné. Par conséquent, la variable objective à minimiser est la suivante.

\begin{align}
E 
&= -log p( w_{t-1},w_{t+1} | w_{t} ) \\
&= -log p(w_{t-1},w_{t})*p(w_{t+1},w_{t}) \\
&= -log \prod_{i}\frac{exp(p(w_{i},w_{t}))}{\sum_{j}exp(p(w_{j},w_{t}))}
\end{align}

Ici, la molécule est un mot pour la taille de la fenêtre, mais le dénominateur doit calculer le nombre total de mots. Puisque ce n'est pas possible, nous l'approcherons avec un échantillonnage négatif.

Code d'échantillonnage négatif

Les mots sortis par échantillonnage négatif sont déterminés par la fréquence d'apparition des mots comme indiqué dans la référence [1]. Le programme ressemble à ceci:

def sample_negative(sample_size):
    prob = {}
    word2cnt = dict(Counter(list(itertools.chain.from_iterable(corpus))))
    
    pow_sum = sum([v**0.75 for v in word2cnt.values()])
    for word in word2cnt:
        prob[word] = word_counts[word]**0.75 / pow_sum
    words = np.array(list(word2cnt.keys()))
    while True:
        word_list = []
        sampled_index = np.array(multinomial(sample_size, list(prob.values())))
        for index, count in enumerate(sampled_index):
            for _ in range(count):
                 word_list.append(words[index])
        yield word_list

Créer un modèle

Il existe également un moyen d'exprimer un mot avec Onehot pour saisir un mot, mais cela augmenterait la dimension du nombre de mots.Après l'avoir converti en vecteur de mot à l'aide du calque d'incorporation, appliquez-le à Encoder et Decoder. L'évaluation prend le produit interne des vecteurs de mots et le produit avec la fonction log sigmoïde. La formule de calcul est la suivante.

L= \sum_{i} log \sigma({v'}_{w_{i}}^{T}v_{w_{I}})+\sum_{i}log \sigma(-{v'}_{w_{i}}^{T}v_{w_{I}})

class SkipGram(nn.Module):
    def __init__(self, V, H):
        super(SkipGram, self).__init__()
        self.encode_embed = nn.Embedding(V, H)
        self.decode_embed = nn.Embedding(V, H)
        
        self.encode_embed.weight.data.uniform_(-0.5/H, 0.5/H)
        self.decode_embed.weight.data.uniform_(0.0, 0.0)
        
    def forward(self, contexts, center, neg_target):
        embed_ctx = self.encode_embed(contexts)
        embed_center = self.decode_embed(center)
        neg_embed_center= self.encode_embed(neg_target)

        #produit intérieur
        ##Exemple positif
        score = torch.matmul(embed_ctx, torch.t(embed_center))
        score = torch.sum(score, dim=2).view(1, -1)
        log_target = F.logsigmoid(score)
        
        ##Exemple négatif
        neg_score = torch.matmul(embed_ctx, torch.t(neg_embed_center))
        neg_score = -torch.sum(neg_score, dim=2).view(1, -1)
        log_neg_target = F.logsigmoid(neg_score)

        return -1 * (torch.mean(log_target) + torch.mean(log_neg_target))

Il semble qu'il soit courant de séparer l'incorporation de l'encodeur et du décodeur. Puisqu'il s'agit d'un problème de maximisation, il est multiplié par un moins.

résultat

Screen Shot 2019-12-10 at 17.02.41.png

La précision n'est pas bonne dans son ensemble et il est nécessaire de définir le planificateur et le taux d'apprentissage de manière appropriée.

Je n'ai pas organisé le code, je publierai donc tout le code après l'avoir organisé.

Les références

[1] Distributed Representations of Words and Phrases and their Compositionality [2] word2vec Parameter Learning Explained

Recommended Posts

J'ai créé Word2Vec avec Pytorch
J'ai fait un blackjack avec du python!
J'ai fait un blackjack avec Python.
J'ai créé wordcloud avec Python.
J'ai fait une loterie avec Python.
J'ai essayé d'implémenter Attention Seq2Seq avec PyTorch
J'ai essayé d'implémenter DeepPose avec PyTorch
J'ai créé un démon avec Python
J'ai essayé d'implémenter la régularisation Shake-Shake (ShakeNet) avec PyTorch
Word2Vec avec BoUoW
Jouez avec PyTorch
[Introduction à Pytorch] J'ai joué avec sinGAN ♬
J'ai essayé d'implémenter DeepPose avec PyTorch PartⅡ
J'ai essayé d'implémenter CVAE avec PyTorch
À partir de PyTorch
J'ai fait une carte hexadécimale avec Python
J'ai fait un générateur Hanko avec GAN
J'ai fait un jeu rogue-like avec Python
J'ai fait un simple blackjack avec Python
J'ai créé un fichier de configuration avec Python
J'ai fait une application WEB avec Django
J'ai fait un simulateur de neurones avec Python
J'ai fait un robot de remplacement de tampon avec une ligne
J'ai essayé d'implémenter la lecture de Dataset avec PyTorch
J'ai fait une prévision météo de type bot avec Python.
J'ai créé une application graphique avec Python + PyQt5
J'ai fait mon chien "Monaka Bot" avec Line Bot
J'ai essayé de créer un bloqueur de filles pourries sur Twitter avec Python ①
[Python] J'ai créé un téléchargeur Youtube avec Tkinter.
J'ai fait un simple portefeuille de Bitcoin avec pycoin
J'ai créé un Bot LINE avec Serverless Framework!
J'ai fait un graphique de nombres aléatoires avec Numpy
J'ai fait un jeu de cueillette avec Python
Made Mattermost Bot avec Python (+ Flask)
Utilisez RTX 3090 avec PyTorch
〇✕ J'ai fait un jeu
En forme de conteneur réalisé avec C # 1
Installer la diffusion de la torche avec PyTorch 1.7
J'ai créé un installateur Ansible
[AWS] J'ai créé un BOT de rappel avec LINE WORKS
J'ai fait un Twitter BOT avec GAE (python) (avec une référence)
J'ai créé un bot de livre de compte de ménage avec LINE Bot
J'ai essayé de déplacer Faster R-CNN rapidement avec pytorch
J'ai essayé d'implémenter et d'apprendre DCGAN avec PyTorch
J'ai créé un serveur syslog prêt à l'emploi avec Play with Docker
J'ai fait un jeu d'éclairage de sapin de Noël avec Python
J'ai créé une fenêtre pour la sortie du journal avec Tkinter
J'ai créé une application de notification de nouvelles en ligne avec Python
J'ai créé un environnement Python3 sur Ubuntu avec direnv.
J'ai essayé de faire LINE BOT avec Python et Heroku
[Introduction à Pytorch] J'ai essayé de catégoriser Cifar10 avec VGG16 ♬
J'ai essayé d'implémenter SSD avec PyTorch maintenant (Dataset)
J'ai eu une erreur lors de l'utilisation de Tensorboard avec Pytorch