{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Practical 12 \n",
"\n",
"This practical has two parts (jupyter notebooks), **Part I: Word embeddings** and **Part II: Transformers**.\n",
"\n",
"# Part I: Word embeddings\n",
"\n",
"This Jupyter Notebook consists of the following parts:\n",
"1. [Word Embeddings](#word_embeddings) \n",
" 1. [Word2Vec](#word2vec) \n",
" 2. [Word2Vec Architectures](#word2vec_arch) \n",
" 3. [Word Embeddings Visualisation](#visual)\n",
"2. [Exploring Word Vectors with GloVe](glove)\n",
" 1. [Loading Word Vectors](#loading)\n",
" 2. [Finding Closest Vectors](#finding)\n",
" 3. [Word Analogies with Vector Arithmetic](#analogies)\n",
"3. [Motivation for Part II: Transformers](#transformers)\n",
"\n",
"\n",
"Check out a supplementary jupyter notebook for Part I, if interested in Skip-Gram implementation."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"# Word embeddings"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Word2Vec\n",
"\n",
"There are two classes of vector models: count-based (TF-IDF, Bag-of-Words) and neural-based. In this practical we will be focusing on neural word embeddings, i.e. word embeddings learned by a neural network.\n",
"\n",
"**Main idea:** to use neural architectures that are predicting (not counting) the next word or a context of a given word.\n",
"\n",
"One of the most known such models is **Word2Vec**. It is based on a neural network that is predicting the probability of a word given it's context. It was created by Mikolov et al. (2013). Here are the main papers on the topic:\n",
"\n",
"* [Efficient Estimation of Word Representations in Vector Space](https://arxiv.org/pdf/1301.3781.pdf)\n",
"* [Distributed Representations of Words and Phrases and their Compositionality](https://arxiv.org/abs/1310.4546)\n",
"\n",
"These vectors are ususally reffered to as **_distributed representations of words_** or **_word embeddings_**.\n",
"\n",
"_As word embeddings are a key building block of deep learning models for NLP, word2vec is often assumed to belong to the same group. Technically however, word2vec is not be considered to be part of deep learning, as its architecture is neither deep nor uses non-linearities_ \n",
"\n",
"*a quote from [Sebastian Ruder's blog](https://ruder.io/word-embeddings-1/) \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Word2Vec Architectures\n",
"\n",
"There are two Word2Vec architectures: Skip-Gram and CBOW.\n",
"\n",
"**Skip-Gram** predicts context words given the central word. Skip-Gram with negative sampling is the most popular approach.\n",
"\n",
"**CBOW (Continuous Bag-of-Words)** predicts the central word from the sum of context vectors. This simple sum of word vectors is called \"bag of words\", which gives the name for the model.\n",
"\n",
"\n",
"\n",
"\n",
"*the image is taken for [Lena Voita's blog](https://lena-voita.github.io/nlp_course/word_embeddings.html#main_content) \n",
"*if interested, please, check it out, it is very informative and illustrative"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### How does it work?\n",
"\n",
"Word2vec takes a large text corpus as input and maps each word to a vector, producing word coordinates as output. It first creates a dictionary by training on the input text data, and then calculates a vector representation of the words. The vector representation is learned on contextual proximity: words that occur in the text next to the same words (and therefore, according to the distributive hypothesis, have a similar meaning) will have close coordinates in the vector representation. \n",
"\n",
"To calculate the proximity of words, usually the cosine or euclidean distances between vectors are used.\n",
"\n",
"Using distributed representations you can build semantic proportions (also known as analogies) and solve examples like:\n",
"\n",
"*king: male = queen: female*\n",
" $\\Rightarrow$\n",
"*king - man + woman = queen*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Word Embeddings Visualization\n",
"\n",
"Go to https://projector.tensorflow.org/ and visualize Word2Vec embeddings. \n",
"\n",
"Original Word2Vec repository: https://code.google.com/archive/p/word2vec/"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"# Exploring Word Vectors with GloVe:\n",
"\n",
"As we have seen, the word2vec algorithms (such as Skip-Gram) predicts words in a context (e.g. what is the most likely word to appear in \"the cat ? the mouse\"), while GloVe vectors are based on global counts across the corpus — [see How is GloVe different from word2vec?](https://www.quora.com/How-is-GloVe-different-from-word2vec) on Quora for some better explanations.\n",
"\n",
"The best feature of GloVe is that multiple sets of pre-trained vectors are easily available for [download](https://nlp.stanford.edu/projects/glove/), so that's what we'll use here.\n",
"\n",
"Part II of this notebook is taken from [practical-pytorch tutorials](https://github.com/spro/practical-pytorch/blob/master/glove-word-vectors/glove-word-vectors.ipynb)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Installing torchtext"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"#! pip install torchtext"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Loading Word Vectors\n",
"Torchtext includes functions to download GloVe (and other) embeddings"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"from torchtext.vocab import GloVe"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
".vector_cache/glove.6B.zip: 862MB [02:42, 5.32MB/s] \n",
"100%|█████████▉| 399999/400000 [00:07<00:00, 55651.76it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loaded 400000 words\n"
]
}
],
"source": [
"glove = GloVe(name='6B', dim=50)\n",
"print('Loaded {} words'.format(len(glove.itos)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Loaded 400000 words\n",
"The returned GloVe object includes attributes:\n",
"\n",
"- stoi string-to-index returns a dictionary of words to indexes\n",
"- itos index-to-string returns an array of words by index\n",
"- vectors returns the actual vectors. To get a word vector get the index to get the vector:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def get_word(word):\n",
" return glove.vectors[glove.stoi[word]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Finding Closest Vectors\n",
"\n",
"Going from word → vector is easy enough, but to go from vector → word takes more work. Here I'm (naively) calculating the distance for each word in the vocabulary, and sorting based on that distance:\n",
"\n",
"Anyone with a suggestion for optimizing this, please let me know!"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"from tqdm import tqdm_notebook as tqdm\n",
"def closest(vec, n=10):\n",
" \"\"\"\n",
" Find the closest words for a given vector\n",
" \"\"\"\n",
" all_dists = [(w, torch.dist(vec, get_word(w))) for w in tqdm(glove.itos)]\n",
" return sorted(all_dists, key=lambda t: t[1])[:n]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This will return a list of (word, distance) tuple pairs. Here's a helper function to print that list:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def print_tuples(tuples):\n",
" for tuple in tuples:\n",
" print('(%.4f) %s' % (tuple[1], tuple[0]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now using a known word vector we can see which other vectors are closest:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
":6: TqdmDeprecationWarning: This function will be removed in tqdm==5.0.0\n",
"Please use `tqdm.notebook.tqdm` instead of `tqdm.tqdm_notebook`\n",
" all_dists = [(w, torch.dist(vec, get_word(w))) for w in tqdm(glove.itos)]\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "7b6796e5aca840a88f2e25ade0a5f5b0",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/400000 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"(0.0000) neuron\n",
"(3.6448) neuronal\n",
"(3.7174) presynaptic\n",
"(3.7488) synapse\n",
"(3.7969) excitability\n",
"(3.8072) neurons\n",
"(3.8454) synapses\n",
"(3.9334) pre-synaptic\n",
"(3.9602) axon\n",
"(4.0266) axons\n"
]
}
],
"source": [
"print_tuples(closest(get_word('neuron')))"
]
},
{
"attachments": {
"Screenshot%202020-03-17%20at%2019.10.40.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Word Analogies with Vector Arithmetic\n",
"The most interesting feature of a well-trained word vector space is that certain semantic relationships (beyond just close-ness of words) can be captured with regular vector arithmetic.\n",
"\n",
"\n",
"\n",
"(image borrowed from a slide from [a slide from Omer Levy and Yoav Goldberg](https://levyomer.wordpress.com/2014/04/25/linguistic-regularities-in-sparse-and-explicit-word-representations/))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# In the form w1 : w2 :: w3 : ?\n",
"def analogy(w1, w2, w3, n=10, filter_given=True):\n",
" # w2 - w1 + w3 = w4\n",
" closest_words = closest(get_word(w2) - get_word(w1) + get_word(w3), n=n)\n",
" print('\\n[%s - %s + %s = ?]' % (w1, w2, w3))\n",
" # Optionally filter out given words\n",
" if filter_given:\n",
" closest_words = [t for t in closest_words if t[0] not in [w1, w2, w3]]\n",
" \n",
" print_tuples(closest_words[:n])"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
":6: TqdmDeprecationWarning: This function will be removed in tqdm==5.0.0\n",
"Please use `tqdm.notebook.tqdm` instead of `tqdm.tqdm_notebook`\n",
" all_dists = [(w, torch.dist(vec, get_word(w))) for w in tqdm(glove.itos)]\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "98c394174809481f9705bf6edf088ba3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/400000 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"[king - man + queen = ?]\n",
"(2.8391) woman\n",
"(3.3545) girl\n",
"(3.9518) boy\n",
"(4.0233) her\n",
"(4.0554) herself\n",
"(4.1365) she\n",
"(4.3874) blind\n",
"(4.4540) mother\n",
"(4.4820) lover\n"
]
}
],
"source": [
"analogy('king', 'man', 'queen')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Comment:** One of the applications of word embeddings is for example using them in the embedding layer of your model instead of using randomly initialised input that is being corrected during training. \n",
"\n",
"These pre-trained word embeddings (from Word2Vec, Glove, etc.) can either be kept static or modified during training.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"# Motivation for Part II: Transformers"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Word embeddings that we discussed above have one major limitation – they are **static**. This means that each word has a vector that does not change given different contexts.\n",
"\n",
"While **contextualized** word embeddings can give words different embeddings based on the meaning they carry in the context of the sentence."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_\"If we’re using this GloVe representation, then the word “stick” would be represented by this vector no-matter what the context was. “Wait a minute” said a number of NLP researchers (Peters et. al., 2017, McCann et. al., 2017, and yet again Peters et. al., 2018 in the ELMo paper ), “stick”” has multiple meanings depending on where it’s used. Why not give it an embedding based on the context it’s used in – to both capture the word meaning in that context as well as other contextual information?”. And so, contextualized word-embeddings were born...\"_"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"*the image and the quote are taken from [Jay Alammar's blogpost](https://jalammar.github.io/illustrated-bert/) about BERT, ELMo and co."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Contextualized embeddings can be captured with Transformer-based models like BERT that are usually trained to predict randomly masked words. \n",
"See **Part II** of this practical to learn more about transformers!"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}