Anda di halaman 1dari 13

Subscribe to DeepL Pro to edit this document.

Visit www.DeepL.com/pro for more information.

Menskalakan dataset untuk


meningkatkan akurasi model
Penskalaan dataset adalah proses memastikan bahwa variabel-variabelnya terbatas
pada rentang yang terbatas. Pada bagian ini, kita akan membatasi nilai variabel
independen pada nilai antara 0 dan 1 dengan membagi setiap nilai input dengan
nilai maksimum yang mungkin ada di dataset. Nilai maksimumnya adalah 255,
yang sesuai dengan piksel putih:
Kode berikut ini tersedia
sebagai Scaling_the_dataset.ipynb dalam folder Bab03 ini
repositori GitHub buku ini - https://tinyurl.com/mcvp-packt

1. Ambil dataset, serta gambar pelatihan dan target, seperti yang telah kita
lakukan di bagian sebelumnya:
dari set data impor torchvision
from torch.utils.data import Dataset, DataLoader
import torch
import torch.nn as nn
device = "cuda" if torch.cuda.is_available() else "cpu"
import numpy as np
data_folder = '~/data/FMNIST' # Ini bisa berupa direktori apa
saja
# ingin mengunduh FMNIST ke
fmnist = datasets.FashionMNIST(data_folder, download = True, \
kereta = Benar)
tr_images = fmnist.data
tr_target = fmnist.targets
2. Modifikasi FMNISTDataset, yang mengambil data, sehingga gambar
input dibagi dengan 255 (intensitas/nilai maksimum piksel):
class FMNISTDataset(Dataset):
def init (self, x, y):
x = x.float()/255
x = x.view(-1,28*28)
self.x, self.y = x, y
def getitem (self, ix):
x, y = self.x[ix], self.y[ix]
return x.to(device), y.to(device)
def len (diri sendiri):
return len(self.x)

Perhatikan bahwa satu-satunya perubahan yang kami buat di sini


dibandingkan dengan bagian sebelumnya adalah, kami membagi data
input dengan nilai piksel maksimum yang mungkin - 255.

Karena nilai piksel berkisar antara 0 hingga 255, maka membaginya


dengan 255 akan menghasilkan nilai yang selalu berada di antara 0
hingga 1.
3. Latih model, seperti yang kita lakukan pada langkah 4, 5, 6, dan 7 pada bagian
sebelumnya:

Mengambil data:
def get_data():
train = FMNISTDataset(tr_gambar, tr_target)
trn_dl = DataLoader(train, batch_size = 32, shuffle = True)
return trn_dl

Tentukan model:
dari torch.optim impor SGD
def get_model():
model = nn.Sequential(
nn.Linear(28 * 28, 1000),
nn.ReLU(),
nn.Linear(1000, 10)
).ke (perangkat)
loss_fn = nn.CrossEntropyLoss()
optimizer = SGD(model.parameters(), lr=1e-2)
model pengembalian, loss_fn, pengoptimal
Tentukan fungsi untuk melatih dan memvalidasi sekumpulan data:
def train_batch(x, y, model, opt, loss_fn):
model.train()
# panggil model Anda seperti fungsi python apa pun pada
batch Anda
# Jumlah masukan
prediksi = model(x)
# menghitung kerugian
batch_loss = loss_fn(prediksi, y)
# berdasarkan operan ke depan dalam `model(x)` menghitung
semua
# gradien dari 'model.parameters()'
batch_loss.backward()
# terapkan bobot-baru = f(bobot-lama, gradien-bobot-lama)
# di mana "f" adalah pengoptimal
pengoptimalisasi.step()
# Mengisi memori untuk perhitungan berikutnya
optimizer.zero_grad()
return batch_loss.item()
@torch.no_grad()
def akurasi(x, y, model):
model.eval()
# dapatkan matriks prediksi untuk tensor gambar `x`
prediksi = model(x)
# menghitung jika lokasi maksimum di setiap baris
# bertepatan dengan kebenaran dasar
nilai_maks, argmaks = prediksi.maks(-1)
is_correct = argmaxes == y
return is_correct.cpu().numpy().tolist()

Latih model selama periode waktu yang


meningkat:
trn_dl = get_data()
model, loss_fn, pengoptimal = get_model()
kerugian, akurasi = [], []
untuk epoch dalam range(5):
cetak (zaman)
epoch_losses, epoch_accuracies = [], []
for ix, batch in enumerate(iter(trn_dl)):
x, y = batch
batch_loss = train_batch(x, y, model,
pengoptimal,
loss_fn)
epoch_losses.append(batch_loss)
epoch_loss = np.array(epoch_losses).mean()
for ix, batch in enumerate(iter(trn_dl)):
x, y = batch
is_correct = akurasi(x, y, model)
epoch_accuracies.extend(is_correct)
epoch_accuracy = np.mean(epoch_accuracies)
losses.append(epoch_loss)
accurations.append(epoch_accuracy)

Variasi untuk nilai training loss dan akurasi adalah sebagai berikut:

Seperti yang dapat kita lihat, kerugian pelatihan secara konsisten berkurang
dan akurasi pelatihan secara konsisten meningkat, sehingga meningkatkan
epoch ke akurasi ~85%.
Bandingkan output sebelumnya dengan skenario di mana data input tidak
diskalakan, di mana training loss tidak berkurang secara konsisten, dan akurasi
dataset pelatihan di
akhir dari lima zaman hanya 12%.

Mari kita selami alasan mengapa penskalaan dapat

membantu di sini. Mari kita ambil contoh bagaimana nilai

sigmoid dihitung:

Pada tabel berikut ini, kami telah menghitung kolom Sigmoid berdasarkan rumus
sebelumnya:
Pada tabel sebelah kiri, kita dapat melihat bahwa ketika nilai bobot lebih dari 0,1,
nilai Sigmoid tidak bervariasi dengan peningkatan (perubahan) nilai bobot. Selain
itu, nilai Sigmoid hanya berubah sedikit ketika bobotnya sangat kecil; satu-satunya
cara untuk memvariasikan nilai Sigmoid adalah dengan membuat bobotnya
berubah menjadi sangat, sangat kecil.
Namun, nilai Sigmoid berubah secara signifikan pada tabel sebelah kanan ketika
nilai inputnya kecil.
Alasannya adalah karena eksponensial dari nilai negatif yang besar (yang
dihasilkan dari mengalikan nilai bobot dengan angka yang besar) sangat
mendekati 0, sedangkan nilai eksponensial bervariasi ketika bobot dikalikan
dengan input berskala, seperti yang terlihat pada tabel sebelah kanan.
Sekarang kita telah memahami bahwa nilai Sigmoid tidak banyak berubah kecuali
nilai bobotnya sangat kecil, sekarang kita akan belajar tentang bagaimana nilai bobot
dapat dipengaruhi ke arah nilai yang optimal.
Penskalaan dataset input sehingga berisi rentang nilai yang jauh
lebih kecil umumnya membantu dalam mencapai akurasi model
yang lebih baik.

Selanjutnya, kita akan belajar tentang dampak dari salah satu hiperparameter
utama lainnya dari jaringan saraf: ukuran batch.
Memahami dampak dari memvariasikan
ukuran batch
Pada bagian sebelumnya, 32 titik data dipertimbangkan per batch dalam kumpulan
data pelatihan. Hal ini menghasilkan jumlah pembaruan bobot yang lebih banyak
per epoch karena ada
1.875 pembaruan bobot per epoch (60.000/32 hampir sama dengan 1.875, di mana
60.000 adalah jumlah gambar pelatihan).
Selain itu, kami tidak mempertimbangkan kinerja model pada dataset yang tidak
terlihat
(kumpulan data validasi). Kami akan membahas hal ini di bagian ini.

Pada bagian ini, kami akan membandingkan yang berikut ini:


Nilai kerugian dan akurasi data pelatihan dan validasi ketika ukuran
batch pelatihan adalah 32.
Nilai kerugian dan akurasi dari data pelatihan dan validasi ketika ukuran
batch pelatihan adalah 10.000.

Sekarang setelah kita membawa data validasi ke dalam gambar, mari kita jalankan
kembali kode yang disediakan di bagian Membangun jaringan syaraf dengan kode
tambahan untuk menghasilkan data validasi, serta untuk menghitung nilai
kerugian dan akurasi dari kumpulan data validasi.
Kode untuk ukuran Batch 32 dan ukuran Batch 10.000 bagian tersedia
sebagai Varying_batch_size.ipynb di folder Chapter03 pada
repositori GitHub buku ini - https://tinyurl.com/mcvp-
packt

Ukuran batch 32
Mengingat bahwa kita telah membangun model yang menggunakan ukuran batch
32 selama pelatihan, kami akan menguraikan kode tambahan yang digunakan untuk
mengerjakan validasi
dataset. Kita akan melewatkan rincian pelatihan model karena ini sudah ada di
bagian Membangun jaringan saraf. Mari kita mulai:
1. Unduh dan impor gambar pelatihan dan target:
dari torchvision mengimpor
dataset impor obor
data_folder = '~/data/FMNIST' # Ini bisa berupa direktori apa
saja
# ingin mengunduh FMNIST ke
fmnist = datasets.FashionMNIST(data_folder, download = True, \
kereta = Benar)
tr_images = fmnist.data
tr_target = fmnist.targets

2. Dengan cara yang mirip dengan gambar pelatihan, kita harus mengunduh
dan mengimpor dataset validasi dengan menetapkan train = False
saat memanggil metode FashionMNIST di dataset kita:
val_fmnist =datasets.FashionMNIST(data_folder,download=True, \
train = False)
val_gambar = val_fmnist.data
val_target = val_fmnist.target

3. Impor paket yang relevan dan tentukan perangkat:


import matplotlib.pyplot as plt
%matplotlib impor
sebaris numpy
sebagai np
from torch.utils.data import Dataset, DataLoader
import torch
import torch.nn as nn
device = 'cuda' if torch.cuda.is_available() else 'cpu'

4. Tentukan kelas dataset (FashionMNIST), fungsi-fungsi yang akan


digunakan untuk melatih sekumpulan data (train_batch), menghitung
akurasi (akurasi), dan kemudian mendefinisikan arsitektur model,
fungsi loss, dan pengoptimal (get_model). Perhatikan bahwa fungsi untuk
mendapatkan data akan menjadi satu-satunya fungsi yang akan memiliki
deviasi dari apa yang telah kita lihat pada bagian sebelumnya (karena kita
sekarang bekerja pada set data pelatihan dan validasi), jadi kita akan
membuatnya pada langkah berikutnya:
class FMNISTDataset(Dataset):
def init (self, x, y):
x = x.float()/255
x = x.view(-1,28*28)
self.x, self.y = x, y
def getitem (self, ix):
x, y = self.x[ix], self.y[ix]
return x.to(device), y.to(device)
def len (diri sendiri):
return len(self.x)

from torch.optim import SGD, Adam


def get_model():
model = nn.Sequential(
nn.Linear (28 * 28, 1000),
nn.ReLU(),
nn.Linear(1000, 10)
).ke
(perangkat)

loss_fn = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=1e-2)
model pengembalian, loss_fn, pengoptimal

def train_batch(x, y, model, opt, loss_fn):


model.train()
prediksi = model(x)
batch_loss = loss_fn(prediksi, y)
batch_loss.backward()
optimizer.step()
optimizer.zero_grad()
return batch_loss.item()

def akurasi(x, y, model):


model.eval()
# ini sama dengan @torch.no_grad
# di bagian atas fungsi, satu-satunya perbedaan
# being, grad tidak dihitung dalam lingkup with
dengan torch.no_grad():
prediksi = model(x)
nilai_maks, argmaks = prediksi.maks(-1)
is_correct = argmaxes == y
return is_correct.cpu().numpy().tolist()

5. Tentukan sebuah fungsi yang akan mengambil data, yaitu get_data.


Fungsi ini akan mengembalikan data pelatihan dengan ukuran batch 32
dan dataset validasi dengan ukuran batch yang merupakan panjang dari
data validasi (kita tidak akan menggunakan data validasi untuk melatih
model; kita hanya akan menggunakannya untuk memahami keakuratan
model pada data yang tidak terlihat):
def get_data():
train = FMNISTDataset(tr_gambar, tr_target)
trn_dl = DataLoader(train, batch_size = 32, shuffle = True)
val = FMNISTDataset(val_gambar, val_target)
val_dl = DataLoader(val, ukuran_batch =
len(val_images
), shuffle =
False)
return trn_dl, val_dl
Pada kode sebelumnya, kita telah membuat sebuah objek dari kelas
FMNISTDataset bernama val, sebagai tambahan dari objek train yang
telah kita lihat sebelumnya. Selanjutnya, DataLoader untuk validasi
(val_dl) telah diambil dengan
ukuran batch len(val_images), sedangkan ukuran batch trn_dl adalah
32. Hal ini karena data pelatihan digunakan untuk melatih model sementara
kita mengambil metrik akurasi dan loss dari data validasi. Pada bagian ini
dan selanjutnya, kami mencoba untuk memahami dampak dari variasi
ukuran batch_size berdasarkan waktu pelatihan dan akurasi model.

6. Tentukan fungsi yang menghitung hilangnya data validasi; bahwa


adalah, val_loss. Perhatikan bahwa kita menghitung ini secara terpisah
karena kehilangan
data pelatihan akan dihitung saat melatih model:
@torch.no_grad()
def val_loss(x, y, model):
model.eval()
prediksi = model(x)
val_rugi = loss_fn(prediksi, y)
return val_loss.item()

Seperti yang Anda lihat, kita menggunakan torch.no_grad karena


kita tidak melatih model dan hanya mengambil prediksi. Selanjutnya,
kita melewatkan prediksi kita melalui fungsi loss (loss_fn) dan
mengembalikan nilai loss (val_loss.item()).

7. Ambil DataLoader pelatihan dan validasi. Juga, inisialisasi model, fungsi


kerugian, dan pengoptimal:
trn_dl, val_dl = get_data()
model, loss_fn, pengoptimal = get_model()

8. Latih model, sebagai berikut:

Inisialisasi daftar yang berisi akurasi pelatihan dan validasi, serta nilai
kerugian dari epoch yang meningkat:

kereta_kerugian, kereta_akurasi = [], []


val_kerugian, val_akurasi = [], []

Ulangi lima zaman dan inisialisasi daftar yang berisi akurasi dan kerugian
di seluruh kumpulan data pelatihan dalam zaman tertentu:
untuk epoch dalam range(5):
cetak (zaman)
train_epoch_losses, train_epoch_accuracies = [], []
Ulangi melalui kumpulan data pelatihan dan hitung akurasi
(train_epoch_accuracy) dan nilai kerugian (train_epoch_loss)
dalam satu epoch:

for ix, batch in enumerate(iter(trn_dl)):


x, y = batch
batch_loss = train_batch(x, y, model, pengoptimal, \
loss_fn)
train_epoch_losses.append(batch_loss)
train_epoch_loss = np.array(train_epoch_losses).mean()

for ix, batch in enumerate(iter(trn_dl)):


x, y = batch
is_correct = akurasi(x, y, model)
train_epoch_accuracies.extend(is_correct)
train_epoch_accuracy = np.mean(train_epoch_accuracies)

Hitung nilai kerugian dan akurasi dalam satu batch data validasi (karena
ukuran batch data validasi sama dengan panjang data validasi):

for ix, batch in enumerate(iter(val_dl)):


x, y = batch
val_adalah_benar = akurasi(x, y, model)
validation_loss = val_loss(x, y, model)
val_epoch_accuracy = np.mean(val_is_correct)

Perhatikan bahwa pada kode sebelumnya, nilai kerugian dari data


validasi dihitung menggunakan fungsi val_loss dan disimpan
dalam variabel validation_loss. Selanjutnya, akurasi dari semua titik
data validasi disimpan dalam daftar val_is_correct, sementara rata-rata
dari ini disimpan dalam variabel val_epoch_accuracy.

Terakhir, kami menambahkan nilai akurasi dan kerugian dari dataset


pelatihan dan validasi ke daftar yang berisi nilai validasi dan akurasi
agregat tingkat epoch. Kami melakukan ini agar kami dapat melihat
peningkatan tingkat epoch di langkah berikutnya:
train_losses.append(train_epoch_loss)
train_accuracies.append(train_epoch_accuracy)
val_losses.append(validation_loss)
val_accuracies.append(val_epoch_accuracy)
9. Memvisualisasikan peningkatan nilai akurasi dan kerugian dalam dataset
pelatihan dan validasi dengan bertambahnya waktu:
epochs = np.arange(5)+1
import matplotlib.ticker as mtick
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
%matplotlib inline
plt.subplot(211)
plt.plot(epochs, train_losses, 'bo', label='Kerugian
pelatihan') plt.plot(epochs, val_losses, 'r', label='K e r u g i a n
validasi')
plt.gca().xaxis.set_major_locator(mticker.MultipleLocator(1)
) plt.title('Kerugian pelatihan dan validasi \
when batch size is 32')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.grid('off')
plt.show()
plt.subplot(212)
plt.plot(epochs, train_accuracies, 'bo', \
label = 'Akurasi pelatihan')
plt.plot(epochs, val_accuracies, 'r', \
label = 'Akurasi validasi')
plt.gca().xaxis.set_major_locator(mticker.MultipleLocator(1)
) plt.title('Akurasi pelatihan dan validasi \
when batch size is 32')
plt.xlabel('Epochs')
plt.ylabel('Akurasi')
plt.gca().set_yticklabels(['{:.0f}%'.format(x*100) \
for x in plt.gca().get_yticks()])
plt.legend()
plt.grid('off')
plt.show()
Kode sebelumnya memberi kita keluaran sebagai berikut:

Seperti yang Anda lihat, akurasi pelatihan dan validasi mencapai ~85% pada
akhir lima epoch ketika ukuran batch 32. Selanjutnya, kita akan memvariasikan
parameter batch_size
ketika melatih DataLoader dalam fungsi get_data untuk melihat dampaknya
terhadap akurasi pada akhir lima epoch.

Ukuran batch 10.000


Pada bagian ini, kita akan menggunakan 10.000 titik data per batch sehingga kita
dapat memahami dampak dari variasi ukuran batch.
Perhatikan bahwa kode yang disediakan pada bagian Ukuran
batch 32 tetap sama persis di sini, kecuali kode pada langkah 5. Di
sini, kita akan menentukan DataLoaders untuk dataset pelatihan
dan validasi
dalam fungsi get_data. Kami menganjurkan Anda untuk merujuk
ke fungsi
notebook masing-masing yang tersedia di repositori
GitHub buku ini saat menjalankan kode.

Kita akan memodifikasi get_data sehingga memiliki ukuran batch 10.000


ketika mengambil DataLoader pelatihan dari dataset pelatihan, sebagai berikut:
def get_data():
train = FMNISTDataset(tr_gambar, tr_target)
trn_dl = DataLoader(train, batch_size = 10000, shuffle = True)
val = FMNISTDataset(val_gambar, val_target)
val_dl = DataLoader(val, ukuran_batch = len(val_images), \
shuffle = False)
return trn_dl, val_dl

Dengan hanya membuat perubahan yang diperlukan pada langkah 5 dan setelah menjalankan
semua langkah hingga langkah 9, variasi dalam akurasi pelatihan dan validasi dan kehilangan
selama peningkatan epoch ketika ukuran batch 10.000 adalah sebagai berikut:

Di sini, kita dapat melihat bahwa nilai akurasi dan loss tidak mencapai tingkat yang sama
dengan skenario sebelumnya, di mana ukuran batch adalah 32, karena bobot waktu
diperbarui lebih sedikit ketika ukuran batch 32 (1875). Pada skenario dengan ukuran batch
10.000, terdapat enam kali pembaruan bobot per epoch karena terdapat 10.000 titik data per
batch, yang berarti total ukuran data pelatihan adalah 60.000.
Sejauh ini, kita telah mempelajari cara menskalakan dataset, serta dampak dari
memvariasikan ukuran batch pada waktu pelatihan model untuk mencapai akurasi
tertentu. Pada bagian selanjutnya, kita akan mempelajari dampak dari memvariasikan
pengoptimal kerugian pada dataset yang sama

Anda mungkin juga menyukai