82 lines
2.1 KiB
Python
82 lines
2.1 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
# Wprowadzamy minibatche
|
||
|
|
||
|
import sys
|
||
|
import torch
|
||
|
from torch import optim
|
||
|
import itertools
|
||
|
|
||
|
# 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_classification import vectorizer, vector_length, process_line, vectorize_batch
|
||
|
|
||
|
from my_neural_network import MyNeuralNetwork
|
||
|
|
||
|
# Rozmiar minibatcha
|
||
|
batch_size = 16
|
||
|
|
||
|
regressor = MyNeuralNetwork(vector_length)
|
||
|
|
||
|
# Pomocnicza funkcja do batchowania
|
||
|
def grouper(n, iterable):
|
||
|
it = iter(iterable)
|
||
|
while True:
|
||
|
chunk = tuple(itertools.islice(it, n))
|
||
|
if not chunk:
|
||
|
return
|
||
|
yield chunk
|
||
|
|
||
|
|
||
|
# Tym razem użyjemy optymalizatora
|
||
|
optimizer = optim.Adam(regressor.parameters())
|
||
|
|
||
|
|
||
|
# Funkcja kosztu.
|
||
|
def loss_fun(y_hat, y_exp):
|
||
|
return torch.sum((y_hat - y_exp)**2) / batch_size
|
||
|
|
||
|
|
||
|
# 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 = 500
|
||
|
i = 1
|
||
|
closs = torch.tensor(0.0, dtype=torch.float, requires_grad=False)
|
||
|
|
||
|
for batch in grouper(batch_size, sys.stdin):
|
||
|
t = [process_line(line) for line in batch]
|
||
|
contents = [entry[0] for entry in t]
|
||
|
# y_exp będzie teraz wektorem!
|
||
|
y_exp = torch.tensor([entry[1] for entry in t], dtype=torch.float)
|
||
|
|
||
|
optimizer.zero_grad()
|
||
|
|
||
|
x = vectorize_batch(contents).float()
|
||
|
|
||
|
# wartość z predykcji (też wektor!)
|
||
|
y_hat = regressor(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[0].item(), " => ", y_hat[0].item(),
|
||
|
" | Avg loss: ", (closs / step).item())
|
||
|
closs = torch.tensor(0.0, dtype=torch.float, requires_grad=False)
|
||
|
|
||
|
i += 1
|
||
|
|
||
|
|
||
|
# serializujemy nasz model
|
||
|
torch.save(regressor, "model.bin")
|