14.3. Sözcük Gömme Ön Eğitimi İçin Veri Kümesi
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in SageMaker Studio Lab

Artık word2vec modellerinin teknik ayrıntılarını ve yaklaşıklama eğitim yöntemlerini bildiğimize göre, uygulamalarını inceleyelim. Özellikle, Section 14.1 içinde skip-gram modelini ve Section 14.2 içinde negatif örneklemeyi örnek olarak alacağız. Bu bölümde, sözcük gömme modeli ön eğitimi için veri kümesi ile başlıyoruz: Verilerin orijinal biçimi eğitim sırasında yinelenebilen minigruplar haline dönüştürülecektir.

import math
import os
import random
from d2l import mxnet as d2l
from mxnet import gluon, np
import math
import os
import random
import torch
from d2l import torch as d2l

14.3.1. Veri Kümesini Okuma

Burada kullandığımız veri kümesi Penn Tree Bank (PTB)’dir. Bu külliyat, Wall Street Journal makalelerinden örneklenmiştir ve eğitim, geçerleme ve test kümelerine bölünmüştür. Özgün biçimde, metin dosyasının her satırı boşluklarla ayrılmış bir sözcükler cümlesini temsil eder. Burada her sözcüğe bir belirteç gibi davranıyoruz.

#@save
d2l.DATA_HUB['ptb'] = (d2l.DATA_URL + 'ptb.zip',
                       '319d85e578af0cdc590547f26231e4e31cdf1e42')

#@save
def read_ptb():
    """Load the PTB dataset into a list of text lines."""
    data_dir = d2l.download_extract('ptb')
    # Read the training set.
    with open(os.path.join(data_dir, 'ptb.train.txt')) as f:
        raw_text = f.read()
    return [line.split() for line in raw_text.split('\n')]

sentences = read_ptb()
f'# sentences: {len(sentences)}'
'# sentences: 42069'
#@save
d2l.DATA_HUB['ptb'] = (d2l.DATA_URL + 'ptb.zip',
                       '319d85e578af0cdc590547f26231e4e31cdf1e42')

#@save
def read_ptb():
    """Load the PTB dataset into a list of text lines."""
    data_dir = d2l.download_extract('ptb')
    # Read the training set.
    with open(os.path.join(data_dir, 'ptb.train.txt')) as f:
        raw_text = f.read()
    return [line.split() for line in raw_text.split('\n')]

sentences = read_ptb()
f'# sentences: {len(sentences)}'
'# sentences: 42069'

Eğitim kümesini okuduktan sonra, 10 kereden az görünen herhangi bir sözcüğün “<unk>” belirteci ile değiştirildiği külliyat için bir sözcük dağarcığı oluşturuyoruz. Özgün veri kümesinin nadir (bilinmeyen) sözcükleri temsil eden “<unk>” belirteçleri de içerdiğini unutmayın.

vocab = d2l.Vocab(sentences, min_freq=10)
f'vocab size: {len(vocab)}'
'vocab size: 6719'
vocab = d2l.Vocab(sentences, min_freq=10)
f'vocab size: {len(vocab)}'
'vocab size: 6719'

14.3.2. Alt Örnekleme

Metin verileri genellikle “the”, “a” ve “in” gibi yüksek frekanslı sözcüklere sahiptir: Hatta çok büyük külliyatta milyarlarca kez ortaya çıkabilirler. Ancak, bu sözcükler genellikle bağlam pencerelerinde birçok farklı sözcükle birlikte ortaya çıkar ve çok az yararlı sinyaller sağlar. Örneğin, bir bağlam penceresinde (“çip”) “chip” sözcüğünü göz önünde bulundurun: Sezgisel olarak düşük frekanslı bir “intel” sözcüğüyle birlikte oluşması, eğitimde yüksek frekanslı bir sözcük “a” ile birlikte oluşmasından daha yararlıdır. Dahası, büyük miktarda (yüksek frekanslı) sözcüklerle eğitim yavaştır. Böylece, sözcük gömme modellerini eğitiyorken, yüksek frekanslı sözcükler alt örneklenebilir (Mikolov et al., 2013). Özellikle, veri kümesindeki dizine alınmış her bir \(w_i\) sözcüğü aşağıdaki olasılıkla atılacaktır.

(14.3.1)\[P(w_i) = \max\left(1 - \sqrt{\frac{t}{f(w_i)}}, 0\right),\]

burada \(f(w_i)\), \(w_i\) sözcüklerinin sayısının veri kümelerindeki toplam sözcük sayısına oranıdır ve \(t\) sabit (deneyde \(10^{-4}\)) bir hiper parametredir. Sadece göreli frekans \(f(w_i) > t\) (yüksek frekanslı) olursa \(w_i\) sözcüğü atılabilir ve sözcüğün göreli frekansı ne kadar yüksek olursa, atılma olasılığı o kadar yüksektir.

#@save
def subsample(sentences, vocab):
    """Yüksek frekanslı sözcükleri alt örnekle."""
    # '<unk>' andıçlarını hariç tut
    sentences = [[token for token in line if vocab[token] != vocab.unk]
                 for line in sentences]
    counter = d2l.count_corpus(sentences)
    num_tokens = sum(counter.values())

    # Alt örnekleme sırasında `token` tutulursa True döndür
    def keep(token):
        return(random.uniform(0, 1) <
               math.sqrt(1e-4 / counter[token] * num_tokens))

    return ([[token for token in line if keep(token)] for line in sentences],
            counter)

subsampled, counter = subsample(sentences, vocab)
#@save
def subsample(sentences, vocab):
    """Yüksek frekanslı sözcükleri alt örnekle."""
    # '<unk>' andıçlarını hariç tut
    sentences = [[token for token in line if vocab[token] != vocab.unk]
                 for line in sentences]
    counter = d2l.count_corpus(sentences)
    num_tokens = sum(counter.values())

    # Alt örnekleme sırasında `token` tutulursa True döndür
    def keep(token):
        return(random.uniform(0, 1) <
               math.sqrt(1e-4 / counter[token] * num_tokens))

    return ([[token for token in line if keep(token)] for line in sentences],
            counter)

subsampled, counter = subsample(sentences, vocab)

Aşağıdaki kod parçacığı, alt örnekleme öncesi ve sonrasında cümle başına belirteç sayısının histogramını çizer. Beklendiği gibi, alt örnekleme, yüksek frekanslı sözcükleri düşürerek cümleleri önemli ölçüde kısaltır ve bu da eğitim hızlandırmasına yol açacaktır.

d2l.show_list_len_pair_hist(['origin', 'subsampled'], '# tokens per sentence',
                            'count', sentences, subsampled);
../_images/output_word-embedding-dataset_f77071_39_0.svg
d2l.show_list_len_pair_hist(['origin', 'subsampled'], '# tokens per sentence',
                            'count', sentences, subsampled);
../_images/output_word-embedding-dataset_f77071_42_0.svg

Bireysel belirteçler için, yüksek frekanslı “the” sözcüğünün örnekleme oranı 1/20’den azdır.

def compare_counts(token):
    return (f'# of "{token}": '
            f'before={sum([l.count(token) for l in sentences])}, '
            f'after={sum([l.count(token) for l in subsampled])}')

compare_counts('the')
'# of "the": before=50770, after=2045'
def compare_counts(token):
    return (f'# of "{token}": '
            f'before={sum([l.count(token) for l in sentences])}, '
            f'after={sum([l.count(token) for l in subsampled])}')

compare_counts('the')
'# of "the": before=50770, after=2090'

Buna karşılık, düşük frekanslı “join” sözcüğü tamamen tutulur.

compare_counts('join')
'# of "join": before=45, after=45'
compare_counts('join')
'# of "join": before=45, after=45'

Alt örneklemeden sonra, belirteçleri külliyat için indekslerine eşliyoruz.

corpus = [vocab[line] for line in subsampled]
corpus[:3]
[[], [2, 392, 32, 2115, 145, 406], [12, 5277, 3054, 1580]]
corpus = [vocab[line] for line in subsampled]
corpus[:3]
[[], [392, 2115, 18], [22, 5277, 3054, 1580]]

14.3.3. Merkezi Sözcükleri ve Bağlam Sözcüklerini Ayıklamak

Aşağıdaki get_centers_and_contexts işlevi, corpus’ten tüm merkez sözcükleri ve onların bağlam sözcüklerini ayıklar. Bağlam penceresi boyutu olarak rastgele olarak 1 ile max_window_size arasında bir tamsayıya eşit olarak örnekler. Herhangi bir merkez sözcük için, uzaklığı örneklenen bağlam penceresi boyutunu aşmayan sözcükler, bağlam sözcükleridir.

#@save
def get_centers_and_contexts(corpus, max_window_size):
    """skip-gramdaki merkez sözcüklerini ve bağlam sözcüklerini döndürür."""
    centers, contexts = [], []
    for line in corpus:
        # Bir "merkez sözcük-bağlam sözcüğü" çifti oluşturmak için
        # her cümlede en az 2 kelime olması gerekir
        if len(line) < 2:
            continue
        centers += line
        for i in range(len(line)):  #  `i` merkezli bağlam penceresi
            window_size = random.randint(1, max_window_size)
            indices = list(range(max(0, i - window_size),
                                 min(len(line), i + 1 + window_size)))
            # Merkez sözcüğü bağlam sözcüklerinden çıkar
            indices.remove(i)
            contexts.append([line[idx] for idx in indices])
    return centers, contexts
#@save
def get_centers_and_contexts(corpus, max_window_size):
    """skip-gramdaki merkez sözcüklerini ve bağlam sözcüklerini döndürür."""
    centers, contexts = [], []
    for line in corpus:
        # Bir "merkez sözcük-bağlam sözcüğü" çifti oluşturmak için
        # her cümlede en az 2 kelime olması gerekir
        if len(line) < 2:
            continue
        centers += line
        for i in range(len(line)):  #  `i` merkezli bağlam penceresi
            window_size = random.randint(1, max_window_size)
            indices = list(range(max(0, i - window_size),
                                 min(len(line), i + 1 + window_size)))
            # Merkez sözcüğü bağlam sözcüklerinden çıkar
            indices.remove(i)
            contexts.append([line[idx] for idx in indices])
    return centers, contexts

Ardından, sırasıyla 7 ve 3 sözcükten oluşan iki cümle içeren yapay bir veri kümesi oluşturuyoruz. Maksimum bağlam penceresi boyutunun 2 olmasını sağlayın ve tüm merkez sözcüklerini ve onların bağlam sözcüklerini yazdırın.

tiny_dataset = [list(range(7)), list(range(7, 10))]
print('dataset', tiny_dataset)
for center, context in zip(*get_centers_and_contexts(tiny_dataset, 2)):
    print('center', center, 'has contexts', context)
dataset [[0, 1, 2, 3, 4, 5, 6], [7, 8, 9]]
center 0 has contexts [1, 2]
center 1 has contexts [0, 2]
center 2 has contexts [0, 1, 3, 4]
center 3 has contexts [1, 2, 4, 5]
center 4 has contexts [2, 3, 5, 6]
center 5 has contexts [3, 4, 6]
center 6 has contexts [4, 5]
center 7 has contexts [8]
center 8 has contexts [7, 9]
center 9 has contexts [8]
tiny_dataset = [list(range(7)), list(range(7, 10))]
print('dataset', tiny_dataset)
for center, context in zip(*get_centers_and_contexts(tiny_dataset, 2)):
    print('center', center, 'has contexts', context)
dataset [[0, 1, 2, 3, 4, 5, 6], [7, 8, 9]]
center 0 has contexts [1, 2]
center 1 has contexts [0, 2]
center 2 has contexts [0, 1, 3, 4]
center 3 has contexts [1, 2, 4, 5]
center 4 has contexts [2, 3, 5, 6]
center 5 has contexts [4, 6]
center 6 has contexts [5]
center 7 has contexts [8, 9]
center 8 has contexts [7, 9]
center 9 has contexts [7, 8]

PTB veri kümesi üzerinde eğitim yaparken, maksimum bağlam penceresi boyutunu 5’e ayarladık. Aşağıdaki, veri kümelerindeki tüm merkez sözcüklerini ve onların bağlam sözcüklerini ayıklar.

all_centers, all_contexts = get_centers_and_contexts(corpus, 5)
f'# center-context pairs: {sum([len(contexts) for contexts in all_contexts])}'
'# center-context pairs: 1501007'
all_centers, all_contexts = get_centers_and_contexts(corpus, 5)
f'# center-context pairs: {sum([len(contexts) for contexts in all_contexts])}'
'# center-context pairs: 1500630'

14.3.4. Negatif Örnekleme

Yaklaşıklama eğitim için negatif örnekleme kullanıyoruz. Gürültülü sözcükleri önceden tanımlanmış bir dağıtıma göre örneklemek için aşağıdaki RandomGenerator sınıfını tanımlıyoruz; burada (muhtemelen normalleştirilmemiş) örnekleme dağılımı sampling_weights argümanı üzerinden geçirilir.

#@save
class RandomGenerator:
    """Örnekleme ağırlıklarına göre {1, ..., n} arasından rastgele çek."""
    def __init__(self, sampling_weights):
        # Hariç tut
        self.population = list(range(1, len(sampling_weights) + 1))
        self.sampling_weights = sampling_weights
        self.candidates = []
        self.i = 0

    def draw(self):
        if self.i == len(self.candidates):
            # `k` rastgele örnekleme sonuçlarını önbelleğe al
            self.candidates = random.choices(
                self.population, self.sampling_weights, k=10000)
            self.i = 0
        self.i += 1
        return self.candidates[self.i - 1]
#@save
class RandomGenerator:
    """Örnekleme ağırlıklarına göre {1, ..., n} arasından rastgele çek."""
    def __init__(self, sampling_weights):
        # Hariç tut
        self.population = list(range(1, len(sampling_weights) + 1))
        self.sampling_weights = sampling_weights
        self.candidates = []
        self.i = 0

    def draw(self):
        if self.i == len(self.candidates):
            # `k` rastgele örnekleme sonuçlarını önbelleğe al
            self.candidates = random.choices(
                self.population, self.sampling_weights, k=10000)
            self.i = 0
        self.i += 1
        return self.candidates[self.i - 1]

Örneğin, \(P(X=1)=2/9, P(X=2)=3/9\) ve \(P(X=3)=4/9\) örnekleme olasılıkları ile 1, 2 ve 3 indeksleri arasından 10 adet \(X\) rasgele değişkenini çekebiliriz.

generator = RandomGenerator([2, 3, 4])
[generator.draw() for _ in range(10)]
[3, 1, 1, 3, 3, 2, 3, 1, 3, 1]

Bir çift merkez sözcük ve bağlam sözcüğü için, rastgele K (deneyde 5) gürültü sözcüğü örnekleriz. Word2vec makalesindeki önerilere göre, \(w\) gürültü sözcüğünün \(P(w)\) örnekleme olasılığı, 0.75’in (Mikolov et al., 2013) gücüne yükseltilmiş olarak sözlükteki göreli frekansına ayarlanır.

#@save
def get_negatives(all_contexts, vocab, counter, K):
    """Negatif örneklemede gürültü sözcüklerini döndür."""
    # Sözlükte 1, 2, ... (dizin 0 hariç tutulan bilinmeyen belirteçtir)
    # olan kelimeler için örnekleme ağırlıkları
    sampling_weights = [counter[vocab.to_tokens(i)]**0.75
                        for i in range(1, len(vocab))]
    all_negatives, generator = [], RandomGenerator(sampling_weights)
    for contexts in all_contexts:
        negatives = []
        while len(negatives) < len(contexts) * K:
            neg = generator.draw()
            # Gürültü sözcükleri bağlam sözcükleri olamaz
            if neg not in contexts:
                negatives.append(neg)
        all_negatives.append(negatives)
    return all_negatives

all_negatives = get_negatives(all_contexts, vocab, counter, 5)
#@save
def get_negatives(all_contexts, vocab, counter, K):
    """Negatif örneklemede gürültü sözcüklerini döndür."""
    # Sözlükte 1, 2, ... (dizin 0 hariç tutulan bilinmeyen belirteçtir)
    # olan kelimeler için örnekleme ağırlıkları
    sampling_weights = [counter[vocab.to_tokens(i)]**0.75
                        for i in range(1, len(vocab))]
    all_negatives, generator = [], RandomGenerator(sampling_weights)
    for contexts in all_contexts:
        negatives = []
        while len(negatives) < len(contexts) * K:
            neg = generator.draw()
            # Gürültü sözcükleri bağlam sözcükleri olamaz
            if neg not in contexts:
                negatives.append(neg)
        all_negatives.append(negatives)
    return all_negatives

all_negatives = get_negatives(all_contexts, vocab, counter, 5)

14.3.5. Minigruplarda Eğitim Örneklerini Yükleme

Bağlam sözcükleri ve örneklenmiş gürültü sözcükleri ile birlikte tüm merkezi sözcükler çıkarıldıktan sonra, eğitim sırasında yinelemeli olarak yüklenebilecek örneklerin minigruplarına dönüştürülecektir.

Bir minigrupta, \(i.\) örnek bir merkez sözcük ve onun \(n_i\) bağlam sözcükleri ve \(m_i\) gürültü sözcükleri içerir. Değişen bağlam penceresi boyutları nedeniyle \(n_i+m_i\) farklı \(i\)’ler için değişiklik gösterir. Böylece, her örnek için bağlam sözcüklerini ve gürültü sözcüklerini contexts_negatives değişkeninde bitiştiririz ve bitiştirme uzunluğu \(\max_i n_i+m_i\)’a (max_len) ulaşana kadar sıfırlarla dolgularız. Kaybın hesaplanmasında dolguları hariç tutmak için bir maske değişkeni, masks, tanımlıyoruz. masks’taki elemanlar ve contexts_negatives’teki elemanlar arasında bire bir karşılık vardır, burada masks’daki sıfırlar (aksi takdirde birler) contexts_negatives’teki dolgulara karşılık gelir.

Pozitif ve negatif örnekleri ayırt etmek için contexts_negatives içindeki gürültü sözcüklerinden labels değişkeni aracılığıyla bağlam sözcüklerini ayırırız. masks’e benzer şekilde, labels’daki elemanlar ve contexts_negatives’teki elemanlar arasında bire bir karşılık vardır ve labels’daki birler (aksi takdirde sıfırlar) contexts_negatives’teki bağlam sözcüklerine (olumlu örneklere) karşılık gelir.

Yukarıdaki fikir aşağıdaki batchify işlevinde uygulanmaktadır. Girdi data toplu boyutuna eşit uzunlukta bir listedir; her öğesi center merkez sözcüklerinden, context bağlam sözcüklerinden ve negative gürültü sözcüklerinden oluşan bir örnektir. Bu işlev, maske değişkeni de dahil olmak üzere eğitim sırasında hesaplamalar için yüklenebilecek bir minigrup döndürür.

#@save
def batchify(data):
    """Negatif örnekleme ile skip-gram için bir minigrup örnek döndür."""
    max_len = max(len(c) + len(n) for _, c, n in data)
    centers, contexts_negatives, masks, labels = [], [], [], []
    for center, context, negative in data:
        cur_len = len(context) + len(negative)
        centers += [center]
        contexts_negatives += [context + negative + [0] * (max_len - cur_len)]
        masks += [[1] * cur_len + [0] * (max_len - cur_len)]
        labels += [[1] * len(context) + [0] * (max_len - len(context))]
    return (np.array(centers).reshape((-1, 1)), np.array(
        contexts_negatives), np.array(masks), np.array(labels))
#@save
def batchify(data):
    """Negatif örnekleme ile skip-gram için bir minigrup örnek döndür."""
    max_len = max(len(c) + len(n) for _, c, n in data)
    centers, contexts_negatives, masks, labels = [], [], [], []
    for center, context, negative in data:
        cur_len = len(context) + len(negative)
        centers += [center]
        contexts_negatives += [context + negative + [0] * (max_len - cur_len)]
        masks += [[1] * cur_len + [0] * (max_len - cur_len)]
        labels += [[1] * len(context) + [0] * (max_len - len(context))]
    return (torch.tensor(centers).reshape((-1, 1)), torch.tensor(
        contexts_negatives), torch.tensor(masks), torch.tensor(labels))

Bu işlevi iki örnekten oluşan bir minigrup kullanarak test edelim.

x_1 = (1, [2, 2], [3, 3, 3, 3])
x_2 = (1, [2, 2, 2], [3, 3])
batch = batchify((x_1, x_2))

names = ['centers', 'contexts_negatives', 'masks', 'labels']
for name, data in zip(names, batch):
    print(name, '=', data)
centers = [[1.]
 [1.]]
contexts_negatives = [[2. 2. 3. 3. 3. 3.]
 [2. 2. 2. 3. 3. 0.]]
masks = [[1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 0.]]
labels = [[1. 1. 0. 0. 0. 0.]
 [1. 1. 1. 0. 0. 0.]]
x_1 = (1, [2, 2], [3, 3, 3, 3])
x_2 = (1, [2, 2, 2], [3, 3])
batch = batchify((x_1, x_2))

names = ['centers', 'contexts_negatives', 'masks', 'labels']
for name, data in zip(names, batch):
    print(name, '=', data)
centers = tensor([[1],
        [1]])
contexts_negatives = tensor([[2, 2, 3, 3, 3, 3],
        [2, 2, 2, 3, 3, 0]])
masks = tensor([[1, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 0]])
labels = tensor([[1, 1, 0, 0, 0, 0],
        [1, 1, 1, 0, 0, 0]])

14.3.6. Her Şeyi Bir Araya Getirmek

Son olarak, PTB veri kümesini okuyan ve veri yineleyicisini ve sözcük dağarcığını döndüren load_data_ptb işlevini tanımlıyoruz.

#@save
def load_data_ptb(batch_size, max_window_size, num_noise_words):
    """PTB veri kümesini indirin ve ardından belleğe yükleyin."""
    sentences = read_ptb()
    vocab = d2l.Vocab(sentences, min_freq=10)
    subsampled, counter = subsample(sentences, vocab)
    corpus = [vocab[line] for line in subsampled]
    all_centers, all_contexts = get_centers_and_contexts(
        corpus, max_window_size)
    all_negatives = get_negatives(
        all_contexts, vocab, counter, num_noise_words)
    dataset = gluon.data.ArrayDataset(
        all_centers, all_contexts, all_negatives)
    data_iter = gluon.data.DataLoader(
        dataset, batch_size, shuffle=True,batchify_fn=batchify,
        num_workers=d2l.get_dataloader_workers())
    return data_iter, vocab
#@save
def load_data_ptb(batch_size, max_window_size, num_noise_words):
    """Download the PTB dataset and then load it into memory."""
    num_workers = d2l.get_dataloader_workers()
    sentences = read_ptb()
    vocab = d2l.Vocab(sentences, min_freq=10)
    subsampled, counter = subsample(sentences, vocab)
    corpus = [vocab[line] for line in subsampled]
    all_centers, all_contexts = get_centers_and_contexts(
        corpus, max_window_size)
    all_negatives = get_negatives(
        all_contexts, vocab, counter, num_noise_words)

    class PTBDataset(torch.utils.data.Dataset):
        def __init__(self, centers, contexts, negatives):
            assert len(centers) == len(contexts) == len(negatives)
            self.centers = centers
            self.contexts = contexts
            self.negatives = negatives

        def __getitem__(self, index):
            return (self.centers[index], self.contexts[index],
                    self.negatives[index])

        def __len__(self):
            return len(self.centers)

    dataset = PTBDataset(all_centers, all_contexts, all_negatives)

    data_iter = torch.utils.data.DataLoader(dataset, batch_size, shuffle=True,
                                      collate_fn=batchify,
                                      num_workers=num_workers)
    return data_iter, vocab

Veri yineleyicisinin ilk minigrubunu yazdıralım.

data_iter, vocab = load_data_ptb(512, 5, 5)
for batch in data_iter:
    for name, data in zip(names, batch):
        print(name, 'shape:', data.shape)
    break
centers shape: (512, 1)
contexts_negatives shape: (512, 60)
masks shape: (512, 60)
labels shape: (512, 60)
data_iter, vocab = load_data_ptb(512, 5, 5)
for batch in data_iter:
    for name, data in zip(names, batch):
        print(name, 'shape:', data.shape)
    break
centers shape: torch.Size([512, 1])
contexts_negatives shape: torch.Size([512, 60])
masks shape: torch.Size([512, 60])
labels shape: torch.Size([512, 60])

14.3.7. Özet

  • Yüksek frekanslı sözcükler eğitimde o kadar yararlı olmayabilir. Eğitimde hızlanmak için onları alt örnekleyebiliriz.

  • Hesaplama verimliliği için örnekleri minigruplar halinde yükleriz. Dolguları dolgu olmayanlardan ve olumlu örnekleri olumsuz olanlardan ayırt etmek için başka değişkenler tanımlayabiliriz.

14.3.8. Alıştırmalar

  1. Alt örnekleme kullanmıyorsa, bu bölümdeki kodun çalışma süresi nasıl değişir?

  2. RandomGenerator sınıfı k rasgele örnekleme sonuçlarını önbelleğe alır. k’yi diğer değerlere ayarlayın ve veri yükleme hızını nasıl etkilediğini görün.

  3. Bu bölümün kodundaki hangi diğer hiper parametreler veri yükleme hızını etkileyebilir?