#!/usr/bin/env python3 # To samo co linear0.py tylko z automatycznym różniczkowaniem import sys import torch from torch import optim # Preprocessing i wektoryzację tekstów wydzialamy do osobnego modułu, # z którego będzie korzystał zarówno kod do uczenia, jak i predykcji. from analyzer import vectorizer, vector_length, process_line, vectorize_text # Nasz model to zestaw wag w. Na koniec dojdziemy do modeli # Transformer o wielu milionach wag; w pewnym sensie algorytm # uczenia się nie zmieni. # W naszym zadaniu lepiej zacząć od zerowych wag zamiast losowych. # Tym razem zaznaczamy, że względem w będziemy różniczkować w = torch.zeros(vector_length, dtype=torch.double, requires_grad=True) # Tym razem użyjemy optymalizatora optimizer = optim.SGD([w], lr=.0064) def model(w, x): # @ to iloczyn wektorów/macierzy w PyTorchu return x @ w # Funkcja kosztu. def loss_fun(y_hat, y_exp): return (y_hat - y_exp)**2 # Co ile kroków będziemy wypisywali informacje o średniej funkcji kosztu. # To nie jest hiperparametr uczenia, nie ma to żadnego, ani pozytywnego, ani # negatywnego wpływu na uczenie. step = 5000 i = 1 closs = torch.tensor(0.0, dtype=torch.double, requires_grad=False) for line in sys.stdin: optimizer.zero_grad() content, y_exp = process_line(line) x = vectorize_text(content) # wartość z predykcji y_hat = model(w, x) # wyliczamy funkcję kosztu loss = loss_fun(y_hat, y_exp) loss.backward() with torch.no_grad(): closs += loss # Optymalizator automagicznie zadba o aktualizację wag! optimizer.step() # za jakiś czas pokazujemy uśrednioną funkcję kosztu if i % step == 0: print("Sample item: ", y_exp.item(), " => ", y_hat.item(), " | Avg loss: ", (closs / step).item()) closs = torch.tensor(0.0, dtype=torch.double, requires_grad=False) i += 1 # serializujemy nasz model torch.save(w, "model.bin")