Sözcükleri eklemelerle temsil etme

Tamamlandı

Önceki örneğimizde, uzunluğu vocab_sizeolan yüksek boyutlu sözcük paketi vektörleri üzerinde işlem yaptık ve düşük boyutlu konumsal gösterim vektörlerini seyrek tek etkin gösterime açıkça dönüştürdük. Bu tek etkin gösterim bellek açısından verimli değildir. Buna ek olarak, her sözcük birbirinden bağımsız şekilde ele alınır, bu nedenle tek-seçimli kodlanmış vektörler sözcükler arasındaki anlamsal benzerlikleri ifade etmez.

Bu ünitede AG Haber veri kümesini keşfetmeye devam edeceğiz. Başlamak için verileri yükleyelim ve önceki üniteden bazı tanımları alalım.

import tensorflow as tf
import keras
import tensorflow_datasets as tfds
import numpy as np

# In this tutorial, we will be training a lot of models. In order to use GPU memory cautiously,
# we will set tensorflow option to grow GPU memory allocation when required.
physical_devices = tf.config.list_physical_devices('GPU') 
if len(physical_devices)>0:
    tf.config.set_memory_growth(physical_devices[0], True)

dataset = tfds.load('ag_news_subset')
ds_train = dataset['train']
ds_test = dataset['test']

Ekleme nedir?

Eklemenin fikri, sözcüğün anlamsal anlamını yansıtan daha düşük boyutlu yoğun vektörler kullanan sözcükleri temsil etmektir. Daha sonra anlamlı sözcük eklemeleri oluşturmayı ele alacağız, ancak şimdilik eklemeleri bir sözcük vektörünün boyutsallığını azaltmanın bir yolu olarak düşünelim.

Bu nedenle, ekleme katmanı bir sözcüğü giriş olarak alır ve belirtilen embedding_sizeçıkış vektörlerini üretir. Bu, Dense katmanına benzer, ancak giriş olarak tek-seçimli kodlanmış bir vektör almak yerine bir kelime numarasını alabilir.

Ağınızdaki ilk katman olarak ekleme katmanını kullanarak, paket veya sözcüklerden ekleme paketi modeline geçebiliriz. Burada ilk olarak metnimizdeki her sözcüğü ilgili eklemeye dönüştürebilir ve ardından , veya sumgibi averagemax tüm bu ekleme işlemleri üzerinde bazı toplama işlevlerini hesaplayabiliriz.

Beş ardışık kelime için gömme sınıflandırıcıyı gösteren görüntü.

Sınıflandırıcı sinir ağımız aşağıdaki katmanlardan oluşur:

  • Bir dizeyi giriş olarak alan ve belirteç sayılarından oluşan bir tensor üreten TextVectorization katmanı. Makul bir sözcük dağarcığı boyutu vocab_sizebelirleyeceğiz ve daha az kullanılan sözcükleri yoksayacağız. Giriş şekli 1'dir ve sonuç olarak $n$ belirteçleri aldığımızdan çıkış şekli $n$' olur ve bunların her biri 0 vocab_sizeile arasında sayılar içerir.
  • $n$ sayıları alan ve her sayıyı belirli bir uzunluktaki yoğun vektöre (örneğimizde 100) azaltan ekleme katmanı. Bu nedenle, $n$ şeklinin giriş tensörü $n\times 100$ tensor'a dönüştürülür.
  • İlk eksen boyunca bu tensörün ortalamasını alan toplama katmanı, farklı sözcüklere karşılık gelen tüm $n$ giriş tensorlarının ortalamasını hesaplar. Bu katmanı uygulamak için bir Lambda katman kullanacağız ve ortalamayı hesaplamak için bu katmana işlevi geçireceğiz. Çıktının şekli 100 olur ve giriş dizisinin tamamının sayısal gösterimidir.
  • Son yoğun doğrusal sınıflandırıcı.

Bu katmanları aşağıdaki kodla uygulayabiliriz:

vocab_size = 30000
batch_size = 128

vectorizer = keras.layers.TextVectorization(max_tokens=vocab_size)

model = keras.Sequential([
    keras.Input(shape=(1,), dtype=tf.string),
    vectorizer,    
    keras.layers.Embedding(vocab_size,100),
    keras.layers.Lambda(lambda x: tf.reduce_mean(x,axis=1)),
    keras.layers.Dense(4, activation='softmax')
])
model.summary()

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                 ┃ Output Shape              ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ text_vectorization            │ (None, None)              │             0 │
│ (TextVectorization)          │                           │               │
├──────────────────────────────┼───────────────────────────┼───────────────┤
│ embedding (Embedding)        │ (None, None, 100)         │     3,000,000 │
├──────────────────────────────┼───────────────────────────┼───────────────┤
│ lambda (Lambda)              │ (None, 100)               │             0 │
├──────────────────────────────┼───────────────────────────┼───────────────┤
│ dense (Dense)                │ (None, 4)                 │           404 │
└──────────────────────────────┴───────────────────────────┴───────────────┘
 Total params: 3,000,404 (11.45 MB)
 Trainable params: 3,000,404 (11.45 MB)
 Non-trainable params: 0 (0.00 B)

Çıktıda summary , çıkış şekli sütununda ilk tensor boyutu None minibatch boyutuna, ikinci boyut ise belirteç dizisinin uzunluğuna karşılık gelir. Minibatch içindeki tüm belirteç dizilerinin uzunlukları farklıdır. Bununla nasıl başa çıkılacağı sonraki bölümde ele alınacağız.

Ağı aşağıdaki kodla eğitebiliriz:

def extract_text(x):
    return x['title']+' '+x['description']

def tupelize(x):
    return (extract_text(x),x['label'])

print("Training vectorizer")
vectorizer.adapt(ds_train.take(500).map(extract_text))

model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])
model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))

Uyarı

Verilerin bir alt kümesini temel alan vektörleştirici oluşturuyoruz. Bu işlem süreci hızlandırmak için yapılır ve metnimizdeki tüm belirteçler sözlükte bulunmadığında bir duruma neden olabilir. Bu durumda, bu belirteçler göz ardı edilir ve bu durum biraz daha düşük doğruluğa yol açabilir. Ancak gerçek hayatta, metnin bir alt kümesi genellikle iyi bir sözlük tahmini sağlar.

Değişken sekans boyutlarıyla ilgilenme

Şimdi minibatchlerde eğitimin nasıl gerçekleştiğini anlayalım. Yukarıdaki örnekte, giriş tensorunun boyutu 1'dir ve 128 uzun minibatches kullanırız, böylece tensorun gerçek boyutu 128 $\times 1$ olur. Ancak, her tümcedeki belirteçlerin sayısı farklıdır. Katmanı tek bir girişe uygularsak TextVectorization , metnin nasıl belirteç haline getirildiğine bağlı olarak döndürülen belirteçlerin sayısı farklıdır:

print(vectorizer('Hello, world!'))
print(vectorizer('I am glad to meet you!'))

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

tf.Tensor([ 1 45], shape=(2,), dtype=int64)
tf.Tensor([ 112 1271    1    3 1747  158], shape=(6,), dtype=int64)

Bununla birlikte, vektörleştiriciyi birkaç diziye uyguladığımızda, dikdörtgen şeklinde bir tensor üretmesi gerekir, bu nedenle kullanılmayan öğeleri PAD belirteci ile doldurur (bizim örneğimizde sıfırdır):

vectorizer(['Hello, world!','I am glad to meet you!'])

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

<tf.Tensor: shape=(2, 6), dtype=int64, numpy=
array([[   1,   45,    0,    0,    0,    0],
       [ 112, 1271,    1,    3, 1747,  158]])>

Burada eklemeleri görebiliriz:

model.layers[1](vectorizer(['Hello, world!','I am glad to meet you!'])).numpy()

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

array([[[-0.02485236, -0.00416857, -0.06599288, ..., -0.02404598,
          0.03529833, -0.02100844],
        [ 0.22493948,  0.01383338,  0.12420551, ...,  0.19531338,
          0.13524376,  0.04216914],
        [ 0.04510409,  0.00708018, -0.0310419 , ..., -0.0188726 ,
         -0.0179676 , -0.04813331],
        [ 0.04510409,  0.00708018, -0.0310419 , ..., -0.0188726 ,
         -0.0179676 , -0.04813331],
        [ 0.04510409,  0.00708018, -0.0310419 , ..., -0.0188726 ,
         -0.0179676 , -0.04813331],
        [ 0.04510409,  0.00708018, -0.0310419 , ..., -0.0188726 ,
         -0.0179676 , -0.04813331]],

       [[-0.00226152, -0.0972852 , -0.00063103, ...,  0.00504377,
          0.22460397,  0.1497297 ],
        [-0.15621698, -0.13758421, -0.02889572, ..., -0.02577994,
          0.03472563,  0.08767739],
        [-0.02485236, -0.00416857, -0.06599288, ..., -0.02404598,
          0.03529833, -0.02100844],
        [-0.06490357, -0.08200071, -0.06175491, ..., -0.02477042,
         -0.06802022, -0.01040947],
        [ 0.03279151,  0.12563369,  0.06062867, ..., -0.04349922,
         -0.12154414, -0.12533969],
        [-0.14435016, -0.304014  , -0.00378676, ...,  0.05609043,
          0.20370889,  0.28518862]]], dtype=float32)

Uyarı

Doldurma miktarını en aza indirmek için, bazı durumlarda veri kümesindeki tüm dizileri artan uzunlukta (veya daha kesin olarak belirteç sayısı) sıralamak mantıklıdır. Bu, her minibatch'in benzer uzunlukta diziler içermesini sağlar.

Anlamsal eklemeler: Word2Vec

Önceki örneğimizde ekleme katmanı, sözcükleri vektör gösterimleriyle eşlemeyi öğrendi ancak bu gösterimlerin anlamsal anlamı yoktu. Benzer sözcüklerin veya eş anlamlıların bir vektör uzaklığı bakımından birbirine yakın vektörlere (örneğin öklid uzaklığı) karşılık gelen bir vektör gösterimini öğrenmek güzel olacaktır.

Bunu yapmak için , Word2Vec gibi bir teknik kullanarak büyük bir metin koleksiyonu üzerinde ekleme modelimizi önceden eğitmeliyiz. Sözcüklerin dağıtılmış bir gösterimini oluşturmak için kullanılan iki ana mimariyi temel alır:

  • Modeli çevresindeki bağlamdan bir sözcüğü tahmin etmek için eğittiğimiz sürekli sözcük paketi (CBoW). $(W_,W_{-2},W_0,W_1,W_2{-1})$ ngramı göz önünde bulundurulduğunda, modelin amacı $(W_{-2},W_,W_1,W_2{-1})$ değerinden $W_0$ tahmini yapmaktır.
  • Sürekli skip-gram , CBoW'un tersidir. Model, bağlam sözcüklerinin çevresindeki pencereyi tahmin etmek için giriş sözcüğünü ($W_0$) kullanır.

CBoW daha hızlıdır ve skip-gram daha yavaş olsa da, seyrek kullanılan sözcükleri temsil etmek için daha iyi bir iş yapar.

Sözcükleri vektörlere dönüştürmek için hem CBoW hem de Skip-Gram algoritmalarını gösteren diyagram.

Google News veri kümesi üzerinde önceden eğitilmiş Word2Vec yerleştirmesini denemek için gensim kitaplığını kullanabiliriz. Aşağıda 'nöral' ile en benzer sözcükleri buluyoruz.

Uyarı

Sözcük vektörlerini ilk oluşturduğunuzda, bunları indirmek biraz zaman alabilir!

import gensim.downloader as api
w2v = api.load('word2vec-google-news-300')
for w,p in w2v.most_similar('neural'):
    print(f"{w} -> {p}")

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

neuronal -> 0.7804799675941467
neurons -> 0.7326500415802002
neural_circuits -> 0.7252851724624634
neuron -> 0.7174385190010071
cortical -> 0.6941086649894714
brain_circuitry -> 0.6923246383666992
synaptic -> 0.6699118614196777
neural_circuitry -> 0.6638563275337219
neurochemical -> 0.6555314064025879
neuronal_activity -> 0.6531826257705688

Ayrıca, sınıflandırma modelini eğitmek için kullanılacak olan sözcükten vektör eklemeyi ayıklayabiliriz. Ekleme 300 bileşene sahiptir, ancak burada netlik için vektörünün yalnızca ilk 20 bileşenini gösteriyoruz:

w2v['play'][:20]

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

array([ 0.01226807,  0.06225586,  0.10693359,  0.05810547,  0.23828125,
        0.03686523,  0.05151367, -0.20703125,  0.01989746,  0.10058594,
       -0.03759766, -0.1015625 , -0.15820312, -0.08105469, -0.0390625 ,
       -0.05053711,  0.16015625,  0.2578125 ,  0.10058594, -0.25976562],
      dtype=float32)

Anlamsal eklemelerin en iyi özelliği, vektör kodlamasını semantiği temel alarak işleyebilmenizdir. Örneğin, vektör gösterimi kral ve kadın sözcüklerine mümkün olduğunca yakın olan ve erkek sözcüğünden mümkün olduğunca uzak olan bir sözcük bulmak isteyebiliriz:

w2v.most_similar(positive=['king','woman'],negative=['man'])[0]

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

('queen', 0.7118192911148071)

Yukarıdaki örnekte bir miktar Gensim'in iç sihri kullanılıyor, ancak asıl mantık basittir. Gömlemelerle ilgili ilginç bir şey, gömü vektörleri üzerinde normal vektör işlemleri gerçekleştirebilmeniz ve bu işlemlerin kelime anlamlarına yansımasıdır. Yukarıdaki örnek vektör işlemleri açısından ifade edilebilir: KING-MAN+WOMAN'a karşılık gelen vektörü hesaplıyoruz (işlemler + ve - karşılık gelen sözcüklerin vektör gösterimleri üzerinde gerçekleştirilir) ve ardından sözlükte bu vektöre en yakın sözcüğü buluruz:

# get the vector corresponding to king-man+woman
qvec = w2v['king'] - w2v['man'] + w2v['woman']
# find the index of the closest embedding vector, excluding input words
d = np.sum((w2v.vectors-qvec)**2,axis=1)
exclude = {w2v.key_to_index[w] for w in ['king', 'man', 'woman']}
d[list(exclude)] = np.inf
min_idx = np.argmin(d)
# find the corresponding word
w2v.index_to_key[min_idx]

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

'queen'

En yakın vektörünü bulmak için NumPy'yi kullanarak vektörümüzle kelime dağarcığındaki tüm vektörler arasındaki uzaklıkların vektörünü hesaplayıp kullanarak argminen yakın sözcüğün dizinini buluruz. Yöntem bunu otomatik olarak yaptığı için giriş sözcüklerini (king, man, woman) aramanın most_similar dışında tutarız.

Word2Vec, sözcük semantiğini ifade etmek için harika bir yol gibi görünse de, aşağıdakiler de dahil olmak üzere birçok dezavantajı vardır:

  • Hem CBoW hem de skip-gram modelleri tahmine dayalı eklemelerdir ve yalnızca yerel bağlamı dikkate alır. Word2Vec genel bağlamdan yararlanmaz.
  • Word2Vec, sözcük morfolojisini, yani sözcüğün anlamının kök gibi sözcüğün farklı bölümlerine bağlı olabileceği gerçeğini dikkate almaz.

FastText, ikinci sınırlamayı aşmaya çalışır ve her kelime için vektör gösterimlerini ve her kelimenin içinde bulunan karakter n-gramlarını öğrenerek Word2Vec'in üzerine inşa eder. Gösterimlerin değerleri daha sonra her eğitim adımında tek bir vektörde ortalanır. Bu, ön eğitime çok sayıda ek hesaplama eklese de, sözcük gömmelerinin alt sözcük bilgilerini kodlamasını sağlar.

Başka bir yöntem olan GloVe, sözcük bağlamı matrisinin faktörizasyonuna bağlı olarak sözcük ekleme işlemlerine farklı bir yaklaşım kullanır. İlk olarak, farklı bağlamlardaki sözcük oluşumlarının sayısını sayan büyük bir matris oluşturur ve sonra bu matrisi yeniden yapılandırma kaybını en aza indirecek şekilde daha düşük boyutlarda temsil etmeye çalışır.

Gensim kitaplığı bu sözcük eklemelerini destekler ve yukarıdaki model yükleme kodunu değiştirerek bunlarla denemeler yapabilirsiniz.

Keras'ta önceden eğitilmiş eklemeleri kullanma

Yerleştirme katmanımızdaki matrisi, Word2Vec gibi anlamsal gömme yöntemleriyle önceden doldurmak için yukarıdaki örneği değiştirebiliriz. Önceden eğitilmiş ekleme ve metin corpus kelime hazineleri büyük olasılıkla eşleşmez, bu nedenle birini seçmemiz gerekir. Burada iki olası seçeneği keşfedeceğiz: belirteç oluşturucu kelime dağarcığını kullanma ve Word2Vec eklemelerinin kelime dağarcığını kullanma.

Belirteç oluşturucu kelime dağarcığını kullanma

Belirteç oluşturucu kelime dağarcığını kullanırken, kelime dağarcığındaki bazı sözcüklere karşılık gelen Word2Vec eklemeleri bulunur ve bazıları eksik olur. Kelime dağarcığı boyutumuzun vocab_sizeve Word2Vec ekleme vektör uzunluğunun olduğu embed_sizedüşünüldüğünde, ekleme katmanı $\times$vocab_size şeklindeki embed_sizebir ağırlık matrisi ile temsil edilir. Bu matrisi kelime dağarcığını kullanarak dolduracağız:

embed_size = len(w2v.get_vector('hello'))
print(f'Embedding size: {embed_size}')

vocab = vectorizer.get_vocabulary()
W = np.zeros((vocab_size,embed_size))
print('Populating matrix, this will take some time...',end='')
found, not_found = 0,0
for i,w in enumerate(vocab):
    try:
        W[i] = w2v.get_vector(w)
        found+=1
    except KeyError:
        # W[i] = np.random.normal(0.0,0.3,size=(embed_size,))
        not_found+=1

print(f"Done, found {found} words, {not_found} words missing")

Word2Vec kelime dağarcığında bulunmayan sözcükler için bunları sıfır olarak bırakabilir veya rastgele bir vektör oluşturabiliriz.

Önceden eğitilmiş ağırlıklara sahip bir ekleme katmanı tanımlamak için aşağıdaki kodu çalıştırıyoruz:

emb = keras.layers.Embedding(vocab_size,embed_size,weights=[W],trainable=False)
model = keras.Sequential([
    keras.Input(shape=(1,), dtype=tf.string),
    vectorizer, emb,
    keras.layers.Lambda(lambda x: tf.reduce_mean(x,axis=1)),
    keras.layers.Dense(4, activation='softmax')
])

Bu işlem tamamlandıktan sonra modelimizi eğitebiliriz.

model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])
model.fit(ds_train.map(tupelize).batch(batch_size),
          validation_data=ds_test.map(tupelize).batch(batch_size))

Uyarı

Dikkat edin ki trainable=False öğesini, Embedding katmanını oluştururken ayarladık, bu da Gömme katmanını yeniden eğitmediğimiz anlamına gelir. Bu, doğruluğun biraz daha düşük olmasını sağlar, ancak eğitimi hızlandırır.

Gömülü sözcük dağarcığını kullanma

Önceki yaklaşımla ilgili bir sorun, TextVectorization ve Embedding'de kullanılan kelime dağarcığının farklı olmasıdır. Bu sorunun üstesinden gelmek için aşağıdaki çözümlerden birini kullanabiliriz:

  • Word2Vec modelini kelime dağarcığımız üzerinde yeniden eğitin.
  • Veri kümemizi önceden eğitilmiş Word2Vec modelindeki sözlükle yükleyin. Veri kümesini yüklemek için kullanılan sözlükler yükleme sırasında belirtilebilir.

İkinci yaklaşım daha kolay görünüyor, bu nedenle bunu uygulayalım. Her şeyden önce, Word2Vec eklemelerinden alınan belirtilen sözcük dağarcığına sahip bir TextVectorization katman oluştururuz:

vocab = list(w2v.key_to_index.keys())
vectorizer = keras.layers.TextVectorization()
vectorizer.set_vocabulary(vocab)

Şimdi Word2Vec vektörlerinden ekleme ağırlık matrisini oluşturmamız gerekiyor. Her satırın sözlükteki bir sözcükle karşılık geldiği bir matris oluşturur ve Keras ekleme katmanını el ile oluştururuz:

embed_size = w2v.vector_size
vocab_size_w2v = len(vocab) + 2  # +2 for padding and unknown tokens
W = np.zeros((vocab_size_w2v, embed_size))
for i, word in enumerate(vocab):
    W[i + 2] = w2v[word]  # offset by 2 for padding (0) and unknown (1) tokens

emb_w2v = keras.layers.Embedding(vocab_size_w2v, embed_size, weights=[W], trainable=False)

model = keras.Sequential([
    keras.Input(shape=(1,), dtype=tf.string),
    vectorizer,
    emb_w2v,
    keras.layers.Lambda(lambda x: tf.reduce_mean(x,axis=1)),
    keras.layers.Dense(4, activation='softmax')
])
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['acc'])
model.fit(ds_train.map(tupelize).batch(128),validation_data=ds_test.map(tupelize).batch(128),epochs=5)

Bu kodu çalıştırmak aşağıdaki çıkışı oluşturur:

Epoch 1/5
938/938 ━━━━━━━━━━━━━━━━━━━━ 7s 7ms/step - loss: 1.3381 - acc: 0.4961 - val_loss: 1.2996 - val_acc: 0.5682
Epoch 2/5
938/938 ━━━━━━━━━━━━━━━━━━━━ 7s 7ms/step - loss: 1.2591 - acc: 0.5714 - val_loss: 1.2340 - val_acc: 0.5839
Epoch 3/5
938/938 ━━━━━━━━━━━━━━━━━━━━ 7s 7ms/step - loss: 1.1983 - acc: 0.5883 - val_loss: 1.1827 - val_acc: 0.5951
Epoch 4/5
938/938 ━━━━━━━━━━━━━━━━━━━━ 7s 7ms/step - loss: 1.1505 - acc: 0.6001 - val_loss: 1.1417 - val_acc: 0.6021
Epoch 5/5
938/938 ━━━━━━━━━━━━━━━━━━━━ 7s 7ms/step - loss: 1.1122 - acc: 0.6093 - val_loss: 1.1084 - val_acc: 0.6103

Daha yüksek doğruluk görmememizin nedenlerinden biri, veri kümemizdeki bazı sözcüklerin önceden eğitilmiş Word2Vec sözlüğünde eksik olması ve bu nedenle yok sayılmalarıdır. Önceden eğitilen Word2Vec modeli, AG Haber sınıflandırma veri kümesinden farklı bir etki alanı ve sözcük dağarcığı dağılımına sahip Olan Google News corpus'ta eğitildi. Eğitim verilerimizde mevcut olan ancak Word2Vec kelime dağarcığında bulunmayan sözcükler sıfır vektörle eşlenir ve bu da sınıflandırıcı için kullanılabilir etkili sinyali azaltır. Buna ek olarak, ekleme katmanında kullanmak trainable=False , modelin özel sınıflandırma görevimize vektör sözcüğünü uyarlayamaması anlamına gelir ve bu da göreve özgü özellikleri öğrenme becerisini sınırlar. Bunun üstesinden gelmek için veri kümemize göre kendi eklemelerimizi eğitebiliriz.

Uyarı

Sıfırdan eğitim ekleme işlemlerine kıyasla burada görülen doğruluk oranının daha düşük olması beklenmektedir. Önceden eğitilen Word2Vec modeli, AG Haber sınıflandırma veri kümesinden farklı bir kelime dağarcığına ve etki alanına sahip Olan Google News corpus'ta eğitilmiştir. Modülün eğitim verilerinde bulunan ancak Word2Vec kelime dağarcığında bulunmayan sözcükler sessizce yoksayılır (sıfır vektöre eşlenir), böylece sınıflandırıcı için kullanılabilir etkili sinyal azaltılır. Etki alanına özgü görevlerde en iyi sonuçları elde etmek için etki alanı içi verilere ekleme işlemlerine ince ayarlamalar yapmayı göz önünde bulundurun.

Kendi eklemelerinizi eğitin

Örneklerimizde önceden eğitilmiş semantik eklemeler kullandık, ancak bu eklemelerin CBoW veya skip-gram mimarileri kullanılarak nasıl eğitilebileceğini görmek ilginç. Bu alıştırma bu modülün ötesine geçer, ancak ilgilenenler Word2Vec modelini eğitme konusunda bu resmi TensorFlow öğreticisini gözden geçirmek isteyebilirler. Ayrıca gensim çerçevesi, resmi belgelerde açıklandığı gibi en sık kullanılan eklemeleri birkaç kod satırına eğitmek için kullanılabilir.

Bağlamsal eklemeler

Word2Vec gibi geleneksel önceden eğitilmiş ekleme gösterimlerinin önemli sınırlamalarından biri, bir sözcüğün bir anlamını yakalayabilseler bile farklı anlamları ayırt edememeleridir. Bu, aşağı akış modellerinde sorunlara neden olabilir.

Örneğin, 'play' sözcüğünün bu iki farklı cümlede farklı anlamı vardır:

  • Tiyatroda bir oyuna gittim.
  • John arkadaşlarıyla oynamak istiyor.

Bahsettiğimiz önceden eğitilmiş eklemeler, aynı eklemedeki 'play' sözcüğünün her iki anlamını da temsil eder. Bu sınırlamayı aşmak için, büyük bir metin kümesi üzerinde eğitilen ve sözcüklerin farklı bağlamlarda nasıl bir araya getirilebileceğini bilendil modelini temel alan eklemeler oluşturmamız gerekir. Bağlamsal eklemelerin tartışılması bu modülün kapsamı dışındadır, ancak sonraki ünitede dil modellerinden bahsederken bunlara geri döneceğiz.