Title: 컴퓨터 비전(Vision)을 위한 전이학습(Transfer Learning) — 파이토치 한국어 튜토리얼 (PyTorch tutorials in Korean)
Open Graph Title: 컴퓨터 비전(Vision)을 위한 전이학습(Transfer Learning)
Description: Author: Sasank Chilamkurthy, 번역: 박정환,. 이 튜토리얼에서는 전이학습(Transfer Learning)을 이용하여 이미지 분류를 위한 합성곱 신경망을 어떻게 학습시키는지 배워보겠습니다. 전이학습에 대해서는 CS231n 노트 에서 더 많은 내용을 읽어보실 수 있습니다. 위 노트를 인용해보면, 실제로 충분한 크기의 데이터셋을 갖추기는 상대적으로 드물기 때문에, (무작위 초기화를 통해) 맨 처음부터 합성곱 신경망(Convolutional Network) 전체를 학습하는 사람은 매우 적습니다. 대신, 매우 ...
Open Graph Description: Author: Sasank Chilamkurthy, 번역: 박정환,. 이 튜토리얼에서는 전이학습(Transfer Learning)을 이용하여 이미지 분류를 위한 합성곱 신경망을 어떻게 학습시키는지 배워보겠습니다. 전이학습에 대해서는 CS231n 노트 에서 더 많은 내용을 읽어보실 수 있습니다. 위 노트를 인용해보면, 실제로 충분한 크기의 데이터셋을 갖추기는 상대적으로 드물기 때문에, (무작위 초기화를 통해) 맨 처음부터 합성곱 신경망(Convolutional Network) 전체를 학습하는 사람은 매우 적습니다. 대신, 매우 ...
Opengraph URL: https://tutorials.pytorch.kr/beginner/transfer_learning_tutorial.html
Domain: tutorials.pytorch.kr
{
"@context": "https://schema.org",
"@type": "Article",
"name": "\ucef4\ud4e8\ud130 \ube44\uc804(Vision)\uc744 \uc704\ud55c \uc804\uc774\ud559\uc2b5(Transfer Learning)",
"headline": "\ucef4\ud4e8\ud130 \ube44\uc804(Vision)\uc744 \uc704\ud55c \uc804\uc774\ud559\uc2b5(Transfer Learning)",
"description": "PyTorch Documentation. Explore PyTorch, an open-source machine learning library that accelerates the path from research prototyping to production deployment. Discover tutorials, API references, and guides to help you build and deploy deep learning models efficiently.",
"url": "/beginner/transfer_learning_tutorial.html",
"articleBody": "\ucc38\uace0 Go to the end to download the full example code. \ucef4\ud4e8\ud130 \ube44\uc804(Vision)\uc744 \uc704\ud55c \uc804\uc774\ud559\uc2b5(Transfer Learning)# Author: Sasank Chilamkurthy\ubc88\uc5ed: \ubc15\uc815\ud658 \uc774 \ud29c\ud1a0\ub9ac\uc5bc\uc5d0\uc11c\ub294 \uc804\uc774\ud559\uc2b5(Transfer Learning)\uc744 \uc774\uc6a9\ud558\uc5ec \uc774\ubbf8\uc9c0 \ubd84\ub958\ub97c \uc704\ud55c \ud569\uc131\uacf1 \uc2e0\uacbd\ub9dd\uc744 \uc5b4\ub5bb\uac8c \ud559\uc2b5\uc2dc\ud0a4\ub294\uc9c0 \ubc30\uc6cc\ubcf4\uaca0\uc2b5\ub2c8\ub2e4. \uc804\uc774\ud559\uc2b5\uc5d0 \ub300\ud574\uc11c\ub294 CS231n \ub178\ud2b8 \uc5d0\uc11c \ub354 \ub9ce\uc740 \ub0b4\uc6a9\uc744 \uc77d\uc5b4\ubcf4\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc704 \ub178\ud2b8\ub97c \uc778\uc6a9\ud574\ubcf4\uba74, \uc2e4\uc81c\ub85c \ucda9\ubd84\ud55c \ud06c\uae30\uc758 \ub370\uc774\ud130\uc14b\uc744 \uac16\ucd94\uae30\ub294 \uc0c1\ub300\uc801\uc73c\ub85c \ub4dc\ubb3c\uae30 \ub54c\ubb38\uc5d0, (\ubb34\uc791\uc704 \ucd08\uae30\ud654\ub97c \ud1b5\ud574) \ub9e8 \ucc98\uc74c\ubd80\ud130 \ud569\uc131\uacf1 \uc2e0\uacbd\ub9dd(Convolutional Network) \uc804\uccb4\ub97c \ud559\uc2b5\ud558\ub294 \uc0ac\ub78c\uc740 \ub9e4\uc6b0 \uc801\uc2b5\ub2c8\ub2e4. \ub300\uc2e0, \ub9e4\uc6b0 \ud070 \ub370\uc774\ud130\uc14b(\uc608. 100\uac00\uc9c0 \ubd84\ub958\uc5d0 \ub300\ud574 120\ub9cc\uac1c\uc758 \uc774\ubbf8\uc9c0\uac00 \ud3ec\ud568\ub41c ImageNet)\uc5d0\uc11c \ud569\uc131\uacf1 \uc2e0\uacbd\ub9dd(ConvNet)\uc744 \ubbf8\ub9ac \ud559\uc2b5\ud55c \ud6c4, \uc774 \ud569\uc131\uacf1 \uc2e0\uacbd\ub9dd\uc744 \uad00\uc2ec\uc788\ub294 \uc791\uc5c5 \uc744 \uc704\ud55c \ucd08\uae30 \uc124\uc815 \ub610\ub294 \uace0\uc815\ub41c \ud2b9\uc9d5 \ucd94\ucd9c\uae30(fixed feature extractor)\ub85c \uc0ac\uc6a9\ud569\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uc804\uc774\ud559\uc2b5 \uc2dc\ub098\ub9ac\uc624\uc758 \uc8fc\uc694\ud55c 2\uac00\uc9c0\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4: \ud569\uc131\uacf1 \uc2e0\uacbd\ub9dd\uc758 \ubbf8\uc138\uc870\uc815(finetuning): \ubb34\uc791\uc704 \ucd08\uae30\ud654 \ub300\uc2e0, \uc2e0\uacbd\ub9dd\uc744 ImageNet 1000 \ub370\uc774\ud130\uc14b \ub4f1\uc73c\ub85c \ubbf8\ub9ac \ud559\uc2b5\ud55c \uc2e0\uacbd\ub9dd\uc73c\ub85c \ucd08\uae30\ud654\ud569\ub2c8\ub2e4. \ud559\uc2b5\uc758 \ub098\uba38\uc9c0 \uacfc\uc815\ub4e4\uc740 \ud3c9\uc0c1\uc2dc\uc640 \uac19\uc2b5\ub2c8\ub2e4. \uace0\uc815\ub41c \ud2b9\uc9d5 \ucd94\ucd9c\uae30\ub85c\uc368\uc758 \ud569\uc131\uacf1 \uc2e0\uacbd\ub9dd: \uc5ec\uae30\uc11c\ub294 \ub9c8\uc9c0\ub9c9\uc5d0 \uc644\uc804\ud788 \uc5f0\uacb0 \ub41c \uacc4\uce35\uc744 \uc81c\uc678\ud55c \ubaa8\ub4e0 \uc2e0\uacbd\ub9dd\uc758 \uac00\uc911\uce58\ub97c \uace0\uc815\ud569\ub2c8\ub2e4. \uc774 \ub9c8\uc9c0\ub9c9\uc758 \uc644\uc804\ud788 \uc5f0\uacb0\ub41c \uacc4\uce35\uc740 \uc0c8\ub85c\uc6b4 \ubb34\uc791\uc704\uc758 \uac00\uc911\uce58\ub97c \uac16\ub294 \uacc4\uce35\uc73c\ub85c \ub300\uccb4\ub418\uc5b4 \uc774 \uacc4\uce35\ub9cc \ud559\uc2b5\ud569\ub2c8\ub2e4. # License: BSD # Author: Sasank Chilamkurthy import torch import torch.nn as nn import torch.optim as optim from torch.optim import lr_scheduler import torch.backends.cudnn as cudnn import numpy as np import torchvision from torchvision import datasets, models, transforms import matplotlib.pyplot as plt import time import os from PIL import Image from tempfile import TemporaryDirectory cudnn.benchmark = True plt.ion() # \ub300\ud654\ud615 \ubaa8\ub4dc \u003ccontextlib.ExitStack object at 0x7f0dab1b6e50\u003e \ub370\uc774\ud130 \ubd88\ub7ec\uc624\uae30# \ub370\uc774\ud130\ub97c \ubd88\ub7ec\uc624\uae30 \uc704\ud574 torchvision\uacfc torch.utils.data \ud328\ud0a4\uc9c0\ub97c \uc0ac\uc6a9\ud558\uaca0\uc2b5\ub2c8\ub2e4. \uc5ec\uae30\uc11c \ud480\uace0\uc790 \ud558\ub294 \ubb38\uc81c\ub294 \uac1c\ubbf8 \uc640 \ubc8c \uc744 \ubd84\ub958\ud558\ub294 \ubaa8\ub378\uc744 \ud559\uc2b5\ud558\ub294 \uac83\uc785\ub2c8\ub2e4. \uac1c\ubbf8\uc640 \ubc8c \uac01\uac01\uc758 \ud559\uc2b5\uc6a9 \uc774\ubbf8\uc9c0\ub294 \ub300\ub7b5 120\uc7a5 \uc815\ub3c4 \uc788\uace0, 75\uac1c\uc758 \uac80\uc99d\uc6a9 \uc774\ubbf8\uc9c0\uac00 \uc788\uc2b5\ub2c8\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \ub9e8 \ucc98\uc74c\ubd80\ud130 \ud559\uc2b5\uc744 \ud55c\ub2e4\uba74 \uc774\ub294 \uc77c\ubc18\ud654\ud558\uae30\uc5d0\ub294 \uc544\uc8fc \uc791\uc740 \ub370\uc774\ud130\uc14b\uc785\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \uc6b0\ub9ac\ub294 \uc804\uc774\ud559\uc2b5\uc744 \ud560 \uac83\uc774\ubbc0\ub85c, \uc77c\ubc18\ud654\ub97c \uc81c\ubc95 \uc798 \ud560 \uc218 \uc788\uc744 \uac83\uc785\ub2c8\ub2e4. \uc774 \ub370\uc774\ud130\uc14b\uc740 ImageNet\uc758 \uc544\uc8fc \uc791\uc740 \uc77c\ubd80\uc785\ub2c8\ub2e4. \ucc38\uace0 \ub370\uc774\ud130\ub97c \uc5ec\uae30 \uc5d0\uc11c \ub2e4\uc6b4\ub85c\ub4dc \ubc1b\uc544 \ud604\uc7ac \ub514\ub809\ud1a0\ub9ac\uc5d0 \uc555\ucd95\uc744 \ud478\uc2ed\uc2dc\uc624. # \ud559\uc2b5\uc744 \uc704\ud574 \ub370\uc774\ud130 \uc99d\uac00(augmentation) \ubc0f \uc77c\ubc18\ud654(normalization) # \uac80\uc99d\uc744 \uc704\ud55c \uc77c\ubc18\ud654 data_transforms = { \u0027train\u0027: transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), \u0027val\u0027: transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), } data_dir = \u0027data/hymenoptera_data\u0027 image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in [\u0027train\u0027, \u0027val\u0027]} dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4, shuffle=True, num_workers=4) for x in [\u0027train\u0027, \u0027val\u0027]} dataset_sizes = {x: len(image_datasets[x]) for x in [\u0027train\u0027, \u0027val\u0027]} class_names = image_datasets[\u0027train\u0027].classes # CUDA \ub610\ub294 MPS, MTIA, XPU \uc640 \uac19\uc740 `\uac00\uc18d\uae30(accelerator) \u003chttps://pytorch.org/docs/stable/torch.html#accelerators\u003e`__ \uc5d0\uc11c \ubaa8\ub378\uc744 \ud559\uc2b5\ud560 \uc218 \uc788\ub3c4\ub85d \ud569\ub2c8\ub2e4. # \ud604\uc7ac \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uac00\uc18d\uae30\uac00 \uc788\ub2e4\uba74 \uc0ac\uc6a9\ud558\uace0, \uadf8\ub807\uc9c0 \uc54a\uc73c\uba74 CPU\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4. device = torch.accelerator.current_accelerator().type if torch.accelerator.is_available() else \"cpu\" print(f\"Using {device} device\") Using cuda device \uc77c\ubd80 \uc774\ubbf8\uc9c0 \uc2dc\uac01\ud654\ud558\uae30# \ub370\uc774\ud130 \uc99d\uac00\ub97c \uc774\ud574\ud558\uae30 \uc704\ud574 \uc77c\ubd80 \ud559\uc2b5\uc6a9 \uc774\ubbf8\uc9c0\ub97c \uc2dc\uac01\ud654\ud574\ubcf4\uaca0\uc2b5\ub2c8\ub2e4. def imshow(inp, title=None): \"\"\"tensor\ub97c \uc785\ub825\ubc1b\uc544 \uc77c\ubc18\uc801\uc778 \uc774\ubbf8\uc9c0\ub85c \ubcf4\uc5ec\uc90d\ub2c8\ub2e4.\"\"\" inp = inp.numpy().transpose((1, 2, 0)) mean = np.array([0.485, 0.456, 0.406]) std = np.array([0.229, 0.224, 0.225]) inp = std * inp + mean inp = np.clip(inp, 0, 1) plt.imshow(inp) if title is not None: plt.title(title) plt.pause(0.001) # \uac31\uc2e0\uc774 \ub420 \ub54c\uae4c\uc9c0 \uc7a0\uc2dc \uae30\ub2e4\ub9bd\ub2c8\ub2e4. # \ud559\uc2b5 \ub370\uc774\ud130\uc758 \ubc30\uce58\ub97c \uc5bb\uc2b5\ub2c8\ub2e4. inputs, classes = next(iter(dataloaders[\u0027train\u0027])) # \ubc30\uce58\ub85c\ubd80\ud130 \uaca9\uc790 \ud615\ud0dc\uc758 \uc774\ubbf8\uc9c0\ub97c \ub9cc\ub4ed\ub2c8\ub2e4. out = torchvision.utils.make_grid(inputs) imshow(out, title=[class_names[x] for x in classes]) \ubaa8\ub378 \ud559\uc2b5\ud558\uae30# \uc774\uc81c \ubaa8\ub378\uc744 \ud559\uc2b5\ud558\uae30 \uc704\ud55c \uc77c\ubc18 \ud568\uc218\ub97c \uc791\uc131\ud574\ubcf4\uaca0\uc2b5\ub2c8\ub2e4. \uc5ec\uae30\uc11c\ub294 \ub2e4\uc74c \ub0b4\uc6a9\ub4e4\uc744 \uc124\uba85\ud569\ub2c8\ub2e4: \ud559\uc2b5\ub960(learning rate) \uad00\ub9ac(scheduling) \ucd5c\uc801\uc758 \ubaa8\ub378 \uad6c\ud558\uae30 \uc544\ub798\uc5d0\uc11c scheduler \ub9e4\uac1c\ubcc0\uc218\ub294 torch.optim.lr_scheduler \uc758 LR \uc2a4\ucf00\uc974\ub7ec \uac1d\uccb4(Object)\uc785\ub2c8\ub2e4. def train_model(model, criterion, optimizer, scheduler, num_epochs=25): since = time.time() # Create a temporary directory to save training checkpoints with TemporaryDirectory() as tempdir: best_model_params_path = os.path.join(tempdir, \u0027best_model_params.pt\u0027) torch.save(model.state_dict(), best_model_params_path) best_acc = 0.0 for epoch in range(num_epochs): print(f\u0027Epoch {epoch}/{num_epochs - 1}\u0027) print(\u0027-\u0027 * 10) # \uac01 \uc5d0\ud3ed(epoch)\uc740 \ud559\uc2b5 \ub2e8\uacc4\uc640 \uac80\uc99d \ub2e8\uacc4\ub97c \uac16\uc2b5\ub2c8\ub2e4. for phase in [\u0027train\u0027, \u0027val\u0027]: if phase == \u0027train\u0027: model.train() # \ubaa8\ub378\uc744 \ud559\uc2b5 \ubaa8\ub4dc\ub85c \uc124\uc815 else: model.eval() # \ubaa8\ub378\uc744 \ud3c9\uac00 \ubaa8\ub4dc\ub85c \uc124\uc815 running_loss = 0.0 running_corrects = 0 # \ub370\uc774\ud130\ub97c \ubc18\ubcf5 for inputs, labels in dataloaders[phase]: inputs = inputs.to(device) labels = labels.to(device) # \ub9e4\uac1c\ubcc0\uc218 \uacbd\uc0ac\ub3c4\ub97c 0\uc73c\ub85c \uc124\uc815 optimizer.zero_grad() # \uc21c\uc804\ud30c # \ud559\uc2b5 \uc2dc\uc5d0\ub9cc \uc5f0\uc0b0 \uae30\ub85d\uc744 \ucd94\uc801 with torch.set_grad_enabled(phase == \u0027train\u0027): outputs = model(inputs) _, preds = torch.max(outputs, 1) loss = criterion(outputs, labels) # \ud559\uc2b5 \ub2e8\uacc4\uc778 \uacbd\uc6b0 \uc5ed\uc804\ud30c + \ucd5c\uc801\ud654 if phase == \u0027train\u0027: loss.backward() optimizer.step() # \ud1b5\uacc4 running_loss += loss.item() * inputs.size(0) running_corrects += torch.sum(preds == labels.data) if phase == \u0027train\u0027: scheduler.step() epoch_loss = running_loss / dataset_sizes[phase] epoch_acc = running_corrects.double() / dataset_sizes[phase] print(f\u0027{phase} Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}\u0027) # \ubaa8\ub378\uc744 \uae4a\uc740 \ubcf5\uc0ac(deep copy)\ud568 if phase == \u0027val\u0027 and epoch_acc \u003e best_acc: best_acc = epoch_acc torch.save(model.state_dict(), best_model_params_path) print() time_elapsed = time.time() - since print(f\u0027Training complete in {time_elapsed // 60:.0f}m {time_elapsed % 60:.0f}s\u0027) print(f\u0027Best val Acc: {best_acc:4f}\u0027) # \uac00\uc7a5 \ub098\uc740 \ubaa8\ub378 \uac00\uc911\uce58\ub97c \ubd88\ub7ec\uc624\uae30 model.load_state_dict(torch.load(best_model_params_path, weights_only=True)) return model \ubaa8\ub378 \uc608\uce21\uac12 \uc2dc\uac01\ud654\ud558\uae30# \uc77c\ubd80 \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud55c \uc608\uce21\uac12\uc744 \ubcf4\uc5ec\uc8fc\ub294 \uc77c\ubc18\ud654\ub41c \ud568\uc218\uc785\ub2c8\ub2e4. def visualize_model(model, num_images=6): was_training = model.training model.eval() images_so_far = 0 fig = plt.figure() with torch.no_grad(): for i, (inputs, labels) in enumerate(dataloaders[\u0027val\u0027]): inputs = inputs.to(device) labels = labels.to(device) outputs = model(inputs) _, preds = torch.max(outputs, 1) for j in range(inputs.size()[0]): images_so_far += 1 ax = plt.subplot(num_images//2, 2, images_so_far) ax.axis(\u0027off\u0027) ax.set_title(f\u0027predicted: {class_names[preds[j]]}\u0027) imshow(inputs.cpu().data[j]) if images_so_far == num_images: model.train(mode=was_training) return model.train(mode=was_training) \ud569\uc131\uacf1 \uc2e0\uacbd\ub9dd \ubbf8\uc138\uc870\uc815(finetuning)# \ubbf8\ub9ac \ud559\uc2b5\ud55c \ubaa8\ub378\uc744 \ubd88\ub7ec\uc628 \ud6c4 \ub9c8\uc9c0\ub9c9\uc758 \uc644\uc804\ud788 \uc5f0\uacb0\ub41c \uacc4\uce35\uc744 \ucd08\uae30\ud654\ud569\ub2c8\ub2e4. model_ft = models.resnet18(weights=\u0027IMAGENET1K_V1\u0027) num_ftrs = model_ft.fc.in_features # \uc5ec\uae30\uc11c \uac01 \ucd9c\ub825 \uc0d8\ud50c\uc758 \ud06c\uae30\ub294 2\ub85c \uc124\uc815\ud569\ub2c8\ub2e4. # \ub610\ub294, ``nn.Linear(num_ftrs, len (class_names))`` \ub85c \uc77c\ubc18\ud654\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. model_ft.fc = nn.Linear(num_ftrs, 2) model_ft = model_ft.to(device) criterion = nn.CrossEntropyLoss() # \ubaa8\ub4e0 \ub9e4\uac1c\ubcc0\uc218\ub4e4\uc774 \ucd5c\uc801\ud654\ub418\uc5c8\ub294\uc9c0 \uad00\ucc30 optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9) # 7 \uc5d0\ud3ed\ub9c8\ub2e4 0.1\uc529 \ud559\uc2b5\ub960 \uac10\uc18c exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1) Downloading: \"https://download.pytorch.org/models/resnet18-f37072fd.pth\" to /root/.cache/torch/hub/checkpoints/resnet18-f37072fd.pth 0%| | 0.00/44.7M [00:00\u003c?, ?B/s] 19%|\u2588\u2589 | 8.62M/44.7M [00:00\u003c00:00, 88.9MB/s] 45%|\u2588\u2588\u2588\u2588\u258d | 20.0M/44.7M [00:00\u003c00:00, 105MB/s] 70%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588 | 31.4M/44.7M [00:00\u003c00:00, 111MB/s] 98%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u258a| 43.8M/44.7M [00:00\u003c00:00, 118MB/s] 100%|\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 44.7M/44.7M [00:00\u003c00:00, 112MB/s] \ud559\uc2b5 \ubc0f \ud3c9\uac00\ud558\uae30# CPU\uc5d0\uc11c\ub294 15-25\ubd84 \uac00\ub7c9, GPU\uc5d0\uc11c\ub294 1\ubd84 \uc774\ub0b4\uc758 \uc2dc\uac04\uc774 \uac78\ub9bd\ub2c8\ub2e4. model_ft = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=25) Epoch 0/24 ---------- train Loss: 0.5939 Acc: 0.6885 val Loss: 0.8893 Acc: 0.6993 Epoch 1/24 ---------- train Loss: 0.6983 Acc: 0.7705 val Loss: 0.4179 Acc: 0.8562 Epoch 2/24 ---------- train Loss: 0.6475 Acc: 0.7459 val Loss: 0.4117 Acc: 0.8235 Epoch 3/24 ---------- train Loss: 0.6479 Acc: 0.7172 val Loss: 0.2584 Acc: 0.8824 Epoch 4/24 ---------- train Loss: 0.4011 Acc: 0.8320 val Loss: 0.2526 Acc: 0.9150 Epoch 5/24 ---------- train Loss: 0.4271 Acc: 0.8156 val Loss: 0.4152 Acc: 0.8431 Epoch 6/24 ---------- train Loss: 0.3674 Acc: 0.8525 val Loss: 0.5579 Acc: 0.8235 Epoch 7/24 ---------- train Loss: 0.5191 Acc: 0.8033 val Loss: 0.3694 Acc: 0.9085 Epoch 8/24 ---------- train Loss: 0.3877 Acc: 0.8484 val Loss: 0.3182 Acc: 0.8889 Epoch 9/24 ---------- train Loss: 0.3061 Acc: 0.8689 val Loss: 0.2674 Acc: 0.9085 Epoch 10/24 ---------- train Loss: 0.2626 Acc: 0.8975 val Loss: 0.2540 Acc: 0.9216 Epoch 11/24 ---------- train Loss: 0.2475 Acc: 0.8893 val Loss: 0.2299 Acc: 0.9150 Epoch 12/24 ---------- train Loss: 0.2699 Acc: 0.8934 val Loss: 0.2357 Acc: 0.9346 Epoch 13/24 ---------- train Loss: 0.2592 Acc: 0.8893 val Loss: 0.2183 Acc: 0.9150 Epoch 14/24 ---------- train Loss: 0.2211 Acc: 0.9098 val Loss: 0.2056 Acc: 0.9216 Epoch 15/24 ---------- train Loss: 0.2748 Acc: 0.8730 val Loss: 0.2230 Acc: 0.9281 Epoch 16/24 ---------- train Loss: 0.2723 Acc: 0.8893 val Loss: 0.2201 Acc: 0.9150 Epoch 17/24 ---------- train Loss: 0.2833 Acc: 0.8730 val Loss: 0.2336 Acc: 0.9085 Epoch 18/24 ---------- train Loss: 0.2625 Acc: 0.8852 val Loss: 0.2231 Acc: 0.9216 Epoch 19/24 ---------- train Loss: 0.2774 Acc: 0.8689 val Loss: 0.2051 Acc: 0.9281 Epoch 20/24 ---------- train Loss: 0.2649 Acc: 0.8730 val Loss: 0.2416 Acc: 0.9085 Epoch 21/24 ---------- train Loss: 0.2558 Acc: 0.8811 val Loss: 0.2479 Acc: 0.9085 Epoch 22/24 ---------- train Loss: 0.2218 Acc: 0.9180 val Loss: 0.2061 Acc: 0.9281 Epoch 23/24 ---------- train Loss: 0.2908 Acc: 0.8811 val Loss: 0.2034 Acc: 0.9281 Epoch 24/24 ---------- train Loss: 0.2541 Acc: 0.8852 val Loss: 0.2047 Acc: 0.9346 Training complete in 0m 28s Best val Acc: 0.934641 visualize_model(model_ft) \uace0\uc815\ub41c \ud2b9\uc9d5 \ucd94\ucd9c\uae30\ub85c\uc368\uc758 \ud569\uc131\uacf1 \uc2e0\uacbd\ub9dd# \uc774\uc81c, \ub9c8\uc9c0\ub9c9 \uacc4\uce35\uc744 \uc81c\uc678\ud55c \uc2e0\uacbd\ub9dd\uc758 \ubaa8\ub4e0 \ubd80\ubd84\uc744 \uace0\uc815\ud574\uc57c \ud569\ub2c8\ub2e4. requires_grad = False \ub85c \uc124\uc815\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uace0\uc815\ud558\uc5ec backward() \uc911\uc5d0 \uacbd\uc0ac\ub3c4\uac00 \uacc4\uc0b0\ub418\uc9c0 \uc54a\ub3c4\ub85d \ud574\uc57c\ud569\ub2c8\ub2e4. \uc774\uc5d0 \ub300\ud55c \ubb38\uc11c\ub294 \uc5ec\uae30 \uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. model_conv = torchvision.models.resnet18(weights=\u0027IMAGENET1K_V1\u0027) for param in model_conv.parameters(): param.requires_grad = False # \uc0c8\ub85c \uc0dd\uc131\ub41c \ubaa8\ub4c8\uc758 \ub9e4\uac1c\ubcc0\uc218\ub294 \uae30\ubcf8\uac12\uc774 requires_grad=True \uc784 num_ftrs = model_conv.fc.in_features model_conv.fc = nn.Linear(num_ftrs, 2) model_conv = model_conv.to(device) criterion = nn.CrossEntropyLoss() # \uc774\uc804\uacfc\ub294 \ub2e4\ub974\uac8c \ub9c8\uc9c0\ub9c9 \uacc4\uce35\uc758 \ub9e4\uac1c\ubcc0\uc218\ub4e4\ub9cc \ucd5c\uc801\ud654\ub418\ub294\uc9c0 \uad00\ucc30 optimizer_conv = optim.SGD(model_conv.fc.parameters(), lr=0.001, momentum=0.9) # 7 \uc5d0\ud3ed\ub9c8\ub2e4 0.1\uc529 \ud559\uc2b5\ub960 \uac10\uc18c exp_lr_scheduler = lr_scheduler.StepLR(optimizer_conv, step_size=7, gamma=0.1) \ud559\uc2b5 \ubc0f \ud3c9\uac00\ud558\uae30# CPU\uc5d0\uc11c \uc2e4\ud589\ud558\ub294 \uacbd\uc6b0 \uc774\uc804\uacfc \ube44\uad50\ud588\uc744 \ub54c \uc57d \uc808\ubc18 \uac00\ub7c9\uc758 \uc2dc\uac04\ub9cc\uc774 \uc18c\uc694\ub420 \uac83\uc785\ub2c8\ub2e4. \uc774\ub294 \ub300\ubd80\ubd84\uc758 \uc2e0\uacbd\ub9dd\uc5d0\uc11c \uacbd\uc0ac\ub3c4\ub97c \uacc4\uc0b0\ud560 \ud544\uc694\uac00 \uc5c6\uae30 \ub54c\ubb38\uc785\ub2c8\ub2e4. \ud558\uc9c0\ub9cc, \uc21c\uc804\ud30c\ub294 \uacc4\uc0b0\uc774 \ud544\uc694\ud569\ub2c8\ub2e4. model_conv = train_model(model_conv, criterion, optimizer_conv, exp_lr_scheduler, num_epochs=25) Epoch 0/24 ---------- train Loss: 0.8177 Acc: 0.5574 val Loss: 0.4051 Acc: 0.8170 Epoch 1/24 ---------- train Loss: 0.8206 Acc: 0.7049 val Loss: 0.2138 Acc: 0.9346 Epoch 2/24 ---------- train Loss: 0.5332 Acc: 0.7869 val Loss: 0.2195 Acc: 0.9346 Epoch 3/24 ---------- train Loss: 0.4048 Acc: 0.8238 val Loss: 0.1820 Acc: 0.9477 Epoch 4/24 ---------- train Loss: 0.4770 Acc: 0.7869 val Loss: 0.1642 Acc: 0.9346 Epoch 5/24 ---------- train Loss: 0.6722 Acc: 0.7418 val Loss: 0.1688 Acc: 0.9608 Epoch 6/24 ---------- train Loss: 0.5322 Acc: 0.7869 val Loss: 0.2213 Acc: 0.9150 Epoch 7/24 ---------- train Loss: 0.4525 Acc: 0.8197 val Loss: 0.2171 Acc: 0.9216 Epoch 8/24 ---------- train Loss: 0.4098 Acc: 0.8648 val Loss: 0.1640 Acc: 0.9542 Epoch 9/24 ---------- train Loss: 0.3833 Acc: 0.8566 val Loss: 0.1604 Acc: 0.9608 Epoch 10/24 ---------- train Loss: 0.4098 Acc: 0.8074 val Loss: 0.1924 Acc: 0.9412 Epoch 11/24 ---------- train Loss: 0.3515 Acc: 0.8566 val Loss: 0.1576 Acc: 0.9608 Epoch 12/24 ---------- train Loss: 0.4229 Acc: 0.8033 val Loss: 0.1597 Acc: 0.9673 Epoch 13/24 ---------- train Loss: 0.2507 Acc: 0.9016 val Loss: 0.1785 Acc: 0.9542 Epoch 14/24 ---------- train Loss: 0.3376 Acc: 0.8648 val Loss: 0.2217 Acc: 0.9412 Epoch 15/24 ---------- train Loss: 0.3572 Acc: 0.8770 val Loss: 0.1593 Acc: 0.9542 Epoch 16/24 ---------- train Loss: 0.2928 Acc: 0.8443 val Loss: 0.1557 Acc: 0.9608 Epoch 17/24 ---------- train Loss: 0.4276 Acc: 0.7951 val Loss: 0.1593 Acc: 0.9608 Epoch 18/24 ---------- train Loss: 0.3870 Acc: 0.8361 val Loss: 0.1854 Acc: 0.9542 Epoch 19/24 ---------- train Loss: 0.2849 Acc: 0.8770 val Loss: 0.1601 Acc: 0.9542 Epoch 20/24 ---------- train Loss: 0.3713 Acc: 0.8402 val Loss: 0.1900 Acc: 0.9346 Epoch 21/24 ---------- train Loss: 0.4344 Acc: 0.7951 val Loss: 0.1784 Acc: 0.9542 Epoch 22/24 ---------- train Loss: 0.3614 Acc: 0.8279 val Loss: 0.1841 Acc: 0.9608 Epoch 23/24 ---------- train Loss: 0.2707 Acc: 0.8811 val Loss: 0.1838 Acc: 0.9608 Epoch 24/24 ---------- train Loss: 0.2565 Acc: 0.9016 val Loss: 0.1494 Acc: 0.9608 Training complete in 0m 19s Best val Acc: 0.967320 visualize_model(model_conv) plt.ioff() plt.show() \ub2e4\ub978 \uc774\ubbf8\uc9c0\ub4e4\uc5d0 \ub300\ud55c \ucd94\ub860# \ud559\uc2b5\ub41c \ubaa8\ub378\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud574 \uc608\uce21\ud558\uace0, \uc608\uce21\ub41c \ud074\ub798\uc2a4 \ub808\uc774\ube14\uc744 \uc774\ubbf8\uc9c0\uc640 \ud568\uaed8 \uc2dc\uac01\ud654\ud569\ub2c8\ub2e4. def visualize_model_predictions(model,img_path): was_training = model.training model.eval() img = Image.open(img_path) img = data_transforms[\u0027val\u0027](img) img = img.unsqueeze(0) img = img.to(device) with torch.no_grad(): outputs = model(img) _, preds = torch.max(outputs, 1) ax = plt.subplot(2,2,1) ax.axis(\u0027off\u0027) ax.set_title(f\u0027Predicted: {class_names[preds[0]]}\u0027) imshow(img.cpu().data[0]) model.train(mode=was_training) visualize_model_predictions( model_conv, img_path=\u0027data/hymenoptera_data/val/bees/72100438_73de9f17af.jpg\u0027 ) plt.ioff() plt.show() \ub354 \ubc30\uc6cc\ubcfc \ub0b4\uc6a9# \uc804\uc774\ud559\uc2b5\uc758 \uc751\uc6a9 \uc0ac\ub840(application)\ub4e4\uc744 \ub354 \uc54c\uc544\ubcf4\ub824\uba74, /intermediate/quantized_transfer_learning_tutorial \uc744 \ucc38\uc870\ud574\ubcf4\uc138\uc694. Total running time of the script: (0 minutes 54.560 seconds) Download Jupyter notebook: transfer_learning_tutorial.ipynb Download Python source code: transfer_learning_tutorial.py Download zipped: transfer_learning_tutorial.zip",
"author": {
"@type": "Organization",
"name": "PyTorch Contributors",
"url": "https://pytorch.org"
},
"image": "../_static/img/pytorch_seo.png",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "/beginner/transfer_learning_tutorial.html"
},
"datePublished": "2023-01-01T00:00:00Z",
"dateModified": "2023-01-01T00:00:00Z"
}
| article:modified_time | 2022-11-30T07:09:41+00:00 |
| og:type | article |
| og:site_name | PyTorch Tutorials KR |
| og:image | ../_static/img/pytorch_seo.png |
| og:image:alt | PyTorch Tutorials KR |
| og:ignore_canonical | true |
| docsearch:language | ko |
| docbuild:last-update | 2022년 11월 30일 |
| None | 2 |
| pytorch_project | tutorials |
Links:
Viewport: width=device-width, initial-scale=1