Notice
Recent Posts
Recent Comments
NeuroWhAI의 잡블로그
[Rust] 드롭아웃(Dropout) - '밑바닥부터 시작하는 딥러닝' 6장 본문
※ 실제로 동작하는 전체 소스코드는 GitHub에서 보실 수 있습니다.
(가중치 초기화 방법들(Xavier, He)은 코드로 구현은 하였지만 글은 넘어갑니다.)
드롭아웃은 오버피팅(과적합)을 방지하기 위해서 순전파시 일정 확률로 특정 출력값을 0으로 만들고
역전파시에도 기울기의 해당 부분들을 0으로 만들어서 보냅니다.
보통 일정 확률로 신경망의 뉴런을 비활성화한다 혹은 끈다고 설명합니다.
학습이 좀 느려진다는 단점은 있지만 쉽게 과적합을 어느정도 이겨낼 수 있습니다.
비슷하게 배치정규화라는 놈도 과적합을 방지해주지만 이건 학습 속도가 훨씬 빠릅니다.
아래 코드는 드롭아웃 계층을 어떻게 구현했는지만 넣어놨습니다.
코드:
impl Layer for Dropout {
fn forward(&mut self, x: &Matrix<f32>) -> Matrix<f32> {
if self.train_flag {
let rand_matrix = Matrix::from_fn(x.rows(), x.cols(), |_, _| rand::random::<f32>());
self.mask = PartialMatrix::le(&rand_matrix, self.dropout_ratio);
let mut out = utils::copy_matrix(x);
self.mask.set(&mut out, 0.0);
out
}
else {
x * (1.0 - self.dropout_ratio)
}
}
fn backward(&mut self, dout: &Matrix<f32>) -> Matrix<f32> {
let mut masked_dout = utils::copy_matrix(dout);
self.mask.set(&mut masked_dout, 0.0);
masked_dout
}
}
결과:
[Optimizer - SGD] Loss: 490.0664, Acc: 0.196, Test Acc: 0.222 Loss: 383.53577, Acc: 0.703, Test Acc: 0.678 Loss: 210.64793, Acc: 0.806, Test Acc: 0.792 ... Loss: 67.24843, Acc: 0.908, Test Acc: 0.901 Loss: 66.1453, Acc: 0.911, Test Acc: 0.902 Loss: 65.10284, Acc: 0.914, Test Acc: 0.905 Final test acc: 0.916 [With dropout] Loss: 493.32635, Acc: 0.122, Test Acc: 0.13 Loss: 456.39633, Acc: 0.562, Test Acc: 0.536 Loss: 332.7797, Acc: 0.719, Test Acc: 0.699 ... Loss: 81.6619, Acc: 0.9, Test Acc: 0.902 Loss: 80.01616, Acc: 0.902, Test Acc: 0.905 Loss: 78.53487, Acc: 0.905, Test Acc: 0.905 Final test acc: 0.908
뭔가 오히려 드롭아웃을 사용한게 최종 정확도가 더 떨어지는데
가중치가 랜덤으로 초기화 되는거랑 학습 속도가 떨어지는 특성 때문에 그럴겁니다.
주목해야 할 부분은 드롭아웃을 사용했을땐 학습 정확도와 테스트 정확도의 차이가 별로 크지 않다는거죠!
'개발 및 공부 > 알고리즘' 카테고리의 다른 글
[알고리즘] 백준 '이항 쇼다운' (0) | 2019.01.06 |
---|---|
[C++] KMP 알고리즘 구현 (0) | 2018.11.29 |
[Rust] 매개변수 갱신법들 - '밑바닥부터 시작하는 딥러닝' 6장 (0) | 2018.07.27 |
[Rust] 계층(레이어), 오차역전파 - '밑바닥부터 시작하는 딥러닝' 5장 (0) | 2018.07.25 |
[Rust] 계산 그래프 - '밑바닥부터 시작하는 딥러닝' 5장 (0) | 2018.07.16 |
Comments