작성
·
38
0
안녕하세요 선생님
얼마전 머신러닝 완벽가이드 강좌에 소프트맥스 질문 드렸던 사람입니다.
저는 소프트맥스 연산에 대한 하드웨어 가속기 설계 연구를 진행하고 있는 석사 과정생입니다.
그 때 남겨주셨던 답변에 대해 답을 드리면, Softmax의 Input 정밀도라는 것은, 마지막 FC layer를 통과한 후, Softmax층의 input으로 들어가는 값에 몇 bit를 할당할 것이냐에 관한 내용입니다. 즉 제가 알고 싶은 내용을 다시 정리해보면 다음과 같습니다.
softmax의 input (혹은 output도)에 많은 bit가 할당되면, H/W resource가 커지게 되므로, 모델의 accuracy를 크게 저해하지 않는 수준에서 어느 정도의 정밀도를 유지해야 하는지 알고 싶습니다. 하여 모델에서 softmax input 전에 따로 텐서 안의 값들을 특정 소수점 자리에서 반올림 해주는 함수를 정의해 반올림을 거치거나, 기존의 FP32를 FP16으로 casting을 거치도록 하여 좀 더 낮은 정밀도에서 잘 돌아가는 지 시뮬레이션을 해보는 중이었습니다. 저의 시뮬레이션 내용은 아래에 첨부하겠습니다. (rounding의 경우는 텐서 안의 값들이 제대로 반올림이 안된 것인지, 아니면 다른 이유가 있는 것인지.. 소수점 10번째에서 rounding을 하든, 20번째, 30번째에서 하든 accuracy에 큰 변화가 없고 거의 36프로 정도를 보였습니다.)
또 일반적으로 H/W설계 시에 floating point보다 fixed point가 구현이 훨씬 간단하며, 리소스 사용량이 매우 적은데, 소프트웨어적으로 모델을 학습시킬 때의 데이터는 대부분 float 32 또는 float 64를 이용하는 것 같습니다. 이는 역전파 과정에서 높은 정밀도가 필요하기 때문이 아닐까 싶은데, 모델 학습 시에 fixed point를 사용했을 때 발생할 수 있는 문제점이 있을까요 ? (소수점 10째자리에서 반올림을 하든, 20,30째자리에서 반올림을 하든 이론상으로는 정밀도가 높아질수록 accuracy가 높아져야 될 것 같은데 제 시뮬레이션 상으로는 모두 36프로의 정확도를 보여 코드에 문제가 있는 것인지, 아니면 알고리즘적으로 문제가 있는 것인지 궁금합니다.) 또한, FP16으로 표현 가능한 최대 정밀도의 값들이 훈련 시에 자주 사용되는지, 실제로 필요한 수준의 정밀도인지 궁금합니다.
softmax 층의 input으로 들어가는 logit값(?)들의 range가 어느 정도인지도 궁금합니다. 아마 모델과 사용하는 데이터에 따라 크게 달라질 것 같기는 한데, 제가 읽었던 softmax accelerator관련 논문들에서는 일반적으로 softmax의 input의 range를 [-10,10]으로 가정을 했습니다. (알고리즘 분야가 아닌 하드웨어 논문들이기는 합니다..ㅠㅠ)
허나 실제 학습 시에 floating point를 사용한다는 것은 분명 logit값이 10보다 매우 큰 값이기 때문일 것 같은데 왜 논문들에서는 저런 범위를 가정했는지 궁금하여 든 생각이 혹시 practical한 모델 내에서는 softmax로 들어가기 전에 특정 범위 안으로 들어가도록 전 처리를 해주는 layer가 따로 있는 것인지 궁금했습니다.
또 학습이 점점 진행되면서 logit 값이 학습 후반부로 갈수록 일반적으로 수렴하는 분포(?)가 있는 것인지 궁금합니다.. (epoch별로 logit 값을 출력해보고 싶은데, 아직 코딩에 익숙치 않아 난항을 겪고 있습니다)
본질적으로 softmax를 사용하는 이유가 궁금합니다.. multi classification에서 결국 하나의 class로 분류하는 것이 목적인데, 그러면 최종 logit값들 중 가장 큰 값을 선택하면 되는데 왜 굳이 softmax를 통해 확률 분포를 만든 후에 가장 높은 확률의 class로 선택하는지가 궁금합니다. (어차피 softmax를 취한 후의 maximum이나 취하기 전의 maximum이나 같을텐데)
( 시뮬레이션 내용 )
지난 번의 코드는 깃헙에서 임의로 가져온 코드라 조금 더 제대로 된 코드로 실습하고자 이번에는 선생님의 강의 자료인 VGG_Practice 실습 코드를 이용했습니다. 실습 코드의 모델 정의 부분에서 소프트 맥스 layer 직전에 rounding, 혹은 casting하는 부분을 추가한 것 외에 달라진 점은 없습니다.
그림 1: float 16
그림 2. float 16 결과
그림 3. rounding (소수점 10째자리에서 반올림)
그림 4. rounding 결과
회로 설계 관련 연구를 진행하다 보니 AI 알고리즘에 대한 지식이 부족하여 다소 난해하게 질문드리게 된 점 정말 죄송합니다.. 또 하드웨어적 관점에서 생각하다보니 알고리즘 부분과는 다소 동떨어진 질문이 있을 수도 있을 것 같은데, 그런 부분이 있다면 죄송합니다 ㅠㅠ
몇 년전, 동아리 활동을 하면서 머신러닝에 관심을 갖게 되어 선생님의 강의를 수강하고, 잘 공부했었던 기억이 있어 이렇게 다시 찾아 질문 드리게 되었습니다.
긴 내용 읽어주셔서 감사드립니다..
답변 1
0
안녕하십니까,
다시 여기서 뵙게 되는 군요. 반갑습니다^^
예전에 pytorch로 질문주셨는데, 다시 TF로 질문을 올리셨군요.
아, 하드웨어 분야를 전공으로 하셨군요. 이제 질문이 연관이 됩니다. 제가 '소프트맥스 연산에 대한 하드웨어 가속기 설계 연구'가 뭔지 몰라서 검색해 봤더니, 정말 이런 논문이 있더군요. 근데 제가 하드웨어 쪽은 몰라서, 가속기 설계 연구에 도움이 될 지 모르겠습니다.
먼저 좀 쉬운 질문 부터 답변 드리겠습니다.
네 맞습니다. logit의 argmax 결과나 logit을 softmax 적용 후 argmax 결과가 동일합니다. 그럼에도 불구하고 사용하는 이유는
첫째로 예측 확률을 계산하기 위해서 입니다. 그러니까, 가장 높은 예측값을 기반으로 해당 클래스값을 예측하지만, 예측 확률 또한 얻기 위할 때 사용됩니다.
두번째로 Loss 함수에 입력시 사용될 수 있습니다(이게 좀 헷갈립니다). Pytorch를 사용하신다면 nn.CrossEntropy의 입력 인자로 logit 값을 넣어줘야 하며, softmax를 적용하면 안됩니다. nn.CrossEntropy 내부에서 softmax를 적용하기 때문에 입력 인자로 softmax 적용된 tensor를 넣으면 두번 softmax가 적용되게 됩니다. Tensorflow의 경우 CategoricalCrossEntropy는 인자로 logit을 넣을 지, logit에 softmax가 적용된 값을 넣을지 구분값이 있습니다. default는 logit에 softmax가 적용된 값을 넣는 것입니다. 그래서 어떤 framework 을 쓰느냐에 따라 헷갈리는 부분이 있습니다.
2. 딥러닝 모델로 생성되는 logit값 범위는 그렇게 크지는 않습니다. 보통 이미지 데이터를 입력할 경우 픽셀값을 0 ~ 1로 정규화 하고, weight들의 값이 매우 작기 때문에 logit 값은 일반적으로 소수점 이하입니다.
제일 중요한 1번 답변을 정확히 드리기가 어렵군요. 왜냐하면 Deep Learning 모델에서 Softmax Layer만 별도의 정밀도를 유지하는 경우는 제가 보질 못했습니다. 보통은 학습 파라미터(Weight, bias)와 Activation 출력값을 모두 정밀도를 낮추는 것을 수행하지만, Softmax Layer만 S/W적으로 정밀도를 낮추는 것을 적용하지는 않습니다. 이것만 낮춘다고 H/W 리소스를 절약할 것 같지 않습니다. 보통 Weight등의 tensor는 float32 입니다. 이걸 인위적으로 float16으로 낮추면 성능이 많이 떨어집니다. Deep Learning은 정밀도가 꽤 중요한 편입니다.
Float16으로 성능 저하를 최소로 하면서 S/W적으로 낮출때는 Pytorch는 AMP(Automatic Mixed Precision), TF는 Mixed Precision Policy를 이용합니다. 근데 이건 S/W적인 것이고, AMP등이 동작하려면 H/W에서 지원이 되어야 합니다(NVIDIA, TPU 모두 지원됨)
H/W를 전문으로 하시는 지라, 제 답변이 도움이 될지 모르겠습니다. 더 궁금하신 점 있으시면 여기에 다시 글 부탁드립니다.
감사합니다.
logit 값의 범위가 그렇게 중요한건 아니라고 생각됩니다만, 꼭 아셔야 겠다면, 특정 범위가 있는지는 잘 모르겠습니다. 보통은 입력값도 작고, weight값도 작아서 logit은 +-로 0. 대 이하값이 많이 나옵니다. 그리고 층이 많아 진다고 logit값이 커지지는 않습니다. 다만 epoch가 많아질 수록 classification layer를 통과하게 되면 모델이 학습이 되기 때문에 예측되는 class index의 값만 커집니다.
또, 1번 답변 부분에서 저의 경우 weight이 아닌 input 에 대한 precision만 변경했는데 이 경우에는 accuracy 저하가 거의 없었습니다. 이러한 결과는 타당한 걸까요 ?
=> input precision만 변경하는 것 의미가 없을 것 같습니다만, Layer 내부에서는 weight 값과 multiplication 됩니다. 입력값이 float16이면 형변환되어서 float32로 matrix연산 적용되어서 그렇지 않나 싶습니다.
마지막으로 CNN은 아니지만 Transformer 쪽에서는 Weight, Activation등에 대한 software baseline이 FP16이라는 말을 어디서 얼핏본 것 같은데, 모델 별로 precision이 많이 달라지는 것인지 궁금합니다.
=> 모델별로 달라지지 않습니다. 일반 Dense/Linear, CNN, Transformer 모두 AMP등으로 FP16을 적용합니다.
선생님 빠른 답변 감사드립니다 ! ㅠㅠ
혹시 2번 답변 부분에서, 제가 지난번 pytorch 코드로 CIFAR-100데이터셋을 가지고 logit값을 출력해보았을 때, 0을 중심으로 하는 정규분포를 따라 분포하고, 0과 1사이의 작은 값들이 많이 분포하여 있기는 하였으나,
한 input당 100개의 logit이 있고(class가 100개이므로), 그 100개의 logit이 모두 (-10,10) 범위 안에 속하는 input이 전체 input의 52.50%, (-15,15)안에 있는 input이 90%정도, (-20,20)이면 99%정도였습니다. 또 epoch가 진행될 수록 logit값이 점점 커졌는데(가중치가 곱해지고 편향도 더해지므로 당연한 결과라고 생각했습니다.) 이러한 경향성이 맞는 걸까요 ?
logit 대부분이 작은 값이라 하더라도, multiclassification에서는 결국 큰 값을 걸러내는 것이기 때문에, 큰 값의 분포가 상당히 중요하다고 생각했습니다.
또, 1번 답변 부분에서 저의 경우 weight이 아닌 input 에 대한 precision만 변경했는데 이 경우에는 accuracy 저하가 거의 없었습니다. 이러한 결과는 타당한 걸까요 ?
마지막으로 CNN은 아니지만 Transformer 쪽에서는 Weight, Activation등에 대한 software baseline이 FP16이라는 말을 어디서 얼핏본 것 같은데, 모델 별로 precision이 많이 달라지는 것인지 궁금합니다.