יש שאלה? התחבר לקהילה בפורום הביקור של TensorFlow

Word2Vec

צפה ב- TensorFlow.org הפעל בגוגל קולאב צפה במקור ב- GitHubהורד מחברת

Word2Vec אינו אלגוריתם יחיד, אלא מדובר במשפחה של ארכיטקטורות מודל ואופטימיזציות שניתן להשתמש בהן כדי ללמוד טבילות מילים מערכי נתונים גדולים. ההטבעות שנלמדו באמצעות Word2Vec הוכיחו שהן מצליחות במגוון משימות עיבוד שפה טבעית במורד הזרם.

מאמרים אלה הציעו שתי שיטות ללימוד ייצוגים של מילים:

  • מודל שקית-מילים רציף המנבא את המילה האמצעית על סמך מילות ההקשר הסובבות. ההקשר מורכב מכמה מילים לפני ואחרי המילה הנוכחית (האמצעית). ארכיטקטורה זו נקראת מודל תיק מילים שכן אין חשיבות לסדר המילים בהקשר.
  • דגם Skip-gram רציף המנבא מילים בטווח מסוים לפני ואחרי המילה הנוכחית באותו משפט. דוגמה מעובדת לכך מובאת להלן.

תשתמש בגישת ה- skip-gram במדריך זה. ראשית, תחקור דלג על גרמים ומושגים אחרים באמצעות משפט יחיד להמחשה. לאחר מכן, תאמן את דגם Word2Vec שלך על מערך נתונים קטן. מדריך זה מכיל גם קוד לייצוא ההטבעות המאומנות ולהמחשתם במקרן ההטבעה של TensorFlow .

דגימת דילוג ודגימה שלילית

בעוד מודל שקית-מילים מנבא מילה בהתחשב בהקשר השכן, מודל דלג-גרם מנבא את ההקשר (או השכנים) של מילה, בהתחשב במילה עצמה. המודל מאומן על דלג על גרם, שהם n- גרם המאפשרים דילוג על אסימונים (ראה דוגמה בתרשים למטה). ניתן לייצג את ההקשר של מילה באמצעות קבוצה של זוגות דילוג של (target_word, context_word) כאשר context_word מופיע בהקשר הסמוך של target_word .

שקול את המשפט הבא בן 8 מילים.

הדרך הרחבה נצנצה בשמש החמה.

מילות ההקשר לכל אחת משמונה המילים של משפט זה מוגדרות על ידי גודל חלון. גודל החלון קובע את טווח המילים משני צידי target_word שיכולה להיחשב target_word context word . התבונן בטבלה זו של דלג על מילות יעד בהתבסס על גדלי חלונות שונים.

word2vec_skipgrams

מטרת האימון של מודל ה- skip-gram היא למקסם את ההסתברות לחיזוי מילים בהקשר בהינתן מילת היעד. עבור רצף של מילים w 1 , w 2 , ... w T , ניתן לכתוב את המטרה כהסתברות היומן הממוצעת

word2vec_skipgram_objective

כאשר c הוא גודל הקשר האימון. ניסוח ה- skip-gram הבסיסי מגדיר הסתברות זו באמצעות פונקציית softmax.

word2vec_full_softmax

כאשר v ו- v ' הם ייצוג וקטורי מטרה והקשר של מילים ו- W הוא גודל אוצר המילים.

חישוב המכנה של ניסוח זה כרוך בביצוע מילת רך מלאה על כל מילות אוצר המילים שלעתים קרובות היא מונחים גדולים (10 5 -10 7 ).

פונקציית אובדן הערכת ניגודיות רעש היא קירוב יעיל לסופטמקס מלא. במטרה ללמוד טבילות מילים במקום לדגמן את התפלגות המילים, ניתן לפשט את אובדן ה- NCE באמצעות דגימה שלילית.

מטרת הדגימה השלילית הפשוטה עבור מילת יעד היא להבחין בין מילת ההקשר לבין מספר דגימות שליליות שנלקחו מהתפלגות הרעש P n (w) של מילים. ליתר דיוק, קירוב יעיל של softmax מלא על אוצר המילים הוא, עבור זוג דלג-גרם, להוות את האובדן של מילת מטרה כבעיית סיווג בין מילת ההקשר לבין מספר דגימות שליליות.

מדגם שלילית מוגדרת זוג (target_word, context_word) כך context_word אינו מופיע window_size השכונה של target_word. עבור המשפט לדוגמא, אלה כמה דוגמאות שליליות פוטנציאליות (כאשר window_size הוא 2).

(hot, shimmered)
(wide, hot)
(wide, sun)

בחלק הבא תיצור דגימות דילוג ודוגמאות שליליות למשפט בודד. תוכלו ללמוד גם על טכניקות תת-דגימה ולהכשיר מודל סיווג לדוגמאות אימונים חיוביות ושליליות בהמשך ההדרכה.

להכין

import io
import re
import string
import tensorflow as tf
import tqdm

from tensorflow.keras import Model
from tensorflow.keras.layers import Dot, Embedding, Flatten
from tensorflow.keras.layers.experimental.preprocessing import TextVectorization
# Load the TensorBoard notebook extension
%load_ext tensorboard
SEED = 42
AUTOTUNE = tf.data.AUTOTUNE

וקטור משפט לדוגמא

שקול את המשפט הבא:
The wide road shimmered in the hot sun.

אסימון המשפט:

sentence = "The wide road shimmered in the hot sun"
tokens = list(sentence.lower().split())
print(len(tokens))
8

צור אוצר מילים לשמירת מיפויים מסימנים למדדים שלמים.

vocab, index = {}, 1  # start indexing from 1
vocab['<pad>'] = 0  # add a padding token
for token in tokens:
  if token not in vocab:
    vocab[token] = index
    index += 1
vocab_size = len(vocab)
print(vocab)
{'<pad>': 0, 'the': 1, 'wide': 2, 'road': 3, 'shimmered': 4, 'in': 5, 'hot': 6, 'sun': 7}

צור אוצר מילים הפוך כדי לשמור מיפויים ממדדים שלמים לאסימונים.

inverse_vocab = {index: token for token, index in vocab.items()}
print(inverse_vocab)
{0: '<pad>', 1: 'the', 2: 'wide', 3: 'road', 4: 'shimmered', 5: 'in', 6: 'hot', 7: 'sun'}

וקטור המשפט שלך.

example_sequence = [vocab[word] for word in tokens]
print(example_sequence)
[1, 2, 3, 4, 5, 1, 6, 7]

צור דילוג גרם ממשפט אחד

מודול tf.keras.preprocessing.sequence מספק פונקציות שימושיות המפשטות את הכנת הנתונים עבור Word2Vec. אתה יכול להשתמש tf.keras.preprocessing.sequence.skipgrams כדי ליצור זוגות דלג גרם מן example_sequence עם נתון window_size מן אסימונים בטווח [0, vocab_size) .

window_size = 2
positive_skip_grams, _ = tf.keras.preprocessing.sequence.skipgrams(
      example_sequence,
      vocabulary_size=vocab_size,
      window_size=window_size,
      negative_samples=0)
print(len(positive_skip_grams))
26

תסתכל על כמה דלגים חיוביים.

for target, context in positive_skip_grams[:5]:
  print(f"({target}, {context}): ({inverse_vocab[target]}, {inverse_vocab[context]})")
(1, 4): (the, shimmered)
(4, 3): (shimmered, road)
(4, 5): (shimmered, in)
(3, 2): (road, wide)
(1, 7): (the, sun)

דגימה שלילית לדילוג גרם אחד

הפונקציה skipgrams מחזירה את כל זוגות ה- Skip-gram החיוביים על ידי החלקה מעל טווח חלונות נתון. כדי לייצר זוגות מדלגים נוספים המשמשים דוגמאות שליליות לאימון, עליך לדגום מילים אקראיות מאוצר המילים. השתמש בפונקציה tf.random.log_uniform_candidate_sampler כדי לדגום num_ns מספר שלילי עבור מילת יעד נתונה בחלון. אתה יכול להתקשר לפונקציה על מילת היעד של דלג-גרם אחד ולהעביר את מילת ההקשר ככיתה אמיתית כדי לא לכלול אותה מהדגימה.

# 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])
tf.Tensor([2 1 4 3], shape=(4,), dtype=int64)
['wide', 'the', 'shimmered', 'road']

בנה דוגמא אחת להכשרה

(target_word, context_word) חיובי נתון (target_word, context_word) , כעת יש לך num_ns הקשר שנדגמו שליליות שאינן מופיעות בשכונת גודל החלון של target_word . אצווה 1 חיובי context_word ו num_ns מילים בהקשר שלילי לתוך מותח אחד. זה מייצר קבוצה של דלג חיובי (שכותרתו 1 ) ודגימות שליליות (שכותרתו 0 ) עבור כל מילת יעד.

# Add a dimension so you can use concatenation (on the next step).
negative_sampling_candidates = tf.expand_dims(negative_sampling_candidates, 1)

# Concat positive context word with negative sampled words.
context = tf.concat([context_class, negative_sampling_candidates], 0)

# Label first context word as 1 (positive) followed by num_ns 0s (negative).
label = tf.constant([1] + [0]*num_ns, dtype="int64")

# Reshape target to shape (1,) and context and label to (num_ns+1,).
target = tf.squeeze(target_word)
context = tf.squeeze(context)
label = tf.squeeze(label)

התבונן בהקשר ובתוויות המתאימות למילת היעד מדוגמת ה- skip-gram לעיל.

print(f"target_index    : {target}")
print(f"target_word     : {inverse_vocab[target_word]}")
print(f"context_indices : {context}")
print(f"context_words   : {[inverse_vocab[c.numpy()] for c in context]}")
print(f"label           : {label}")
target_index    : 1
target_word     : the
context_indices : [4 2 1 4 3]
context_words   : ['shimmered', 'wide', 'the', 'shimmered', 'road']
label           : [1 0 0 0 0]

תפל של טנזורים (target, context, label) מהווה דוגמה לאימון לאימון דגם הדגימה השלילי של Word2Vec. שימו לב שהיעד הוא של צורה (1,) בעוד (1+num_ns,) ותווית הם של צורה (1+num_ns,)

print("target  :", target)
print("context :", context)
print("label   :", label)
target  : tf.Tensor(1, shape=(), dtype=int32)
context : tf.Tensor([4 2 1 4 3], shape=(5,), dtype=int64)
label   : tf.Tensor([1 0 0 0 0], shape=(5,), dtype=int64)

סיכום

תמונה זו מסכמת את הנוהל של יצירת דוגמא להכשרה ממשפט.

word2vec_negative_sampling

הידר את כל השלבים לפונקציה אחת

טבלת דגימה מדלגת גרם

מערך נתונים גדול פירושו אוצר מילים גדול יותר עם מספר גבוה יותר של מילים תכופות יותר כגון מילות עצירה. דוגמאות אימונים המתקבלות מדגימה של מילים נפוצות (כגון the , is , on ) אינן מוסיפות מידע שימושי רב למודל ממנו ניתן ללמוד. מיקולוב ואח '. להציע דגימת משנה של מילים תכופות כפרקטיקה מועילה לשיפור איכות ההטבעה.

הפונקציה tf.keras.preprocessing.sequence.skipgrams מקבלת טיעון טבלת דגימה כדי לקודד את ההסתברויות לדגימת כל אסימון. אתה יכול להשתמש tf.keras.preprocessing.sequence.make_sampling_table כדי ליצור טבלת דגימה הסתברותית המבוססת על תדר מילים ולהעביר אותה לפונקציית skipgrams . בדוק את ההסתברויות לדגימה עבור גודל vocab_size 10.

sampling_table = tf.keras.preprocessing.sequence.make_sampling_table(size=10)
print(sampling_table)
[0.00315225 0.00315225 0.00547597 0.00741556 0.00912817 0.01068435
 0.01212381 0.01347162 0.01474487 0.0159558 ]

sampling_table[i] מציין את ההסתברות לדגימת המילה הנפוצה ביותר ה- i במערך נתונים. הפונקציה מניחה את התפלגות Zipf של תדרי המילה לדגימה.

צור נתוני אימון

הידר את כל השלבים המתוארים לעיל לפונקציה שניתן לקרוא לה ברשימת משפטים וקטוריים המתקבלים מכל מערך טקסט. שימו לב כי טבלת הדגימה בנויה לפני הדגימה של זוגות מילים מדלגים. תשתמש בפונקציה זו בסעיפים המאוחרים יותר.

# Generates skip-gram pairs with negative sampling for a list of sequences
# (int-encoded sentences) based on window size, number of negative samples
# and vocabulary size.
def generate_training_data(sequences, window_size, num_ns, vocab_size, seed):
  # Elements of each training example are appended to these lists.
  targets, contexts, labels = [], [], []

  # Build the sampling table for vocab_size tokens.
  sampling_table = tf.keras.preprocessing.sequence.make_sampling_table(vocab_size)

  # Iterate over all sequences (sentences) in dataset.
  for sequence in tqdm.tqdm(sequences):

    # Generate positive skip-gram pairs for a sequence (sentence).
    positive_skip_grams, _ = tf.keras.preprocessing.sequence.skipgrams(
          sequence,
          vocabulary_size=vocab_size,
          sampling_table=sampling_table,
          window_size=window_size,
          negative_samples=0)

    # Iterate over each positive skip-gram pair to produce training examples
    # with 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")

      # Build context and label vectors (for one target word)
      negative_sampling_candidates = tf.expand_dims(
          negative_sampling_candidates, 1)

      context = tf.concat([context_class, negative_sampling_candidates], 0)
      label = tf.constant([1] + [0]*num_ns, dtype="int64")

      # Append each element from the training example to global lists.
      targets.append(target_word)
      contexts.append(context)
      labels.append(label)

  return targets, contexts, labels

הכן נתוני אימון עבור Word2Vec

עם הבנה כיצד לעבוד עם משפט אחד עבור מודל Word2Vec מבוסס דגימה שלילי על-גרם, תוכל להמשיך ליצור דוגמאות אימונים מרשימת משפטים גדולה יותר!

הורד קורפוס טקסט

תשתמש בקובץ טקסט של כתיבתו של שייקספיר לצורך הדרכה זו. שנה את השורה הבאה כדי להריץ קוד זה על הנתונים שלך.

path_to_file = tf.keras.utils.get_file('shakespeare.txt', 'https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt')
Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt
1122304/1115394 [==============================] - 0s 0us/step

קרא טקסט מהקובץ והסתכל בשורות הראשונות.

with open(path_to_file) as f: 
  lines = f.read().splitlines()
for line in lines[:20]:
  print(line)
First Citizen:
Before we proceed any further, hear me speak.

All:
Speak, speak.

First Citizen:
You are all resolved rather to die than to famish?

All:
Resolved. resolved.

First Citizen:
First, you know Caius Marcius is chief enemy to the people.

All:
We know't, we know't.

First Citizen:
Let us kill him, and we'll have corn at our own price.

השתמש בשורות שאינן ריקות לבניית אובייקט tf.data.TextLineDataset לשלבים הבאים.

text_ds = tf.data.TextLineDataset(path_to_file).filter(lambda x: tf.cast(tf.strings.length(x), bool))

וקטור משפטים מהקורפוס

אתה יכול להשתמש בשכבת TextVectorization כדי TextVectorization על משפטים מהקורפוס. למידע נוסף על שימוש בשכבה זו במדריך סיווג טקסט זה. שימו לב מהמשפטים הראשונים לעיל שהטקסט צריך להיות במקרה אחד ויש להסיר פיסוק. לשם כך, הגדר custom_standardization function בה ניתן להשתמש בשכבת TextVectorization.

# Now, create a custom standardization function to lowercase the text and
# remove punctuation.
def custom_standardization(input_data):
  lowercase = tf.strings.lower(input_data)
  return tf.strings.regex_replace(lowercase,
                                  '[%s]' % re.escape(string.punctuation), '')


# Define the vocabulary size and number of words in a sequence.
vocab_size = 4096
sequence_length = 10

# Use the text vectorization layer to normalize, split, and map strings to
# integers. Set output_sequence_length length to pad all samples to same length.
vectorize_layer = TextVectorization(
    standardize=custom_standardization,
    max_tokens=vocab_size,
    output_mode='int',
    output_sequence_length=sequence_length)

התקשר adapt על בסיס הנתונים טקסט כדי ליצור אוצר מילים.

vectorize_layer.adapt(text_ds.batch(1024))

לאחר get_vocabulary() של השכבה הותאם לייצג את קורפוס הטקסט, ניתן לגשת לאוצר המילים באמצעות get_vocabulary() . פונקציה זו מחזירה רשימה של כל אסימוני אוצר המילים הממוינים (יורדים) לפי התדירות שלהם.

# Save the created vocabulary for reference.
inverse_vocab = vectorize_layer.get_vocabulary()
print(inverse_vocab[:20])
['', '[UNK]', 'the', 'and', 'to', 'i', 'of', 'you', 'my', 'a', 'that', 'in', 'is', 'not', 'for', 'with', 'me', 'it', 'be', 'your']

ניתן להשתמש כעת text_ds הווקטוריזית ליצירת וקטורים לכל רכיב ב- text_ds .

# Vectorize the data in text_ds.
text_vector_ds = text_ds.batch(1024).prefetch(AUTOTUNE).map(vectorize_layer).unbatch()

השג רצפים ממערך הנתונים

כעת יש לךtf.data.Dataset של משפטים מקודדים שלמים. להכנת מערך הנתונים לאימון מודל Word2Vec, שטחו את מערך הנתונים לרשימת רצפי וקטורי המשפט. שלב זה נדרש מכיוון שהיית חוזר על כל משפט במערך הנתונים כדי לייצר דוגמאות חיוביות ושליליות.

sequences = list(text_vector_ds.as_numpy_iterator())
print(len(sequences))
32777

התבונן בכמה דוגמאות sequences .

for seq in sequences[:5]:
  print(f"{seq} => {[inverse_vocab[i] for i in seq]}")
[ 89 270   0   0   0   0   0   0   0   0] => ['first', 'citizen', '', '', '', '', '', '', '', '']
[138  36 982 144 673 125  16 106   0   0] => ['before', 'we', 'proceed', 'any', 'further', 'hear', 'me', 'speak', '', '']
[34  0  0  0  0  0  0  0  0  0] => ['all', '', '', '', '', '', '', '', '', '']
[106 106   0   0   0   0   0   0   0   0] => ['speak', 'speak', '', '', '', '', '', '', '', '']
[ 89 270   0   0   0   0   0   0   0   0] => ['first', 'citizen', '', '', '', '', '', '', '', '']

צור דוגמאות אימונים מרצפים

sequences היא כעת רשימה של משפטים מקודדים. פשוט התקשרו לפונקציה create_training_data generate_training_data() שהוגדרה קודם לכן כדי ליצור דוגמאות אימונים למודל Word2Vec. לסיכום, הפונקציה חוזרת על כל מילה מכל רצף כדי לאסוף מילות הקשר חיוביות ושליליות. אורך היעד, ההקשרים והתוויות צריכים להיות זהים, המייצגים את המספר הכולל של דוגמאות אימון.

targets, contexts, labels = generate_training_data(
    sequences=sequences,
    window_size=2,
    num_ns=4,
    vocab_size=vocab_size,
    seed=SEED)
print(len(targets), len(contexts), len(labels))
100%|██████████| 32777/32777 [00:25<00:00, 1267.26it/s]
64720 64720 64720

הגדר את מערך הנתונים לביצועים

כדי לבצע אצווה יעיל למספר הגדול ביותר של דוגמאות אימונים, השתמש בממשק ה- APItf.data.Dataset . לאחר שלב זה, יהיה לך אובייקטtf.data.Dataset של (target_word, context_word), (label) אלמנטים לאימון מודל ה- Word2Vec שלך!

BATCH_SIZE = 1024
BUFFER_SIZE = 10000
dataset = tf.data.Dataset.from_tensor_slices(((targets, contexts), labels))
dataset = dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True)
print(dataset)
<BatchDataset shapes: (((1024,), (1024, 5, 1)), (1024, 5)), types: ((tf.int32, tf.int64), tf.int64)>

הוסף cache() prefetch() לשיפור הביצועים.

dataset = dataset.cache().prefetch(buffer_size=AUTOTUNE)
print(dataset)
<PrefetchDataset shapes: (((1024,), (1024, 5, 1)), (1024, 5)), types: ((tf.int32, tf.int64), tf.int64)>

מודל והדרכה

ניתן ליישם את מודל Word2Vec כמסווג כדי להבחין בין מילות ההקשר האמיתיות ממילות דלג ומילים בהקשר שקרי המתקבלות באמצעות דגימה שלילית. אתה יכול לבצע מוצר נקודתי בין הטביעה של מילות היעד וההקשר כדי להשיג חיזויים לתוויות ולחשב אובדן כנגד תוויות אמיתיות במערך הנתונים.

דגם Word2Vec בסיווג משנה

השתמש ב- Keras Subclassing API להגדרת מודל Word2Vec שלך עם השכבות הבאות:

  • target_embedding : שכבת tf.keras.layers.Embedding המסתכלת על הטבעה של מילה כאשר היא מופיעה כמילת יעד. מספר הפרמטרים בשכבה זו הם (vocab_size * embedding_dim) .
  • context_embedding : עוד שכבת tf.keras.layers.Embedding המסתכלת על הטבעה של מילה כשהיא מופיעה כמילת הקשר. מספר הפרמטרים בשכבה זו זהים לאלו target_embedding , כלומר (vocab_size * embedding_dim) .
  • dots : שכבת tf.keras.layers.Dot המחשבת את tf.keras.layers.Dot הנקודה של tf.keras.layers.Dot מטרה והקשר מזוג אימונים.
  • flatten : שכבת tf.keras.layers.Flatten כדי לשטח את התוצאות של שכבת dots לוגיטים.

בעזרת המודל המשנה לקבוצות משנה ניתן להגדיר את פונקציית call() המקבלת זוגות (target, context) אשר לאחר מכן ניתן להעביר לשכבת ההטבעה המתאימה להם. context_embedding מחדש את context_embedding כדי לבצע מוצר target_embedding עם target_embedding והחזיר את התוצאה השטוחה.

class Word2Vec(Model):
  def __init__(self, vocab_size, embedding_dim):
    super(Word2Vec, self).__init__()
    self.target_embedding = Embedding(vocab_size,
                                      embedding_dim,
                                      input_length=1,
                                      name="w2v_embedding")
    self.context_embedding = Embedding(vocab_size,
                                       embedding_dim,
                                       input_length=num_ns+1)
    self.dots = Dot(axes=(3, 2))
    self.flatten = Flatten()

  def call(self, pair):
    target, context = pair
    word_emb = self.target_embedding(target)
    context_emb = self.context_embedding(context)
    dots = self.dots([context_emb, word_emb])
    return self.flatten(dots)

הגדר פונקצית אובדן ומודל הידור

לשם פשטות, תוכלו להשתמש ב- tf.keras.losses.CategoricalCrossEntropy כחלופה לאובדן הדגימה השלילי. אם ברצונך לכתוב פונקציית אובדן מותאם אישית משלך, תוכל לעשות זאת באופן הבא:

def custom_loss(x_logit, y_true):
      return tf.nn.sigmoid_cross_entropy_with_logits(logits=x_logit, labels=y_true)

הגיע הזמן לבנות את המודל שלך! בצע את הכיתה שלך ב- Word2Vec עם ממד הטבעה של 128 (אתה יכול להתנסות בערכים שונים). tf.keras.optimizers.Adam את המודל עם האופטימיזציה tf.keras.optimizers.Adam .

embedding_dim = 128
word2vec = Word2Vec(vocab_size, embedding_dim)
word2vec.compile(optimizer='adam',
                 loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
                 metrics=['accuracy'])

הגדר גם התקשרות חוזרת כדי להיכנס לסטטיסטיקה של אימונים עבור tensorboard.

tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir="logs")

אימן את המודל באמצעות dataset שהוכן לעיל למספר תקופות כלשהו.

word2vec.fit(dataset, epochs=20, callbacks=[tensorboard_callback])
Epoch 1/20
63/63 [==============================] - 2s 11ms/step - loss: 1.6082 - accuracy: 0.2308
Epoch 2/20
63/63 [==============================] - 0s 5ms/step - loss: 1.5889 - accuracy: 0.5539
Epoch 3/20
63/63 [==============================] - 0s 5ms/step - loss: 1.5412 - accuracy: 0.6001
Epoch 4/20
63/63 [==============================] - 0s 5ms/step - loss: 1.4585 - accuracy: 0.5751
Epoch 5/20
63/63 [==============================] - 0s 5ms/step - loss: 1.3600 - accuracy: 0.5834
Epoch 6/20
63/63 [==============================] - 0s 5ms/step - loss: 1.2628 - accuracy: 0.6110
Epoch 7/20
63/63 [==============================] - 0s 5ms/step - loss: 1.1719 - accuracy: 0.6456
Epoch 8/20
63/63 [==============================] - 0s 5ms/step - loss: 1.0875 - accuracy: 0.6791
Epoch 9/20
63/63 [==============================] - 0s 5ms/step - loss: 1.0092 - accuracy: 0.7101
Epoch 10/20
63/63 [==============================] - 0s 5ms/step - loss: 0.9366 - accuracy: 0.7379
Epoch 11/20
63/63 [==============================] - 0s 5ms/step - loss: 0.8695 - accuracy: 0.7622
Epoch 12/20
63/63 [==============================] - 0s 5ms/step - loss: 0.8076 - accuracy: 0.7848
Epoch 13/20
63/63 [==============================] - 0s 5ms/step - loss: 0.7507 - accuracy: 0.8050
Epoch 14/20
63/63 [==============================] - 0s 5ms/step - loss: 0.6985 - accuracy: 0.8217
Epoch 15/20
63/63 [==============================] - 0s 5ms/step - loss: 0.6507 - accuracy: 0.8368
Epoch 16/20
63/63 [==============================] - 0s 5ms/step - loss: 0.6071 - accuracy: 0.8506
Epoch 17/20
63/63 [==============================] - 0s 5ms/step - loss: 0.5673 - accuracy: 0.8633
Epoch 18/20
63/63 [==============================] - 0s 5ms/step - loss: 0.5311 - accuracy: 0.8741
Epoch 19/20
63/63 [==============================] - 0s 5ms/step - loss: 0.4981 - accuracy: 0.8842
Epoch 20/20
63/63 [==============================] - 0s 5ms/step - loss: 0.4681 - accuracy: 0.8936
<tensorflow.python.keras.callbacks.History at 0x7f120c5b5210>

Tensorboard מראה כעת את הדיוק והאובדן של מודל Word2Vec.

%tensorboard --logdir logs

הטמעת בדיקה וניתוח

השג את המשקולות מהמודל באמצעות get_layer() ו- get_weights() . get_vocabulary() מספקת את אוצר המילים לבניית קובץ מטא-נתונים עם אסימון אחד בכל שורה.

weights = word2vec.get_layer('w2v_embedding').get_weights()[0]
vocab = vectorize_layer.get_vocabulary()

צור ושמור את הווקטורים וקובץ המטא נתונים.

out_v = io.open('vectors.tsv', 'w', encoding='utf-8')
out_m = io.open('metadata.tsv', 'w', encoding='utf-8')

for index, word in enumerate(vocab):
  if index == 0:
    continue  # skip 0, it's padding.
  vec = weights[index]
  out_v.write('\t'.join([str(x) for x in vec]) + "\n")
  out_m.write(word + "\n")
out_v.close()
out_m.close()

הורד את vectors.tsv ו- metadata.tsv כדי לנתח את vectors.tsv ההטבעה .

try:
  from google.colab import files
  files.download('vectors.tsv')
  files.download('metadata.tsv')
except Exception:
  pass

הצעדים הבאים

מדריך זה הראה לך כיצד להטמיע מודל Word2Vec מדלג על דגימה עם דגימה שלילית מאפס ולדמיין את הטביעות למילים שהושגו.