pytorch --> c code 변환 (SSD Network) - 학습 검증 issue

2023. 1. 13. 15:34GPU

python과 pytorch library로 동작하는 SSD를 low level 구현을 위해 c로 작성했다.

연산 검증까지 마무리 된 상태에서 학습이 잘 되는지를 확인하기 위한 검증 단계에 있는데 문제가 발생했다.

초반 iteration에서 loss가 inf로 발산

- b=4로 두고 학습시킬때, 초반 학습 단계 (12 iteration 이내에서) class loss가 inf로 발산하는 문제이다.

- augmentation단계에서 gt에 문제가 생기는지 (localization issue이긴 하지만) 확인해 봤지만 문제는 없었다. 

- class loss가 갑자기 크게 나오는 포인트 찾으려고 test로 loss_c 값들 출력하도록 돌렸는데, 초반 loss_c값이 크게 잡히고, 일단 32 iter까지 문제없이 도는 중 --> 즉 초반 어떤 dataset을 사용하는지에 따라 (random) 학습 경향성 차이로 달라진다는 건데, 
12 iter만에 inf로 발산하는건 어디 문제가 있을 것 같은데, 아닌가?

- 일단 지켜보겠음. 

>>>> 찾았다

inf로 발산 case

pos class loss계산하면서 일부 값이 inf로 발산 --> loss_c는 누적 합이기 때문에 이 하나의 inf로 바로 inf로 발산해 버림

좀 더 detail 하게 확인해 봤을 때, exp sum을 하는 과정에서 inf로 발산한다. 

더 detail하게 살펴보면 class output 값들 중 96 정도로 크게 나오는 값이 있고, 이를 softmax 하기 위해 exp sum을 구하는 과정에서 해당 값이 inf이 된다.
하지만 다시 log 처리해주면 값이 작아지기 때문에 출력되야 하는데, inf로 한번 가면  연산식이 꼬여서 출력이 다 inf로 가는 것 같다. (double로 표현할 수 있는 값이상이 되면 inf가 되고 연산이 동작하지 않는다고 함)

해결방법은 exp 를 했을 때 inf가 되는 값을 float max로 처리하고 역으로 다시 output을 save 하면 된다. 어차피 저 정도로 튀는 값이면 저 값이 조금 작아지더라도 학습에 유의미한 영향을 끼치진 않을 것이기 때문. 

그래도 이정도면 빨리 해결한 편이라 뿌듯. 

(찾는데 중간 값들 다 출력해 보느라 시간이 꽤 걸렸지만, 원래 코드 새로 짜는 거보다 문제를 찾는 게 더 어려운 법이다.)

혹시 다른 문제가 생긴다면 추가 작성하겠다. 

 

+ 추가작성 - 1

- inf를 강제로 낮춰서 돌아가도록 했을 때, 학습이 어느정도 진행된다. 

- 하지만 후반에 OOM issue로 끊기고 이어서 돌렸을 때 error 발생하는데 inf 관련 에러.

- output class 에서 inf가 되는 값이 너무 많아짐... ㅠ 
(class가 21개일때 21개중 12개가 inf가 되고 exp sum이 결국 inf로 가게됨)
이때 위에서 강제로 처리했던 float max로 되게 하면 큰 값들 사이에 격차가 사라져서 학습이 이상해지는 것 같다.

- 이건 일단 exp sum 계산을 double로 계산해서 (일단은 exp 결과가 double max 이하) 추이를 확인하겠다.

 

++ 추가작성 - 2

말도안돼는 출력 값

- double 로 해도 더 학습이 진행되면서 (1000 iter 더 진행) 말도안되는 output 출력값이 나와서 double overflow로 inf로 가는듯...

- 근데 왜 이렇게 큰 값이 나오게 된걸까 ? 처음 학습부터 잘못된걸까 ? 

- 다시 0 iter부터 추이를 확인해보려한다.
일단 초반에 작은 값에서 시작하지만, 15(person) class index가 많다보니 15 output이 몇 iter안에 크게 출력 됨.

이런식으로


근데 사실 background 비율이 더 높아서 그렇게 따지면 0 (background) output이 커져야 하는거 아닌가 ?

- 어디선가 잘못된 것 같기는 한데, 그게 어디인지 모르겠다.........

 

++ 추가작성 3

 그동안 위의 문제들을 모두 해결하고 현재 학습 진행 중 상태

- 문제 1 ) 위의 문제들은 코드 디버깅 과정 중 언제인지 모르겠는데 loss gradient계산 값을 다른 pointer에 (output) update하고 있어서 생긴 문제였음. 그러다보니 gradient가 계속 0으로 초기화 되서 생기는 문제

- 문제 2 ) batch = 4 로 학습시 위의 문제들이 동일하게 발생 (batch = 1 에서는 발생 X) 
 batch 연산 상 문제가 발생한 것으로 판단하고 다시 처음부터 검증하기로 결정했다. 결론적으로 2가지 문제가 있었는데,
  1) multi-featuremap 결과를 output pointer로 재 배열하는 과정에서 batch * box# 이 되야하는데, layer별 batch * box# 으로 write되고 있다보니 계산 과정에서 prior box와 matching error 발생. 따라서 output, gradient 재 배열쪽을 수정해서 해결

  2) 하지만 여전히 학습 error가 발생. 검증 과정 중 loc 연산까지는 동일하지만 conf loss 계산 과정에서 negative box index가 다름을 확인함. 알고보니 batch별로 계산된 pos index 에 따라 neg index를 결정해야하지만, 전체 batch를 묶어서 계산하다보니 error 발생. --> batch 별로 sorting하도록 수정해서 해결

생각보다 너무 오래 걸려버렸다...

해결은 했지만, 문제는 너무 느린 학습 속도로 인해 정확도 검증이 점점 늦어지는 상태 (90h에 6k iteration 도는 상태... 겨우 3 epoch)

 

어쨌든, 해결로 본 글을 마무리한다.

결론은, 문제는 내 코드라는 것..... 검증 했다고 방심말고 다시 검증하자! (왜냐면 검증도 내가한거니깐 100% 믿을 수는 없다)

'GPU' 카테고리의 다른 글

g++ compile error  (2) 2024.04.03
pytorch resume 시 error  (1) 2023.11.07
[Ubuntu 16.04] 하드디스크 Input/output error 부터 컴퓨터 사망까지  (2) 2023.09.06
Senet TensorRT Test 과정 - 1 try  (0) 2020.01.02