Download main.py from bctnry/sanime2x: direct link, hf CLI and curl.
- Browser
- Download file 3.18 kB
-
https://huggingface.co/bctnry/sanime2x/resolve/main/main.py
- Command line
-
hf download hf://bctnry/sanime2x/main.py
-
curl -L -o main.py https://huggingface.co/bctnry/sanime2x/resolve/main/main.py
3.18 kB
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from model_cnn import PlainCNN | |
| from dataloader2 import SAnime2XDataset | |
| device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') | |
| n_layer = 12 | |
| lr_peak = 2.5e-4 | |
| n_steps = 10000 | |
| batch_size = 8 | |
| patch_size = 96 | |
| zoom = 2 | |
| ds = SAnime2XDataset('/home/bctnry/s/sanime2x-2k/') | |
| model = PlainCNN(n_layer) | |
| model = model.to(device) | |
| optimizer = torch.optim.AdamW(model.parameters(), lr=lr_peak) | |
| scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 2500, gamma=0.9) | |
| PSNR_EVAL_IDX = torch.randint(ds.val_size, (2,)) | |
| def val_psnr(model): | |
| calc = [] | |
| idx = PSNR_EVAL_IDX | |
| images = ds.get_val_images(idx) | |
| se_images = ds.get_val_shrink_enlarged_images(idx, zoom=zoom) | |
| model.eval() | |
| with torch.no_grad(): | |
| for k, img in enumerate(images): | |
| se_img = se_images[k] | |
| h, w = img.shape[1], img.shape[2] | |
| p_h, p_w = h // patch_size, w // patch_size | |
| # we can largely ignore the edges without compromising | |
| # too much about the accuracy of this measuring. | |
| for j in range(0, p_h): | |
| for i in range(0, p_w): | |
| cropped = img[:, | |
| j*patch_size:(j+1)*patch_size, | |
| i*patch_size:(i+1)*patch_size] | |
| cropped = cropped.reshape(1, *cropped.shape) | |
| cropped = cropped.to(device) | |
| se_cropped = se_img[:, | |
| j*patch_size:(j+1)*patch_size, | |
| i*patch_size:(i+1)*patch_size] | |
| se_cropped = se_cropped.reshape(1, *se_cropped.shape) | |
| se_cropped = se_cropped.to(device) / 255 | |
| res = model(se_cropped) | |
| cropped = cropped / 255 | |
| loss = F.mse_loss(res, cropped) | |
| calc.append(loss.item()) | |
| total_loss = sum(calc) / len(calc) | |
| psnr = -10*torch.log10(torch.Tensor([total_loss])).item() | |
| return psnr | |
| losses = [] | |
| avg_span = 50 | |
| last_psnr = 0 | |
| for i in range(n_steps): | |
| model.train() | |
| enlarged, cropped = ds.get_train_random_crop(n=batch_size, zoom=zoom) | |
| enlarged = enlarged.to(device) | |
| cropped = cropped.to(device) | |
| calculated = model(enlarged) | |
| loss = F.l1_loss(calculated, cropped) | |
| optimizer.zero_grad() | |
| loss.backward() | |
| optimizer.step() | |
| scheduler.step() | |
| losses.append(loss.item()) | |
| if len(losses) > avg_span: | |
| losses = losses[1:] | |
| avgloss = sum(losses)/len(losses) | |
| print(f'Step {i+1}: loss={loss.item():.4f} avgloss={avgloss:.4f} last_psnr={last_psnr:.4f} dB') | |
| # print(f'Step {i+1}: loss={loss.item():.4f} avgloss={avgloss:.4f}') | |
| # if i % 500 == 499: | |
| if i % 500 == 499: | |
| last_psnr = val_psnr(model) | |
| if i % 100 == 99: | |
| torch.save({ | |
| 'model': model.state_dict(), | |
| 'optim': optimizer.state_dict(), | |
| }, 'model_cnn.pt') | |
| torch.save({ | |
| 'model': model.state_dict(), | |
| 'optim': optimizer.state_dict(), | |
| }, 'model_cnn.pt') | |