티스토리 뷰
Overfitting : 학습데이터에 너무 최적화되어 weight 값이 잡히고, 이후 학습 데이터가 아닌 새로운 데이터에는 올바른 값을 내보내지 못하는 형상. 매개변수에 비해 상대적으로 훈련 데이터 수가 적을 때 일어난다.
Regularization : 데이터에 너무 과적합되어 모델이 피팅되었으니, 이를 좀 덜 적합하게 하고, 이후 새로운 데이터에도 일반적으로 들어맞는 모델을 만들어야 한다. 이 때, 과적합이 아닌 일반성을 띄게 해주는 기법
파라미터 : 훈련 데이터의 정보를 담는 슬롯
정보의 슬롯이 많아서 필요없는 특수한 정보 (MNIST에서의 예는 어떤 사람의 특유의 필체 같은 것 , 사실은 숫자의 모양만 알면 됨) 같은것이 너무 많이 들어가 일반적인 데이터는 판단을 못하게 되는 것입니다. 사실 파라미터가 많다는 것은 학습용 데이터가 적다는 이야기도 됩니다.
즉 학습용 데이터를 늘리거나, 뉴럴 네트워크를 단순화 시키던가 하면 오버피팅을 방지할 수 있습니다.
하지만 이런 방법 외에도 레귤라이제이션이라고 뉴럴 네트워크에 규제를 가해서 부수적이고 우연, 특수한 정보는 담지 않도록 만드는 방법도 있습니다.
책에서는 Weight Decay 와 Drop bit이 나옵니다.
L2-regularization : 새로운 손실함수 = 기존 손실함수 / 1/2 * ㅅ * (가중치의 제곱의 합) --> 큰 가중치는 많이 낮추고, 작은 가중치는 적게 낮춘다. ( 큰건 중요하고 적은건 별로면 두가지가 균형이 맞게 되는것과 비슷함 )
람다 ㅅ 에 따라서 패널티를 생각하는데, 극단적으로 람다가 0이라고 하면 패널티가 없다고 하는 것과 같습니다.
weight_decay = 0
for idx in range(1, self.hidden_layer_num + 2): # 다음 아파인층에서
W = self.params['W' + str(idx)] #웨이트 다 더하고
weight_decay += 0.5 * self.weight_decay_lambda * np.sum(W ** 2) # 1/2 * 람다 *제곱의 합
return self.last_layer.forward(y, t) + weight_decay # = 손실함수
def gradient(self, x, t):
"""기울기를 구한다(오차역전파법).
Parameters
----------
x : 입력 데이터
t : 정답 레이블
Returns
-------
각 층의 기울기를 담은 딕셔너리(dictionary) 변수
grads['W1']、grads['W2']、... 각 층의 가중치
grads['b1']、grads['b2']、... 각 층의 편향
"""
# forward
self.loss(x, t)
# backward
dout = 1
dout = self.last_layer.backward(dout)
layers = list(self.layers.values())
layers.reverse()
for layer in layers:
dout = layer.backward(dout)
# 결과 저장
grads = {}
for idx in range(1, self.hidden_layer_num+2): # 아래는 크로스 엔트로피 미분 + 람다* 아래는 엘투패널티 미분[웨이트 매트릭스 거의 그 자체였음]
grads['W' + str(idx)] = self.layers['Affine' + str(idx)].dW + self.weight_decay_lambda * self.layers['Affine' + str(idx)].W #
grads['b' + str(idx)] = self.layers['Affine' + str(idx)].db # 편향은 미분해봤자 0이니깐 크로스엔트로피 미분만 생각함
return grads
L1-regularization : 새로운 손실함수 = 기존함수 + ㅅ *(가중치의 절대값의 합) --> 큰 가중치나 작은 가중치나 동일하게 낮춰줍니다. (작은 가중치는 결국 0이되어서 날라가고, 큰 가중치들만 남아있게 됩니다. 중요한정보만 살리고 별로인건 날린다는 의미와 비슷합니다. )
두 레귤레이션은 정보를 날리게 하는 것에 의미가 있습니다.
Dropout : 뉴런을 무작위로 선택해 삭제하여 신호전달을 차단합니다.
마찬가지로 오버피팅을 방지하기 위해서 사용합니다.
Dropout도 층입니다. (순전파 역전파 존재)
class Dropout:
"""
http://arxiv.org/abs/1207.0580
"""
def __init__(self, dropout_ratio=0.5): # 몇 %만큼 죽이고 학습을 시킨다.
self.dropout_ratio = dropout_ratio
self.mask = None
def forward(self, x, train_flg=True):#훈련할때는 뉴런들을 랜덤하게 죽이면서 학습
if train_flg:
self.mask = np.random.rand(*x.shape) > self.dropout_ratio#rand는 0~1사이의 수를 랜덤하게 데이터 뽑는것 // 셀프.마스크 는 드롭아웃레이트보다 큰 값은 트루, 아닌값은 폴스인 트루폴스로 이루어진 행렬이된다.
return x * self.mask
else:#훈련아닐때는 죽이지않는다.
return x * (1.0 - self.dropout_ratio)
def backward(self, dout):
return dout * self.mask
dropout층에서는 흘려보낼 미분을 구하는게 목적 ( 학습시킬 파라미터가 없음 )
sigmoid relu softmax 와 같음
affine bath-nomalization 은 학습 시킴
'Study > 인공지능' 카테고리의 다른 글
하이퍼파라미터 튜닝 ( 인공지능 기초 #22 ) (0) | 2020.12.04 |
---|---|
심층신경망 (0) | 2020.10.27 |
배치 정규화 ( 인공지능 기초 #19 ) (0) | 2020.10.26 |
Xavier/He 초기값 ( 인공지능 기초 # 18 ) (0) | 2020.10.26 |
optimizer 종합 banch mark ( 인공지능 기초 # 17) (0) | 2020.10.25 |