You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
모델을 이용할 때마다 학습시키는 것 보다, 학습 된 모델을 불러와서 이용하는게 더 시간적으로 좋기 때문!
2. Pretrained model 이용 방법
<기존 방법>
(1) CNN 모델의 구조를 미리 만들어 둔다.
(2) 그 구조를 변수에 담는다.
(3) 변수(모델)에 Train 데이터를 통해 학습시킨다.
<Pretrained 된 모델 불러와서 이용하기>
(1) (이용할 Pretrained 모델과 동일한) CNN 모델의 구조를 미리 만들어 둔다.
(2) 그 구조를 변수에 담는다.
(3) 변수(모델)에 Pretrained 모델을 불러온다.
Pretrained 모델을 이용하는 것은 미리 학습 된 모델을 이용하는 것이다. 즉, '모델에 Train 데이터로 학습 시키는 과정을 생략하는 것'이다.
3. CNN 모델 구성하기
(1) Input
나의 이미지
(2) CNN 레이어
1) Layer 1
Convolution
ReLU
MaxPool
2) Layer 2
Convolution
ReLU
MaxPool
3) FC Layer (Fully-Connected Layer)
view (FC를 위한 작업)
FC1
ReLU
FC2
(3) Cross Entropy Loss
SoftMax
NLL loss
4. 구성한 CNN 모델 코드로 작성해 보기
# 1. Input Image : 3 * 64 * 128 (RGB 3채널 * Height * Width)# 2. Layer 1Convolutionlayer= (in_c=3, out_c=6, kernel_size=5, stride=1) # RGB의 3 채널을 받아서, output은 6채널로!MaxPoollayer= (kernel_size=2, stride=2)
# 3. Layer 2Convolutionlayer= (in_c=6, out_c=16, kernel_size=5, stride=1) # 6 채널을 받아서, output은 16채널로!MaxPoollayer= (kernel_size=2, stride=2)
# 4. FC Layerview# Layer 2 까지 거친 output은 [16, 13, 29] 이다. FC를 이용하기 전에 직선으로 펼치기 위해 batch_size * [16, 13, 29]를 한다. => batch_size * [6032]Fully_Connectlayer# input으로 6032를 받아서, output은 120으로!Fully_Connectlayer# input으로 120을 받아서, output은 2로! Grey인지 Red인지 구분하는 Binary classification이기 때문이다.
5. 전체 코드 작성해보기
# 1. 라이브러리 로드importtorchimporttorch.nnasnnimporttorch.nn.functionalasFimporttorcdh.optimasoptimfromtorch.utils.dataimportDataLoaderimporttorchvisionimporttorchvision.transformastransforms# 2. GPU 사용 설정device='cuda'iftorch.cuda.is_available() els'cpu'torch.manual_seed(777) # 랜덤 값 Seed 고정ifdevice=='cuda':
torch.cuda.manual_seed_all(777)
# 3. 데이터 로드trans=transforms.Compose([
transforms.ToTensor() # 불러올 때 Tensor로 바꿔서 불러옴
])
train_data=torch.vision.datasets.ImageFolder(root='./custom_data/train_data', transform=trans) # 지난 시간에 만들어 둔 train_data!data_loader=DataLoader(dataset=train_data, batch_size=8, shuffle=True, num_workers=2) # Data Loader 설정# 4. CNN 모델 만들어 놓기classCNN(nn.Module):
def__init_(self):
super(CNN, self).__init()
# Layer 1self.layer1=nn.Sequential(
nn.Conv2d(3, 6, 5), # RGB 3채널 입력, 6채널 출력, 필터 5nn.ReLU(),
nn.MaxPool2d(2),
)
# Layer 2self.layer2=nn.Sequential(
nn.Conv2d(6, 16, 5), # 6채널 입력, 16채널 출력, 필터 5nn.ReLU(),
nn.MaxPool2d(2),
)
# FC Layerself.layer3=nn.Sequential(
nn.Linear(16*13*29, 120), # FC1nn.ReLU(),
nn.Linear(120, 2) # FC2
)
# 모델의 forward 정의defforward(self, x):
out=self.layer1(x) # Layer 1 통과# print(out.shape) # 꿀팁! 이런 방식으로 모델이 forward할 때 점차 바뀌는 output의 shape을 체크할 수 있다. 나중에 추가적으로 모델의 레이어 구조 등을 변형하고 싶을 때 이 방법이 유용하다. 이 코드로 shape만 확인하고 바로 꼭 지워주는 센스! out=self.layer2(out) # Layer 2 통과# print(out.shape)out=out.view(out.shape[0], -1) # Flatten으로 펼치기# print(out.shape)out=self.layer3(out) # FC1 & FC 2 통과returnout# (생략 가능) 5. CNN 모델을 오류 없이 만들었는지 테스트 해보기net=CNN().to(device)
test_input= (torch.Tensor(3, 3, 64, 128)).to(device)
test_out=net(test_input)
# 6. Optimizer와 Loss 설정optimizer=optim.Adam(net.parameters(), lr=0.00005)
loss_func=nn.CrossEntropyLoss().to(device)
total_batch=len(data_loader)
epochs=7# 7. 모델 학습 시작!forepochinrange(epochs):
avg_cost=0.0fornum, datainenumerate(data_loader):
imgs, labels=dataimgs=imgs.to(device) # 독립 변수labels=labels.to(device) # 종속 변수out=net(imgs) # 모델에 독립 변수를 넣어 Prediction 얻기loss=loss_func(out, labels)
# BPoptimizer.zero_grad()
loss.backward()
optimizer.step()
avg_cost+=loss/total_batchprint('[Epoch:{}] cost = {}'.format(epoch+1, avg_cost))
print('Learning Finished!')
# 8. 학습된 CNN 모델 저장하기torch.save(net.state_dict(), "./model/model.pth") # 경로를 지정해서 학습된 모델 저장# 9. Pretrained 된 CNN 모델 : 불러와서 이용하기'''<기존 방법> (1) CNN 모델의 구조를 미리 만들어 둔다. (2) 그 구조를 변수에 담는다. (3) 변수(모델)에 Train 데이터를 통해 학습시킨다.<Pretrained 된 모델 불러와서 이용하기> (1) (이용할 Pretrained 모델과 동일한) CNN 모델의 구조를 미리 만들어 둔다. (2) 그 구조를 변수에 담는다. (3) 변수(모델)에 Pretrained 모델을 불러온다. - Pretrained 모델을 이용하는 것은 미리 학습 된 모델을 이용하는 것이다. 즉, '모델에 Train 데이터로 학습 시키는 과정을 생략하는 것'이다.'''new_net=CNN().to(device) # 이용할 Pretrained 모델과 동일한 구조를 가진 모델!new_net.load_state_dict(torch.load('./model/model.pth')) # 거기에 Pretrained 모델을 담는다.# (생략 가능) 10. Pretrainted 된 CNN 모델 : 구조 확인print(net.layer1[0])
print(new_net.layer1[0])
print(net.layer1[0].weight[0][0][0])
print(new_net.layer1[0].weight[0][0][0])
net.layer1[0].weight[0] ==new_net.layer1[0].weight[0]
# 11. Pretrained 된 CNN 모델 : 테스트 데이터 로드 (기존과 동일)trans=torchvision.transforms.Compose([
transforms.Resize((64, 128))
transforms.ToTensor()
])
test_data=torchvision.datasets.ImageFolder(root='./custom_data/test_data', transform=trans) # test data 로드test_set=DataLoader(dataset=test_data, batch_size=len(test_data)) # DataLoader 이용!# 12. Pretrainted 된 CNN 모델 : 모델 평가 (기존과 동일)withtorch.no_grad(): # 모델 평가시에는 Gradient Descent 안함!fornum, datainenumerate(test_set):
imgs, label=dataimgs=imgs.to(device)
label=label.to(device)
prediction=net(imgs)
correct_prediction=torch.argmax(prediction, 1) ==labelaccuracy=correct_prediction.float().mean()
print('Accuracy:', accuracy.item())