Code does not match explanation
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.3k
- Forks
- 379
- Avg merge
- 3h 30m
- Merged PRs (30d)
- 8
Description
The word2vec tutorial at first gives one definition of negative sampling:
A negative sample is defined as a
(target_word, context_word)pair such that thecontext_worddoes not appear in thewindow_sizeneighborhood of thetarget_word. For the example sentence, these are a few potential negative samples (whenwindow_sizeis2)
However, the implementation uses a second definition:
To produce additional skip-gram pairs that would serve as negative samples for training, you need to sample random words from the vocabulary.
There are several places where this second definition is used. First in the "small" example:
# Get target and context words for one positive skip-gram.
target_word, context_word = positive_skip_grams[0]
# Set the number of negative samples per positive context.
num_ns = 4
context_class = tf.reshape(tf.constant(context_word, dtype="int64"), (1, 1))
negative_sampling_candidates, _, _ = tf.random.log_uniform_candidate_sampler(
true_classes=context_class, # class that should be sampled as 'positive'
num_true=1, # each positive skip-gram has 1 positive context class
num_sampled=num_ns, # number of negative context words to sample
unique=True, # all the negative samples should be unique
range_max=vocab_size, # pick index of the samples from [0, vocab_size]
seed=SEED, # seed for reproducibility
name="negative_sampling" # name of this operation
)
print(negative_sampling_candidates)
print([inverse_vocab[index.numpy()] for index in negative_sampling_candidates])
It's used again in the Summary diagram, and later in the definition for generate_training_data:
# Iterate over each positive skip-gram pair to produce training examples
# with a positive context word and negative samples.
for target_word, context_word in positive_skip_grams:
context_class = tf.expand_dims(
tf.constant([context_word], dtype="int64"), 1)
negative_sampling_candidates, _, _ = tf.random.log_uniform_candidate_sampler(
true_classes=context_class,
num_true=1,
num_sampled=num_ns,
unique=True,
range_max=vocab_size,
seed=seed,
name="negative_sampling")
With a large enough sequence, random sampling is unlikely to pick samples near target_word purely by chance, and as a result the model "works". However if you test with a small example, you can see that this form of sampling excludes only the context_word.
My understanding is that for a context window of [the wide road shimmered] with the target word road, the positive (+) and negative (-) examples should be like this:
[the wide road shimmered] in the hot sun
+++ ++++ +++++++++ -- --- --- ---
Positive samples for road come from [the, wide, shimmered] and negative samples for the context word shimmered come from [in, the, hot, sun].
Either the text's definition of negative sampling should be changed, or the code should be changed to discard positive samples from the neg_sampling_candidates.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in docs/tutorials/word2vec.ipynb and compare the negative-sampling explanation with the small example, summary diagram, and generate_training_data implementation. Run the small example to reproduce the discrepancy. Done means the text and implementation consistently describe negative samples, with the tutorial output and examples updated accordingly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, tensorflow
- Domain
- documentation, machine-learning
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100