(save_path: Path, data_folder: Path, regen_data: bool, resample: bool)
| 324 | |
| 325 | |
| 326 | def train(save_path: Path, data_folder: Path, regen_data: bool, resample: bool): |
| 327 | train_data, val_data = get_train_val_data(data_folder, regen_data) |
| 328 | train_zip_list = get_title_files_author_categories_zip_list(train_data) |
| 329 | val_zip_list = get_title_files_author_categories_zip_list(val_data) |
| 330 | |
| 331 | classifier_config = CategoryConfig(common.categories) |
| 332 | author_map = get_author_map(data_folder, regen_data) |
| 333 | file_map = get_file_map(data_folder, regen_data) |
| 334 | commit_classifier = CommitClassifier( |
| 335 | XLMR_BASE, author_map, file_map, classifier_config |
| 336 | ).to(device) |
| 337 | |
| 338 | # Lets train this bag of bits |
| 339 | class_weights = gen_class_weights(train_zip_list) |
| 340 | loss = torch.nn.CrossEntropyLoss(weight=class_weights) |
| 341 | optimizer = torch.optim.Adam(commit_classifier.parameters(), lr=3e-3) |
| 342 | |
| 343 | num_epochs = 25 |
| 344 | batch_size = 256 |
| 345 | |
| 346 | if resample: |
| 347 | # Lets not use this |
| 348 | train_zip_list = balance_dataset(train_zip_list) |
| 349 | data_size = len(train_zip_list) |
| 350 | |
| 351 | print(f"Training on {data_size} examples.") |
| 352 | # We can fit all of val into one batch |
| 353 | val_batch = generate_batch(val_zip_list) |
| 354 | |
| 355 | for i in tqdm(range(num_epochs), desc="Epochs"): |
| 356 | start = 0 |
| 357 | random.shuffle(train_zip_list) |
| 358 | while start < data_size: |
| 359 | end = start + batch_size |
| 360 | # make the last batch bigger if needed |
| 361 | if end > data_size: |
| 362 | end = data_size |
| 363 | train_batch = train_zip_list[start:end] |
| 364 | train_batch = generate_batch(train_batch) |
| 365 | l = train_step(train_batch, commit_classifier, optimizer, loss) |
| 366 | start = end |
| 367 | |
| 368 | val_l = eval_step(val_batch, commit_classifier, loss) |
| 369 | tqdm.write( |
| 370 | f"Finished epoch {i} with a train loss of: {l.item()} and a val_loss of: {val_l.item()}" |
| 371 | ) |
| 372 | |
| 373 | with torch.no_grad(): |
| 374 | commit_classifier.eval() |
| 375 | val_inpts, val_targets = val_batch |
| 376 | val_output = commit_classifier(val_inpts) |
| 377 | val_preds = torch.argmax(val_output, dim=1) |
| 378 | val_acc = torch.sum(val_preds == val_targets).item() / len(val_preds) |
| 379 | print(f"Final Validation accuracy is {val_acc}") |
| 380 | |
| 381 | print(f"Jobs done! Saving to {save_path}") |
| 382 | torch.save(commit_classifier.state_dict(), save_path) |
| 383 |
no test coverage detected
searching dependent graphs…