python

[python] github .py 파일 실행해보기 (train.py, utils.py)

독립성이 강한 ISFP 2024. 9. 10. 11:46
728x90
반응형

 

터미널에서 CUDA_VISIBLE_DEVICES=0 python train.py 실행

 

실행하기 전, 경로 설정을 해줘야 함. 

필요한 파일들을 동일한 경로에 넣기.

train.py 파일을 수정해서 현재 경로에 데이터셋이 잘 다운로드 될 수 있도록 설정하기.

 

https://github.com/facebookresearch/mixup-cifar10/blob/main/train.py

 

mixup-cifar10/train.py at main · facebookresearch/mixup-cifar10

mixup: Beyond Empirical Risk Minimization. Contribute to facebookresearch/mixup-cifar10 development by creating an account on GitHub.

github.com

 

 


스크립트 설정 및 라이선스 정보

#!/usr/bin/env python3 -u
# Copyright (c) 2017-present, Facebook, Inc.
# All rights reserved.
# This source code is licensed under the license found in the LICENSE file in
# the root directory of this source tree.

#!/usr/bin/env python3 -u: 이 줄은 스크립트가 실행될 Python 인터프리터를 지정합니다. -u 옵션은 출력 버퍼링을 비활성화하여 즉시 터미널에 결과가 출력되도록 합니다. 주로 실시간 로그를 보고자 할 때 사용됩니다.

저작권 및 라이선스 정보: 이 코드는 Facebook에서 작성되었으며, 저작권이 그들에게 있음을 명시합니다. 해당 코드는 LICENSE 파일에 있는 조건에 따라 사용할 수 있습니다. 이는 코드를 사용할 때 라이선스 조건을 확인하고 따라야 한다는 의미입니다.


필요한 라이브러리 불러오기

from __future__ import print_function
import argparse
import csv
import os
import numpy as np
import torch
from torch.autograd import Variable
import torch.backends.cudnn as cudnn
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import models
from utils import progress_bar

 

from __future__ import print_function: Python 2와 Python 3의 호환성을 보장하기 위한 구문으로, Python 3의 print() 함수를 Python 2에서도 사용할 수 있게 합니다.

필요한 모듈 불러오기: 다양한 라이브러리를 불러옵니다.

argparse: 명령행에서 인자를 받아올 수 있도록 하는 모듈.

csv: CSV 파일을 읽고 쓰기 위한 모듈.

os: 운영체제와 상호작용하는 기능을 제공.

numpy: 과학 연산을 위한 배열 처리 라이브러리.

torch, torch.nn, torch.optim: PyTorch 라이브러리로, 신경망 구성과 학습에 필요한 모듈.

torchvision: 이미지 처리에 필요한 데이터셋 및 변환 도구.

models: 모델 아키텍처를 불러오는 모듈 

utils: progress_bar 함수를 불러와 학습 진행 상황을 출력하기 위해 사용합니다.


명령행 인자 설정

parser = argparse.ArgumentParser(description='PyTorch CIFAR10 Training')
parser.add_argument('--lr', default=0.1, type=float, help='learning rate')
parser.add_argument('--resume', '-r', action='store_true', help='resume from checkpoint')
parser.add_argument('--model', default="ResNet18", type=str, help='model type (default: ResNet18)')
parser.add_argument('--name', default='0', type=str, help='name of run')
parser.add_argument('--seed', default=0, type=int, help='random seed')
parser.add_argument('--batch-size', default=128, type=int, help='batch size')
parser.add_argument('--epoch', default=200, type=int, help='total epochs to run')
parser.add_argument('--no-augment', dest='augment', action='store_false', help='use standard augmentation (default: True)')
parser.add_argument('--decay', default=1e-4, type=float, help='weight decay')
parser.add_argument('--alpha', default=1., type=float,
help='mixup interpolation coefficient (default: 1)')
args = parser.parse_args()

 

명령행 인자 설정: argparse 모듈을 이용해 학습 실행 시 다양한 하이퍼파라미터를 명령행에서 받을 수 있게 설정합니다.

--lr: 학습률을 설정합니다 (기본값: 0.1).

--resume: 체크포인트에서 학습을 이어받을지 여부를 설정 (기본값: False).

--model: 사용할 모델의 이름을 지정합니다 (기본값: ResNet18).

--name: 실행의 이름을 지정합니다 (기본값: “0”).

--seed: 랜덤 시드를 설정하여 재현 가능한 학습을 보장합니다 (기본값: 0).

--batch-size: 배치 크기를 설정합니다 (기본값: 128).

--epoch: 학습할 에포크 수를 설정합니다 (기본값: 200).

--no-augment: 데이터 증강을 사용할지 여부를 결정합니다.

--decay: 가중치 감소를 설정합니다 (기본값: 1e-4).

--alpha: Mixup 기법에서 사용할 보간 계수를 설정합니다.


CUDA 사용 여부 및 학습 관련 변수 설정

use_cuda = torch.cuda.is_available()
best_acc = 0 # best test accuracy
tart_epoch = 0 # start from epoch 0 or last checkpoint epoch

if args.seed != 0:
    torch.manual_seed(args.seed)
 

use_cuda: 현재 시스템에서 CUDA(GPU)가 사용 가능한지 여부를 확인하고, 사용 가능하면 True로 설정합니다.

best_acc: 테스트 정확도를 기록하는 변수로, 최고 성능을 기록합니다.

start_epoch: 학습을 몇 번째 에포크에서 시작할지를 나타냅니다. 처음 시작할 때는 0부터 시작합니다.

• args.seed: 랜덤 시드 값을 설정하여 학습 결과의 재현성을 보장


Data

데이터 준비 및 데이터 로더 설정

데이터 증강 설정

if args.augment:
    transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])
else:  
    transform_train = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])

 

테스트 데이터 변환

transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])

 

데이터셋과 데이터로더 설정

trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=args.batch_size, shuffle=True, num_workers=8)
testset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=8)

Model

1. if args.resume:

체크포인트에서 학습을 재개하는 경우입니다. 이 코드는 사용자가 --resume 플래그를 전달했을 때 작동합니다.

if args.resume:
    # Load checkpoint.
    print('==> Resuming from checkpoint..')
    assert os.path.isdir('checkpoint'), 'Error: no checkpoint directory found!'
    checkpoint = torch.load('./checkpoint/ckpt.t7' + args.name + '_' + str(args.seed))

    net = checkpoint['net']
    best_acc = checkpoint['acc']
    start_epoch = checkpoint['epoch'] + 1
    rng_state = checkpoint['rng_state']
    torch.set_rng_state(rng_state)


torch.load: 이전 학습에서 저장된 모델 상태를 불러옵니다.

checkpoint[‘net’]: 저장된 모델을 불러오고, 이 모델을 현재 모델로 설정합니다.

best_acc: 이전 학습에서의 최고 정확도를 불러옵니다.

start_epoch: 이전 학습이 끝난 시점에서 다음 에포크부터 학습을 재개합니다.

rng_state: 이전 학습 시점의 난수 발생기를 복원합니다.

2. else: 모델 생성

체크포인트에서 시작하지 않는 경우, 새로운 모델을 생성하는 부분입니다.

else
    print('==> Building model..')
    net = models.__dict__[args.model]()

 

디렉토리 및 로그 설정 부분

3. 로그 및 결과 저장 폴더 설정

결과를 저장할 디렉토리를 만들고, 학습 로그를 저장할 파일 경로를 정의합니다.

if not os.path.isdir('results'):  
    os.mkdir('results')
    logname = ('results/log_' + net.__class__.__name__ + '_' + args.name + '_' + str(args.seed) + '.csv')

 

checkpoint 파일은 모델의 가중치와 상태를 저장하는 파일이고, results 파일은 학습 중 발생한 성능 지표를 기록한 로그 파일

 

GPU 설정

if use_cuda:  
    net.cuda() # CUDA가 사용 가능한지 확인하고, 가능하다면 모델을 GPU로 이동
    net = torch.nn.DataParallel(net) # 모델을 병렬적으로 여러 GPU에서 학습할 수 있게 설정
    print(torch.cuda.device_count()) # 사용 가능한 GPU의 수를 출력
    cudnn.benchmark = True # CUDA에서의 연산 성능을 최적화
    print('Using CUDA..')

 

손실함수 설정

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=args.lr, momentum=0.9, weight_decay=args.decay)


Mixup 데이터 및 손실 함수 정의

def mixup_data(x, y, alpha=1.0, use_cuda=True):
    if alpha > 0
        lam = np.random.beta(alpha, alpha)
    else:  
        lam = 1
   
    batch_size = x.size()[0]
    if use_cuda:
        index = torch.randperm(batch_size).cuda()
    else:
        index = torch.randperm(batch_size)


    mixed_x = lam * x + (
1 - lam) * x[index, :]
    y_a, y_b = y, y[index]
    return mixed_x, y_a, y_b, lam

 

1. mixup_data 함수

목적: Mixup 기법을 사용하여 입력 데이터와 레이블을 섞어서 새로운 학습 데이터를 생성합니다. Mixup은 두 개의 샘플을 선형 결합하여 모델의 일반화 성능을 높이는 기법입니다.

세부 설명:

Alpha 값 설정: alpha 값이 0보다 크면 Beta 분포를 사용해 섞이는 정도인 lam 값을 설정합니다. 그렇지 않으면 lam을 1로 설정합니다.

데이터 인덱스 섞기: torch.randperm을 사용해 배치 사이즈만큼 무작위로 섞인 인덱스를 생성하고, 해당 인덱스를 사용해 데이터를 섞습니다. use_cuda가 True면 GPU에서 연산이 진행됩니다.

섞인 데이터 생성: lam * x + (1 - lam) * x[index, :] 연산을 통해 두 샘플을 lam에 따라 섞은 데이터를 생성합니다.

레이블도 함께 섞음: 레이블도 동일한 방식으로 섞여 두 레이블을 y_ay_b로 반환합니다.

def mixup_criterion(criterion, pred, y_a, y_b, lam):    
    return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)
 

2. mixup_criterion 함수:

 

목적: 섞인 데이터를 기반으로 손실을 계산합니다.

세부 설명:

두 레이블 y_a, y_b에 대해 각각 예측 결과 pred과의 손실을 계산하고, lam1-lam으로 가중합을 적용해 최종 손실 값을 반환합니다.

 

728x90
반응형