Credits: Forked from TensorFlow by Google
Refer to the setup instructions.
The goal of this exercise is to train a skip-gram model over Text8 data.
# These are all the modules we'll be using later. Make sure you can import them
# before proceeding further.
import collections
import math
import numpy as np
import os
import random
import tensorflow as tf
import urllib
import zipfile
from matplotlib import pylab
from sklearn.manifold import TSNE
Download the data from the source website if necessary.
url = 'http://mattmahoney.net/dc/'
def maybe_download(filename, expected_bytes):
"""Download a file if not present, and make sure it's the right size."""
if not os.path.exists(filename):
filename, _ = urllib.urlretrieve(url + filename, filename)
statinfo = os.stat(filename)
if statinfo.st_size == expected_bytes:
print 'Found and verified', filename
else:
print statinfo.st_size
raise Exception(
'Failed to verify ' + filename + '. Can you get to it with a browser?')
return filename
filename = maybe_download('text8.zip', 31344016)
Found and verified text8.zip
Read the data into a string.
def read_data(filename):
f = zipfile.ZipFile(filename)
for name in f.namelist():
return f.read(name).split()
f.close()
words = read_data(filename)
print 'Data size', len(words)
Data size 17005207
Build the dictionary and replace rare words with UNK token.
vocabulary_size = 50000
def build_dataset(words):
count = [['UNK', -1]]
count.extend(collections.Counter(words).most_common(vocabulary_size - 1))
dictionary = dict()
for word, _ in count:
dictionary[word] = len(dictionary)
data = list()
unk_count = 0
for word in words:
if word in dictionary:
index = dictionary[word]
else:
index = 0 # dictionary['UNK']
unk_count = unk_count + 1
data.append(index)
count[0][1] = unk_count
reverse_dictionary = dict(zip(dictionary.values(), dictionary.keys()))
return data, count, dictionary, reverse_dictionary
data, count, dictionary, reverse_dictionary = build_dataset(words)
print 'Most common words (+UNK)', count[:5]
print 'Sample data', data[:10]
del words # Hint to reduce memory.
Most common words (+UNK) [['UNK', 418391], ('the', 1061396), ('of', 593677), ('and', 416629), ('one', 411764)] Sample data [5243, 3083, 12, 6, 195, 2, 3136, 46, 59, 156]
Function to generate a training batch for the skip-gram model.
data_index = 0
def generate_batch(batch_size, num_skips, skip_window):
global data_index
assert batch_size % num_skips == 0
assert num_skips <= 2 * skip_window
batch = np.ndarray(shape=(batch_size), dtype=np.int32)
labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)
span = 2 * skip_window + 1 # [ skip_window target skip_window ]
buffer = collections.deque(maxlen=span)
for _ in range(span):
buffer.append(data[data_index])
data_index = (data_index + 1) % len(data)
for i in range(batch_size / num_skips):
target = skip_window # target label at the center of the buffer
targets_to_avoid = [ skip_window ]
for j in range(num_skips):
while target in targets_to_avoid:
target = random.randint(0, span - 1)
targets_to_avoid.append(target)
batch[i * num_skips + j] = buffer[skip_window]
labels[i * num_skips + j, 0] = buffer[target]
buffer.append(data[data_index])
data_index = (data_index + 1) % len(data)
return batch, labels
batch, labels = generate_batch(batch_size=8, num_skips=2, skip_window=1)
for i in range(8):
print batch[i], '->', labels[i, 0]
print reverse_dictionary[batch[i]], '->', reverse_dictionary[labels[i, 0]]
3083 -> 5243 originated -> anarchism 3083 -> 12 originated -> as 12 -> 3083 as -> originated 12 -> 6 as -> a 6 -> 12 a -> as 6 -> 195 a -> term 195 -> 6 term -> a 195 -> 2 term -> of
Train a skip-gram model.
batch_size = 128
embedding_size = 128 # Dimension of the embedding vector.
skip_window = 1 # How many words to consider left and right.
num_skips = 2 # How many times to reuse an input to generate a label.
# We pick a random validation set to sample nearest neighbors. here we limit the
# validation samples to the words that have a low numeric ID, which by
# construction are also the most frequent.
valid_size = 16 # Random set of words to evaluate similarity on.
valid_window = 100 # Only pick dev samples in the head of the distribution.
valid_examples = np.array(random.sample(xrange(valid_window), valid_size))
num_sampled = 64 # Number of negative examples to sample.
graph = tf.Graph()
with graph.as_default():
# Input data.
train_dataset = tf.placeholder(tf.int32, shape=[batch_size])
train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])
valid_dataset = tf.constant(valid_examples, dtype=tf.int32)
# Variables.
embeddings = tf.Variable(
tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
softmax_weights = tf.Variable(
tf.truncated_normal([vocabulary_size, embedding_size],
stddev=1.0 / math.sqrt(embedding_size)))
softmax_biases = tf.Variable(tf.zeros([vocabulary_size]))
# Model.
# Look up embeddings for inputs.
embed = tf.nn.embedding_lookup(embeddings, train_dataset)
# Compute the softmax loss, using a sample of the negative labels each time.
loss = tf.reduce_mean(
tf.nn.sampled_softmax_loss(softmax_weights, softmax_biases, embed,
train_labels, num_sampled, vocabulary_size))
# Optimizer.
optimizer = tf.train.AdagradOptimizer(1.0).minimize(loss)
# Compute the similarity between minibatch examples and all embeddings.
# We use the cosine distance:
norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keep_dims=True))
normalized_embeddings = embeddings / norm
valid_embeddings = tf.nn.embedding_lookup(
normalized_embeddings, valid_dataset)
similarity = tf.matmul(valid_embeddings, tf.transpose(normalized_embeddings))
num_steps = 100001
with tf.Session(graph=graph) as session:
tf.global_variables_initializer().run()
print "Initialized"
average_loss = 0
for step in xrange(num_steps):
batch_data, batch_labels = generate_batch(
batch_size, num_skips, skip_window)
feed_dict = {train_dataset : batch_data, train_labels : batch_labels}
_, l = session.run([optimizer, loss], feed_dict=feed_dict)
average_loss += l
if step % 2000 == 0:
if step > 0:
average_loss = average_loss / 2000
# The average loss is an estimate of the loss over the last 2000 batches.
print "Average loss at step", step, ":", average_loss
average_loss = 0
# note that this is expensive (~20% slowdown if computed every 500 steps)
if step % 10000 == 0:
sim = similarity.eval()
for i in xrange(valid_size):
valid_word = reverse_dictionary[valid_examples[i]]
top_k = 8 # number of nearest neighbors
nearest = (-sim[i, :]).argsort()[1:top_k+1]
log = "Nearest to %s:" % valid_word
for k in xrange(top_k):
close_word = reverse_dictionary[nearest[k]]
log = "%s %s," % (log, close_word)
print log
final_embeddings = normalized_embeddings.eval()
Initialized Average loss at step 0 : 8.58149623871 Nearest to been: unfavourably, marmara, ancestral, legal, bogart, glossaries, worst, rooms, Nearest to time: conformist, strawberries, sindhi, waterfall, xia, nominates, psp, sensitivity, Nearest to over: overlord, panda, golden, semigroup, rawlings, involved, shreveport, handling, Nearest to not: hymenoptera, reintroducing, lamiaceae, because, davao, omnipotent, combustion, debilitating, Nearest to three: catalog, koza, gn, braque, holstein, postgresql, luddite, justine, Nearest to if: chilled, vince, fiddler, represented, sandinistas, happiness, lya, glands, Nearest to there: coast, photosynthetic, kimmei, legally, inner, illyricum, formats, fullmetal, Nearest to between: chuvash, prinz, suitability, wolfe, guideline, computability, diminutive, paulo, Nearest to from: tanganyika, workshop, elphinstone, spearhead, resurrected, kevlar, shangri, loves, Nearest to state: sextus, wuppertal, glaring, inches, unrounded, courageous, adler, connie, Nearest to on: gino, phocas, rhine, jg, macrocosm, jackass, jays, theorie, Nearest to and: standings, towed, reyes, willard, equality, juggling, wladislaus, faked, Nearest to eight: gresham, dogg, moko, tennis, superseded, telegraphy, scramble, vinod, Nearest to they: prisons, divisor, coder, ribeira, willingness, factional, nne, lotta, Nearest to more: blues, fur, sterling, tangier, khwarizmi, discouraged, cal, deicide, Nearest to other: enemies, bogged, brassicaceae, lascaux, dispense, alexandrians, crimea, dou, Average loss at step 2000 : 4.39983723116 Average loss at step 4000 : 3.86921076906 Average loss at step 6000 : 3.72542127335 Average loss at step 8000 : 3.57835536212 Average loss at step 10000 : 3.61056993055 Nearest to been: glossaries, legal, unfavourably, be, hadad, wore, scarcity, were, Nearest to time: strawberries, conformist, gleichschaltung, waterfall, molality, nominates, baal, dole, Nearest to over: golden, semigroup, catus, motorways, brick, shehri, mussolini, overlord, Nearest to not: hinayana, it, often, they, boots, also, noaa, lindsey, Nearest to three: four, seven, six, five, nine, eight, two, zero, Nearest to if: glands, euros, wallpaper, redefine, toho, confuse, unsound, shepherd, Nearest to there: it, they, fullmetal, pace, legally, harpsichord, mma, bug, Nearest to between: chuvash, wandering, from, kirsch, pursuant, eurocents, suitability, jackie, Nearest to from: into, in, workshop, to, at, misogynist, elphinstone, spearhead, Nearest to state: sextus, glaring, connie, adler, esoteric, didactic, handedness, presidents, Nearest to on: in, at, for, ruminants, wakefulness, torrey, foley, gino, Nearest to and: or, who, but, zelda, of, for, thirst, chisel, Nearest to eight: nine, six, seven, five, four, three, zero, two, Nearest to they: he, prisons, there, we, hydrate, it, not, cumbersome, Nearest to more: skye, blues, trypomastigotes, deicide, most, readable, used, sterling, Nearest to other: trochaic, hush, surveyors, joachim, differentiation, attackers, reverence, attestation, Average loss at step 12000 : 3.66169466591 Average loss at step 14000 : 3.60342905837 Average loss at step 16000 : 3.57761328053 Average loss at step 18000 : 3.57667332476 Average loss at step 20000 : 3.53310145146 Nearest to been: be, become, was, hadad, unfavourably, were, wore, partido, Nearest to time: gleichschaltung, strawberries, year, nominates, conformist, etch, admittedly, treasuries, Nearest to over: golden, semigroup, motorways, rawlings, triangle, trey, ustawa, mattingly, Nearest to not: they, boots, often, dieppe, still, hinayana, nearly, be, Nearest to three: two, four, five, seven, eight, six, nine, one, Nearest to if: wallpaper, euros, before, toho, unsound, so, bg, pfc, Nearest to there: they, it, he, usually, which, we, not, transactions, Nearest to between: from, with, about, near, reactance, eurocents, wandering, voltaire, Nearest to from: into, workshop, by, between, in, on, elphinstone, under, Nearest to state: glaring, esoteric, succeeding, sextus, vorarlberg, presidents, depends, connie, Nearest to on: in, at, upon, during, from, janis, foley, nubian, Nearest to and: or, thirst, but, where, s, who, pfaff, including, Nearest to eight: nine, seven, six, five, four, three, zero, one, Nearest to they: there, he, we, not, it, you, prisons, who, Nearest to more: less, most, deicide, skye, trypomastigotes, interventionism, toed, drummond, Nearest to other: such, joachim, hush, attackers, surveyors, trochaic, differentiation, reverence, Average loss at step 22000 : 3.59519316927 Average loss at step 24000 : 3.55378576797 Average loss at step 26000 : 3.56455037558 Average loss at step 28000 : 3.5040882225 Average loss at step 30000 : 3.39208897972 Nearest to been: become, be, were, was, spotless, hadad, by, hausdorff, Nearest to time: gleichschaltung, year, day, nominates, jesus, strawberries, way, admittedly, Nearest to over: golden, semigroup, motorways, rawlings, interventionism, counternarcotics, adaption, brick, Nearest to not: often, they, it, never, still, nor, boots, pki, Nearest to three: four, six, two, eight, five, seven, nine, zero, Nearest to if: when, before, so, should, toho, where, bg, wallpaper, Nearest to there: they, it, which, usually, he, that, also, now, Nearest to between: with, from, in, panasonic, presupposes, churchmen, hijacking, where, Nearest to from: into, elphinstone, workshop, between, through, speculates, sosa, in, Nearest to state: esoteric, glaring, presidents, vorarlberg, atmosphere, succeeding, lute, connie, Nearest to on: upon, in, janis, during, torrey, against, infield, catalans, Nearest to and: or, thirst, in, but, of, sobib, cleaves, including, Nearest to eight: nine, six, four, seven, three, zero, five, one, Nearest to they: we, there, he, you, it, these, who, i, Nearest to more: less, most, deicide, faster, toed, very, skye, tonic, Nearest to other: different, attackers, joachim, various, such, many, differentiation, these, Average loss at step 32000 : 3.49501452419 Average loss at step 34000 : 3.48593705952 Average loss at step 36000 : 3.50112806576 Average loss at step 38000 : 3.49244426501 Average loss at step 40000 : 3.3890105716 Nearest to been: become, be, were, was, jolie, hausdorff, spotless, had, Nearest to time: year, way, gleichschaltung, period, day, stanislav, stage, outcome, Nearest to over: through, semigroup, rawlings, golden, about, brick, on, motorways, Nearest to not: they, radiated, never, pki, still, omnipotent, hinayana, really, Nearest to three: four, six, five, two, seven, eight, one, nine, Nearest to if: when, before, where, then, bg, because, can, should, Nearest to there: they, it, he, usually, this, typically, still, often, Nearest to between: with, in, from, about, against, churchmen, johansen, presupposes, Nearest to from: into, through, elphinstone, in, workshop, between, suing, under, Nearest to state: esoteric, presidents, atmosphere, vorarlberg, lute, succeeding, glaring, didactic, Nearest to on: upon, at, in, during, unitarians, under, catalans, batavians, Nearest to and: or, but, s, incapacitation, including, while, of, which, Nearest to eight: nine, six, seven, four, five, three, one, two, Nearest to they: we, he, there, you, she, i, not, it, Nearest to more: less, most, deicide, toed, greater, faster, quite, longer, Nearest to other: various, different, attackers, joachim, clutter, nz, trochaic, apulia, Average loss at step 42000 : 3.45294014364 Average loss at step 44000 : 3.47660055941 Average loss at step 46000 : 3.47458503014 Average loss at step 48000 : 3.47261548793 Average loss at step 50000 : 3.45390708435 Nearest to been: become, be, had, was, were, hausdorff, prem, remained, Nearest to time: way, year, period, stv, day, gleichschaltung, stage, outcome, Nearest to over: through, golden, semigroup, about, brick, counternarcotics, theremin, mattingly, Nearest to not: they, still, never, really, sometimes, it, kiwifruit, nearly, Nearest to three: five, four, six, seven, two, eight, one, nine, Nearest to if: when, before, where, because, connexion, though, so, whether, Nearest to there: they, it, he, this, now, often, usually, still, Nearest to between: with, from, fashioned, churchmen, panasonic, explores, within, racial, Nearest to from: into, through, under, elphinstone, between, workshop, circumpolar, idiom, Nearest to state: atmosphere, vorarlberg, esoteric, presidents, madhya, majority, moulin, bowmen, Nearest to on: upon, in, catalans, tezuka, minotaurs, wakefulness, batavians, guglielmo, Nearest to and: or, but, thirst, signifier, which, however, including, unattractive, Nearest to eight: six, nine, seven, five, four, three, zero, two, Nearest to they: we, there, he, you, it, she, these, not, Nearest to more: less, most, quite, very, further, faster, toed, deicide, Nearest to other: various, different, many, attackers, are, joachim, nihilo, reject, Average loss at step 52000 : 3.43597227755 Average loss at step 54000 : 3.25126817495 Average loss at step 56000 : 3.35102432287 Average loss at step 58000 : 3.44654818082 Average loss at step 60000 : 3.4287913968 Nearest to been: become, be, was, prem, had, remained, hadad, stanislavsky, Nearest to time: year, way, period, stv, barely, name, stage, restoring, Nearest to over: about, through, golden, adaption, counternarcotics, up, mattingly, brick, Nearest to not: still, never, nor, kiwifruit, they, nearly, therefore, rarely, Nearest to three: two, five, four, six, seven, eight, one, nine, Nearest to if: when, though, before, where, although, because, can, could, Nearest to there: they, it, he, still, she, we, this, often, Nearest to between: with, from, churchmen, among, ethical, within, vma, panasonic, Nearest to from: through, into, under, during, between, in, suing, across, Nearest to state: atmosphere, infringe, madhya, vorarlberg, government, bowmen, vargas, republic, Nearest to on: upon, through, within, ridiculous, janis, in, under, over, Nearest to and: or, while, including, but, of, like, whose, bannister, Nearest to eight: nine, six, five, four, seven, zero, three, two, Nearest to they: we, there, you, he, it, these, she, prisons, Nearest to more: less, most, quite, further, toed, very, faster, rather, Nearest to other: different, various, many, nihilo, these, amour, including, screenplays, Average loss at step 62000 : 3.38358767056 Average loss at step 64000 : 3.41693099326 Average loss at step 66000 : 3.39588000977 Average loss at step 68000 : 3.35567189544 Average loss at step 70000 : 3.38878934443 Nearest to been: become, be, was, prem, remained, were, being, discounts, Nearest to time: year, way, day, period, barely, ethos, stage, reason, Nearest to over: about, through, fortunately, semigroup, theremin, off, loudest, up, Nearest to not: still, nor, never, they, actually, nearly, unelected, therefore, Nearest to three: five, two, four, six, seven, eight, nine, zero, Nearest to if: when, though, before, where, because, then, after, since, Nearest to there: they, it, he, often, she, we, usually, still, Nearest to between: among, with, within, from, ethical, churchmen, racial, prentice, Nearest to from: through, into, within, during, under, until, between, across, Nearest to state: city, atmosphere, desks, surrounding, preservation, bohr, principal, republic, Nearest to on: upon, tezuka, through, within, wakefulness, catalans, at, ingeborg, Nearest to and: or, but, while, including, thirst, jerzy, massing, abadan, Nearest to eight: seven, six, nine, five, four, three, two, zero, Nearest to they: we, you, he, there, she, it, prisons, who, Nearest to more: less, most, quite, very, faster, smaller, further, larger, Nearest to other: various, different, some, screenplays, lab, many, including, debugging, Average loss at step 72000 : 3.41103189731 Average loss at step 74000 : 3.44926435578 Average loss at step 76000 : 3.4423020488 Average loss at step 78000 : 3.41976813722 Average loss at step 80000 : 3.39511853886 Nearest to been: become, be, remained, was, grown, were, prem, already, Nearest to time: year, way, period, reason, barely, distance, stage, day, Nearest to over: about, fortunately, through, semigroup, further, mattingly, rawlings, golden, Nearest to not: still, they, nor, never, we, kiwifruit, noaa, really, Nearest to three: five, two, seven, four, eight, six, nine, zero, Nearest to if: when, where, though, before, since, because, although, follows, Nearest to there: they, it, he, we, she, still, typically, actually, Nearest to between: with, among, within, in, racial, around, from, serapeum, Nearest to from: into, through, in, within, under, using, during, towards, Nearest to state: city, atmosphere, ferro, vorarlberg, surrounding, republic, madhya, national, Nearest to on: upon, poll, in, from, tezuka, janis, through, within, Nearest to and: or, but, including, while, s, which, thirst, although, Nearest to eight: nine, seven, six, five, four, three, zero, two, Nearest to they: we, you, there, he, she, it, these, not, Nearest to more: less, most, smaller, very, faster, quite, rather, larger, Nearest to other: various, different, joachim, including, theos, smaller, individual, screenplays, Average loss at step 82000 : 3.40933967865 Average loss at step 84000 : 3.41618054378 Average loss at step 86000 : 3.31485116804 Average loss at step 88000 : 3.37068593091 Average loss at step 90000 : 3.2785516749 Nearest to been: become, be, was, prem, remained, grown, recently, already, Nearest to time: year, way, period, day, barely, battle, buds, name, Nearest to over: through, about, fortunately, off, theremin, semigroup, extraterrestrial, mattingly, Nearest to not: nor, still, never, otherwise, generally, separately, gown, hydrate, Nearest to three: four, five, six, two, eight, seven, nine, zero, Nearest to if: when, where, before, though, because, since, then, while, Nearest to there: they, it, he, we, she, still, typically, fiorello, Nearest to between: with, among, within, from, churchmen, prentice, racial, panasonic, Nearest to from: through, into, across, during, towards, until, at, within, Nearest to state: bohr, city, atmosphere, ferro, bowmen, republic, retaliation, vorarlberg, Nearest to on: upon, in, tezuka, at, during, within, via, catalans, Nearest to and: or, including, but, while, like, thirst, with, schuman, Nearest to eight: seven, nine, six, five, four, three, zero, two, Nearest to they: we, there, he, you, she, it, prisons, these, Nearest to more: less, most, very, faster, larger, quite, smaller, better, Nearest to other: different, various, tamara, prosthetic, including, individual, failing, restaurants, Average loss at step 92000 : 3.40355363208 Average loss at step 94000 : 3.35647508007 Average loss at step 96000 : 3.34374570692 Average loss at step 98000 : 3.4230104093 Average loss at step 100000 : 3.36909827 Nearest to been: become, be, grown, was, being, already, remained, prem, Nearest to time: way, year, day, period, years, days, mothersbaugh, separators, Nearest to over: through, about, semigroup, further, fortunately, off, into, theremin, Nearest to not: never, nor, still, dieppe, really, unelected, actually, now, Nearest to three: four, two, five, seven, six, eight, nine, zero, Nearest to if: when, though, where, before, is, abe, then, follows, Nearest to there: they, it, he, we, still, she, typically, often, Nearest to between: within, with, among, churchmen, around, explores, from, reactance, Nearest to from: into, through, within, across, in, between, using, workshop, Nearest to state: atmosphere, bohr, national, ferro, germ, desks, city, unpaid, Nearest to on: upon, in, within, tezuka, janis, batavians, about, macrocosm, Nearest to and: or, but, purview, thirst, sukkot, epr, including, honesty, Nearest to eight: seven, nine, six, four, five, three, zero, one, Nearest to they: we, there, you, he, she, prisons, it, these, Nearest to more: less, most, very, quite, faster, larger, rather, smaller, Nearest to other: various, different, tamara, theos, some, cope, many, others,
num_points = 400
tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000)
two_d_embeddings = tsne.fit_transform(final_embeddings[1:num_points+1, :])
def plot(embeddings, labels):
assert embeddings.shape[0] >= len(labels), 'More labels than embeddings'
pylab.figure(figsize=(15,15)) # in inches
for i, label in enumerate(labels):
x, y = embeddings[i,:]
pylab.scatter(x, y)
pylab.annotate(label, xy=(x, y), xytext=(5, 2), textcoords='offset points',
ha='right', va='bottom')
pylab.show()
words = [reverse_dictionary[i] for i in xrange(1, num_points+1)]
plot(two_d_embeddings, words)