This repository has been archived by the owner on Jan 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 538
Word embeddings update #159
Merged
Merged
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit
Hold shift + click to select a range
3ab1d2c
Mask accidental hits
leezu b69382e
Simplify frequent token subsampling
leezu a74ac4a
Remove tqdm dependency
leezu 28528fa
Simplifications
leezu 68185ac
Support read from vec format
leezu c9dc46a
Add back DeduplicatedFasttext
leezu d85af54
Average the subword embeddings for FastText
leezu 73bde08
Fix Fasttext hash function for ngrams containing non-ASCII data
leezu 517a37e
Merge train_word2vec and train_fasttext
leezu 880acb9
Clean up fasttext evaluation binary script
leezu d4a3874
Remove waitall
leezu 32a1839
Only evaluate at end of training by default
leezu 68ad3f5
Set mxnet env variables
leezu 0007f67
Increase number of subword units considered by default
leezu 9fe1ca6
Update hyperparameters
leezu 9700e11
Fix cbow
leezu 61f9f5f
Use separate batch-size for evaluation
leezu b338e8d
Fix lint
leezu 09fb6df
Rerun extended_results.ipynb and commit dependant results/*tvs files …
leezu e215118
Clean up TokenEmbedding API docs
leezu ab1b5ed
Refactor TokenEmbedding OOV inference
leezu 4d02b7a
Use GluonNLP load_fasttext_model for word embeddings evaluation script
leezu f3b257b
Add tests
leezu 6eb685f
Remove deprecated to_token_embedding method from train/embedding.py
leezu 35bcb7b
Merge TokenEmbedding.extend in TokenEmbedding.__setitem__
leezu 7da4c6f
Use full link to #11314
leezu 08858d7
Improve test coverage
leezu 5e960fa
Update notebook
leezu 348c46f
Fix doc
leezu f5cfc84
Cache word ngram hashes
leezu 7e531d4
Move results to dmlc/web-data
leezu 897b000
Move candidate_sampler to scripts
leezu 1637ef7
Update --negative doc
leezu 546a9af
Match old default behavior of TokenEmbedding and add warnings
leezu 4a32070
Match weight context in UnigramCandidateSampler
leezu c307061
Add Pad test case with empty ndarray input
leezu e90bd33
Address review comments
leezu 9c79163
Fix doc and superfluous inheritance
leezu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Merge TokenEmbedding.extend in TokenEmbedding.__setitem__
Previously __setitem__ was only allowed to update known tokens.
- Loading branch information
commit 35bcb7bc0a2852b052b705ac945366275313a96d
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -158,20 +158,26 @@ class TokenEmbedding(object): | |
init_unknown_vec : callback | ||
The callback used to initialize the embedding vector for the unknown | ||
token. Only used if `unknown_token` is not None. | ||
allow_extend : bool, default True | ||
If True, embedding vectors for previously unknown words can be added | ||
via token_embedding[tokens] = vecs. If False, only vectors for known | ||
tokens can be updated. | ||
unknown_lookup : object subscriptable with list of tokens returning nd.NDarray, default None | ||
If not None, unknown_lookup[tokens] is called for any unknown tokens. | ||
The result is cached if unknown_autoextend is True. | ||
unknown_autoextend : bool, default True | ||
If True, any unknown token for which a vector was looked up in | ||
unknown_lookup together with the resulting vector will be added to | ||
token_to_idx, idx_to_token and idx_to_vec, adding a new index. | ||
token_to_idx, idx_to_token and idx_to_vec, adding a new index. This | ||
option is ignored if allow_extend is False. | ||
|
||
""" | ||
|
||
def __init__(self, unknown_token='<unk>', init_unknown_vec=nd.zeros, | ||
def __init__(self, unknown_token='<unk>', init_unknown_vec=nd.zeros, allow_extend=True, | ||
unknown_lookup=None, unknown_autoextend=True): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. set default values so that it's consistent with existing behavior There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
self._unknown_token = unknown_token | ||
self._init_unknown_vec = init_unknown_vec | ||
self._allow_extend = allow_extend | ||
self._unknown_lookup = unknown_lookup | ||
self._unknown_autoextend = unknown_autoextend | ||
self._idx_to_token = [unknown_token] if unknown_token else [] | ||
|
@@ -424,6 +430,23 @@ def unknown_token(self): | |
""" | ||
return self._unknown_token | ||
|
||
@property | ||
def allow_extend(self): | ||
"""Allow extension of the TokenEmbedding with new tokens. | ||
|
||
If True, `TokenEmbedding[tokens] = vec` can introduce new tokens that | ||
were previously unknown. New indices will be assigned to the newly | ||
introduced tokens. If False, only known tokens can be updated. | ||
|
||
Returns | ||
------- | ||
bool: | ||
Extension of the TokenEmbedding is allowed. | ||
|
||
""" | ||
return self._allow_extend | ||
|
||
|
||
@property | ||
def unknown_lookup(self): | ||
"""Vector lookup for unknown tokens. | ||
|
@@ -505,7 +528,7 @@ def __getitem__(self, tokens): | |
else: | ||
if self.unknown_lookup is not None and self.unknown_autoextend: | ||
new_tokens = [t for t in tokens if t not in self.token_to_idx] | ||
self.extend(new_tokens, self.unknown_lookup[new_tokens]) | ||
self[new_tokens] = self.unknown_lookup[new_tokens] | ||
|
||
indices = [self._token_to_idx[token] for token in tokens] | ||
vecs = nd.Embedding( | ||
|
@@ -515,7 +538,7 @@ def __getitem__(self, tokens): | |
return vecs[0] if to_reduce else vecs | ||
|
||
def _check_vector_update(self, tokens, new_embedding): | ||
"""Check that tokens and embedding are in the format for __setitem__ and extend.""" | ||
"""Check that tokens and embedding are in the format for __setitem__.""" | ||
assert self._idx_to_vec is not None, '`idx_to_vec` has not been initialized.' | ||
|
||
if not isinstance(tokens, (list, tuple)) or len(tokens) == 1: | ||
|
@@ -539,6 +562,8 @@ def _check_vector_update(self, tokens, new_embedding): | |
def __setitem__(self, tokens, new_embedding): | ||
"""Updates embedding vectors for tokens. | ||
|
||
If self.allow_extend is True, vectors for previously unknown tokens can be introduced. | ||
|
||
Parameters | ||
---------- | ||
tokens : hashable object or a list or tuple of hashable objects | ||
|
@@ -549,8 +574,26 @@ def __setitem__(self, tokens, new_embedding): | |
the glossary. If `tokens` is a singleton, it must be 1-D or 2-D. If `tokens` is a list | ||
of multiple strings, it must be 2-D. | ||
""" | ||
if self.allow_extend and self._idx_to_vec is None: | ||
# Initialize self._idx_to_vec | ||
assert C.UNK_IDX == 0 | ||
self._idx_to_vec = self._init_unknown_vec(shape=(1, new_embedding.shape[-1])) | ||
|
||
tokens = self._check_vector_update(tokens, new_embedding) | ||
|
||
if self.allow_extend: | ||
# Add new / previously unknown tokens | ||
for token in filter(lambda t: t not in self._token_to_idx, tokens): | ||
idx = len(self._token_to_idx) | ||
self._token_to_idx[token] = idx | ||
self._idx_to_token.append(token) | ||
|
||
# Extend shape of idx_to_vec | ||
idx_to_vec = nd.zeros(shape=(len(self._token_to_idx), | ||
self.idx_to_vec.shape[1])) | ||
idx_to_vec[:self.idx_to_vec.shape[0]] = self._idx_to_vec | ||
self._idx_to_vec = idx_to_vec | ||
|
||
indices = [] | ||
for token in tokens: | ||
if token in self._token_to_idx: | ||
|
@@ -568,41 +611,6 @@ def __setitem__(self, tokens, new_embedding): | |
|
||
self._idx_to_vec[nd.array(indices)] = new_embedding | ||
|
||
def extend(self, tokens, embedding): | ||
"""Adds tokens using the vectors in embedding. | ||
|
||
Parameters | ||
---------- | ||
tokens : hashable object or a list or tuple of hashable objects | ||
A token or a list of tokens whose embedding vector are to be updated. | ||
embedding : mxnet.ndarray.NDArray | ||
An NDArray to be assigned to the embedding vectors of `tokens`. Its length must be equal | ||
to the number of `tokens` and its width must be equal to the dimension of embedding of | ||
the glossary. If `tokens` is a singleton, it must be 1-D or 2-D. If `tokens` is a list | ||
of multiple strings, it must be 2-D. | ||
""" | ||
if self._idx_to_vec is None: | ||
assert C.UNK_IDX == 0 | ||
self._idx_to_vec = self._init_unknown_vec(shape=(1, embedding.shape[-1])) | ||
|
||
tokens = self._check_vector_update(tokens, embedding) | ||
|
||
for token in tokens: | ||
if token in self._token_to_idx: | ||
raise KeyError('Token "{token}" is known. ' | ||
'Use `token_embedding["{token}"] = embedding` ' | ||
' to update its embedding '.format(token=token)) | ||
|
||
idx_to_vec = nd.empty(shape=(self.idx_to_vec.shape[0] + len(tokens), | ||
self.idx_to_vec.shape[1])) | ||
idx_to_vec[:self.idx_to_vec.shape[0]] = self._idx_to_vec | ||
idx_to_vec[self.idx_to_vec.shape[0]:] = embedding | ||
|
||
self._token_to_idx.update( | ||
(token, i) for i, token in enumerate(tokens, self.idx_to_vec.shape[0])) | ||
self._idx_to_vec = idx_to_vec | ||
self._idx_to_token += tokens | ||
|
||
@classmethod | ||
def _check_source(cls, source): | ||
"""Checks if a pre-trained token embedding source name is valid. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default True (1 space)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks