pytorch - flatten과 averaging pooling, training 방법 기본기, layer 구성법

1. flatten vs. average pooling

 

flatten은 feature map을 벡터로 적절한 순서대로 쌓고

 

import torch

t = torch.tensor([[[1,2],
                   [3,4]],
                  [[5, 6],
                   [7,8]]])

print(torch.flatten(t))
tensor([1, 2, 3, 4, 5, 6, 7, 8])

print(torch.flatten(t, start_dim = 1))
tensor([[1, 2, 3, 4],
        [5, 6, 7, 8]])

 

feature map이 [1,2,3,4]랑 [5,6,7,8]인데 이 둘을 2가지 방식으로 flatten시켰다?

 

이건 그림 안그려봐도 결과 코드가 이해가 될듯..

 

[1,2,3,4]랑 [5,6,7,8]을 적절하게 쌓았네

 

------------------------------------------------------------------------------------------------------------------------------------------

 

adaptive average pooling은 채널 정보는 남기고 공간 정보만 압축한다고?

 

m = torch.nn.AdaptiveAvgPool2d((2,3))

input = torch.randn(1, 64, 8, 9)

output = m(input)


print(input.shape)
torch.Size([1, 64, 8, 9])

print(output.shape)
torch.Size([1, 64, 2, 3])

 

 

공간 정보만 압축된다는거 보임?

 

근데 pooling 자체가 뭔지 생각해보면

 

 

 

공간정보라는게 위처럼 spatial map을 압축시킨다는 의미

 

이러면 이해가 되는구만

 

채널은 위 그림에서 1채널로 그대로지만

 

 

2. layer 구성하기

 

layer를 구성할때는 input, output 채널의 크기, size, shape등을 항상 고려하고 있어야한다.

 

에러가 난다면.. print를 찍어보면서 이런 부분들이 문제가 아닌지 확인해봐야함

 

 

 

3. model 훈련하는 방법 기본기

 

optimizer.zero_grad()로 optimizer에 loss의 gradient가 쌓이는데 먼저 zero로 초기화시켜야한다

 

나중에 또 언급하겠지만 backward할때는 스칼라인 loss를 먼저 계산하고 loss에 backward해야한다.

 

그러면 이제 알아서 loss에 대한 함수로부터 미분 시킨거 구해줄거

 

optimizer.step()으로 optimizer를 업데이트해나간다

 

tensor를 gpu tensor로 만드는 방법은 .cuda()

 

tensor의 유형을 변경하는 방법으로 .float(), .long() 등등

 

정확도 계산에서 pred_label == label이라는 boolean tensor를 이용한다는 점을 기억하면 좋을 것 같다

 

#optimizer에 저장된 미분값을 0으로 초기화
optimizer.zero_grad()

#GPU 연산을 위해 이미지와 정답 tensor를 GPU로 보내기
#필요한 경우 타입 변환이 필요
img, label = img.float().cuda(), label.long().cuda()
#img.label = map(lambda t: t.cuda(), (img.float(),label))

#모델에 이미지를 forward
pred_logit = model(img)

#loss 계산
loss = criterion(pred_logit, label)

#loss를 계산하고, backward
#backprpagation
loss.backward()
optimizer.step()

#accuracy 계산
pred_label = torch.argmax(pred_logit, 1)
acc = (pred_label == label).sum().item() / len(img)

 

추가로 나중에 또 언급하겠지만 pred_logit=model(img) 같은 경우 model의 forward pass를 파악하는 것이 중요한데

 

이 경우 forward 함수가 list에 값을 넣은 것을 반환하지 않아서 pred_logit=model(img)[0] 이게 아니고 pred_logit=model(img) 이것을 쓰는게 맞다

 

그러니까 forward 함수를 잘 보고... 어디를 반환해야하는지 잘 보라는

 

 

 

validation에서는 불필요한 gradient를 계산하지 않기 위해 with torch.no_grad():로 걸어준다

 

경험상 반드시 해주는게 좋다..

 

 

pre train된 모형으로 fine-tuning하는 것이 보통 성능이 좋다

 

pre train한 모형을 쓰지 않고 직접 훈련 시킨 경우 validation acc를 보면 0.17~0.37

 

 

pre train한 모형을 사용하면 0.58까지도 올라간다

 

 

TAGS.

Comments