본문 바로가기

AI studying/TIL

deep learning & pytorch

파이토치 기초

역전파 흐름 w/ 예제

활성화 함수 모듈화로 구현

등등 정리 예정

 

파이토치 공식문서 주석달기 미션 수행

 

1. Data load

 

'''이미지 랜덤으로 크기 조절 및 자르고, 텐서변환'''
data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'val': 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 = '/content/hymenoptera_data'
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
                                          data_transforms[x])
                  for x in ['train', 'val']}  # 이미지 데이터셋 생성
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
                                             shuffle=True, num_workers=4)
              for x in ['train', 'val']}  # 데이터 로더 생성
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}

class_names = image_datasets['train'].classes  # 클래스 이름 설정


'''장치 설정 (CUDA 사용 가능시 GPU 사용, 그렇지 않으면 CPU 사용)'''
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

 

2. Visualize few images

'''Tensor 이미지를 화면에 표시하는 함수'''
def imshow(inp, title=None):
    # Tensor를 numpy 배열로 변환 및 정규화
    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)

# 훈련 데이터에서 배치 하나를 가져옴
inputs, classes = next(iter(dataloaders['train']))

# 배치에서 그리드 형태로 이미지 생성
out = torchvision.utils.make_grid(inputs)

# 이미지 화면에 표시
imshow(out, title=[class_names[x] for x in classes])

 

3. Train model

 

'''모델 훈련 함수 정의'''
def train_model(model, criterion, optimizer, scheduler, num_epochs=25):
    since = time.time()  # 시작 시간 기록

    # 훈련 체크포인트를 저장할 임시 디렉터리 생성
    with TemporaryDirectory() as tempdir:
        best_model_params_path = os.path.join(tempdir, 'best_model_params.pt')

        torch.save(model.state_dict(), best_model_params_path)  # 모델 초기 가중치 저장
        best_acc = 0.0  # 최고 정확도 초기화

        for epoch in range(num_epochs):  # 각 epoch에 대해 반복
            print(f'Epoch {epoch}/{num_epochs - 1}')  # 현재 epoch 출력
            print('-' * 10)

            # 각 epoch는 훈련 및 검증 단계로 구성
            for phase in ['train', 'val']:
                if phase == 'train':
                    model.train()  # 모델을 훈련 모드로 설정
                else:
                    model.eval()   # 모델을 평가 모드로 설정

                running_loss = 0.0  # 누적 손실 초기화
                running_corrects = 0  # 누적 정확도 초기화

                # 데이터 반복
                for inputs, labels in dataloaders[phase]:
                    inputs = inputs.to(device)  # 입력 데이터를 GPU로 이동
                    labels = labels.to(device)  # 라벨 데이터를 GPU로 이동

                    # 매개변수 경사 초기화
                    optimizer.zero_grad()

                    # forward
                    # train 단계에서만 연산 기록 추적
                    with torch.set_grad_enabled(phase == 'train'):
                        outputs = model(inputs)  # 모델의 예측값 계산
                        _, preds = torch.max(outputs, 1)  # 예측된 클래스 추출
                        loss = criterion(outputs, labels)  # 손실 계산

                        # train 단계에서만 역전파 및 최적화
                        if phase == 'train':
                            loss.backward()  # 역전파를 통해 그라디언트 계산
                            optimizer.step()  # 옵티마이저 업데이트

                    # 통계
                    running_loss += loss.item() * inputs.size(0)  # 손실 누적
                    running_corrects += torch.sum(preds == labels.data)  # 정확도 누적

                if phase == 'train':
                    scheduler.step()  # 학습률 스케줄러 업데이트

                epoch_loss = running_loss / dataset_sizes[phase]  # epoch 손실 계산
                epoch_acc = running_corrects.double() / dataset_sizes[phase]  # epoch 정확도 계산

                print(f'{phase} Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}')  # 손실과 정확도 출력

                # 최적 모델 복사
                if phase == 'val' and epoch_acc > best_acc:
                    best_acc = epoch_acc  # 최고 정확도 업데이트
                    torch.save(model.state_dict(), best_model_params_path)  # 모델 가중치 저장

            print()  # 줄바꿈

        time_elapsed = time.time() - since  # 전체 훈련 시간 계산
        print(f'Training complete in {time_elapsed // 60:.0f}m {time_elapsed % 60:.0f}s')  # 훈련 시간 출력
        print(f'Best val Acc: {best_acc:4f}')  # 최고 검증 정확도 출력

        # 최적 모델 가중치 로드
        model.load_state_dict(torch.load(best_model_params_path))
    return model  # 최적 모델 반환

 

4. Visualizing predictions

 

'''모델 예측 시각화 함수 정의'''
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['val']):  # 검증 데이터 로더에서 데이터 가져오기
            inputs = inputs.to(device)  # 입력 데이터를 GPU로 이동
            labels = labels.to(device)  # 라벨 데이터를 GPU로 이동

            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('off')  # 축 제거
                ax.set_title(f'predicted: {class_names[preds[j]]}')  # 예측된 클래스 타이틀 설정
                imshow(inputs.cpu().data[j])  # 이미지를 시각화

                if images_so_far == num_images:  # 시각화할 이미지 수에 도달하면
                    model.train(mode=was_training)  # 원래의 훈련 상태로 복구
                    return  # 함수 종료
        model.train(mode=was_training)  # 원래의 훈련 상태로 복구

 ... 복습 후 업로드 하기

'AI studying > TIL' 카테고리의 다른 글

ML regression wrap-up report  (0) 2024.07.25
AI_lab 중간 회고!  (0) 2024.07.16
[ML] Classification 정리  (0) 2024.06.05
코딩테스트 공부하기  (0) 2024.05.21
Python EDA  (1) 2024.05.01