가중치의 초기값
- 오버피팅을 억제하기 위해 '가중치 감소(가중치 매개변수의 값이 작아지도록 학습)'기법을 사용
- L1규제: 가중치의 절대값에 비례하는 비용이 추가
- L2규제: 가중치의 제곱에 비례하는 비용이 추가(weight decay)
- 둘 다 쓸 수 있는데 이 방식을 ElasticNet이라고 부름
- keras에서 regularizers.l2(0.001)로 주면 가중치 행렬의 모든 원소를 제곱하고 0.001을 곱하여 네트워크의 전체 손실에 더해진다는 의미
- 이 페널티는 훈련할 때만 추가되고, 손실은 테스트보다 훈련할 때 더 높을것임
- 훨씬 오버피팅에 잘 견딤
- 만약 0으로 두면? -> 오차역전파법에서 모든 가중치의 값이 똑같이 갱신되기 때문에 가중치를 여러개 갖는 의미 사라짐
- 그러므로 가중치가 고르게 되면 안되므로 초기값을 무작위로 설정
은닉층의 활성화 값 분포
- sigmoid는 0과 1에 가까워지면 미분이 0이 됨 -> 0,1에 치우쳐 분포하게 되면 역전파의 기울기 값이 점점 작아지다가 사라짐 -> 층을 깊게하는 딥러닝에서 기울기 소실은 심각한 문제 -> Xavier 초기값 사용
- 각 층의 활성화 값은 적당히 고루 분포되어야함 -> 층과 층 사이에 적당하게 다양한 데이터가 흐르게 해야 학습이 효율적
- 신경망에 아주 작은 데이터가 흐른다는 것은 역전파 때 가중치의 기울기도 작아진다는 것을 의미
- ReLU는 He 가중치 초기값을 사용하면 층이 깊어져도 활성화 값의 분포가 균일하게 유지되기 때문에 역전파 때도 적절한 값이 나올 것으로 기대
- 가중치 초기 값을 적절히 설정하면 각 층의 활성화값 분포가 적당히 퍼지면서 학습이 원활하게 수행
배치 정규화 (Batch Normalization)
- 가중치 초기값으로 활성화값 분포를 퍼지게 하는 것이 아니라 각 층이 활성화를 적당히 퍼뜨리도록 '강제'
- 학습이 빠르고, 초기값에 크기 의존 X, 오버피팅 억제(drop-out 필요성 감소)
- 활성화 함수 앞에 붙이는지 뒤에 붙이는게 나은지는 아직 논의 중..
오버피팅
- 매개변수가 많고, 표현력이 높은 모델( 데이터에 비해 지나치게 깊은 경우), 훈련데이터가 적은 경우
- 오버피팅은 가중치 매개변수의 값이 커서 발생하는 경우가 많음 -> 가중치 값을 줄여줌
- 모델이 클수록 더 빠르게 훈련 데이터를 모델링 할 수 있지만, 오버피팅에 민감해 짐(결국 훈련과 검증 손실 사이에 큰 차이가 발생)
드롭아웃
- 신경망이 복잡해지면 가중치 감소만으로는 대응하기 어려움
- 뉴런을 임의로 삭제하면서 학습 -> Test때는 모든 뉴런에 신호를 전달
- 단, 시험때는 각 뉴런의 출력에 훈련 때 삭제한 비율을 곱하여 출력
- 앙상블 학습과 같은 효과를 하나의 네트워크로 구현했다고 생각
- 보통 0.2 - 0.5 사이로 지정
- 케라스에서 출력층 바로 뒤에 붙임, 테스트에서는 출력 그대로 사용
하이퍼 파라미터
- 하이퍼 파라미터의 성능을 평가할 때는 시험데이터를 사용해서는 안됨 -> validation data에서 평가
- 하이퍼 파라미터 값의 범위를 설정 -> 무작위로 추출 -> 학습하고 평가 -> 범위를 좁혀감
- 여러번 validation data에서 평가해서 하이퍼 파라미터를 조정하면 이것 또한 오버피팅
- k-fold, shuffling을 사용한 반복 k-fold 사용
modelling tip
-
많은 수의 범주를 분류할 때 중간층의 크기가 너무 작아 네트워크에 정보의 병목이 생기지 않도록 함
-
가용한 훈련 데이터가 적다면 overfitting을 피하기 위해 은닉 층의 수를 줄인 모델이 좋음(1,2개)
-
가용한 데이터가 적다면 K-FOLD
평가
- 클래스 분포가 균일한 분류 문제에서는 정확도와 ROC-AUC
- 클래스 분포가 균일 하지 않은 문제는 정밀도와 재현율
- 랭킹 문제나 다중 레이블 문제에는 평균 정밀도(정밀도에 대한 재현율의 곡선의 아랫부분 면적)
- ROC: 거짓양성비율(false positive rate)에 대한 재현율의 곡선
- ROC-AUC: ROC곡선의 아랫부분 면적(roc_auc_score())
- 평균 정밀도: 정밀도에 대한 재현율의 곡선(정밀도-재현율 곡선)의 아랫부분 면적(average_precision_score())
지도학습
-
대부분 분류와 회귀말고도
-
시퀀스 생성: 사진이 주어지면 이를 설명하는 캡션을 생성
-
구문 트리: 문장이 주어지면 분해된 구문 트리를 예측
-
물체 감지: 사진이 주어지면 사진 안의 특정 물체 주위에 bounding box그림
-
이미지 분할: 사진이 주어졌을때 픽셀 다누이로 특정 물체에 마스킹
비지도 학습
- 데이터 시각화, 데이터 압축, 데이터의 노이즈 제거 또는 데이터에 있는 상관관계를 더 잘 이해하기 위해 사용
자기 지도 학습
- 지도 학습의 특별한 경우지만 레이블이 보통 경험적인 알고리즘(heuristic algorithm)을 사용해서 입력 데이터로부터 생성
- 오토인코더: 생성된 타깃(정답)은 수정하지 않은 원본 입력
- 타깃이 있고 손실 함수를 최소화 하도록 학습되기 때문에 지도 학습으로 보이지만, 입력 데이터의 차원 축소 용도로 사용될 때는 비지도 학습으로 볼 수 있음
- 지난 프레임이 주어졌을 때 비디오의 다음 프레임을 예측하는 것
- 이전 단어가 주어졌을 때 다음 단어를 예측하는 것(이 경우에는 미래의 입력 데이터로부터 지도되기 때문에 시간에 따른 지도학습)
강화 학습
- 에이전트(agent)는 환경에 대한 정보를 받아 보상을 최대화 하는 행동을 선택하도록 학습
- 강화 학습으로 훈련된 신경망은 비디오 게임화면을 입력으로 받고 게임 점수를 최대화하기 위한 게임 내의 행동을 출력
- 게임 이외에 아직 실제적인 성공 사례는 없음
- 자율 주행 자동차, 자원 관리, 교육 등에 쓰일 수 있음
특성 공학
-
특성을 더 간단한 방식으로 표현하여 문제를 쉽게 만듦
-
시계 이미지를 입력으로 받고 하루의 시간을 출력하는 모델을 개발한다면, 원본 픽셀을 입력하는것 보다 합성곱 신경망사용
-
또는 시계바늘 끝의 좌표대신 극좌표를 이용 -> 머신러닝 전혀 필요 X -> 간단한 반올림 연산과 딕셔너리 참조만 하면 하루 시간 추정은 충분..
-
하지만 이제는 대부분 특성공학이 필요하지 않다!! 왜냐!
- 좋은 특성은 적은 자원으로 잘 풀 수 있다.. 시계바늘 극좌표로 표시해 푸는것처럼..
- 좋은 특성은 더 적은 데이터로 풀 수 있음
CNN
-
피처맵의 깊이는 네트워크에서 점진적으로 증가하지만, 피처맵의 크기는 감소
-
pretrained 모델을 쓸 때, 새로운 데이터셋이 원본 모델이 훈련한 데이터셋과 많이 다르다면 천제 Conv기반 층을 사용하는 것 보다는 모델의 하위 층(엣지, 색, 질감 등 일반적인 피처맵 추출) 몇 개만 피처 추출에 사용하는 것이 좋음
(상위층(강아지눈이나 고양이 귀처럼 추상적인 개념)은 학습된 데이터에 특화되어있으므로)
-
데이터 증식을 사용한 특성추출
- pretrained 모델을 컴파일하고 훈련하기전에 Conv기반 층을 동결하는 것은 아주 중요함
- 동결: 훈련하는동안 가중치가 업데이트되지 않도록 막는다는 뜻
- Dense층은 랜덤하게 초기화되었기 때문에 매우 큰 가중치 업데이트 값이 네트워크에 전파될 것이다
- Dense층만 가중치 훈련
-
미세조정
Pooling
왜 풀링 층을 빼고 Conv맵을 계속 유지하지 않고, 다운 샘플링을 하는가?
- 피처의 공간적 계층 구조를 학습하는 데 도움이 되지 않는다.
- 예를 들면 3x3 윈도우는 초기 인풋의 7x7윈도우 영역에 대한 정보만 담고있다. 즉 전체 입력에 대한 정보를 가지고 있지 않다.
- 폴링을 하지않으면 예를들어 (3번째)최종 피처맵이 22x22x64 이면 30,976개의 원소를 가진다. 그리고 512크기의 Dense층과 연결한다면 약 15.8백만개의 가중치 파라미터가 생기는데 작은 모델치고는 너무 많은 가중치고, 심각한 오버피팅 발생
- 간단히 말해서 downSampling을 사용하는 이유는 처리할 피처맵의 가중치 개수를 줄이기 위해서
- 다운샘플링 방법으로 폴링 말고 Conv층에서 stride로 사용가능
- Max-Pooling이 Average-Pooling보다 나은 이유는 피처가 피처맵의 각 타일에서 어떤 패턴이나 개념의 존재 여부를 인코딩하는 경향이 있기 때문 (그래서 피처 맵임)
adaptive pooling
Outlier/unbalanced
-
선형 모델은 중요 피처들의 값이 정규 분포 형태를 유지하는 것을 선호
- StandardScaler.fit_transform
- log
-
데이터 범위가 다른 feature가 있다면 Standardization - feature의 scale이 다르면 global minimum을 찾아가는 gradient descent의 경로가 scale이 큰 feature에 영향을 많이 받음
-
outlier 판단 - IQR(사분위 값 편자 이용) * 1.5 로 최대값, 최솟값을 결정 후 나머지 범위는 outlier로 판단
Encoding
- 레이블로 인코딩하게되면 어느 특정 알고리즘에서 가중치가 더 부여되거나 중요하게 인식할 수 있음
- 레이블 인코딩은 선형회귀같은 ML알고리즘에는 적용 X(트리 계열의 ML알고리즘은 숫자의 이러한 특성을 반영하지 않으므로 레이블 인코딩 무관) -> One-hot Encoding
Ensemble Learning
- 여러개의 분류기를 생성하고, 그 예측을 결합함으로써 도출
-
voting: 전체 데이터에 대해서 서로 다른 알고리즘을 가진 분류기를 결합
-
hard voting - 다수결
-
soft voting - 분류기들의 레이블 값 결정 확률을 평균내서 가장 높은 레이블 값을 보팅 (일반적으로 hard voting보다 우수)
-
bagging: 서로 같은 유형의 알고리즘 기반이지만, 데이터 샘플링(bootstraping)을 서로 다르게 가져가면서 학습을 하고 보팅 (random forest)
- Random Forest: 병렬처리 효과적, 서브세트의 데이터 건수 == 전체 데이터 건수와 동일, bootstrapping
-
boosting: 여러개의 분류기가 순차적으로 학습, 앞에서 학습한 분류기가 예측이 틀린 데이터에 대해서는 올바르게 예측할 수 있도록 다음 분류기에게 가중치(weigh)을 부여하면서 학습 (XGBoost)
- XGBoost:
- 학습 시간이 오래걸림, 병렬학습 가능
- Gradient boosting 기반(일반적으로 random forest보다 우수)
- GBM의 단점인 느린 수행시간, 과적합 규제(Regularization)부재 등의 문제를 해결
- 일반적으로 분류와 회귀 영역에서 뛰어남
- Tree pruning - 더이상 긍정 이득이 없는 분할을 가지치기 -> 분할 수 감소
- 자체 내장된 교차 검증 + 조기 중단
- 결손값 자체 처리
- 하이퍼 파라미터는 주로 딕셔너리 형태로 입력
- LightGBM:
- XGBoost보다 학습시간이 짧고, 예측 성능은 별다른 차이X, 메모리 사용량 적음
- 카테고리형 자동변환과 최적 변환(원-핫 인코딩 없어도 카테고리형 피처를 최적으로 변환하고, 이에 따른 노드 분할 수행)
- 데이터가 적으면(10,000건 이하) overfitting 위험
- 리프중심 트리분할(Leaf wise) : 트리 균형 x, max delta loss를 가지는 리프노드를 지속적으로 분할 -> 비대칭 (depth가 상대적으로 깊음: 설정 필요) -> 균형트리 분할 방식보다 예측 오류 손실을 최소화 할 수 있다는 것이 구현 사상
- 대부분 트리기반 알고리즘은 균형트리분할(Level wise)를 사용했는데, 균형을 유지해야 하기 때문에 트리의 깊이를 최소화 -> 오버피팅에 보다 강한 구조 (하지만 시간이 걸림)
-
stagging: 여러가지 다른 모델의 예측 결괏값을 다시 학습데이터로 만들어서 다른 모델(meta model)로 재학습
*bootstraping : 개별 Classifier에게 데이터를 샘플링해서 추출하는 방식, 교차검증과는 다르게 중첩을 허용
GridSearchCV
교차 검증과 최적 하이퍼 파라미터 튜닝을 한번에...!!
Classifier나 Regressor와 같은 알고리즘에 사용되는 하이퍼 파라미터를 순차적으로 입력하면서 도출 가능
ex)
LGBM_clf = LGBMClassifier(n_estimators=200)
params = {'num_leaces': [32, 64],
'max_depth': [128,160],
'min_child_samples': [60, 100],
'subsample': [0.8 ,1]}
gridcv = GridSearchCV(lgqbm_clf, param_grid = params)
gridcv.fit(X_train, y_train, early_stoppping_round = 30, eval_matric = "auc", eval_set=[(X_train, y_train), (X_test, y_test)])
print('GirdSearchCV 최적 parameter: ', gridcv.best_params)
lgqbm_roc_score = roc_auc_score(y_test, gridcv.predict_proba(X_test)[:, 1], average = 'macro')
print('ROC-AUC: {0: .4f}'.format(lgqbm_roc_score))
주의
- 대표성 있는 데이터: 데이터가 특정 순서대로 있는데 val,test세트로 나누면 문제가 되므로, 훈련 세트와 테스트 세트로 나누기 전에 데이터를 무작위로 섞음
- 시간의 방향: 과거로부터 미래를 예측하려고하면 분할하기 전에 무작위로 섞어서는 절대 안됨
- 데이터 중복: 한 데이터셋에 어떤 데이터 포인트가 두 번 등장하면, 데이터를 섞고 훈련 세트와 검증 세트로 나누었을 때 훈련 세트와 검증 세트에 데이터 포인트가 중복 될 수 있음 -> 훈련 데이터의 일부로 테스트하는 최악의 경우 발생
- 섞이지 않아야 할 그룹을 지정하여 keras에서 GroupKFold 클래스를 cross_validate()에 적용
- 일반적으로 0~1 사이 값
- 모든 feature는 대체로 비슷한 범위를 가져야함
- 꼭 필수는 아니지만 엄격한 정규화도 자주 사용됨
- 각 feature별로 평균이 0이 되도록 정규화
- 각 feature별로 표준 편차가 1이 되도록 정규화
- x -= x.mean(axis=0) # x가 2D행렬이라 가정, x.mean은 브로드캐스팅됨
- x /= x.std(axis=0)
- 누락된 값은 0(사전에 정의된 의미있는 값이 아니라면)으로 두면 네트워크가 누란된 값을 무시하는 법을 배움, 물론 다른값으로 채울 수 있음