-
[cs231n] 6강 신경망 훈련하기 (4/4, 하이퍼파라미터 최적화 (hyperparameter optimization))AI 2021. 3. 11. 12:02
어떻게 이 하이퍼파라미터들을 선택할 수 있을까요? 하이퍼파라미터 최적화를 하고 모든 파라미터의 최선값을 고르는 거죠?
우리가 사용할 전략은 어떤 하이퍼파라미터에 대해서든지, 예를 들면 학습률이죠. 교차 검증 (cross-validation)을 하는 겁니다. 교차 검증은 훈련 셋에 대해서 훈련을 하고, 검증 셋에 대해서 평가를 하는거죠. 이 하이퍼파라미터가 얼마나 잘 하는지에 대해서요. 전형적으로 우리는 이것을 여러 단계로 하고 싶습니다. 그래서 우리는 굵은 (coarse) 단계 (stage)를 먼저해서 떨어져서 분포해 있는 값들을 고를 수 있습니다. 그리고 몇 에포크 (epoch)만 학습합니다. 그리고 단지 몇 에포크만으로도 여러분은 어떤 하이퍼파라미터들의 어떤 값들이 좋은지 꽤 잘 알게 됩니다. NaN인지 금방 알 수 있고 아무것도 일어나지 않는 지 알 수 있고, 거기에 따라서 조정할 수 있죠. 보통 그것을 하고 나면, 여러분은 어디가 꽤 좋은 범위인 지를 알 수 있고, 더 세부적으로 샘플링해보고 싶은 범위를 알게 되죠. 이것이 두번째 단계인데, 더 긴 시간 동안 실행해 보고 그 영역에서 더 자세히 검색해 보고 싶을 겁니다. 훈련 루프 (loop)에서 NaN과 같은 폭발을 감지하는 팁 (tip)이 있는데, 몇 가지 하이퍼파라미터를 샘플링해서, 훈련을 시작하고, 매 이터레이션 (iteration)이나 매 에포크마다 비용을 보는 겁니다. 여러분의 초기 비용보다 훨씬 큰 비용을 얻는다면, 예를 들면, 초기비용보다 3배 더 크다면, 올바른 방향으로 가고 있지 않다는 겁니다. 그건 매우 빠르게 매우 커질 거고, 여러분은 그냥 루프를 빠져나와서 이 하이퍼파라미터 선택을 멈추고 다른 것을 선택하면 됩니다.
이것의 예로서, 굵은 (coarse) 탐색을 5 에포크동안 한다고 해보죠. 이것은 앞서서 얘기한 망과 비슷하죠. 우리는 이 모든 검증 정확도를 얻는 것을 볼 수 있습니다. 더 좋은 값을 내는 것들을 빨간색으로 하이라이트했습니다. 이것들이 더 자세히 들여다 볼 영역이 될 것입니다. 주목해야 할 점은 보통 로그 공간에서 최적화하는 것이 더 좋다는 것입니다. 그래서 동일하게 1e -0.01과 100사이를 샘플링하기 보다 여러분들은 사실 10의 어떤 범위 제곱을 할 것입니다. 왜냐면 학습률은 여러분의 경사 업데이트를 곱하기 때문입니다. 그래서 이런 곱셉 효과가 나타나고 그래서 어떤 값으로 곱하거나 나눠지는 학습률 영역을 고려하는 것이 더 의미가 있는거죠. 동일하게 샘플링하는 것 보다는요. 여러분은 여기서 몇 자리수를 다루게 될 겁니다.
그걸 일단 찾으면, 여러분의 범위를 조정할 수 있습니다. 이경우, 우리는 10의 -4제곱 부터 10의 0제곱까지 범위를 가집니다. 이것은 우리가 좁혀가야 할 좋은 범위죠. 이걸 다시해 볼 수 있죠. 여기서 우리는 비교적 좋은 53%의 정확도를 얻는다는 것을 알 수 있습니다. 이건 우리가 올바른 방향으로 나가고 있다는 것을 의미하죠.
한 가지 지적하고 싶은 것은 사실 여기에 문제가 있다는 겁니다. 문제는 우리의 모든 좋은 학습률은 이 -4제곱범위에 있다는 겁니다. 우리가 지정한 학습률은 10의 -4부터 10의 0까지 가고 있기 때문에, 모든 좋은 학습률은 우리가 샘플링하는 가장자리에 있다는 의미가 됩니다. 이건 나쁘죠. 우리의 공간을 충분히 탐색하지 않았다는 것을 의미하니까요. 우리는 사실 10의 -5제곱 혹은 -6제곱으로 가보고 싶을 겁니다. 아래쪽으로 계속 이동하면 훨씬 더 좋은 범위가 있을수도 있죠. 여러분의 범위는 중간의 어떤 좋은 값이 되도록 하고 싶거나, 여러분이 맞췄다 혹은 범위를 완전히 탐색했다는 느낌을 얻는 어떤 곳의 값이길 원할 겁니다.
또 다른 것은 일종의 그리드 탐색 (grid search)을 사용해서 우리의 다양한 하이퍼파라미터들을 모두 샘플링 할 수 있을 겁니다. 조합의 고정된 집합에 대해서 샘플링할 수 있고, 각각의 하이퍼파라미터에 대한 값의 고정된 집합에 대해서 샘플링할 수도 있습니다. 이 모든 값에 대해서 그리드 방식으로 샘플링하는거죠. 그러나 실제에선 , 임의의 레이아웃 (layout)부터 샘플하는 것이 더 좋습니다. 어떤 범위에서 각 하이퍼파라미터의 임의의 값을 샘플링하는거죠. 그대신 여기 이 두 하이퍼파라미터를 얻을 거고, 그것으로부터 샘플을 하고 싶을 겁니다. 그대신 오른쪽과 같은 샘플을 얻는 거죠. 이렇게 하는 이유는 만약 함수가 정말 다른 변수보다 어떤 변수에 대한 함수라면, (보통 참인데요) 우리는 우리가 가진 차원보다 더 낮은 효과적인 차원을 얻습니다. 그럼 여러분은 더 많은 중요한 변수의 샘플을 얻을 겁니다. 여러분은 제가 위에 그린 녹색 함수에서 이 모양을 볼 수 있을 겁니다. 여기 보면, 단지 그리드 레이아웃을 했을 때, 단지 3개의 값만 샘플할 수 있었고, 좋은 영역을 놓쳤죠. 사실상 우리는 전체적으로 훨씬 더 유용한 신호를 얻게 될 것입니다. 왜냐면, 우리는 중요한 변수의 더 많은 다양한 샘플을 가지기 때문입니다.
가지고 놀 하이퍼파라미터들은, 학습률에 대해서 얘기했고, 여러 종류의 감소 일정 (decay schedule), 업데이트 타입, 정규화 (regularization), 그리고 망 아키텍처, 그리고 숨겨진 단위의 수, 깊이, 이 모든 것들이 최적화할 수 있는 하이퍼파라미터들입니다. 이것들의 일부에 대해서 얘기했고, 더 많은 것들에 대해서는 다음 강의에서 얘기하겠습니다. 여러분들이 턴테이블 (turn table)의 모든 손잡이들을 튜닝한다면 (tuning), 여러분들은 신경망을 하는 사람이니까, 음악을 생각할 수 있고, 출력은 원하는 손실함수이고 여러분들은 모든 것들을 적절히 조정해서 원하는 출력을 얻게 되는거죠. 여러분이 하는 건 정말 일종의 예술이죠.
실제에선, 여러분은 많은 하이퍼파라미터 최적화를 할거고, 교차 검증을 많이 할 겁니다. 숫자를 얻기 위해서는 수많은 하이퍼파라미터에 대해서 교차검증을 할거고, 그것들 모두를 모니터링하고 뭐가 더 좋은지, 뭐가 더 나쁜지 볼 것입니다. 여기 우리의 모든 손실 곡선이 있죠. 맞는 것을 골라서 다시 조정하고 이 과정을 계속 거치죠.
앞서 얘기했듯이, 이 손실 곡선 각각을 모니터링해보면, 학습률은 중요합니다. 그러나 여러분은 얼마나 다양한 학습률에 대해서 어떤 학습률이 좋고 나쁜지 느끼게 될 겁니다. 만약 매우 높은 폭발하는 것이 있으면, 이게 손실 폭발이죠. 그럼, 학습률이 매우 높은 겁니다. 만약 그게 너무 선형적이고 너무 평평하면, 그것이 너무 낮거나 충분히 변하지 않고 있다는 것을 알게 될 겁니다. 가파르게 변화하다가 평평해 지는 것을 얻으면, 이것도 또한 너무 높다는 것을 표시하는 겁니다. 왜냐면 이경우, 여러분은 너무 큰 점프를 해서, 지역 최적 (local optimization)에 잘 안착하지 못한 것이니까요. 좋은 학습률은 보통 이렇게 보이는 것으로 끝납니다. 비교적 가파른 곡선이 나오다가 그다음 계속해서 내려가는 거죠. 그다음 여러분은 거기서부터 학습률을 계속 조정할 겁니다. 이건 연습을 통해서 보게 될 것입니다.
거의 끝에 다 왔는데요. 마지막으로 지적하고 싶은 것은 손실 곡선이 잠시동안 평평하다가 갑자기 학습을 하는 것을 본다면,
잠재적인 이유는 초기화가 잘못됐기 때문일 겁니다. 이 경우, 경사가 초기에 아주 잘 흐르지 않아서 아무것도 학습이 안되는 겁니다. 그리고 어떤 지점에서 올바른 방향으로 조정하게 된거죠. 한쪽으로 기울어져서 훈련이 시작된 거죠.
이런 것을 본 적이 많습니다. 시간을 두고 뭐가 잘못됐는지 보는거죠. 그럼 보통 정확도를 모니터링하고 시각화합니다. 만약 훈련 정확도와 검증 정확도 사이에 간격이 크다면, 보통 과적합되었다는 것을 의미하고 정규화 (regularization) 강도를 높이고 싶을 겁니다. 간격이 없다면, 모델의 용량 (capacity)을 키우고 싶을 겁니다. 왜냐면, 과적합된 적이 없기 때문에, 잠재적으로 그걸 더 키울수 있는 거죠.
일반적으로 우리는 업데이트, 즉 가중치에 대한 가중치 업데이트 비율을 추적하고 싶습니다. 우리는 파라미터들의 놈 (norm)을 취해서 그것들이 얼마나 큰 지에 대한 감을 얻을 수 있고, 업데이트 크기를 얻었을 때, 그것의 놈을 취해서, 그것이 얼마나 큰지 에 대한 감을 얻을 수 있죠. 그리고 우리는 이 비율이 0.001 근처가 되길 원합니다. 이 범위에는 많은 분산이 있어서 이것에 대해서 정확할 필요는 없습니다. 여러분의 값에 비해서 업데이트가 너무 크거나 너무 작게 되지 않기를 바란다는 의미입니다. 지배적이거나 아무 영향이 없는 것을 원하지 않는 것이죠. 이건 그냥 문제가 무엇인지 디버깅하는 데 도움을 주는 것입니다.
요약하면, 오늘 우리는 활성함수, 데이타 전처리, 가중치 초기화, 배치 정규화, 학습 과정 베이비시팅, 그리고 하이퍼파라미터 최적화를 봤습니다. 이것들은 각각에 대해 일종의 기억해야 할 것들입니다. 렐루를 사용하기, 평균을 빼기, 자비에 초기화를 사용하기, 배치 정규화 사용, 그리고 하이퍼파라미터를 임의로 샘플링하기죠. 다음시간에는 신경망 학습에 대해서 다른 주제들로 이야기 하겠습니다.
'AI' 카테고리의 다른 글