단위 테스트는 당신의 친구입니다
작가들 사이에 "모든 글은 다시 쓰기"입니다. 즉, 글쓰기의 대부분이 수정되고 있습니다. 프로그래머 (또는 최소한 데이터 과학자)에게 표현은 "모든 코딩은 디버깅 중"으로 표현 될 수 있습니다.
코드를 작성할 때마다 코드가 의도 한대로 작동하는지 확인해야합니다. 정확성을 검증하기 위해 내가 찾은 가장 좋은 방법은 코드를 작은 세그먼트로 나누고 각 세그먼트가 작동하는지 확인하는 것입니다. 이것은 세그먼트 출력을 정답이라고 알고있는 것과 비교하여 수행 할 수 있습니다. 이것을 단위 테스트 라고 합니다. 좋은 단위 테스트를 작성하는 것은 좋은 통계 학자 / 데이터 과학자 / 기계 학습 전문가 / 신경망 전문가가되기위한 핵심 요소입니다. 대체물은 없습니다.
네트워크 성능을 조정하기 전에 코드에 버그가 없는지 확인해야합니다! 그렇지 않으면 RMS 타이타닉 에서 갑판 의자를 재배치 할 수도 있습니다 .
신경망에는 다른 유형의 기계 학습 또는 통계 모델보다 검증을 더욱 중요하게하는 두 가지 기능이 있습니다.
신경망은 랜덤 포레스트 또는 로지스틱 회귀와 같은 방식으로 "기성품"알고리즘이 아닙니다. 단순한 피드 포워드 네트워크의 경우에도 네트워크 구성, 연결, 초기화 및 최적화 방법에 대한 수많은 결정을 내릴 책임은 사용자에게 있습니다. 이것은 코드 작성을 의미하고 코드 작성은 디버깅을 의미합니다.
신경망 코드가 예외를 일으키지 않고 실행 되더라도 네트워크에는 여전히 버그가있을 수 있습니다! 이러한 버그는 네트워크가 훈련 할 교활한 종류 일 수도 있지만 차선책으로 해결되지 않거나 결과 네트워크에 원하는 아키텍처가 없습니다. ( 이것은 구문 오류와 의미 오류의 차이점에 대한 예입니다 .)
체이스 로버츠 (Chase Roberts) 의이 " 중간 테스트 기계 학습 코드 방법 "에서는 기계 학습 모델의 단위 테스트에 대해 자세히 설명합니다. 이 기사에서 버그가있는 코드 예제를 빌 렸습니다.
def make_convnet(input_image):
net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool2')
net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
net = slim.max_pool2d(net, [2, 2], scope='pool3')
net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
return net
오류가 보입니까? 이전 결과가 새 변수로 덮어 쓰기 때문에 많은 다른 작업이 실제로 사용 되지 않습니다 . 네트워크에서이 코드 블록을 사용하면 계속 훈련되고 가중치가 업데이트되고 손실이 줄어들 수 있지만 코드는 의도 한대로 작동하지 않습니다. 저자는 또한 작은 따옴표 나 큰 따옴표를 사용하는 데 일관성이 없지만 순전히 문체입니다.
신경망과 관련된 가장 일반적인 프로그래밍 오류는 다음과 같습니다.
- 변수는 만들어 지지만 사용되지는 않습니다 (보통 복사-붙여 넣기 오류로 인해).
- 그라디언트 업데이트에 대한 표현식이 올바르지 않습니다.
- 체중 업데이트는 적용되지 않습니다.
- 손실 함수는 올바른 척도로 측정되지 않습니다 (예를 들어, 교차 엔트로피 손실은 확률 또는 로짓으로 표현 될 수 있음)
- 손실은 작업에 적합하지 않습니다 (예 : 회귀 작업에 범주 형 교차 엔트로피 손실 사용).
걷기 전에 기어 다니십시오. 달리기 전에 걷기
넓고 깊은 신경망과 이국적인 배선을 가진 신경망은 현재 머신 러닝의 핵심입니다. 그러나 이러한 네트워크는 완전히 형성되지 않았습니다. 그들의 디자이너는 더 작은 단위에서 그들까지 구축했습니다. 먼저 단일 숨겨진 계층으로 소규모 네트워크를 구축하고 올바르게 작동하는지 확인하십시오. 그런 다음 모델 복잡성을 점진적으로 추가하고 각각의 모델이 제대로 작동하는지 확인하십시오.
한 레이어에 너무 적은 뉴런 은 네트워크가 학습하는 표현을 제한하여 언더 피팅을 유발할 수 있습니다. 네트워크가 훈련 데이터를 "암기"하기 때문에 너무 많은 뉴런이 과적 합을 유발할 수 있습니다.
수학적으로 문제를 모델링하는 데 필요한 소수의 뉴런 만 있다는 것을 수학적으로 증명할 수 있더라도 "몇 가지 더 많은"뉴런이 있으면 옵티마이 저가 "좋은"구성을 쉽게 찾을 수있는 경우가 종종 있습니다. (그러나 나는 이것이 왜 그런지를 완전히 이해하지 못한다고 생각합니다.) XOR 문제와 관련하여 여기에 대한 예를 제공합니다 .MOR <0.001이 너무 높은 XOR에 대해 NN을 훈련시키는 데 반복이 필요하지 않습니까? .
숨겨진 레이어 수를 선택하면 네트워크가 원시 데이터에서 추상화를 배울 수 있습니다. 딥 러닝은 요즘의 모든 분노이며 많은 레이어를 가진 네트워크는 인상적인 결과를 보여주었습니다. 그러나 너무 많은 숨겨진 계층을 추가하면 과적 합의 위험이 발생하거나 네트워크를 최적화하기가 매우 어려워 질 수 있습니다.
영리한 네트워크 배선을 선택하면 많은 작업을 수행 할 수 있습니다. 데이터 소스가 특수한 네트워크 아키텍처에 적합합니까? 컨볼 루션 신경망은 "구조화 된"데이터 소스, 이미지 또는 오디오 데이터에서 인상적인 결과를 얻을 수 있습니다. 반복적 인 신경망은 자연어 또는 시계열 데이터와 같은 순차적 데이터 유형에 적합합니다. 잔여 연결은 딥 피드 포워드 네트워크를 향상시킬 수 있습니다.
신경망 훈련은 자물쇠 따기와 같습니다
최신의 결과를 얻거나 단순히 좋은 결과를 얻으려면 함께 작동하도록 구성된 모든 부품을 설정해야 합니다 . 실제로 학습하는 신경망 구성을 설정하는 것은 잠금 장치를 선택하는 것과 매우 유사합니다. 모든 부분을 올바르게 정렬해야합니다 . 올바른 위치에 단일 텀블러를 설치하는 것만으로는 충분하지 않지만 아키텍처 만 또는 최적화 프로그램 만 설정해도 충분하지 않습니다.
구성 선택 조정은 하나의 구성 선택 (예 : 학습 속도)이 다른 선택 (예 : 단위 수)보다 중요하거나 중요하지 않다고 말하는 것만 큼 간단하지 않습니다. 이러한 선택은 모두 다른 선택과 상호 작용하므로 선택은 다른 곳에서 이루어진 다른 선택과 함께 잘 할 수 있습니다 .
이는 정규화 옵션이나 수치 최적화 옵션이 아닌 구성 옵션의 전체 목록입니다.
이 모든 주제는 활발한 연구 분야입니다.
네트워크 초기화 는 종종 신경망 버그의 원인으로 간과됩니다. 너무 큰 간격으로 초기화하면 초기 가중치가 너무 크게 설정 될 수 있습니다. 이는 단일 뉴런이 네트워크 동작에 비해 큰 영향을 미칩니다.
신경망과 회귀 모델의 주요 차이점은 신경망은 활성화 함수 라는 많은 비선형 함수의 구성이라는 것 입니다. (참고 : 신경망과 선형 회귀의 본질적인 차이점은 무엇입니까? )
고전 신경망 결과는 S 자형 활성화 기능 (물류 또는 기능) 에 중점을 둡니다 . 최근 결과에 따르면 ReLU (또는 유사한) 단위는 기울기가 가파르 기 때문에 더 잘 작동하는 경향이 있으므로 업데이트를 빠르게 적용 할 수 있습니다. 신경망에서 왜 ReLU를 사용하고 어떻게 사용 하는가?를 참조하십시오. ReLU에 대한 한 가지주의는 "죽은 뉴런"현상인데, 이는 학습을 방해 할 수 있습니다. 새는 relus 및 유사한 변종은이 문제를 피합니다. 보다탄
다른 많은 옵션이 있습니다. 참조 : 장단점이있는 신경망의 포괄적 인 활성화 기능 목록
잔여 연결은 신경망을 쉽게 훈련시킬 수있는 깔끔한 개발입니다. "이미지 인식을위한 딥
레지던트 학습" Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun In : CVPR. (2016). 또한, 잔차 블록 내에서 동작 순서를 변경하면 결과 네트워크가 더욱 향상 될 수있다. " 깊은 잔여 네트워크에서 아이디 매핑 Kaiming 그는, 상서 장, Shaoqing 랜 및 지앤 일에 의해"
볼록하지 않은 최적화는 어렵다
신경망의 목적 함수는 숨겨진 단위가없고 모든 활성화가 선형이고 설계 행렬이 전체 순위 인 경우에만 볼록합니다.이 구성은 일반적인 회귀 문제이기 때문입니다.
다른 모든 경우에 최적화 문제는 볼록하지 않으며 볼록하지 않은 최적화는 어렵습니다. 신경망 훈련의 과제는 잘 알려져 있습니다 ( 심층 신경망을 훈련하기 어려운 이유는 무엇입니까? 참조 ). 또한 신경망에는 매우 많은 수의 매개 변수가 있으므로 1 차 방법으로 만 제한됩니다 ( 뉴턴의 방법이 기계 학습에 널리 사용되지 않는 이유는 무엇입니까? 참조 ). 이것은 매우 활발한 연구 분야입니다.
학습 속도를 너무 크게 설정하면 "캐년"의 한 쪽에서 다른쪽으로 도약하기 때문에 최적화가 분기됩니다. 이 값을 너무 작게 설정하면 실제 진행 상황을 막을 수 있으며 SGD 고유의 노이즈가 경사도 추정치를 압도 할 수 있습니다.
그라디언트 클리핑 은 그라디언트가 임계 값을 초과하면 그라디언트의 규범을 다시 조정합니다. 나는 이것이 일반적으로 1.0의 설정 및 잊어 버림 매개 변수라고 생각했지만 LSTM 언어 모델을 0.25로 설정하여 크게 향상시킬 수 있음을 발견했습니다. 왜 그런지 모르겠습니다.
학습 속도 예약 은 교육 과정에서 학습 속도를 낮출 수 있습니다. 내 경험상, 스케쥴링을 사용하는 것은 정규 표현식 과 매우 흡사 합니다. 하나의 문제 ( "특정 시대 이후 계속 배우는 방법")를 두 가지 문제 ( "특정 시대 이후 계속 배우는 방법")를 대체합니다. ? "및"좋은 일정을 어떻게 선택합니까? "). 다른 사람들은 일정이 필수적이라고 주장합니다. 내가 결정하게 해줄 게
좋은 미니 배치 크기를 선택하면 학습 과정에 간접적으로 영향을 줄 수 있습니다. 더 큰 미니 배치는 작은 미니 배치보다 분산이 적습니다 ( 대수 ). 미니 배치가 그라디언트의 방향에 대한 정보를 제공 할 수있을만큼 커야하지만 SGD가 네트워크를 정규화 할 수있을만큼 작아야합니다.
확률 론적 경사 하강 에는 바닐라 SGD를 향상시키기 위해 운동량, 적응 학습률, Nesterov 업데이트 등을 사용 하는 여러 가지 변형 이 있습니다. 더 나은 최적화를 설계하는 것은 매우 활발한 연구 분야입니다. 몇 가지 예 :
아담 옵티마이 저가 처음 나왔을 때 많은 관심을 끌었습니다. 그러나 최근의 일부 연구에 따르면 운동량을 가진 SGD는 신경망에 대한 적응 형 그래디언트 방법을 능가 할 수 있습니다. " 머신 러닝에서 적응 형 그라디언트 방법의 한계 값 "Ashia C. Wilson, Rebecca Roelofs, Mitchell Stern, Nathan Srebro, Benjamin Recht
그러나 다른 한편으로,이 최근 논문은 적응 속도 방법과 SGD 간의 모멘텀을 좁히는 새로운 적응 학습 속도 최적화 프로그램을 제안합니다. " 교육 깊은 신경망에 적응 그라데이션 방법의 일반화 격차를 징후이 첸, Quanquan 구에 의해"
학습 그라디언트 정보를 자동으로 학습하기 위해 히스토리 그라디언트 정보를 채택하는 적응 형 그라디언트 방법은 심층 신경망 훈련에서 추진력으로 확률 적 그라디언트 디센트 (SGD)보다 더 악화되는 것으로 관찰되었습니다. 이것은 적응 적 그라디언트 방법의 일반화 격차를 해소하는 방법을 공개적인 문제로 남겨둔다. 이 연구에서 우리는 Adam, Amsgrad와 같은 적응 형 그래디언트 방법이 때때로 "과도하게 적용됨"을 보여줍니다. 우리는 Partially adaptive momentum 추정 방법 (Padam)이라는 새로운 알고리즘을 설계합니다.이 알고리즘은 Adam / Amsgrad를 SGD와 통합하여 두 세계에서 최고를 달성합니다. 표준 벤치 마크에 대한 실험에 따르면 Padam은 심층 신경망 교육에서 SGD뿐만 아니라 일반화하면서 Adam / Amsgrad와 같은 빠른 수렴 속도를 유지할 수 있습니다.
표준화
데이터의 규모는 훈련에 큰 차이를 만들 수 있습니다.
신경망에 데이터를 제시하기 전에 0 평균 및 단위 분산을 갖거나 와 같이 작은 간격으로 데이터를 표준화 하면 훈련이 향상 될 수 있습니다. 이는 사전 조정에 해당하며 단위 선택이 네트워크 가중치에 미치는 영향을 제거합니다. 예를 들어, 밀리미터 단위의 길이와 킬로미터 단위의 길이는 모두 동일한 개념을 나타내지 만 다른 스케일로 표시됩니다. 데이터를 표준화하는 방법에 대한 정확한 세부 사항은 데이터의 모양에 따라 다릅니다.[ - 0.5 , 0.5 ]
레이어 정규화 는 뉴런 활성화에 대한 평균과 표준 편차를 유지함으로써 네트워크 훈련을 향상시킬 수 있습니다. 이것이 왜 훈련에 도움이되는지 잘 이해하지 못하고 있으며 활발한 연구 분야로 남아 있습니다.
- " 배치 정규화 이해 ", Johan Bjorck, Carla Gomes, Bart Selman
- " 배치 정규화의 이론적 이해를 향하여 "Jonas Kohler, Hadi Daneshmand, Aurelien Lucchi, Ming Zhou, Klaus Neymeyr, Thomas Hofmann
- " 배치 정규화가 최적화를 어떻게 도와 주나요? (아니오, 내부 공변량 변화에 관한 것이 아닙니다) "by Shibani Santurkar, Dimitris Tsipras, Andrew Ilyas, Aleksander Madry
정규화
네트워크 정규화를 선택하고 조정하는 것은 일반화하는 모델 (즉, 훈련 데이터에 적합하지 않은 모델)을 구축하는 데있어 중요한 부분입니다. 그러나 네트워크가 학습 중이 아닌 경우 훈련 데이터의 손실을 줄이기 위해 고군분투 할 때 정규화는 문제가 무엇인지 모호하게 할 수 있습니다.
네트워크가 학습되지 않으면 모든 정규화 기능을 끄고 비정규 화 된 네트워크가 올바르게 작동하는지 확인합니다. 그런 다음 각 정규화 부분을 다시 추가하고 각 정규화가 작동하는지 확인합니다.
이 전략은 일부 정규화가 제대로 설정되지 않은 위치를 찾아 낼 수 있습니다. 몇 가지 예는
엘2 정규화 (일명 중량 감쇄) 또는 정규화가 너무 크게 설정되어 가중치를 이동할 수 없습니다.엘1
정규화의 두 부분이 충돌합니다. 예를 들어, 레이어 정규화와 드롭 아웃을 함께 사용하기 어렵다는 것이 널리 알려져 있습니다. 그 자체만으로도 매우 유용하므로 두 가지 사용법을 이해하는 것이 활발한 연구 분야입니다.
실험 일지 보관
신경망을 설정할 때 매개 변수 설정을 하드 코딩하지 않습니다. 대신 런타임에 읽고 네트워크 구성 세부 정보를 채우는 데 사용되는 구성 파일 (예 : JSON)에서이 작업을 수행합니다. 이 모든 구성 파일을 유지합니다. 매개 변수를 수정하면 새 구성 파일을 만듭니다. 마지막으로, 교육 및 검증에 대한 모든 에포크 손실을 주석으로 추가합니다.
이전 결과를 유지하는 데 너무 강박적인 이유는 이전 실험을 매우 쉽게 되돌아 가서 검토 할 수 있기 때문입니다. 또한 동일한 데드 엔드 실험을 실수로 반복하지 않도록 방지합니다. 심리적으로, 그것은 당신이 뒤돌아 보면서 "글쎄, 프로젝트가 내가 원하는 곳이 아닐 수도 있지만, 내가 주 전에 있었던 곳과 비교하여 진전을 보이고있다 ."케이
예를 들어 LSTM 언어 모델에 대해 배우고 싶었으므로 다른 트위터 사용자에 대한 응답으로 새로운 트윗을 작성하는 트위터 봇을 만들기로 결정했습니다. 나는 자유 시간에 대학원과 직장 사이에서이 일을했습니다. 약 1 년이 걸렸으며, 내가 원하는 것을 한 모델에 도달하기 전에 약 150 가지가 넘는 모델을 반복했습니다. (다양한) 의미가있는 새로운 영어 텍스트를 생성합니다. (한 가지 중요한 문제는 여러 번 시도한 이유 중 하나는 초기 저손실 모델이 훈련 데이터를 기억할 수 있었기 때문에 단순히 샘플 외부 손실을 얻는 것만으로는 충분하지 않았기 때문입니다. 따라서 프롬프트에 응답하여 독일어 텍스트 블록을 그대로 재생했습니다. 모델을 더 자연스럽게 만들고 여전히 손실이 적도록 조정하는 데 약간의 조정이 필요했습니다.)