Catat tanggalnya! Google I / O mengembalikan 18-20 Mei Daftar sekarang
Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

Word2Vec

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHubUnduh buku catatan

Word2Vec bukanlah algoritme tunggal, melainkan sekumpulan arsitektur model dan pengoptimalan yang dapat digunakan untuk mempelajari embeddings kata dari kumpulan data besar. Embeddings yang dipelajari melalui Word2Vec telah terbukti berhasil pada berbagai tugas pemrosesan bahasa natural hilir.

Makalah ini mengusulkan dua metode untuk mempelajari representasi kata:

  • Model Bag-of-Words Berkelanjutan yang memprediksi kata tengah berdasarkan kata konteks sekitarnya. Konteksnya terdiri dari beberapa kata sebelum dan sesudah kata saat ini (tengah). Arsitektur ini disebut model bag-of-words karena urutan kata dalam konteks tidak penting.
  • Model Continuous Skip-gram yang memprediksi kata-kata dalam rentang tertentu sebelum dan sesudah kata saat ini dalam kalimat yang sama. Contoh yang berhasil diberikan di bawah ini.

Anda akan menggunakan pendekatan skip-gram dalam tutorial ini. Pertama, Anda akan menjelajahi skip-gram dan konsep lainnya menggunakan satu kalimat untuk ilustrasi. Selanjutnya, Anda akan melatih model Word2Vec Anda sendiri pada kumpulan data kecil. Tutorial ini juga berisi kode untuk mengekspor embeddings terlatih dan memvisualisasikannya di Proyektor Embedding TensorFlow .

Lewati-gram dan Sampling Negatif

Sementara model bag-of-words memprediksi sebuah kata dengan konteks bertetangga, model skip-gram memprediksi konteks (atau tetangga) dari sebuah kata, mengingat kata itu sendiri. Model ini dilatih pada skip-gram, yaitu n-gram yang memungkinkan token dilewati (lihat diagram di bawah untuk mengetahui contohnya). Konteks sebuah kata dapat direpresentasikan melalui satu set pasangan skip-gram (target_word, context_word) mana context_word muncul dalam konteks tetangga dari target_word .

Perhatikan kalimat 8 kata berikut.

Jalan lebar berkilau di bawah terik matahari.

Kata konteks untuk masing-masing dari 8 kata dalam kalimat ini ditentukan oleh ukuran jendela. Ukuran jendela menentukan rentang kata di kedua sisi target_word yang dapat dianggap sebagai context word . Lihat tabel skip-gram ini untuk kata-kata target berdasarkan ukuran jendela yang berbeda.

word2vec_skipgrams

Tujuan pelatihan model skip-gram adalah untuk memaksimalkan kemungkinan memprediksi kata konteks yang diberikan kata target. Untuk urutan kata w 1 , w 2 , ... w T , objektif dapat ditulis sebagai probabilitas log rata-rata

word2vec_skipgram_objective

dimana c adalah ukuran konteks pelatihan. Formulasi skip-gram dasar mendefinisikan probabilitas ini menggunakan fungsi softmax.

word2vec_full_softmax

dimana v dan v ' adalah representasi vektor target dan konteks dari kata-kata dan W adalah ukuran kosa kata.

Menghitung penyebut dari formulasi ini melibatkan melakukan softmax penuh atas seluruh kosakata yang seringkali merupakan istilah besar (10 5 -10 7 ).

Fungsi kerugian Estimasi Kontrasif Kebisingan adalah perkiraan yang efisien untuk softmax penuh. Dengan tujuan untuk mempelajari embeddings kata alih-alih memodelkan distribusi kata, kerugian NCE dapat disederhanakan dengan menggunakan pengambilan sampel negatif.

Tujuan pengambilan sampel negatif yang disederhanakan untuk kata target adalah untuk membedakan kata konteks dari jumlah sampel negatif yang diambil dari distribusi noise P n (w) kata. Lebih tepatnya, perkiraan yang efisien dari softmax penuh atas kosakata adalah, untuk pasangan skip-gram, untuk mengajukan kerugian pada kata target sebagai masalah klasifikasi antara kata konteks dan sampel negatif num_ns .

Sampel negatif didefinisikan sebagai pasangan (target_word, context_word) sehingga konteks_word tidak muncul di lingkungan window_size dari target_word. Untuk contoh kalimat, berikut adalah beberapa sampel negatif potensial (jika window_size adalah 2).

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

Di bagian selanjutnya, Anda akan membuat gram-lewati dan sampel negatif untuk satu kalimat. Anda juga akan mempelajari tentang teknik subsampling dan melatih model klasifikasi untuk contoh pelatihan positif dan negatif nanti dalam tutorial.

Mendirikan

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

Buat vektor contoh kalimat

Perhatikan kalimat berikut:
The wide road shimmered in the hot sun.

Tokenkan kalimat:

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

Buat kosakata untuk menyimpan pemetaan dari token ke indeks integer.

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}

Buat kosakata terbalik untuk menyimpan pemetaan dari indeks integer ke token.

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'}

Lakukan vektorisasi kalimat Anda.

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

Hasilkan skip-gram dari satu kalimat

Modul tf.keras.preprocessing.sequence menyediakan fungsi berguna yang menyederhanakan persiapan data untuk Word2Vec. Anda dapat menggunakan tf.keras.preprocessing.sequence.skipgrams untuk menghasilkan pasangan skip-gram dari example_sequence dengan window_size tertentu dari token dalam kisaran [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

Lihatlah beberapa gram-loncatan positif.

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

Pengambilan sampel negatif untuk satu gram-lewati

Fungsi skipgrams mengembalikan semua pasangan skip-gram positif dengan menggeser rentang jendela tertentu. Untuk menghasilkan pasangan skip-gram tambahan yang akan berfungsi sebagai sampel negatif untuk pelatihan, Anda perlu mengambil sampel kata-kata acak dari kosakata. Gunakan tf.random.log_uniform_candidate_sampler fungsi untuk sampel num_ns jumlah sampel negatif untuk kata target yang diberikan dalam jendela. Anda dapat memanggil fungsi pada satu kata target skip-gram dan meneruskan kata konteks sebagai kelas yang benar untuk mengecualikannya dari pengambilan sampel.

# 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']

Buat satu contoh pelatihan

Untuk skip-gram positif (target_word, context_word) , Anda sekarang juga memiliki kata-kata konteks sampel negatif num_ns yang tidak muncul di lingkungan ukuran jendela target_word . Batch 1 positif context_word dan num_ns negatif konteks kata-kata menjadi satu tensor. Ini menghasilkan satu set lewati-gram positif (diberi label sebagai 1 ) dan sampel negatif (diberi label sebagai 0 ) untuk setiap kata target.

# 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)

Lihatlah konteks dan label yang sesuai untuk kata target dari contoh skip-gram di atas.

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    : 6
target_word     : hot
context_indices : [1 2 1 4 3]
context_words   : ['the', 'wide', 'the', 'shimmered', 'road']
label           : [1 0 0 0 0]

Tuple tensor (target, context, label) merupakan satu contoh pelatihan untuk melatih model Word2Vec pengambilan sampel negatif gram-lewati Anda. Perhatikan bahwa target berbentuk (1,) sedangkan konteks dan label berbentuk (1+num_ns,)

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

Ringkasan

Gambar ini merangkum prosedur menghasilkan contoh pelatihan dari sebuah kalimat.

word2vec_negative_sampling

Kumpulkan semua langkah menjadi satu fungsi

Tabel Sampel Lewati-gram

Dataset yang besar berarti kosakata yang lebih besar dengan jumlah kata yang lebih sering lebih tinggi seperti stopwords. Contoh pelatihan yang diperoleh dari sampel sering terjadi kata-kata (seperti the , is , on ) tidak menambahkan banyak informasi yang berguna untuk model untuk belajar dari. Mikolov dkk. menyarankan subsampling dari kata-kata yang sering digunakan sebagai praktik yang berguna untuk meningkatkan kualitas penyematan.

Fungsi tf.keras.preprocessing.sequence.skipgrams menerima argumen tabel pengambilan sampel untuk menyandikan probabilitas pengambilan sampel token apa pun. Anda dapat menggunakan tf.keras.preprocessing.sequence.make_sampling_table untuk menghasilkan tabel sampel probabilistik berbasis peringkat frekuensi kata dan meneruskannya ke fungsi skipgrams . Lihatlah probabilitas sampling untuk 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] menunjukkan probabilitas pengambilan sampel kata paling umum ke-i dalam kumpulan data. Fungsi ini mengasumsikan distribusi frekuensi kata Zipf untuk pengambilan sampel.

Hasilkan data pelatihan

Kumpulkan semua langkah yang dijelaskan di atas ke dalam fungsi yang dapat dipanggil dalam daftar kalimat vektor yang diperoleh dari kumpulan data teks mana pun. Perhatikan bahwa tabel sampling dibuat sebelum sampling pasangan kata skip-gram. Anda akan menggunakan fungsi ini di bagian selanjutnya.

# 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

Siapkan data pelatihan untuk Word2Vec

Dengan pemahaman tentang bagaimana bekerja dengan satu kalimat untuk model Word2Vec berbasis sampling negatif-gram negatif, Anda dapat melanjutkan untuk membuat contoh pelatihan dari daftar kalimat yang lebih besar!

Unduh korpus teks

Anda akan menggunakan file teks tulisan Shakespeare untuk tutorial ini. Ubah baris berikut untuk menjalankan kode ini pada data Anda sendiri.

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

Baca teks dari file dan lihat beberapa baris pertama.

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.

Gunakan baris yang tidak kosong untuk membuat objek tf.data.TextLineDataset untuk langkah selanjutnya.

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

Membuat vektor kalimat dari korpus

Anda dapat menggunakan lapisan TextVectorization untuk membuat vektor kalimat dari korpus. Pelajari lebih lanjut tentang menggunakan lapisan ini dalam tutorial Klasifikasi Teks ini. Perhatikan dari beberapa kalimat pertama di atas bahwa teks harus menggunakan satu huruf besar dan tanda baca perlu dihilangkan. Untuk melakukan ini, tentukan custom_standardization function yang dapat digunakan di lapisan 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)

Panggil adapt pada kumpulan data teks untuk membuat kosakata.

vectorize_layer.adapt(text_ds.batch(1024))

Setelah status lapisan diadaptasi untuk mewakili korpus teks, kosakata dapat diakses dengan get_vocabulary() . Fungsi ini mengembalikan daftar semua token kosakata yang diurutkan (menurun) berdasarkan frekuensinya.

# 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']

Vectorize_layer sekarang dapat digunakan untuk menghasilkan vektor untuk setiap elemen di text_ds .

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

Dapatkan urutan dari kumpulan data

Anda sekarang memilikitf.data.Dataset kalimattf.data.Dataset integer. Untuk menyiapkan kumpulan data untuk melatih model Word2Vec, ratakan kumpulan data ke dalam daftar urutan vektor kalimat. Langkah ini diperlukan karena Anda akan mengulang setiap kalimat dalam kumpulan data untuk menghasilkan contoh positif dan negatif.

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

Lihatlah beberapa contoh dari 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', '', '', '', '', '', '', '', '']

Hasilkan contoh pelatihan dari urutan

sequences sekarang menjadi daftar kalimat yang dikodekan int. Panggil saja fungsi generate_training_data() ditentukan sebelumnya untuk menghasilkan contoh pelatihan untuk model Word2Vec. Singkatnya, fungsi ini mengulang setiap kata dari setiap urutan untuk mengumpulkan kata konteks positif dan negatif. Panjang target, konteks dan label harus sama, mewakili jumlah total contoh pelatihan.

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:30<00:00, 1085.04it/s]
65023 65023 65023

Konfigurasi set data untuk kinerja

Untuk melakukan pengelompokan yang efisien untuk sejumlah besar contoh pelatihan, gunakan APItf.data.Dataset . Setelah langkah ini, Anda akan memiliki objektf.data.Dataset daritf.data.Dataset (target_word, context_word), (label) untuk melatih model Word2Vec Anda!

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)>

Tambahkan cache() dan prefetch() untuk meningkatkan kinerja.

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

Model dan Pelatihan

Model Word2Vec dapat diimplementasikan sebagai pengklasifikasi untuk membedakan antara kata konteks sebenarnya dari skip-gram dan kata konteks palsu yang diperoleh melalui pengambilan sampel negatif. Anda dapat melakukan produk titik antara embeddings kata target dan konteks untuk mendapatkan prediksi label dan menghitung kerugian terhadap label sebenarnya dalam set data.

Model Word2Vec Subclass

Gunakan Keras Subclassing API untuk menentukan model Word2Vec Anda dengan lapisan berikut:

  • target_embedding : Lapisan tf.keras.layers.Embedding yang mencari embedding sebuah kata saat muncul sebagai kata target. Jumlah parameter dalam lapisan ini adalah (vocab_size * embedding_dim) .
  • context_embedding : Layer tf.keras.layers.Embedding lain yang mencari embedding dari sebuah kata saat muncul sebagai kata konteks. Jumlah parameter di lapisan ini sama dengan yang ada di target_embedding , yaitu (vocab_size * embedding_dim) .
  • dots : Lapisan tf.keras.layers.Dot yang menghitung produk titik dari target dan konteks embeddings dari pasangan pelatihan.
  • flatten : Sebuah tf.keras.layers.Flatten layer untuk meratakan hasil layer dots - dots menjadi logits.

Dengan model subclass, Anda bisa mendefinisikan fungsi call() yang menerima pasangan (target, context) yang kemudian bisa diteruskan ke lapisan embedding yang sesuai. Bentuk ulang context_embedding untuk menjalankan produk titik dengan target_embedding dan kembalikan hasil yang diratakan.

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)

Tentukan fungsi kerugian dan model kompilasi

Untuk mempermudah, Anda dapat menggunakan tf.keras.losses.CategoricalCrossEntropy sebagai alternatif dari kerugian pengambilan sampel negatif. Jika Anda ingin menulis fungsi kerugian kustom Anda sendiri, Anda juga dapat melakukannya sebagai berikut:

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

Saatnya membangun model Anda! Buat instance kelas Word2Vec Anda dengan dimensi penyematan 128 (Anda dapat bereksperimen dengan nilai yang berbeda). Kompilasi model dengan pengoptimal 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'])

Juga tentukan callback untuk mencatat statistik pelatihan untuk tensorboard.

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

Latih model dengan dataset disiapkan di atas untuk beberapa periode.

word2vec.fit(dataset, epochs=20, callbacks=[tensorboard_callback])
Epoch 1/20
63/63 [==============================] - 2s 8ms/step - loss: 1.6089 - accuracy: 0.2172
Epoch 2/20
63/63 [==============================] - 0s 6ms/step - loss: 1.5924 - accuracy: 0.5918
Epoch 3/20
63/63 [==============================] - 0s 6ms/step - loss: 1.5537 - accuracy: 0.6396
Epoch 4/20
63/63 [==============================] - 0s 6ms/step - loss: 1.4771 - accuracy: 0.5907
Epoch 5/20
63/63 [==============================] - 0s 6ms/step - loss: 1.3793 - accuracy: 0.5837
Epoch 6/20
63/63 [==============================] - 0s 6ms/step - loss: 1.2807 - accuracy: 0.6060
Epoch 7/20
63/63 [==============================] - 0s 6ms/step - loss: 1.1882 - accuracy: 0.6391
Epoch 8/20
63/63 [==============================] - 0s 6ms/step - loss: 1.1023 - accuracy: 0.6738
Epoch 9/20
63/63 [==============================] - 0s 6ms/step - loss: 1.0224 - accuracy: 0.7061
Epoch 10/20
63/63 [==============================] - 0s 6ms/step - loss: 0.9481 - accuracy: 0.7355
Epoch 11/20
63/63 [==============================] - 0s 6ms/step - loss: 0.8792 - accuracy: 0.7618
Epoch 12/20
63/63 [==============================] - 0s 6ms/step - loss: 0.8157 - accuracy: 0.7862
Epoch 13/20
63/63 [==============================] - 0s 6ms/step - loss: 0.7572 - accuracy: 0.8068
Epoch 14/20
63/63 [==============================] - 0s 6ms/step - loss: 0.7036 - accuracy: 0.8240
Epoch 15/20
63/63 [==============================] - 0s 6ms/step - loss: 0.6546 - accuracy: 0.8406
Epoch 16/20
63/63 [==============================] - 0s 6ms/step - loss: 0.6099 - accuracy: 0.8548
Epoch 17/20
63/63 [==============================] - 0s 6ms/step - loss: 0.5692 - accuracy: 0.8668
Epoch 18/20
63/63 [==============================] - 0s 6ms/step - loss: 0.5323 - accuracy: 0.8781
Epoch 19/20
63/63 [==============================] - 0s 6ms/step - loss: 0.4986 - accuracy: 0.8877
Epoch 20/20
63/63 [==============================] - 0s 6ms/step - loss: 0.4681 - accuracy: 0.8966
<tensorflow.python.keras.callbacks.History at 0x7f8a3061f828>

Tensorboard sekarang menunjukkan akurasi dan kerugian model Word2Vec.

%tensorboard --logdir logs

Menyematkan pencarian dan analisis

Dapatkan bobot dari model menggunakan get_layer() dan get_weights() . Fungsi get_vocabulary() menyediakan kosakata untuk membuat file metadata dengan satu token per baris.

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

Buat dan simpan file vektor dan metadata.

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()

Unduh vectors.tsv dan metadata.tsv untuk menganalisis embeddings yang diperoleh di Proyektor Embedding .

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

Langkah selanjutnya

Tutorial ini telah menunjukkan kepada Anda bagaimana menerapkan model Word2Vec skip-gram dengan pengambilan sampel negatif dari awal dan memvisualisasikan embeddings kata yang diperoleh.