3.5. İmge Sınıflandırma 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

İmge sınıflandırması için yaygın olarak kullanılan veri kümelerinden biri MNIST veri kümesidir (LeCun et al., 1998). Bir kıyaslama veri kümesi olarak iyi bir çalışma gerçekleştirmiş olsa da, günümüz standartlarına göre basit modeller bile %95’in üzerinde sınıflandırma doğruluğu elde ettiğinden daha güçlü modeller ile daha zayıf olanları ayırt etmek için uygun değildir. Bugün, MNIST bir kıyaslama ölçütü olmaktan çok makullük (sanity) kontrolü işlevi görüyor. Biraz daha ileriye gitmek için, önümüzdeki bölümlerdeki tartışmamızı niteliksel olarak benzer, ancak nispeten karmaşık olan 2017’de piyasaya sürülen Fashion-MNIST veri kümesine odaklayacağız (Xiao et al., 2017).

%matplotlib inline
import sys
from d2l import mxnet as d2l
from mxnet import gluon

d2l.use_svg_display()
%matplotlib inline
import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l

d2l.use_svg_display()
%matplotlib inline
import tensorflow as tf
from d2l import tensorflow as d2l

d2l.use_svg_display()

3.5.1. Veri Kümesini Okuma

Fashion-MNIST veri kümesini çerçevemizdeki yerleşik işlevler aracılığıyla indirebilir ve belleğe okuyabiliriz.

mnist_train = gluon.data.vision.FashionMNIST(train=True)
mnist_test = gluon.data.vision.FashionMNIST(train=False)
# 'ToTensor', imge verilerini PIL türünden 32 bit kayan virgüllü sayı tensörlerine
# dönüştürür. Tüm sayıları 255'e böler, böylece tüm piksel değerleri 0 ile 1 arasında olur.
trans = transforms.ToTensor()
mnist_train = torchvision.datasets.FashionMNIST(
    root="../data", train=True, transform=trans, download=True)
mnist_test = torchvision.datasets.FashionMNIST(
    root="../data", train=False, transform=trans, download=True)
mnist_train, mnist_test = tf.keras.datasets.fashion_mnist.load_data()

Fashion-MNIST, her biri eğitim veri kümesinde 6000 görsel ve test veri kümesinde 1000 görsel ile temsil edilen 10 kategorideki görsellerden oluşur. Eğitim için değil, model performansını değerlendirmek için bir test veri kümesi (veya test kümesi) kullanılır.

len(mnist_train), len(mnist_test)
(60000, 10000)
len(mnist_train), len(mnist_test)
(60000, 10000)
len(mnist_train[0]), len(mnist_test[0])
(60000, 10000)

Her girdi imgesinin yüksekliği ve genişliği 28 pikseldir. Veri kümesinin, kanal sayısı 1 olan gri tonlamalı görsellerden oluştuğuna dikkat edin. Kısaca, bu kitapta yüksekliği \(h\) genişliği \(w\) piksel olan herhangi bir imgenin şekli \(h \times w\) veya (\(h\), \(w\))’dir.

mnist_train[0][0].shape
(28, 28, 1)
mnist_train[0][0].shape
torch.Size([1, 28, 28])
mnist_train[0][0].shape
(28, 28)

Fashion-MNIST’teki görseller şu kategorilerle ilişkilidir: Tişört, pantolon, kazak, elbise, ceket, sandalet, gömlek, spor ayakkabı, çanta ve ayak bileği hizası bot. Aşağıdaki işlev, sayısal etiket indeksleri ve metindeki adları arasında dönüştürme yapar.

def get_fashion_mnist_labels(labels):  #@save
    """Fashion-MNIST veri kümesi için metin etiketleri döndürün."""
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]

Şimdi bu örnekleri görselleştirmek için bir işlev oluşturabiliriz.

def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save
    """Görsellerin bir listesini çizin"""
    figsize = (num_cols * scale, num_rows * scale)
    _, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
    axes = axes.flatten()
    for i, (ax, img) in enumerate(zip(axes, imgs)):
        ax.imshow(img.asnumpy())
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
        if titles:
            ax.set_title(titles[i])
    return axes
def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save
    """Görsellerin bir listesini çizin"""
    figsize = (num_cols * scale, num_rows * scale)
    _, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
    axes = axes.flatten()
    for i, (ax, img) in enumerate(zip(axes, imgs)):
        if torch.is_tensor(img):
            # Tensor Image
            ax.imshow(img.numpy())
        else:
            # PIL Image
            ax.imshow(img)
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
        if titles:
            ax.set_title(titles[i])
    return axes
def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):  #@save
    """Görsellerin bir listesini çizin"""
    figsize = (num_cols * scale, num_rows * scale)
    _, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
    axes = axes.flatten()
    for i, (ax, img) in enumerate(zip(axes, imgs)):
        ax.imshow(img.numpy())
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
        if titles:
            ax.set_title(titles[i])
    return axes

Eğitim veri kümesindeki ilk birkaç örnek için görseller ve bunlara karşılık gelen etiketler (metin olarak) aşağıdadır.

X, y = mnist_train[:18]

print(X.shape)
show_images(X.squeeze(axis=-1), 2, 9, titles=get_fashion_mnist_labels(y));
(18, 28, 28, 1)
../_images/output_image-classification-dataset_e45669_65_1.svg
X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))
show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y));
../_images/output_image-classification-dataset_e45669_68_0.svg
X = tf.constant(mnist_train[0][:18])
y = tf.constant(mnist_train[1][:18])
show_images(X, 2, 9, titles=get_fashion_mnist_labels(y));
../_images/output_image-classification-dataset_e45669_71_0.svg

3.5.2. Minigrup Okuma

Eğitim ve test kümelerinden okurken hayatımızı kolaylaştırmak için sıfırdan bir tane oluşturmak yerine yerleşik veri yineleyiciyi kullanıyoruz. Her yinelemede, bir yineleyicinin her seferinde grup (batch_size) boyutundaki bir veri minigrubunu okuduğunu hatırlayın. Ayrıca eğitim verisi yineleyicisi için örnekleri rastgele karıştırıyoruz.

batch_size = 256

def get_dataloader_workers():  #@save
    """Windows dışında, verileri okumak için 4 işlem kullanın."""
    return 0 if sys.platform.startswith('win') else 4

# 'ToTensor', görsel verilerini uint8'den 32-bit kayan virgüllü sayıya dönüştürür.
# Tüm sayıları 255'e böler, böylece tüm piksel değerleri 0 ile 1 arasında olur.
transformer = gluon.data.vision.transforms.ToTensor()
train_iter = gluon.data.DataLoader(mnist_train.transform_first(transformer),
                                   batch_size, shuffle=True,
                                   num_workers=get_dataloader_workers())
batch_size = 256

def get_dataloader_workers():  #@save
    """Verileri okumak için 4 işlem kullanın."""
    return 4

train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,
                             num_workers=get_dataloader_workers())
batch_size = 256
train_iter = tf.data.Dataset.from_tensor_slices(
    mnist_train).batch(batch_size).shuffle(len(mnist_train[0]))

Eğitim verilerini okurken geçen süreye bakalım.

timer = d2l.Timer()
for X, y in train_iter:
    continue
f'{timer.stop():.2f} sec'
'1.90 sec'
timer = d2l.Timer()
for X, y in train_iter:
    continue
f'{timer.stop():.2f} sec'
'2.25 sec'
timer = d2l.Timer()
for X, y in train_iter:
    continue
f'{timer.stop():.2f} sec'
'0.29 sec'

3.5.3. Her Şeyi Bir Araya Getirme

Şimdi Fashion-MNIST veri kümesini alan ve okuyan load_data_fashion_mnist fonksiyonunu tanımlıyoruz. Hem eğitim kümesi hem de geçerleme kümesi için veri yineleyicileri döndürür. Ek olarak, imgeleri başka bir şekle yeniden boyutlandırmak için isteğe bağlı bir argüman kabul eder.

def load_data_fashion_mnist(batch_size, resize=None):  #@save
    """Fashion-MNIST veri kümesini indirin ve ardından belleğe yükleyin."""
    dataset = gluon.data.vision
    trans = [dataset.transforms.ToTensor()]
    if resize:
        trans.insert(0, dataset.transforms.Resize(resize))
    trans = dataset.transforms.Compose(trans)
    mnist_train = dataset.FashionMNIST(train=True).transform_first(trans)
    mnist_test = dataset.FashionMNIST(train=False).transform_first(trans)
    return (gluon.data.DataLoader(mnist_train, batch_size, shuffle=True,
                                  num_workers=get_dataloader_workers()),
            gluon.data.DataLoader(mnist_test, batch_size, shuffle=False,
                                  num_workers=get_dataloader_workers()))
def load_data_fashion_mnist(batch_size, resize=None):  #@save
    """Fashion-MNIST veri kümesini indirin ve ardından belleğe yükleyin."""
    trans = [transforms.ToTensor()]
    if resize:
        trans.insert(0, transforms.Resize(resize))
    trans = transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(
        root="../data", train=True, transform=trans, download=True)
    mnist_test = torchvision.datasets.FashionMNIST(
        root="../data", train=False, transform=trans, download=True)
    return (data.DataLoader(mnist_train, batch_size, shuffle=True,
                            num_workers=get_dataloader_workers()),
            data.DataLoader(mnist_test, batch_size, shuffle=False,
                            num_workers=get_dataloader_workers()))
def load_data_fashion_mnist(batch_size, resize=None):   #@save
    """Fashion-MNIST veri kümesini indirin ve ardından belleğe yükleyin."""
    mnist_train, mnist_test = tf.keras.datasets.fashion_mnist.load_data()
    # Tüm piksel değerleri 0 ile 1 arasında olacak şekilde tüm sayıları 255'e bölün,
    # en sonunda bir grup boyutu ekleyin. Ayrıca etiketi int32'ye çevirin.
    process = lambda X, y: (tf.expand_dims(X, axis=3) / 255,
                            tf.cast(y, dtype='int32'))
    resize_fn = lambda X, y: (
        tf.image.resize_with_pad(X, resize, resize) if resize else X, y)
    return (
        tf.data.Dataset.from_tensor_slices(process(*mnist_train)).batch(
            batch_size).shuffle(len(mnist_train[0])).map(resize_fn),
        tf.data.Dataset.from_tensor_slices(process(*mnist_test)).batch(
            batch_size).map(resize_fn))

Aşağıda, resize bağımsız değişkenini belirterek load_data_fashion_mnist işlevinin görseli yeniden boyutlandırma özelliğini test ediyoruz.

train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:
    print(X.shape, X.dtype, y.shape, y.dtype)
    break
(32, 1, 64, 64) <class 'numpy.float32'> (32,) <class 'numpy.int32'>
train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:
    print(X.shape, X.dtype, y.shape, y.dtype)
    break
torch.Size([32, 1, 64, 64]) torch.float32 torch.Size([32]) torch.int64
train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:
    print(X.shape, X.dtype, y.shape, y.dtype)
    break
(32, 64, 64, 1) <dtype: 'float32'> (32,) <dtype: 'int32'>

Artık ilerleyen bölümlerde Fashion-MNIST veri kümesiyle çalışmaya hazırız.

3.5.4. Özet

  • Fashion-MNIST, 10 kategoriyi temsil eden resimlerden oluşan bir giyim sınıflandırma veri kümesidir. Bu veri kümesini, çeşitli sınıflandırma algoritmalarını değerlendirmek için sonraki bölümlerde kullanacağız.

  • Yüksekliği \(h\) genişliği \(w\) piksel olan herhangi bir imgenin şeklini \(h \times w\) veya (\(h\), \(w\)) olarak saklarız.

  • Veri yineleyiciler, verimli performans için önemli bir bileşendir. Eğitim döngünüzü yavaşlatmaktan kaçınmak için yüksek performanslı hesaplamalardan yararlanan iyi uygulanmış veri yineleyicilerine güvenin.

3.5.5. Alıştırmalar

  1. batch_size değerini (örneğin 1’e) düşürmek okuma performansını etkiler mi?

  2. Veri yineleyici performansı önemlidir. Mevcut uygulamanın yeterince hızlı olduğunu düşünüyor musunuz? İyileştirmek için çeşitli seçenekleri keşfediniz.

  3. Çerçevenin çevrimiçi API belgelerine bakın. Başka hangi veri kümeleri mevcuttur?