|
|
|
|
|
|
|
import copy |
|
|
|
import torch |
|
from torch import nn |
|
from torch.optim import Adam |
|
from tqdm import tqdm |
|
|
|
from data import get_loaders_n_gram |
|
from methods import MLP |
|
|
|
|
|
def train(loader_train, loader_dev, model, device, optimizer, n_epochs): |
|
acc_best = 0 |
|
model_best = None |
|
criterion = nn.CrossEntropyLoss() |
|
|
|
bar_epochs = tqdm(range(n_epochs), leave=False) |
|
for epoch in bar_epochs: |
|
|
|
bar_epoch = tqdm(loader_train, disable=True, leave=False) |
|
model.train() |
|
for x, y in bar_epoch: |
|
x = x.to(device) |
|
y = y.to(device) |
|
y_out = model(x) |
|
loss = criterion(y_out, y.type(torch.LongTensor)) |
|
loss.backward() |
|
optimizer.step() |
|
loss_iter = loss.item() |
|
bar_epoch.set_postfix({"loss": loss_iter}) |
|
bar_epoch.close() |
|
|
|
bar_dev = tqdm(loader_dev, disable=True, leave=False) |
|
model.eval() |
|
|
|
|
|
ys_pred, ys_true = [], [] |
|
with torch.no_grad(): |
|
for x, y in bar_dev: |
|
x = x.to(device) |
|
y = y.to(device) |
|
y_out = model(x) |
|
y_pred = torch.argmax(y_out, axis=1) |
|
ys_pred.append(y_pred.cpu()) |
|
ys_true.append(y.cpu()) |
|
bar_dev.close() |
|
ys_pred = torch.cat(ys_pred) |
|
ys_true = torch.cat(ys_true) |
|
acc = (ys_pred == ys_true).float().mean() |
|
acc = acc.item() * 100 |
|
if acc > acc_best: |
|
acc_best = acc |
|
model_best = copy.deepcopy(model) |
|
bar_epochs.set_postfix({"acc_best": acc_best}) |
|
|
|
return model_best |
|
|
|
|
|
def test(loader_test, model, device): |
|
model.eval() |
|
ys_pred, ys_true = [], [] |
|
bar_test = tqdm(loader_test, leave=False) |
|
with torch.no_grad(): |
|
for x, y in bar_test: |
|
x = x.to(device) |
|
y = y.to(device) |
|
y_pred = model(x) |
|
y_pred = torch.argmax(y_pred, axis=1) |
|
ys_pred.append(y_pred.cpu()) |
|
ys_true.append(y.cpu()) |
|
|
|
bar_test.close() |
|
|
|
ys_pred = torch.cat(ys_pred) |
|
ys_true = torch.cat(ys_true) |
|
|
|
return ys_pred, ys_true |
|
|
|
|
|
def run( |
|
csv_file, |
|
seed, |
|
n=5, |
|
topk=1000, |
|
ratio_dev=0.1, |
|
ratio_test=0.1, |
|
batch_size=32, |
|
size_hidden=None, |
|
dropout=0.1, |
|
n_epochs=50, |
|
lr=3e-4, |
|
weight_decay=0, |
|
): |
|
|
|
ratio_dev = ratio_dev |
|
ratio_test = ratio_test |
|
batch_size = batch_size |
|
n = n |
|
data = get_loaders_n_gram( |
|
csv_file, |
|
n=n, |
|
topk=topk, |
|
ratio_dev=ratio_dev, |
|
ratio_test=ratio_test, |
|
seed=seed, |
|
batch_size=batch_size, |
|
) |
|
size_x = data["sizes"]["x"] |
|
size_y = data["sizes"]["y"] |
|
loader_train = data["loaders"]["train"] |
|
loader_dev = data["loaders"]["dev"] |
|
loader_test = data["loaders"]["test"] |
|
|
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
|
|
|
if size_hidden is None: |
|
size_hidden = [size_x // 2, size_x // 4] |
|
size_hidden = [size_x] + size_hidden |
|
dropout = dropout |
|
model = MLP( |
|
size_in=size_x, |
|
size_out=size_y, |
|
size_hidden=size_hidden, |
|
dropout=dropout, |
|
) |
|
model = model.to(device) |
|
|
|
|
|
n_epochs = n_epochs |
|
lr = lr |
|
weight_decay = weight_decay |
|
optimizer = Adam( |
|
model.parameters(), |
|
lr=lr, |
|
weight_decay=weight_decay, |
|
) |
|
|
|
|
|
model_best = train(loader_train, loader_dev, model, device, optimizer, n_epochs) |
|
return test(loader_test, model_best, device) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
csv_file = "./_DATA/all_chem_df.csv" |
|
|
|
n_trials = 5 |
|
seeds = list(range(n_trials)) |
|
|
|
topk = 1000 |
|
ratio_dev = 0.1 |
|
ratio_test = 0.2 |
|
batch_size = 32 |
|
|
|
n = 5 |
|
dropout = 0.1 |
|
size_hidden = [512, 256, 128, 32] |
|
|
|
n_epochs = 200 |
|
lr = 3e-5 |
|
weight_decay = 0 |
|
|
|
|
|
|
|
for seed in seeds: |
|
y_pred, y_true = run( |
|
csv_file, |
|
seed, |
|
n, |
|
topk, |
|
ratio_dev, |
|
ratio_test, |
|
batch_size, |
|
size_hidden, |
|
dropout, |
|
n_epochs, |
|
lr, |
|
) |
|
log_file = f"./scores/MLP/{seed}-seed--{n}-gram--topk-{topk}--lr-{lr}.csv" |
|
with open(log_file, "a") as f: |
|
f.write("pred,true\n") |
|
for p, t in zip(y_pred, y_true): |
|
f.write(f"{p},{t}\n") |
|
|