수업내용 정리

[인공지능 응용] loss값을 동적으로 조절하기

Honey Badger 2023. 5. 12. 14:18

테스트 코드


#Pretrained NN이 항상 1이 나오도록 학습시킨다.
#Gound Truth를 1로 넣어주고 학습 시킨 후 모델 저장, 이후 test 해보면 1에 가까운 값이 나온다.
#하지만 1을 넘기는 값이 나오는 문제가 발생.



import torch

import torch.nn as nn
import torchvision.models as models
from torch.autograd import Variable
from torchsummary import summary

from tensorboardX import SummaryWriter

#cuda로 보낸다
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')


print('========VGG 테스트 =========')
print("========입력데이터 생성 [batch, color, image x, image y]=========")
#이미지 사이즈를 어떻게 잡아도 vgg는 다 소화한다.




#1) 텐서보드 생성
tf_summary = SummaryWriter()



#==========================================
#1) 모델 생성
model = models.vgg16(pretrained=True).to(device)


print(model)
print('========= Summary로 보기 =========')
#Summary 때문에 cuda, cpu 맞추어야 함
#뒤에 값이 들어갔을 때 내부 변환 상황을 보여줌
#adaptive average pool이 중간에서 최종값을 바꿔주고 있음
summary(model, (3, 100, 100))


print("========model weight 값 측정=========")
'''
for name, param in model.named_parameters():
    if param.requires_grad:
        print (name, param.data)
'''



#2) loss function
#꼭 아래와 같이 2단계, 클래스 선언 후, 사용
criterion = nn.MSELoss()

#3) activation function
learning_rate = 1e-2
#learning_rate = 0.001  #이렇게 하면 부동 소수점 에러
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

#========================================
#learning rate 조절 시
decay_epoch = [10, 20]
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=decay_epoch, gamma=0.1)
#========================================

#모델이 학습 모드라고 알려줌
model.train()

#----------------------------
#epoch training
for i in range (50):

    #옵티마이저 초기화
    optimizer.zero_grad()

    #입력값 생성하고
    a = torch.randn(12,3,100,100).to(device)

    #모델에 넣은다음
    result = model(a)

    #결과와 동일한 shape을 가진 Ground-Truth 를 읽어서
    #target  = torch.randn_like(result)

    #타겟값을 1로 바꾸어서 네트워크가 무조건 1만 출력하도록 만든다.
    target  = torch.ones_like(result)



    #네트워크값과의 차이를 비교
    loss = criterion(result, target).to(device)

    #=============================
    #loss는 텐서이므로 item()
    print("epoch: {} loss:{} ".format(i, loss.item()))




    # 2) 텐서보드 값 입력
    tf_summary.add_scalar('loss/loss_a', loss.item(), i)





    #loss diff값을 뒤로 보내서 grad에 저장하고
    loss.backward()

    #저장된 grad값을 기준으로 activation func을 적용한다.
    optimizer.step()

    #=============================
    for param_group in optimizer.param_groups:
        print(param_group['lr'])
        tf_summary.add_scalar('learning_rate', param_group['lr'], i)

    scheduler.step()

    #=============================



#3) 텐서보드 꼭 닫기
tf_summary.close()




print("=========== 학습된 파라미터만 저장 ==============")
torch.save(model.state_dict(), 'trained_model.pt')


print("=========== 전체모델 저장 : VGG 처럼 모델 전체 저장==============")
torch.save(model, 'trained_model_all.pt')

 

 

learning late는 위와 같이 동적으로 조절해주는 것이 일반적이다.