71 lines
1.9 KiB
Python
71 lines
1.9 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
# To samo co linear0.py tylko z automatycznym różniczkowaniem
|
||
|
|
||
|
import sys
|
||
|
import torch
|
||
|
|
||
|
# 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)
|
||
|
|
||
|
# Hiperparametr uczenia
|
||
|
learning_rate = torch.tensor(.0032, dtype=torch.double)
|
||
|
|
||
|
|
||
|
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:
|
||
|
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():
|
||
|
w = w - learning_rate * w.grad
|
||
|
closs += loss
|
||
|
|
||
|
# 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
|
||
|
|
||
|
# ponownie ustawiamy (i zerujemy) wagi
|
||
|
w.requires_grad_(True)
|
||
|
|
||
|
|
||
|
# serializujemy nasz model
|
||
|
torch.save(w, "model.bin")
|