# Training Deep Neural Networks
- 현실에서는 데이터가 너무 크기때문에 전체데이터를 가지고 gredient를 계산하지 못한다. GPU의 메모리로는 한계가 있기때문이다. 대신에 데이터셋을 쪼개서 진행한다.

- 예를들면, 데이터셋이 1000개라면 200개씩 나뉘어 로스함수를 여러번 돌려서 파라미터를 업데이트 한다. 이런식으로 데이터를 나누는 과정을 mini-batch라 한다. 데이터의 일부로 하는것이라 정확도가 떨어지지만 일정 수준만 적절하게 샘플링하면 굉장히 효과적으로 잘 작동을 하고 실제로 전체 데이터 통째로 하는 사람은 없다.

- Batch 사이즈에 따라 정확도가 달라지는데 사이즈가 일정 수준에서는 무조건 크다고 좋은것은 아니다. 보통 batch 사이즈를 8, 16, 32, 64, 128, 256, 512, 1024수로 설정하는데 하드웨어가 감당할 수 있는 정도로 하되 보통 64 ~ 128로 많이 한다. 그러면서 감당이 되면 올려보고 올리면서 좋아지는지 체크하면서 해 나간다.
- mini-batch-size가 n개(전체)일때는 항상 최선의 방향으로 나아갈 수 있으나, 계산 이슈의 부담측면에서 한걸음 한걸음 나아가는게 쉽지 않다.
- 반면에 데이터 하나가지고 gredient계산하면서 업데이트 하게 되면(예를들어, 전체 데이터가 10000개일때 1개씩 뽑아서 파라미터를 업데이트를 10000번씩 하게 되면) 당연히 한번 업데이트할 때 하는 업데이트가 최선의 방향으로 가기보다는 이상한 방향으로 많이 빠진다. 그런 식으로 하면 업데이트가 계속 왔다갔다 하면서 실제로 훈련할때 우리 목표로하는 지점에 도달할때까지 많은 시간이 걸리게 된다. (mini-batch-size=1인 경우)
- 그래서 mini-batch-size를 1개에서 전체 n개 사이에서 적절하게 찾아가는것이 중요하다.
- 학술적인 의미에서 Stochastic Gradient Descent는 샘플 한개를 가지고 업데이트하는 방식을 반복해 나가는 과정을 말하며 SGD라고도 말한다. 아래 중간그림을 mini-batch greadient descent라고 하는것이 맞는데 SGD라고도 많이 부른다. 왜냐하면 파이토치, 옵티마이즈 코드가 Gradient Descent 기본적으로 하는 것 자체 이름을 SGD로 지어냈기 때문에 SGD라는 용어가 혼용되어 사용된다.

- 수식으로 비교하면 다음과 같다. 로스가 근사할때 데이터셋 전체를 쓰는게 아니라 데이터의 부분집합으로써 어떤 batch 데이터셋 하나를 뽑아서 그 batch 데이터셋을 가지고 로스를 계산하는 것이 차이점이다.

- mini-batch가 적용된 코드를 보면 for문이 하나가 더 추가되어 x를 batch_sampler같은 batch dataloader를 활용한다. dataloader에 dataset을 넣으면 dataloader가 알아서 데이터를 잘 섞어서 소분을 하는것이 dataloader가 하는 일이다. 그래서 for문을 돌리면 이 소분된 데이터들을 하나씩 하나씩 가져온다.
- 하나씩 하나씩 가져온 데이터를 집어넣고 로스를 계산하고 역전파를 계산하여 최적화를 해나가는 일련의 과정을 이제 앞으로 많이 보게되는 인공지능의 training 방식이라고 할 수 있다.
- 한 데이터셋을 다 보는것 또는 쪼개더라도 한번 다 보는것을 epoch이라고 한다. 이 안에 있는 과정을 step이나 iteration이라고도 부른다.

- 전통적인 뉴럴 네트워크, 딥러닝 이런 작업을 할때는 기본적으로 Adam을 사용하면 된다. Adam이라는것이 지금 단순히 내가 여기서 어느방향으로 가야지만 보는 것 뿐만아니라 이때 가야되는 방향은 지금까지 오던 방향과 얼마나 유사한지라는 관성과 그 다음에 지금 이 시점에 걸음을 얼마나 크게 내딛는 게 좋은지와 같은것들을 골고루 고려할 수 있어서 웬만한 테스트에서 잘 작동하는 방법이라고 생각하면 좋다.
- Optimizer도 결국 Gradient를 어떻게 계산하느냐와 이 Gradient를 계산해서 파라미터를 어떻게 업데이트하냐라는 방법이고, 그것을 할 수 있는것에 대해 다양한 옵셥이 있는데 일단은 아담을 쓰면 처음 선택지로써는 괜찮은 선택지이다.

- 로스함수에서 세타를 업데이트할때 미분에 곱해진 알파가 learning rate이며 이 값에 따라 세타의 움직임을 조절할 수 있다. learning rate는 training과정에서 학습하면서 바뀌는 값이 아닌 우리가 정해놓은 값으로 고정된 하이퍼파라미터이다. learning rate을 너무 낮게하면 로스의 최솟값까지 가는데 한참 걸리고, 너무 높으면 범위가 정해져있으면 괜찮은데 그렇지 않을때는 오버스팅이라는 불안정해지는 상황도 발생한다. 따라서, 적절한 빠르기의 learning rate가 필요하다.
- 1 epoch(전체데이터 한번 보는것)할때 High learning rate는 처음에는 로스함숫값이 잘 감소하다가 일정수준에서는 못 내려가고 정체되는것을 알 수 있다. learning rate 너무 높으면 로스함숫값이 감소가아닌 증가하는 엉뚱한 방향으로 가기도 하거나 너무 느리면 천천히 감소하면서 너무 오래걸려서 더 안좋은 결과가 나올 수 있다.

- 따라서, learning rate scheduler를 정한다. learning rate가 언제 좋은지 잘 모르기때문에 이쯤에는 learning rate를 이 값을 사용하도록 나름대로 스케줄을 정해주는 것이다. 따라서, 임의로 정해주는것이라 정답이 없기에 많은 경험으로 이런거에 대한 감이 많이 발전한다.
- 이론적기반으로 하는것이 아니라 인간의 직관같은것들을 Heuristic이라 한다. 논문에서도 많이 사용되는 용어이다.
- Warm up은 initial step에서 learning rate를 너무 높게 주면 training과정이 unstable해질 수 있거나 반대로 Warm up을 했더니 training과정이 stable해 진다면 안정적이다 풀어진다정도로만 설명을 한다. 따라서 처음에 linear하게 설정하는데 내가 부여할 learning rate값을 만약 10단계로 나뉘어서 준다면 열번에 걸쳐서 learning rate를 바꾸며 목표치까지 올라가는것을 Warm up이라고 한다.
- Decay란 감소라는 말로 train loss가 평탄해질때 learning rate 1/10씩 확 줄이면 train loss도 같이 감소하는 것을 알 수 있다.

- 위 그림은 규칙으로 일정하거나 그렇지않은 epoch마다 learning rate을 줄여나가는 그래프이며 1번은 learning rate가 constant한 모양이고, 2번은 25 epoch마다 learning rate를 1/2씩 줄여나가는 step모양이다. 가장 많이 사용되는 Scheduler은 1,2,4,5,6번 모양이며 그 중 2번이 가장 빈번하게 이용되기에 처음에 시작할때 사용해보는것이 좋다.

- 여러가지 learning rate scheduler는 위 페이지에 들어가면 각각에 대해 사용법까지 자세히 나와있어 직접 만들 필요없이 가져다가 쓰면 된다.

- 훈련용 데이터셋을 train과 valid로 나뉜다. 훈련은 train으로 하되 모델이 얼마나 잘하고 있는지에 대한 평가는 valid로 진행한다. 그 다음에는 최적화를 진행한다. 최적화는 SGD 알고리즘으로 최적의 세타를 찾는다. 이때 파이는 하이퍼파라미터를 말한다. 그 알고리즘에 로스, 훈련용 데이터, 모델을 넣는다. evaluation(평가)에서 P는 Performance metric을 계산하는 과정의 함수이며 최적의 파라미터와 valid 데이터를 넣어서 성능이 얼마나 나오는지를 보고, 특정 파라미터에 대한 성능수치를 보겠다는 것이다. 따라서, evaluation은 하이퍼파라미터 튜닝까지 이어지기 위한 일련의 과정이다.

- 딥러닝이 항상 잘 작동하는것은 아니다. 왜 항상 잘 작동하지 않냐면 딥러닝이 잘 작동한다는 것에는 어떤 전제 조건이 깔려있다. 이 추정된 데이터셋으로 구성된 분포로부터 기대되는 로스값은 이 데이터셋 샘플들로 계산된 로스의 평균이다라는것이 기댓값의 정의이다. 우리가 하고자 하는것이 미니마이즈 시키며 그때의 세타를 찾아가는 과정이다. 하지만 이 과정을 잘한다는것이 목표가 아니다. 측정값의 로스 최솟값을 구하는것보다 실제값의 로스 최솟값을 구하는것이 최종목표이자 전제조건이 된다.
- 하지만, 모든 실제값의 데이터로 로스의 최솟값을 구할 수 없기에 우리가 가지고 있는 데이터셋의 분포가 실제 정말 잘 샘플된거여서 모든 실제값을 다 커버할 수 있는 데이터의 분포를 근사하고 있다고 생각하는 것이다. 위 그림에서 파란색 히스토그램의 P hat과 주황색선 P와 정말 유사하다고 생각하는 것이다.
- 실제의 데이터를 모아서 하는거라 이때의 로스값을 Empirical Risk라 하고 이런 기본적인 전통적인 인공지능이 작동하는 전제조건은 Empirical Risk minimization한다고 말한다. 즉, 주어진 한정된 훈련 데이터의 분포를 따르는 손실 함수의 기대값을 최소화시키는 과정을 Empirical Risk minimization이라고 부른다.
- P hat이 P를 근사하기 위해서는 데이터가 기본적으로 많아야한다. 따라서, 인공지능에서 모델도 중요하지만 데이터에서 시작해서 데이터에서 끝난다고 말할정도로 좋은 데이터가 제일 우선시된다.
- 기존의 데이터의 분포 자체가 바뀌어버린 변화를 disrtibutional Shift라 한다. distributional Shift란 훈련할때 경험한 데이터의 분포가 실제 모델이 사용될 경험하는 데이터의 분포와 다를때를 말한다. 이럴때의 해결방법은 모델을 새로 만들거나 대처하는 다른분야인 Domain adaptation도 있다.

- 머신러닝에서 많이하는 과정이(물론 딥러닝에서도 해야되는 과정) 데이터셋을 나눌때 보통 3단계로 나눈다. train, valid, test로 나뉘는데 train, valid는 실제 데이터를 훈련할때 사용하며 test는 report용이라 훈련을 하면 안된다. 즉, 어떤 수정 하나도 하면 안된다. 만약 데이터셋을 train 70%, valid 20%, test 10%로 나누었을때 valid 데이터가 잘하는 방향으로 모델을 고른것이기에 처음보는 데이터에서 잘한다는 보장이 없다. 다르게보면 객관적으로 하려고 했지만 valid 데이터에 의존성이 생긴것과도 같다. 그래서 마지막에 test 데이터셋으로 성능을 측정해보면서 객관적인 성능을 체크하는 것이다.
- 이러한 이슈들때문에 이 valid 데이터의 종속성을 최대한 제거하기 위해서 K-fold validation을 사용한다. 예를들면, 3-fold validation이라하면 전체데이터를 3개(A,B,C)로 나뉜다. A,B로 train하고 C로 valid하는 경우와 B,C로 train하고 A로 valid하는 경우 그리고 A,C로 train하고 B로 valid하는 경우로 계산한뒤 이 3개의 valid의 평균으로 최종결정한다. 이렇게하게 되면 어떤 특정 validation셋 하나에 의존하는게 조금은 줄어들고 여러가지 조합에 대해서 잘할 수 있게 최대한 객관적으로 해보려는걸 할 수 있다. 이러한 접근이 K-fold validation이다. 여기서 K는 임의로 데이터를 나뉘려는 수에 따라 달라진다.
- 일반적으로는 3단계보다는 train과 valid, eval, test인 2단계로 나뉘어 진행한다. test는 보고용이기때문에 3가지로 잘 나누어하진 않는다.
- k-fold validation은 머신러닝은 데이터크기가 크지않아 사용할 수 있지만 딥러닝은 데이터 크기가 너무나 크기때문에 잘 사용하지 않고 여력이 있을땐 k폴드 대신 하이퍼파라미터를 족므이라도 더 튜닝을 해보고 새로운 learning rate 스케줄을 추출해보며 그 계산량을 다른데 쓰는게 좀 더 낫다.

- 딥러닝은 크기가 큰 데이터의 복잡한 패턴을 배울 수 있지만 머신러닝은 모델이 복잡도가 적은만큼 그만큼 적은 양의 데이터에서는 패턴을 빨리 찾기도한다. 왜냐하면 딥러닝은 파라미터가 많고 고려하는게 많아질수록 잘못 배우거나 쉽게 데이터를 외워버릴 수 있기때문에 그런부분을 방지 할 수 있어서 머신러닝 모델은 데이터 양이 적을때 조금 유리한 측면도 있다.
- Capacity는 어떤 모델의 잠재력 혹은 가능성을 말한다. 모델의 파라미터가 몇개가 있고 어떠한 관계를 가지고 있어 다양한 함수를 배울 수 있을 만큼의 자유도가 높아서 복잡한 패턴들을 나타낼 수 있는가에 대한 용량이나 가능성을 보여주는것이다. 따라서 딥러닝 모델은 기본적으로 Capacity가 높다.
- Complexity는 위 Capacity에서 설명한 용어와도 동일하게 쓰인다. 맥락에 따라 다른 의미로도 쓰이기도 한다. 이미 학습이 끝났을때 아무리 뉴럴네트워크가 복잡하더라도 데이터가 선형으로 단순하다면 이 모델은 크고 복잡하지만 배운 패턴은 심플하다. 그래서 최적화가 된 모델이 지금 배운 패턴이 얼마나 복잡한지에 대해 말할때 Complexity를 쓰기도 한다. Complexity는 이 2가지 모두 쓰인다.
- 따라서 딥러닝 모델은 머신러닝 모델보다 Capacity도 높고 학습이 끝났을때 Complexity가 높은 것들을 잘 해낼 수 있다. 그래서 Large dataset에서 어떤것을 끌어내는게 유리하다.
- 딥러닝은 raw data를 많이 넣으면 모델이 알아서 필요한 패턴을 배울 수 있지만 머신러닝은 raw data를 그냥 넣을 순 없기에 기본적으로 어떤 알고리즘을 통해서든 지식을 통해서든 feature를 뽑아내는 과정을 사람이 해야한다. 이것이 머신러닝과 딥러닝을 구분하는 차이중에 하나이다.
- feature는 특정 task를 수행하기 위해 필요한 어떤 가공된 정보이며, 이 feature를 머신러닝은 직접 찾아서 input으로 넣어줘야 했다면 딥러닝 모델은 feature extraction과 Classifier로 나뉘는데 Classifier는 분류작업을 진행하고 feature extraction에서 끝부분에 인공지능이 직접 찾아낸 이 task를 수행하는데 필요한 추상적인 feature라고 부른다. 따라서 이 feature를 자동으로 했는지 사람이 했는지에 따라 머신러닝과 딥러닝을 가르는 차이가 된다.
- 머신러닝에서 말하는 feature는 data 샘플이 있을때 데이터의 colum 하나하나를 말하며 딥러닝에서는 통째로 feature 혹은 feature vector라고 부른다. 왜냐하면 딥러닝에서는 하나하나가 어떤 의미를 갖는지 모르며 어떤 raw data가 들어올때보다 낮은 차원의 벡터를 하나 만들어 낸 것이다. 이 feature가 중간이나 뒤에 있는 것은 무엇을 나타내는지 이것들을 구분하고 해석하는것이 explainable ai라고 한다. 따라서 기본적으로는 딥러닝의 feature 내용을 알 수 없다.

- 그럼 딥러닝 모델이 무조건 좋은가? No. 머신러닝 모델이 딥러닝보다 잘하는 부분중에 하나가 tabular data 즉 테이블 형태로 주어져서 하나하나가 feature로 된 데이터에서 이다. 잘하는 이유중 첫번째로 각 인공지능 입장에서는 이런 tabular data를 그냥 input으로 넣을때 필요가 없는 정보가 있으면 MLP같은 모델들은 불필요한 feature에 조금 더 취약하다. 아무래도 모델 Capacity가 높은것도 영향이 있는 반면에 tree-based 모델같은 머신러닝에서는 그런 부분들에 영향을 덜 받는 방식으로 작동한다.
- 뉴럴 네트워크는 위 그림과 같이 모든 종류의 선을 연속적으로 만들어 볼 수 있다. 색이 진할수록 확신을 갖고 분류했냐의 기준이다. 빨간색과 파란색에서 구분한 선을 보면 라인을 깔끔하게 그려지는데 decision tree같은 경우는 decision을 가지치기하듯이 나누기에 라인을 꼭 깔끔하게 그릴 필요가 없다.
- tabular data로 보여지는 데이터들의 어떤 특성이라는것은 어떤 정해진 깔끔한 내재된 특성이 있기보다는 그냥 기계적으로 분류하여 잘 처리하게 무엇인가를 수행하게 하는 것일 가능성이 높다. 딥러닝이 잘하는것이 언어 그림과 같은 것들은 이미지의 픽셀 하나하나의 숫자가 바로 인접한 숫자들과의 의미를 정확히 갖고 있다. 하지만 머신러닝의 데이터들의 숫자들은 하나하나가 관계를 갖고 있는것도 아니고 연속적으로 연결된것도 아니고 임의로 뽑아놓고 모아놓은 것들을 임의의 순서로 배열해 놓은것에 불과하다. 이런 영향도 있을 수 있다.
- 결론적으로 딥러닝이 항상 최적의 솔루션은 아니다라는 것과 딥러닝과 머신러닝는 이러한 차이가 있다.
# Methods to Prevent Overfitting

- training을 다 외워버릴때까지 무한히 하면 train loss를 무한정 낮출 수 있지만 그걸 원하는 것이 아니다. 어떤 일반화된 트렌드든 패턴이든 유용한 어떤 transformation 이런것들을 배우고 싶은건데 쓸데없는 노이즈까지 다 외워버리면 의미가 없다.
- 그래서 overfitting을 방지하기 위해서 matric을 쓴다고 하는데 이 matric은 단순히 최적의 파라미터를 고르는데 쓰는것 뿐만아니라 이 performance를 measure하면서 optimize하는 과정에서 쓸 수 있다. 쓰는 2가지 방법이 있는데 하나는 training할때 쓰는 loss와 동일한 loss를 validation에서 똑같이 쓰는 방법과 evaluation matric을 쓰는 방법이 있다.
- 훈련을 하면서 트레이닝 모델을 1step, 1epoch 훈련하고 찍어본다. validation loss와 training loss는 계속 갈수록 감소한다. 그런데 validation loss는 한번 트레이닝하고 찍어보면서 진행하면 계속 같이 감소하다가 일정 수준의 시점부터 올라가기 시작한다. 이것을 보고 이 시점부터는 트레이닝 데이터가 더이상 훈련을 해봤자 어떤 트렌드를 일반화할 수 있는 트렌드를 배우는것이 아니라 그냥 데이터를 외우기 시작했다고 보며 과적합(overfitting)되었다는 판단기준으로 쓸 수 있다.
- 훈련과정에서 일정 주기(epoch)마다 validation loss 또는 validation data에 대한 evaluation matric를 찍어본것으로 기준을 삼아 그 어떤 변화를 기준으로 훈련을 멈추도록 정해주는것이 early stopping이라 한다.

- 사람의 눈에는 이미지가 동일하더라도 위치가 조금이라도 이동하게되면 머신입장에서는 공간상의 위치의 좌표가 모두 바뀌는것이기에 다른 데이터로 판단한다. 우리가 수행하고자하는 task의 본질을 바꾸지 않으면서 하나의 데이터를 가지고 여러개의 더 많은 데이터를 만들어 내는 과정을 Data Augmentation이라 한다.
- 데이터를 훼손하지 않으면서 휘둘리지 않게하는 모델이 이런저런 모든 데이터를 다 경험하면서 그 데이터들에서 다 일관된 좋은 판단을 내릴 수 있게 하는 혹은 모델의 일반화 성능을 높이는 과정을 data augmentation이라고 할수도 있고 경진대회에서도 5~8할 이상의 성능차이가 data augmentation에서 올 수 있다.

- data augmentation 기법도 많기에 해당 링크로 가서 확인해볼 수 있다. 다양한 방법도 있고 사용법도 튜토리얼도 있으니 해보면 크게 어렵지 않다.

- 좌우반전 혹은 왼쪽 그리고 오른쪽으로 구분이 되어야 하는게 아니면 Horizontal Flip, 위 아래가 바뀌는거면 Vertical Flip이라 한다. 하지만 위 아래 바뀌는것은 함부로 쓰면 문제가 발생한다. 해당그림에서는 하늘이 밑으로 가는 경우는 없기에 현실에서 이러한 분포를 배우는것은 보통 악영향을 많이 미칠수도 있으니 적절하게 쓰면 된다.

- 이미지뿐만아니라 오디오나 텍스트 모두 도메인에 맞게 augmentation이 된다. 이미지가 직관적이라 이해하기 쉬워서 예시로 있을뿐이다. 모든 종류의 데이터에서 다 augmentation이 일정부분 쓰인다. 가장 쉽게 사용하는것은 모든 데이터에 있어서 어떤 데이터 x가 있을때 약간의 노이즈를 더하는 것이다. 여기서 노이즈라는 것은 가우시안 노이즈를 말한다. 작은 노이즈는 데이터의 본질에 영향은 끼치지 않지만 새로운 데이터를 만들어 내는 것이다.
- data augmentation에 있어서 색상을 바꾸는 것도 있는데 색상 바꾸는 경우는 조심히 써야 한다. 색상에 영향을 주는 task라면 쓰면 안된다.

- Random Croping은 랜덤으로 자르는건데 효과가 좋아 경진대회에서도 많이 쓰인다. Random Erasing은 랜덤하게 일부러 지우는거고, 둘 다 쓰는것은 효과적이니까 쓸만하면 좋다.

- Dropout은 뉴럴 네트워크에서 일정 연결을 랜덤으로 지워버리는 것이다. 뉴럴 네트워크에서 input에서 hidden layer를 통하여 output으로 갈때 노드 하나하나 모두 꼭 필요한 건 아니다. 일부분 없어도 어느정도 할 수 있어야 한다. 이 말은 똑같이 제대로 예측할 수 있어야 된다.

- dropout을 하는 코드를 보면 히든 레이어의 모양과 동일한 사이즈로 랜덤 숫자를 만들라는 건데 rand는 0~1 사이의 값중에서 랜덤하게 뽑는다. 이 값이 p 보다 작아야 한다고 하는데 p는 임의로 설정할 수 있는 dropout rate값이다. p보다 작으면 True가 되고 크면 False가 된다. 이때, True는 1, False는 0으로 인식하여 hidden과 곱하게되면 랜덤으로 일정 비율의 노드들을 0으로 바꾸는 것이다. 이때 나온 hidden에 웨이트를 곱하고 bias를 더한 값이 예측치가 된다. p는 반드시 0~1사이로 주는건 아니지만 비율을 나타내고 싶어서 일반적으로 쓰인다.
- hidden을 dropout하여 나온 결과물이나 이런 중간과정 없이 나온 결과물이 같은 퍼포먼스를 보이기 기대하는 것이다. 트레인 과정에서는 dropout를 하지만 테스트 과정에서는 dropout적용을 안한다. 다만 히든에 p를 곱하는 새로운 것이 필요하다. p를 곱하는 이유는 dropout을 하게되면 일부 노드들의 크기가 0이되어 전체적인 벡터의 크기(magnitude)가 줄어들기에 스케일을 맞춰주기위해 날려주기 위해서이다.
- data augmentation도 테이터의 수를 늘려서 일반화시키면서 오버피팅을 방지하는 역할이 있듯이 dropout의 중요한 효과중에 하나가 오버피팅을 방지하는 것이다. 왜냐하면 랜덤으로 노드들을 제외시키면서 예측을하며 학습하게되면 특정 노드에 너무 과하게 의존을 하지 않게 된다. 모든 노드를 골고루 랜덤으로 선택하면서 쓰게 되기에 네트워크가 전반적으로 특정 데이터의 경향성이 노이즈에 너무 의존하지 않고 더 일반화된 무언가를 배울 수 있게 할 수 있는 효과가 있다. 그래서 오버피팅 방지가 최종목적이 된다.

- 훈련할때 model.train()을 테스트할때 model.eval()을 반드시 먼저 붙여줘야한다. 여러가지 이유가 있는데 중요한 것중에 하나가 모델안에 dropout같은것이 있으면 트레이닝할때와 테스트할 때의 작동하는 방식이 다르다. 그래서 작동방식이 다르기 때문에 항상 모델이 지금 트레이닝 단계인지 evaluation 단계인지 구분을 하도록 모델이 인식하게 해야한다. 이부분은 모두 설정이 반드시 필요하다.
- with torch.no_grad(): 이 명령어는 gradient 계산을 안하겠다는 것인데 하냐 안하냐에 따라 사용되는 메모리가 완전히 달라진다. 그래서 gradient를 굳이 계산할 필요가 없을때는 항상 forward pass만 하더라도 정확하게 명시를 해주면 쓸데없이 메모리를 사용하지 않는다. 그렇게되면 당연히 연산도 빠르게 된다.
# Classification
- 분류는 아래그림처럼 임의의 이미지가 주어졌을때 이것을 비행기인지 자동차인지 새인지 고양이인지 판단하는 것이다.

- regression은 y = wx + b로 계산하여 output layer의 값들을 찾았을때 가장 높은 값이 타겟값이 되는 것인데 Classification에서는 다음과 같은 문제점이 있다. 첫번째로는 output값이 정해져 있어 해당 타겟값의 크기가 크고 낮음이 정해져 있지 않다. 타겟값을 맞추는것이 목표가 아니라 해당 이미지의 타겟값의 해당되는 숫자가 높아야 한다. 예를들면 고양이 타겟값이 가장 높을때 100이든 500이든 그 수 자체의 의미가 없기에 output으로 해석이 안된다. 또한 output값으로 몇 퍼센트인지 말할 수 있는 확신이 없다.

- 그래서 Softmax를 쓴다. Softmax function을 쓴다는 것은 클래스가 두개보다 많은 여러개인 상황을 말하며, 클래스가 2개일때는 바이너리로 풀 수 있으면 Sigmoid function을 쓰면 된다. Softmax function 작동방식은 아래 그림에서 k=5라 할때, exponential에 각각의 output값을 넣어서 해당 output의 exponential의 값 / exponential 총합을 각각 계산하는것이다. softmax의 큰 장점중에 하나는 모두 더했을때 값이 항상 1이 된다. 따라서 이렇게 값이 나오면 일종의 확률값으로 생각할 수 있다. 변환된 값으로 confidence를 가지고 예측을 하는거라고 해석이 가능하다.

- Classification과 regression의 차이를 많이 들은 점은 Cross Entropy라는 함수를 쓰는것이다. 분류작업의 특성상 Cross Entropy라는 함수로 정의할 경우 많은 것들을 해낼 수가 있다. Cross Entorpy Loss에서 N은 데이터의 샘플수, K는 클래스의 수, yik는 1과 0으로 이루어진 정답라벨에서의 숫자의 위치, y^ik는 i번째 샘플의 k번째 softmax를 뜻한다. 따라서, 예측한 softmax값에 로그를 씌우고 정답인 softmax값을 곱한다는 것이다. 정답라벨이 미치는 영향은 벡터에서 정답은 1 하나이고 나머지는 모두 0 이기에 곱해지면 모두 0이 된다.
- yik에서 정답은 1인 수만 곱셈하게되면 생략이 된 모양이며, 정리된 식에서 Ti는 i번째 샘플의 정답라벨 번호이다. 아래와 같이 계산하게되면 중요한 포인트는 실제로 Cross Entorpy에게 쓰이는것은 정답인것의 Softmax 값이 된다. 중요한 두번째 포인트는 로그를 한 이유이다. y^에 1이 들어갈수록 1이 들어간다는것은 정답라벨에 가까울수록 로그값은 0에 가까이 가게 된다. 로그를 할때 장점은 정답라벨에 대한 컨피던스를 높게 해줄수록 로스가 낮아지고(0에 가까워지고) 정답에 대한 컨피던스 softmax out값을 낮게 해줄수록 로스는 무한대로 계속 높아진다. 이것이 Cross Entropy의 작동원리이다.
- Cross Entropy가 분류문제뿐만아니라 chat gpt처럼 large language모델에도 훈련을 한다.


- Evaluation Metrics는 데이터의 불균형때문에 Accuracy만 이야기하는것이 아니다. 예를들면, 10명의 암환자중 음성이 9명, 양성이 1명이 있다고 할때 ai가 무지성으로 10명 모두 음성이라고 한다면 정확도 계산시 90%를 가진 모델이 된다. 사실 이 모델은 제대로 작동하여 맞춘것이 아니라 무지성으로 답한것이기에 이러한 한계점이 있다. 어떤 데이터의 클래스별 분포를 고려하여 evaluation metrics를 설계해야하는데 task에 따라서 중요한 부분이 다르다.

- 스펨메일 예시에서는 정상메일을 스팸처리하는 경우와 스팸메일을 정상처리하는 경우가 있을때 정상메일을 스팸처리하는 경우가 곤란하기때문에 이 상황은 피하고 싶은 상황이다. 모델이 Positive(스팸)이라고 주장하나 실제는 False인 경우를 말하며 이것을 False Positive(FP)라 한다. 이때 측정하는 것이 Precision이며 FP가 높을수록/낮을수록 Precision은 낮아진다/높아진다.

- 암환자 예시에서는 양성인 환자를 음성으로 판단하는 경우와 음성인 환자를 양성으로 판단하는 경우가 있을때 양성인 환자를 음성으로 판단하는 경우가 끔찍한 상황이다. 모델이 Negative(음성인환자)이라고 주장하나 실제는 False인 경우를 말하며 이것을 False Negative(FN)이라 한다. 이 경우가 최악의 상황이며 이것을 피하고 싶기때문에 Recall이라는 meature를 사용한다. Recall은 FN이 분모에 있어서 커질수록 값이 낮게 잡힌다.

- 이러한 여러가지 맥락을 고려하여 Evaluation Metrics를 잘 설정해야하고 이러한 Metric은 미분을 할 수 없기때문에 실제 훈련할때는 Cross Entropy를 가지고 훈련한다. F1 score는 조화평균이라고도 하는데 취지는 recall과 precision 둘다 잘 측정하려고 하는데 두개의 값 중에 하나가 너무 낮으면 낮은값에 대해서 굉장히 예민하게 작동을 한다. 따라서, F1 score가 하고 싶은것은 recall과 precision 둘 다 잘 고려해서 어느것 하나 못하는 것을 잘 캐치하고 싶은데 단순 평균을 내버리면 한쪽은 잘하고 다른한쪽은 못하는 건 사실 안좋은 상황인데도 불구하고 이것을 고려를 못하게 되는데 조화평균을 하게되면 이 두가지 모두 골고루 잘 고려할 수 있게 낮은 값을 민감하게 반응할 수 있다는 장점이 있다.

- 위에서 예시를 들었던 암환자 음성양성, 메일의 스펨정상은 binary case인 반면에 위 그림처럼 클래스가 여러개가 있는 상황도 있다. 옷 이미지가 주어지면 색상이 무엇인지 분류하는 것이며 색상은 총 19종류가 있다. 색상마다 분포의 차이가 심한건 몇십배 이상 차이가 있을때 이런상황에서 골고루 잘하는 방법이 무엇인가. 만약 정확도를 찾아서 단순히 다 합쳐서 옷 몇만장 중에 몇 장을 맞췄다고 하면 안된다. 따라서, 모든 옷 종류에 대해서 동일한 가중치를 주고 동일한 중요도를 주고 비교하려면 각각에 대해서 정확도를 재고 그 정확도를 평균을 내는 방식으로 접근할 수 있다.
'yeardreamschool4 > AI&Data Science: Core of AI' 카테고리의 다른 글
| Fundamentals of Machine Learning and Essential Mathematics (0) | 2024.06.10 |
|---|