Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Mallin Koulutus | Osio
Pytorch-Osaamisen Perusteet ML-Insinöörille

bookMallin Koulutus

Valmistautuminen mallin koulutukseen

Ensiksi tulee varmistaa, että malli, tappiollisuusfunktio ja optimoija on määritelty oikein. Käydään läpi jokainen vaihe:

  1. Tappiollisuusfunktio: luokittelutehtävissä voidaan käyttää CrossEntropyLoss-funktiota, joka odottaa syötteenä raakoja jatkuvia arvoja (logitit) ja soveltaa automaattisesti softmax-toimintoa;
  2. Optimoija: Adam-optimoijaa voidaan käyttää tehokkaaseen gradienttipäivitykseen.
import torch.nn as nn
import torch.optim as optim
# Define the loss function (cross-entropy for multi-class classification)
criterion = nn.CrossEntropyLoss()
# Define the optimizer (Adam with a learning rate of 0.01)
optimizer = optim.Adam(model.parameters(), lr=0.01)

PyTorchissa cross-entropy-tappio yhdistää log-softmax- ja negatiivinen logaritminen todennäköisyys (NLL) -tappion yhdeksi tappiollisuusfunktioksi:

L=log(ezyj=1Cezj)\mathcal{L} = - \log{\left( \frac{e^{z_y}}{\sum^C_{j=1}e^{z_j}} \right)}

missä:

  • zy on oikean luokan logit;
  • C on luokkien kokonaismäärä.

On myös tärkeää jakaa data koulutus- ja validointijoukkoihin (ihanteellisesti tulisi olla myös erillinen testijoukko). Koska datasetti on melko pieni (1143 riviä), käytetään 80 % ja 20 % jakoa. Tässä tapauksessa validointijoukko toimii myös testijoukkona.

Note
Lisätietoa

80 % koulutukseen ja 20 % testaukseen sopii usein moniin tilanteisiin. Kuitenkin suurilla dataseteillä, kuten miljoonia rivejä sisältävissä, jopa pienempi osuus testijoukolle (10 % tai vähemmän) voi riittää luotettavaan suorituskyvyn arviointiin. Vastaavasti hyvin pienillä dataseteillä (esim. alle tuhat riviä) on tärkeää varmistaa, että testijoukko on riittävän suuri (25–30 %) mallin suorituskyvyn mielekkääseen arviointiin.

Lisäksi tuloksena saadut NumPy-taulukot tulee muuntaa tensoreiksi, sillä PyTorch-mallit vaativat tensorisyötteitä laskentaa varten.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test =  train_test_split(X, y, test_size=0.2, random_state=42)
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
y_test = torch.tensor(y_test, dtype=torch.long)

Koulutussilmukka

Koulutussilmukka sisältää seuraavat vaiheet jokaisella epookilla:

  1. Eteenpäinlaskenta: syöteominaisuuksien läpivienti mallin läpi ennusteiden tuottamiseksi;
  2. Häviön laskenta: ennusteiden vertailu todellisiin arvoihin häviöfunktion avulla;
  3. Takaisinlaskenta: gradienttien laskeminen mallin parametrien suhteen takaisinkytkennän avulla;
  4. Parametrien päivitys: mallin parametrien säätäminen optimoijan avulla;
  5. Edistymisen seuranta: häviön tulostaminen säännöllisesti konvergenssin seuraamiseksi.

Kuten huomaat, koulutusprosessi on samankaltainen kuin lineaarisessa regressiossa.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
import torch.nn as nn import torch import torch.optim as optim import matplotlib.pyplot as plt import os os.system('wget https://staging-content-media-cdn.codefinity.com/courses/1dd2b0f6-6ec0-40e6-a570-ed0ac2209666/section_3/model_definition.py 2>/dev/null') from model_definition import model, X, y from sklearn.model_selection import train_test_split # Set manual seed for reproducibility torch.manual_seed(42) # Reinitialize model after setting seed model.apply(lambda m: m.reset_parameters() if hasattr(m, "reset_parameters") else None) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_train = torch.tensor(X_train, dtype=torch.float32) X_test = torch.tensor(X_test, dtype=torch.float32) y_train = torch.tensor(y_train, dtype=torch.long) y_test = torch.tensor(y_test, dtype=torch.long) # Define the loss function (Cross-Entropy for multi-class classification) criterion = nn.CrossEntropyLoss() # Define the optimizer (Adam with a learning rate of 0.01) optimizer = optim.Adam(model.parameters(), lr=0.01) # Number of epochs epochs = 100 # Store losses for plotting training_losses = [] # Training loop for epoch in range(epochs): # Zero out gradients from the previous step optimizer.zero_grad() # Compute predictions predictions = model(X_train) # Compute the loss loss = criterion(predictions, y_train) # Compute gradients loss.backward() # Update parameters optimizer.step() # Store the loss training_losses.append(loss.item()) # Plot the training loss plt.plot(range(epochs), training_losses, label="Training Loss") plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("Training Loss over Epochs") plt.legend() plt.show()
copy
Note
Huomio

Kutsumalla model(input) kutsutaan automaattisesti mallin forward()-metodia. Tämä johtuu siitä, että nn.Module ylikirjoittaa __call__-metodin, joka sisäisesti kutsuu forward(). On suositeltavaa käyttää model(input) sen sijaan, että käyttäisit model.forward(input), sillä edellinen varmistaa, että kaikki hookit tai lisätoiminnot (esim. model.train() tai model.eval()) otetaan asianmukaisesti huomioon.

Konvergenssin havainnointi

Mallin kouluttamisen lisäksi tallennetaan myös koulutustappio jokaisella epookilla ja piirretään se ajan funktiona. Kuten kuvaajasta nähdään, koulutustappio pienenee aluksi nopeasti ja vakiintuu vähitellen noin epookin 60 kohdalla. Tämän jälkeen tappio pienenee huomattavasti hitaammin, mikä viittaa siihen, että malli on todennäköisesti konvergoitunut. Siksi noin 40 epookkia riittää tämän mallin kouluttamiseen.

question mark

Mikä seuraavista on oikea järjestys PyTorchin koulutussilmukassa?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 1. Luku 18

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

bookMallin Koulutus

Pyyhkäise näyttääksesi valikon

Valmistautuminen mallin koulutukseen

Ensiksi tulee varmistaa, että malli, tappiollisuusfunktio ja optimoija on määritelty oikein. Käydään läpi jokainen vaihe:

  1. Tappiollisuusfunktio: luokittelutehtävissä voidaan käyttää CrossEntropyLoss-funktiota, joka odottaa syötteenä raakoja jatkuvia arvoja (logitit) ja soveltaa automaattisesti softmax-toimintoa;
  2. Optimoija: Adam-optimoijaa voidaan käyttää tehokkaaseen gradienttipäivitykseen.
import torch.nn as nn
import torch.optim as optim
# Define the loss function (cross-entropy for multi-class classification)
criterion = nn.CrossEntropyLoss()
# Define the optimizer (Adam with a learning rate of 0.01)
optimizer = optim.Adam(model.parameters(), lr=0.01)

PyTorchissa cross-entropy-tappio yhdistää log-softmax- ja negatiivinen logaritminen todennäköisyys (NLL) -tappion yhdeksi tappiollisuusfunktioksi:

L=log(ezyj=1Cezj)\mathcal{L} = - \log{\left( \frac{e^{z_y}}{\sum^C_{j=1}e^{z_j}} \right)}

missä:

  • zy on oikean luokan logit;
  • C on luokkien kokonaismäärä.

On myös tärkeää jakaa data koulutus- ja validointijoukkoihin (ihanteellisesti tulisi olla myös erillinen testijoukko). Koska datasetti on melko pieni (1143 riviä), käytetään 80 % ja 20 % jakoa. Tässä tapauksessa validointijoukko toimii myös testijoukkona.

Note
Lisätietoa

80 % koulutukseen ja 20 % testaukseen sopii usein moniin tilanteisiin. Kuitenkin suurilla dataseteillä, kuten miljoonia rivejä sisältävissä, jopa pienempi osuus testijoukolle (10 % tai vähemmän) voi riittää luotettavaan suorituskyvyn arviointiin. Vastaavasti hyvin pienillä dataseteillä (esim. alle tuhat riviä) on tärkeää varmistaa, että testijoukko on riittävän suuri (25–30 %) mallin suorituskyvyn mielekkääseen arviointiin.

Lisäksi tuloksena saadut NumPy-taulukot tulee muuntaa tensoreiksi, sillä PyTorch-mallit vaativat tensorisyötteitä laskentaa varten.

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test =  train_test_split(X, y, test_size=0.2, random_state=42)
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
y_test = torch.tensor(y_test, dtype=torch.long)

Koulutussilmukka

Koulutussilmukka sisältää seuraavat vaiheet jokaisella epookilla:

  1. Eteenpäinlaskenta: syöteominaisuuksien läpivienti mallin läpi ennusteiden tuottamiseksi;
  2. Häviön laskenta: ennusteiden vertailu todellisiin arvoihin häviöfunktion avulla;
  3. Takaisinlaskenta: gradienttien laskeminen mallin parametrien suhteen takaisinkytkennän avulla;
  4. Parametrien päivitys: mallin parametrien säätäminen optimoijan avulla;
  5. Edistymisen seuranta: häviön tulostaminen säännöllisesti konvergenssin seuraamiseksi.

Kuten huomaat, koulutusprosessi on samankaltainen kuin lineaarisessa regressiossa.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
import torch.nn as nn import torch import torch.optim as optim import matplotlib.pyplot as plt import os os.system('wget https://staging-content-media-cdn.codefinity.com/courses/1dd2b0f6-6ec0-40e6-a570-ed0ac2209666/section_3/model_definition.py 2>/dev/null') from model_definition import model, X, y from sklearn.model_selection import train_test_split # Set manual seed for reproducibility torch.manual_seed(42) # Reinitialize model after setting seed model.apply(lambda m: m.reset_parameters() if hasattr(m, "reset_parameters") else None) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_train = torch.tensor(X_train, dtype=torch.float32) X_test = torch.tensor(X_test, dtype=torch.float32) y_train = torch.tensor(y_train, dtype=torch.long) y_test = torch.tensor(y_test, dtype=torch.long) # Define the loss function (Cross-Entropy for multi-class classification) criterion = nn.CrossEntropyLoss() # Define the optimizer (Adam with a learning rate of 0.01) optimizer = optim.Adam(model.parameters(), lr=0.01) # Number of epochs epochs = 100 # Store losses for plotting training_losses = [] # Training loop for epoch in range(epochs): # Zero out gradients from the previous step optimizer.zero_grad() # Compute predictions predictions = model(X_train) # Compute the loss loss = criterion(predictions, y_train) # Compute gradients loss.backward() # Update parameters optimizer.step() # Store the loss training_losses.append(loss.item()) # Plot the training loss plt.plot(range(epochs), training_losses, label="Training Loss") plt.xlabel("Epoch") plt.ylabel("Loss") plt.title("Training Loss over Epochs") plt.legend() plt.show()
copy
Note
Huomio

Kutsumalla model(input) kutsutaan automaattisesti mallin forward()-metodia. Tämä johtuu siitä, että nn.Module ylikirjoittaa __call__-metodin, joka sisäisesti kutsuu forward(). On suositeltavaa käyttää model(input) sen sijaan, että käyttäisit model.forward(input), sillä edellinen varmistaa, että kaikki hookit tai lisätoiminnot (esim. model.train() tai model.eval()) otetaan asianmukaisesti huomioon.

Konvergenssin havainnointi

Mallin kouluttamisen lisäksi tallennetaan myös koulutustappio jokaisella epookilla ja piirretään se ajan funktiona. Kuten kuvaajasta nähdään, koulutustappio pienenee aluksi nopeasti ja vakiintuu vähitellen noin epookin 60 kohdalla. Tämän jälkeen tappio pienenee huomattavasti hitaammin, mikä viittaa siihen, että malli on todennäköisesti konvergoitunut. Siksi noin 40 epookkia riittää tämän mallin kouluttamiseen.

question mark

Mikä seuraavista on oikea järjestys PyTorchin koulutussilmukassa?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 1. Luku 18
some-alt