<jupyter_start><jupyter_text>DataLoader in PyTorch<jupyter_code>from google.colab import drive
drive.mount('/content/gdrive')
%cd /content/gdrive/My Drive/HSE_DL_2021/04_week<jupyter_output>/content/gdrive/My Drive/HSE_DL_2021/04_week<jupyter_text>__DataLoader__ -- класс в PyTorch, который позволяет итеративно проходить по датасету, отвечает за оркестрацию всего процесса работы с датасетом.<jupyter_code>from IPython import display
display.Image('images/DataLoaderParams.png')<jupyter_output><empty_output><jupyter_text>- __dataset__ -- позволяет создать кастомные классы для работы с датасетом, где можно указать логику формирвоания батча.   * как считать данные,  * что отдать на выход- __sampler__ -- определяет порядок элементов из датасета, которые будут идти в батч, то есть это список индексов, объединенных в батч. Удобно переопределять, когда обучение распредленное.    * есть готовые сэмплеры- __collate_fn__ -- позволяет сделать финальную предобработку над батчем данных. Если, например, в батч попали последовательности разных размеров, то после уже сбора батча, можно будет дополнить последовательности нулями относительно максимально длиной последовательности.  * позволяет подготовить данные для батча  Custom Dataset<jupyter_code>import pandas as pd
import pickle
import numpy as np

from torch.utils.data import DataLoader, Dataset, Sampler
from torch.utils.data.dataloader import default_collate
BATCH_SIZE = 128
EPOCHS = 100
with open('data/X_train_cat.pickle', 'rb') as f:
    X, target = pickle.load(f)
X.shape
# пусть у нас лежат данные внутри папки по кускам
# path = spark_data_folder

class CustomDataset(Dataset):
    # Конструктор, где считаем датасет
    def __init__(self, dataset_path):
        # for part in glob(path) - это чтобы пробежаться по спарк файлам
        with open(dataset_path, 'rb') as f:
            self.X, self.target = pickle.load(f)

        return
    
    # Переопределяем метод вычисление размера датасета
    def __len__(self):
        return len(self.X)

    # Переопределяем метод,
    # который достает по индексу наблюдение из датасет
    def __getitem__(self, idx):
        return self.X[idx], self.target[idx]<jupyter_output><empty_output><jupyter_text>Custom Sampler<jupyter_code>np.random.permutation([1,2,3])
class CustomSampler(Sampler):

    # Конструктор, где инициализируем индексы элементов
    def __init__(self, data):
        self.data_indices = np.arange(len(data))

        shuffled_indices = np.random.permutation(len(self.data_indices))

        self.data_indices = np.ascontiguousarray(self.data_indices)[shuffled_indices]

        return

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

    # Возращает итератор,
    # который будет возвращать индексы из перемешанного датасета
    def __iter__(self):
        return iter(self.data_indices)<jupyter_output><empty_output><jupyter_text>Custom Sampler<jupyter_code>def collate(batch):
    return default_collate(batch) # базово превращает в тензор + что-то делает 
    # еще дополнительное
def create_data_loader(train_dataset, train_sampler,
                       test_dataset, test_sampler):
    train_loader = DataLoader(dataset=train_dataset, sampler=train_sampler,
                              batch_size=BATCH_SIZE, collate_fn=collate,
                              shuffle=False)
    # когда мы используем сэмплер - нужно выключать shuffle=False

    test_loader = DataLoader(dataset=test_dataset, sampler=test_sampler,
                             batch_size=BATCH_SIZE, collate_fn=collate,
                             shuffle=False)

    return train_loader, test_loader
# Создаем объекты Custom Dataset и Sampler
train_ds = CustomDataset('data/X_train_cat.pickle')
train_sampler = CustomSampler(train_ds.X)

test_ds = CustomDataset('data/X_test_cat.pickle')
test_sampler = CustomSampler(test_ds.X)
train_loader, test_loader = create_data_loader(train_ds, train_sampler,
                                               test_ds, test_sampler)
def run_train():
    print('Run train')
    for epoch in range(EPOCHS):
        for features, labels in train_loader:
            print(features.shape, labels)
            break

        # Run validation
        print('Run validation')
        for features, labels in test_loader:
            print(features.shape, labels)
            break
            
        break

    return
run_train()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07497168742921857, 'fraction_numerical': 0.0047565118912797286, 'mean_word_length': 3.595213319458897, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '375763', 'license': 'MIT', 'n_tokens_mistral': 1540, 'n_tokens_neox': 1621, 'n_words': 338, 'path': '05 DL/04_week/DataLoader_CustomDataset.ipynb', 'repo_name': 'ksetdekov/HSE_DS', 'size': '4415'}