13.13. Kaggle’da İmge Sınıflandırması (CIFAR-10)
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in SageMaker Studio Lab

Şimdiye kadar, doğrudan tensör formatında imge veri kümelerini elde etmek için derin öğrenme çerçevelerinin üst düzey API’lerini kullanıyoruz. Ancak, özel imge veri kümeleri genellikle imge dosyaları halinde gelir. Bu bölümde, ham imge dosyalarından başlayacağız ve düzenleyeceğiz, okuyacağız, ardından bunları adım adım tensör formatına dönüştüreceğiz.

Bilgisayarla görmede önemli bir veri kümesi olan Section 13.1 içinde CIFAR-10 veri kümesi ile deney yaptık. Bu bölümde, CIFAR-10 imge sınıflandırmasının Kaggle yarışmasını uygulamak için önceki bölümlerde öğrendiğimiz bilgileri uygulayacağız. Yarışmanın web adresi https://www.kaggle.com/c/cifar-10

Fig. 13.13.1 yarışmanın web sayfasındaki bilgileri gösterir. Sonuçları göndermek için bir Kaggle hesabına kayıt olmanız gerekir.

../_images/kaggle-cifar10.png

Fig. 13.13.1 CIFAR-10 imge sınıflandırma yarışması web sayfası bilgileri. Yarışma veri kümesi “Data” (“Veri”) sekmesine tıklanarak elde edilebilir.

import collections
import math
import os
import shutil
import pandas as pd
from d2l import mxnet as d2l
from mxnet import gluon, init, npx
from mxnet.gluon import nn

npx.set_np()
import collections
import math
import os
import shutil
import pandas as pd
import torch
import torchvision
from torch import nn
from d2l import torch as d2l

13.13.1. Veri Kümesini Elde Etme ve Düzenleme

Yarışma veri kümesi, sırasıyla 50000 ve 300000 imge içeren bir eğitim kümesi ve bir test kümesine ayrılmıştır. Test kümesinde, değerlendirme için 10000 imge kullanılacak, kalan 290000 imgeler değerlendirilmeyecek: Bunlar sadece test kümesinin manuel etiketli sonuçlarıyla hile yapmayı zorlaştırmak için dahil edilmiştir. Bu veri kümesindeki imgeler, yüksekliği ve genişliği 32 piksel olan png renkli (RGB kanalları) imge dosyalarıdır. İmgeler, uçaklar, arabalar, kuşlar, kediler, geyik, köpekler, kurbağalar, atlar, tekneler ve kamyonlar olmak üzere toplam 10 kategoriyi kapsar. Fig. 13.13.1 şeklinin sol üst köşesi veri kümesindeki uçakların, arabaların ve kuşların bazı imgelerini gösterir.

13.13.1.1. Veri Kümesini İndirme

Kaggle’a girdi yaptıktan sonra Fig. 13.13.1 içinde gösterilen CIFAR-10 imge sınıflandırma yarışması web sayfasındaki “Veri” (“Data”) sekmesine tıklayabilir ve “Tümünü İndir” (“Download All”) butonuna tıklayarak veri kümesini indirebiliriz. İndirilen dosyayı ../data’da açtıktan ve içinde train.7z ve test.7z’yı açtıktan sonra, tüm veri kümesini aşağıdaki yollarda bulacaksınız:

  • ../data/cifar-10/train/[1-50000].png

  • ../data/cifar-10/test/[1-300000].png

  • ../data/cifar-10/trainLabels.csv

  • ../data/cifar-10/sampleSubmission.csv

train ve test dizinlerinin sırasıyla eğitim ve test imgelerini içerdiği, trainLabels.csv eğitim imgeleri için etiketler sağlar ve sample_submission.csv örnek bir gönderim dosyasıdır.

Başlamayı kolaylaştırmak için ilk 1000 eğitim imgesi ve 5 rastgele test imgesi içeren veri kümesinin küçük ölçekli bir örneğini sağlıyoruz. Kaggle yarışmasının tam veri kümesini kullanmak için aşağıdaki demo değişkenini False olarak ayarlamanız gerekir.

#@save
d2l.DATA_HUB['cifar10_tiny'] = (d2l.DATA_URL + 'kaggle_cifar10_tiny.zip',
                                '2068874e4b9a9f0fb07ebe0ad2b29754449ccacd')

# If you use the full dataset downloaded for the Kaggle competition, set
# `demo` to False
demo = True

if demo:
    data_dir = d2l.download_extract('cifar10_tiny')
else:
    data_dir = '../data/cifar-10/'
#@save
d2l.DATA_HUB['cifar10_tiny'] = (d2l.DATA_URL + 'kaggle_cifar10_tiny.zip',
                                '2068874e4b9a9f0fb07ebe0ad2b29754449ccacd')

# If you use the full dataset downloaded for the Kaggle competition, set
# `demo` to False
demo = True

if demo:
    data_dir = d2l.download_extract('cifar10_tiny')
else:
    data_dir = '../data/cifar-10/'

13.13.1.2. Veri Kümesini Düzenleme

Model eğitimini ve testlerini kolaylaştırmak için veri kümeleri düzenlememiz gerekiyor. Önce csv dosyasındaki etiketleri okuyalım. Aşağıdaki işlev, dosya adının uzantısız kısmını etiketine eşleyen bir sözlük döndürür.

#@save
def read_csv_labels(fname):
    """Read `fname` to return a filename to label dictionary."""
    with open(fname, 'r') as f:
        # Skip the file header line (column name)
        lines = f.readlines()[1:]
    tokens = [l.rstrip().split(',') for l in lines]
    return dict(((name, label) for name, label in tokens))

labels = read_csv_labels(os.path.join(data_dir, 'trainLabels.csv'))
print('# training examples:', len(labels))
print('# classes:', len(set(labels.values())))
# training examples: 1000
# classes: 10
#@save
def read_csv_labels(fname):
    """Read `fname` to return a filename to label dictionary."""
    with open(fname, 'r') as f:
        # Skip the file header line (column name)
        lines = f.readlines()[1:]
    tokens = [l.rstrip().split(',') for l in lines]
    return dict(((name, label) for name, label in tokens))

labels = read_csv_labels(os.path.join(data_dir, 'trainLabels.csv'))
print('# training examples:', len(labels))
print('# classes:', len(set(labels.values())))
# training examples: 1000
# classes: 10

Ardından, reorg_train_valid işlevini esas eğitim kümesinden geçerleme kümesini bölmek için tanımlıyoruz. Bu işlevdeki valid_ratio argümanı, geçerleme kümesindeki örneklerin sayısının orijinal eğitim kümesindeki örneklerin sayısına oranıdır. Daha somut olarak, sınıfın en az örnek içeren imge sayısı \(n\) ve oranı da \(r\) olsun. Geçerleme kümesi her sınıf için \(\max(\lfloor nr\rfloor,1)\) imge ayırır. Örnek olarak valid_ratio=0.1’i kullanalım. Orijinal eğitim kümesi 50000 imgeye sahip olduğundan, train_valid_test/train yolunda eğitim için kullanılan 45000 imge olacak, diğer 5000 imge train_valid_test/valid yolunda geçerleme kümesi olarak bölünecek. Veri kümesini düzenledikten sonra, aynı sınıfın imgeleri aynı klasörün altına yerleştirilir.

#@save
def copyfile(filename, target_dir):
    """Bir dosyayı hedef dizine kopyalayın."""
    os.makedirs(target_dir, exist_ok=True)
    shutil.copy(filename, target_dir)

#@save
def reorg_train_valid(data_dir, labels, valid_ratio):
    """Doğrulama kümesini orijinal eğitim kümesinden ayırın."""
    # Eğitim veri kümesinde en az örneğe sahip sınıfın örnek sayısı
    n = collections.Counter(labels.values()).most_common()[-1][1]
    # Geçerleme kümesi için sınıf başına örnek sayısı
    n_valid_per_label = max(1, math.floor(n * valid_ratio))
    label_count = {}
    for train_file in os.listdir(os.path.join(data_dir, 'train')):
        label = labels[train_file.split('.')[0]]
        fname = os.path.join(data_dir, 'train', train_file)
        copyfile(fname, os.path.join(data_dir, 'train_valid_test',
                                     'train_valid', label))
        if label not in label_count or label_count[label] < n_valid_per_label:
            copyfile(fname, os.path.join(data_dir, 'train_valid_test',
                                         'valid', label))
            label_count[label] = label_count.get(label, 0) + 1
        else:
            copyfile(fname, os.path.join(data_dir, 'train_valid_test',
                                         'train', label))
    return n_valid_per_label
#@save
def copyfile(filename, target_dir):
    """Bir dosyayı hedef dizine kopyalayın."""
    os.makedirs(target_dir, exist_ok=True)
    shutil.copy(filename, target_dir)

#@save
def reorg_train_valid(data_dir, labels, valid_ratio):
    """Doğrulama kümesini orijinal eğitim kümesinden ayırın."""
    # Eğitim veri kümesinde en az örneğe sahip sınıfın örnek sayısı
    n = collections.Counter(labels.values()).most_common()[-1][1]
    # Geçerleme kümesi için sınıf başına örnek sayısı
    n_valid_per_label = max(1, math.floor(n * valid_ratio))
    label_count = {}
    for train_file in os.listdir(os.path.join(data_dir, 'train')):
        label = labels[train_file.split('.')[0]]
        fname = os.path.join(data_dir, 'train', train_file)
        copyfile(fname, os.path.join(data_dir, 'train_valid_test',
                                     'train_valid', label))
        if label not in label_count or label_count[label] < n_valid_per_label:
            copyfile(fname, os.path.join(data_dir, 'train_valid_test',
                                         'valid', label))
            label_count[label] = label_count.get(label, 0) + 1
        else:
            copyfile(fname, os.path.join(data_dir, 'train_valid_test',
                                         'train', label))
    return n_valid_per_label

Aşağıdaki reorg_test işlevi tahmin sırasında veri yükleme için test kümesini düzenler.

#@save
def reorg_test(data_dir):
    """Tahmin sırasında veri yüklemesi için test kümesini düzenleyin."""
    for test_file in os.listdir(os.path.join(data_dir, 'test')):
        copyfile(os.path.join(data_dir, 'test', test_file),
                 os.path.join(data_dir, 'train_valid_test', 'test',
                              'unknown'))
#@save
def reorg_test(data_dir):
    """Tahmin sırasında veri yüklemesi için test kümesini düzenleyin."""
    for test_file in os.listdir(os.path.join(data_dir, 'test')):
        copyfile(os.path.join(data_dir, 'test', test_file),
                 os.path.join(data_dir, 'train_valid_test', 'test',
                              'unknown'))

Son olarak, read_csv_labels, reorg_train_valid ve reorg_test yukarıda tanımlanan işlevleri çağırmak için bir işlev kullanıyoruz.

def reorg_cifar10_data(data_dir, valid_ratio):
    labels = read_csv_labels(os.path.join(data_dir, 'trainLabels.csv'))
    reorg_train_valid(data_dir, labels, valid_ratio)
    reorg_test(data_dir)
def reorg_cifar10_data(data_dir, valid_ratio):
    labels = read_csv_labels(os.path.join(data_dir, 'trainLabels.csv'))
    reorg_train_valid(data_dir, labels, valid_ratio)
    reorg_test(data_dir)

Burada, veri kümesinin küçük ölçekli örneği için toplu iş boyutunu yalnızca 32 olarak ayarlıyoruz. Kaggle yarışmasının tüm veri kümesini eğitip test ederken, batch_size 128 gibi daha büyük bir tamsayıya ayarlanmalıdır. Eğitim örneklerinin %10’unu hiper parametrelerin ayarlanması için geçerleme kümesi olarak ayırdık.

batch_size = 32 if demo else 128
valid_ratio = 0.1
reorg_cifar10_data(data_dir, valid_ratio)
batch_size = 32 if demo else 128
valid_ratio = 0.1
reorg_cifar10_data(data_dir, valid_ratio)

13.13.2. İmge Artırma

Aşırı öğrenmeyi bertaraf etmek için imge artırımı kullanıyoruz. Örneğin, imgeler eğitim sırasında rastgele yatay olarak çevrilebilir. Renkli imgelerin üç RGB kanalı için standartlaştırma da gerçekleştirebiliriz. Aşağıda ayarlayabileceğiniz bu işlemlerin bazıları listelenmektedir.

transform_train = gluon.data.vision.transforms.Compose([
    # İmgeyi hem yükseklik hem de genişlikte 40 piksellik bir kareye ölçeklendirin
    gluon.data.vision.transforms.Resize(40),
    # Orijinal imgenin alanının 0.64 ila 1 katı arasında küçük bir kare
    # oluşturmak için hem yükseklik hem de genişlikte 40 piksellik bir kare
    # imgeyi rastgele kırpın ve ardından hem yükseklik hem de genişlikte
    # 32 piksellik bir kareye ölçeklendirin
    gluon.data.vision.transforms.RandomResizedCrop(32, scale=(0.64, 1.0),
                                                   ratio=(1.0, 1.0)),
    gluon.data.vision.transforms.RandomFlipLeftRight(),
    gluon.data.vision.transforms.ToTensor(),
    # İmgenin her kanalını standartlaştırın
    gluon.data.vision.transforms.Normalize([0.4914, 0.4822, 0.4465],
                                           [0.2023, 0.1994, 0.2010])])
transform_train = torchvision.transforms.Compose([
    # İmgeyi hem yükseklik hem de genişlikte 40 piksellik bir kareye ölçeklendirin
    torchvision.transforms.Resize(40),
    # Orijinal imgenin alanının 0.64 ila 1 katı arasında küçük bir kare
    # oluşturmak için hem yükseklik hem de genişlikte 40 piksellik bir kare
    # imgeyi rastgele kırpın ve ardından hem yükseklik hem de genişlikte
    # 32 piksellik bir kareye ölçeklendirin
    torchvision.transforms.RandomResizedCrop(32, scale=(0.64, 1.0),
                                                   ratio=(1.0, 1.0)),
    torchvision.transforms.RandomHorizontalFlip(),
    torchvision.transforms.ToTensor(),
    # İmgenin her kanalını standartlaştırın
    torchvision.transforms.Normalize([0.4914, 0.4822, 0.4465],
                                     [0.2023, 0.1994, 0.2010])])

Test sırasında, değerlendirme sonuçlarındaki rastgeleliği ortadan kaldırmak için yalnızca imgeler üzerinde standartlaştırma gerçekleştiriyoruz.

transform_test = gluon.data.vision.transforms.Compose([
    gluon.data.vision.transforms.ToTensor(),
    gluon.data.vision.transforms.Normalize([0.4914, 0.4822, 0.4465],
                                           [0.2023, 0.1994, 0.2010])])
transform_test = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize([0.4914, 0.4822, 0.4465],
                                     [0.2023, 0.1994, 0.2010])])

13.13.3. Veri Kümesini Okuma

Ardından, ham imge dosyalarından oluşan düzenlenmiş veri kümesini okuruz. Her örnek bir imge ve bir etiket içerir.

train_ds, valid_ds, train_valid_ds, test_ds = [
    gluon.data.vision.ImageFolderDataset(
        os.path.join(data_dir, 'train_valid_test', folder))
    for folder in ['train', 'valid', 'train_valid', 'test']]
train_ds, train_valid_ds = [torchvision.datasets.ImageFolder(
    os.path.join(data_dir, 'train_valid_test', folder),
    transform=transform_train) for folder in ['train', 'train_valid']]

valid_ds, test_ds = [torchvision.datasets.ImageFolder(
    os.path.join(data_dir, 'train_valid_test', folder),
    transform=transform_test) for folder in ['valid', 'test']]

Eğitim sırasında yukarıda tanımlanan tüm imge artırım işlemlerini belirtmemiz gerekir. Geçerleme kümesi hiper parametre ayarlama sırasında model değerlendirmesi için kullanıldığında, imge artırımdan rastgelelik getirilmemelidir. Son tahminden önce, tüm etiketlenmiş verileri tam olarak kullanmak için modeli birleştirilmiş eğitim kümesi ve geçerleme kümesi üzerinde eğitiriz.

train_iter, train_valid_iter = [gluon.data.DataLoader(
    dataset.transform_first(transform_train), batch_size, shuffle=True,
    last_batch='discard') for dataset in (train_ds, train_valid_ds)]

valid_iter = gluon.data.DataLoader(
    valid_ds.transform_first(transform_test), batch_size, shuffle=False,
    last_batch='discard')

test_iter = gluon.data.DataLoader(
    test_ds.transform_first(transform_test), batch_size, shuffle=False,
    last_batch='keep')
train_iter, train_valid_iter = [torch.utils.data.DataLoader(
    dataset, batch_size, shuffle=True, drop_last=True)
    for dataset in (train_ds, train_valid_ds)]

valid_iter = torch.utils.data.DataLoader(valid_ds, batch_size, shuffle=False,
                                         drop_last=True)

test_iter = torch.utils.data.DataLoader(test_ds, batch_size, shuffle=False,
                                        drop_last=False)

13.13.4. Modeli Tanımlama

Burada, Section 7.6 içinde açıklanan uygulamadan biraz farklı olan HybridBlock sınıfına dayanan artık blokları inşa ediyoruz. Bu, hesaplama verimliliğini artırmak içindir.

class Residual(nn.HybridBlock):
    def __init__(self, num_channels, use_1x1conv=False, strides=1, **kwargs):
        super(Residual, self).__init__(**kwargs)
        self.conv1 = nn.Conv2D(num_channels, kernel_size=3, padding=1,
                               strides=strides)
        self.conv2 = nn.Conv2D(num_channels, kernel_size=3, padding=1)
        if use_1x1conv:
            self.conv3 = nn.Conv2D(num_channels, kernel_size=1,
                                   strides=strides)
        else:
            self.conv3 = None
        self.bn1 = nn.BatchNorm()
        self.bn2 = nn.BatchNorm()

    def hybrid_forward(self, F, X):
        Y = F.npx.relu(self.bn1(self.conv1(X)))
        Y = self.bn2(self.conv2(Y))
        if self.conv3:
            X = self.conv3(X)
        return F.npx.relu(Y + X)

Ardından, ResNet-18 modelini tanımlıyoruz.

def resnet18(num_classes):
    net = nn.HybridSequential()
    net.add(nn.Conv2D(64, kernel_size=3, strides=1, padding=1),
            nn.BatchNorm(), nn.Activation('relu'))

    def resnet_block(num_channels, num_residuals, first_block=False):
        blk = nn.HybridSequential()
        for i in range(num_residuals):
            if i == 0 and not first_block:
                blk.add(Residual(num_channels, use_1x1conv=True, strides=2))
            else:
                blk.add(Residual(num_channels))
        return blk

    net.add(resnet_block(64, 2, first_block=True),
            resnet_block(128, 2),
            resnet_block(256, 2),
            resnet_block(512, 2))
    net.add(nn.GlobalAvgPool2D(), nn.Dense(num_classes))
    return net

Eğitim başlamadan önce Section 4.8.2.2 içinde açıklanan Xavier ilkletme işlemini kullanıyoruz.

def get_net(devices):
    num_classes = 10
    net = resnet18(num_classes)
    net.initialize(ctx=devices, init=init.Xavier())
    return net

loss = gluon.loss.SoftmaxCrossEntropyLoss()

Section 7.6’te açıklanan ResNet-18 modelini tanımlıyoruz.

def get_net():
    num_classes = 10
    net = d2l.resnet18(num_classes, 3)
    return net

loss = nn.CrossEntropyLoss(reduction="none")

13.13.5. Eğitim Fonksiyonunu Tanımlama

Modelleri seçeceğiz ve hiper parametreleri geçerleme kümesindeki modelin performansına göre ayarlayacağız. Aşağıda, model eğitim fonksiyonunu, train, tanımlıyoruz.

def train(net, train_iter, valid_iter, num_epochs, lr, wd, devices, lr_period,
          lr_decay):
    trainer = gluon.Trainer(net.collect_params(), 'sgd',
                            {'learning_rate': lr, 'momentum': 0.9, 'wd': wd})
    num_batches, timer = len(train_iter), d2l.Timer()
    legend = ['train loss', 'train acc']
    if valid_iter is not None:
        legend.append('valid acc')
    animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],
                            legend=legend)
    for epoch in range(num_epochs):
        metric = d2l.Accumulator(3)
        if epoch > 0 and epoch % lr_period == 0:
            trainer.set_learning_rate(trainer.learning_rate * lr_decay)
        for i, (features, labels) in enumerate(train_iter):
            timer.start()
            l, acc = d2l.train_batch_ch13(
                net, features, labels.astype('float32'), loss, trainer,
                devices, d2l.split_batch)
            metric.add(l, acc, labels.shape[0])
            timer.stop()
            if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:
                animator.add(epoch + (i + 1) / num_batches,
                             (metric[0] / metric[2], metric[1] / metric[2],
                              None))
        if valid_iter is not None:
            valid_acc = d2l.evaluate_accuracy_gpus(net, valid_iter,
                                                   d2l.split_batch)
            animator.add(epoch + 1, (None, None, valid_acc))
    measures = (f'train loss {metric[0] / metric[2]:.3f}, '
                f'train acc {metric[1] / metric[2]:.3f}')
    if valid_iter is not None:
        measures += f', valid acc {valid_acc:.3f}'
    print(measures + f'\n{metric[2] * num_epochs / timer.sum():.1f}'
          f' examples/sec on {str(devices)}')
def train(net, train_iter, valid_iter, num_epochs, lr, wd, devices, lr_period,
          lr_decay):
    trainer = torch.optim.SGD(net.parameters(), lr=lr, momentum=0.9,
                              weight_decay=wd)
    scheduler = torch.optim.lr_scheduler.StepLR(trainer, lr_period, lr_decay)
    num_batches, timer = len(train_iter), d2l.Timer()
    legend = ['train loss', 'train acc']
    if valid_iter is not None:
        legend.append('valid acc')
    animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],
                            legend=legend)
    net = nn.DataParallel(net, device_ids=devices).to(devices[0])
    for epoch in range(num_epochs):
        net.train()
        metric = d2l.Accumulator(3)
        for i, (features, labels) in enumerate(train_iter):
            timer.start()
            l, acc = d2l.train_batch_ch13(net, features, labels,
                                          loss, trainer, devices)
            metric.add(l, acc, labels.shape[0])
            timer.stop()
            if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:
                animator.add(epoch + (i + 1) / num_batches,
                             (metric[0] / metric[2], metric[1] / metric[2],
                              None))
        if valid_iter is not None:
            valid_acc = d2l.evaluate_accuracy_gpu(net, valid_iter)
            animator.add(epoch + 1, (None, None, valid_acc))
        scheduler.step()
    measures = (f'train loss {metric[0] / metric[2]:.3f}, '
                f'train acc {metric[1] / metric[2]:.3f}')
    if valid_iter is not None:
        measures += f', valid acc {valid_acc:.3f}'
    print(measures + f'\n{metric[2] * num_epochs / timer.sum():.1f}'
          f' examples/sec on {str(devices)}')

13.13.6. Modeli Eğitme ve Geçerleme

Şimdi, modeli eğitebilir ve geçerleyebiliriz. Aşağıdaki tüm hiper parametreler ayarlanabilir. Örneğin, dönem sayısını artırabiliriz. lr_period ve lr_decay sırasıyla 4 ve 0.9 olarak ayarlandığında, optimizasyon algoritmasının öğrenme oranı her 4 dönem sonrasında 0.9 ile çarpılır. Sadece gösterim kolaylığı için, burada sadece 20 dönemlik eğitim yapıyoruz.

devices, num_epochs, lr, wd = d2l.try_all_gpus(), 20, 0.02, 5e-4
lr_period, lr_decay, net = 4, 0.9, get_net(devices)
net.hybridize()
train(net, train_iter, valid_iter, num_epochs, lr, wd, devices, lr_period,
      lr_decay)
train loss 0.796, train acc 0.715, valid acc 0.406
239.5 examples/sec on [gpu(0), gpu(1)]
../_images/output_kaggle-cifar10_42a34e_126_1.svg
devices, num_epochs, lr, wd = d2l.try_all_gpus(), 20, 2e-4, 5e-4
lr_period, lr_decay, net = 4, 0.9, get_net()
train(net, train_iter, valid_iter, num_epochs, lr, wd, devices, lr_period,
      lr_decay)
train loss 0.832, train acc 0.704, valid acc 0.484
1049.5 examples/sec on [device(type='cuda', index=0), device(type='cuda', index=1)]
../_images/output_kaggle-cifar10_42a34e_129_1.svg

13.13.7. Test Kümesini Sınıflandırma ve Kaggle’da Sonuçları Teslim Etme

Hiper parametrelerle umut verici bir model elde ettikten sonra, modeli yeniden eğitmek ve test kümesini sınıflandırmak için tüm etiketli verileri (geçerleme kümesi dahil) kullanırız.

net, preds = get_net(devices), []
net.hybridize()
train(net, train_valid_iter, None, num_epochs, lr, wd, devices, lr_period,
      lr_decay)

for X, _ in test_iter:
    y_hat = net(X.as_in_ctx(devices[0]))
    preds.extend(y_hat.argmax(axis=1).astype(int).asnumpy())
sorted_ids = list(range(1, len(test_ds) + 1))
sorted_ids.sort(key=lambda x: str(x))
df = pd.DataFrame({'id': sorted_ids, 'label': preds})
df['label'] = df['label'].apply(lambda x: train_valid_ds.synsets[x])
df.to_csv('submission.csv', index=False)
train loss 0.708, train acc 0.751
530.0 examples/sec on [gpu(0), gpu(1)]
../_images/output_kaggle-cifar10_42a34e_135_1.svg
net, preds = get_net(), []
train(net, train_valid_iter, None, num_epochs, lr, wd, devices, lr_period,
      lr_decay)

for X, _ in test_iter:
    y_hat = net(X.to(devices[0]))
    preds.extend(y_hat.argmax(dim=1).type(torch.int32).cpu().numpy())
sorted_ids = list(range(1, len(test_ds) + 1))
sorted_ids.sort(key=lambda x: str(x))
df = pd.DataFrame({'id': sorted_ids, 'label': preds})
df['label'] = df['label'].apply(lambda x: train_valid_ds.classes[x])
df.to_csv('submission.csv', index=False)
train loss 0.717, train acc 0.759
1209.9 examples/sec on [device(type='cuda', index=0), device(type='cuda', index=1)]
../_images/output_kaggle-cifar10_42a34e_138_1.svg

Yukarıdaki kod, biçimi Kaggle yarışmasının gereksinimini karşılayan bir submission.csv dosyası oluşturacaktır. Sonuçları Kaggle’a gönderme yöntemi, Section 4.10 içindeki yönteme benzerdir.

13.13.8. Özet

  • Gerekli formata düzenledikten sonra ham imge dosyalarını içeren veri kümelerini okuyabiliriz.

  • Bir imge sınıflandırma yarışmasında, evrişimli sinir ağlarını, imge artırmayı ve hibrit programlamayı kullanabiliriz.

  • Bir imge sınıflandırma yarışmasında evrişimli sinir ağları ve imge artırmayı kullanabiliriz.

13.13.9. Alıştırmalar

  1. Bu Kaggle yarışması için CIFAR-10 veri kümesinin tamamını kullanın. Hiper parametreleri batch_size = 128, num_epochs = 100, lr = 0.1, lr_period = 50 ve lr_decay = 0.1 olarak ayarlayın. Bu yarışmada hangi doğruluk ve sıralamayı elde edebileceğinizi görün. Onları daha da geliştirebilir misin?

  2. İmge artırmayı kullanmadığınızda hangi doğruluğu elde edebilirsiniz?