[밑바닥부터 시작하는 딥러닝1] 밑딥 스터디 CH6 정리

    반응형

     

     

    Optimization

    • Optimization : parameter의 최적값을 찾는 것

    SGD (확률적 경사 하강법)

    class SGD:
    	def __init__(self, lr = 0.01):
    		self.lr = lr
    	
    	def update(self, params, grads):
    		for key in params.keys():
    			params[key] -= self.lr * grads[key]
    
    $\mathbf{W} \leftarrow \mathbf{W} - \eta \frac{\partial L}{\partial \mathbf{W}}$

     

    단, 

    식으로는 (0,0)이 최솟값이 되지만, 그래프에서는 대부분이 (0,0)방향을 보이지 않음 이런경우 학습 시 비효율적인 움직임을 보임

    momentum

    $\mathbf{v} \leftarrow \alpha \mathbf{v} - \eta \frac{\partial L}{\partial \mathbf{W}}$

    $\mathbf{W} \leftarrow \mathbf{W} + \mathbf{v}$

    class Momentum:
    	def __init__(self, lr = 0.01, momentum=0.9):
    		self.lr = lr
    		self.momentum = momentum
    		self.v = None
    
    	def update(self, params, grads):
    		if self.v is None:
    			self.v = {}
    			for key, val in params.items():
    				self.v[key] = np. zeros_like(val)
    	
    		for key in params.keys():
    			self.v[key] = self.momentum * self.v[key] - self.lr * grads[key]
    			params[key] += self.v[key]
    

    - x축의 힘은 작지만, 방향이 변하지 않아서 한 방향으로 일정하게 가속하므로 SGD보다 더적게 움직이고 도달할 수 있음

    Adagrad

    $\mathbf{h} \leftarrow \mathbf{h} + \left( \frac{\partial L}{\partial \mathbf{W}} \right) \odot \left( \frac{\partial L}{\partial \mathbf{W}} \right)$

    $\mathbf{W} \leftarrow \mathbf{W} - \eta \frac{1}{\sqrt{\mathbf{h}}} \frac{\partial L}{\partial \mathbf{W}}$

    • 개별 parameter에 adaptive하게 lr을 조정하면서 학습 진행
    • 기존 기울기값을 제곱해 계속 더해줌
      • parameter의 원소 중 많이 움직인(크게 갱신된)원소는 lr이 낮아짐
        • 많이 갱신된 원소는 보폭을 줄이고, 적게 갱신된 원소는 보폭을 늘려서 모든 parameter가 최적값을 가지는 속도를 맞추기 위해 + 가속도가 붙어 local minima를 지나칠까봐

    RMSProp

    • AdaGrad는 과거의 기울기를 제곱해 계속 더해가기 때문에 학습을 진행할수록 갱신 강도가 약해짐 ⇒ 이를 보완한 게 RMSProp
    • 먼 과거의 기울기는 서서히 잊고 새로운 기울기 정보를 크게 반영함
    class AdaGrad:
    	def __init__(self, lr=0.01):
    		self.lr = lr
    		sel.fh = None
    	
    	def update(self, params, grads):
    		if self.h is None:
    			self.h = {}
    		for key, val in params.itmes():
    			self.h[key] = np.zeros_like(val)
    
    	for key in params.keys():
    		self.h[key] += grads[key] * grads[key]
    		params[key] -= self.kr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
    
    #1e-7 : 1e-7을 더해놔서, 0으로 나누는 상황을 막아줌
    

    Adam

    • AdaGrad + Momentum

    Weight decay

    • 가중치가 클수록 overfitting이 일어나기 쉬우므로, 가중치를 줄여가는 것
      • 가중치 값이 크면 모델은 더 복잡한 함수를 표현할 수 있음. 모델이 복잡해질수록 train data의 작은 변화와 noise까지 학습할 수 있으므로 overfitting이 일어날 수 있게 됨.
    • weight의 초기값 설정
      • Xavier 초깃값 : 초깃값의 표준편차가 $1/\sqrt{n}$이 되도록 설정
      • He 초깃값 : 초깃값의 표준편차가 $2/\sqrt{n}$이 되도록 설정. ReLU를 사용할 때 주로 사용.(ReLU는 음의 영역이 0이므로 더 넓게 분포시키기 위해 2배의 계수가 필요)

    Batch Normalization

    • 각 layer에서 activate value가 적당히 분포되도록 조정하는 것

    • 데이터 분포가 평균이 0, 분산이 1이 되도록 정규화함
    • activation function의 앞or뒤에 삽입함으로써 데이터 분포가 덜 치우치게 할 수 있음
    • 장점
      • 학습을 빨리 진행할 수 있음
        • ❓ 1. 많은 층을 거치면서 gradient가 너무 작아지거나 커지는 경우를 방지
                2. 각 미니배치 데이터에 대해 평균과 분산을 구한 후 정규화를 수행하므로, 각 층의 input 분포를 안정화시킴
      • 초깃값에 크게 의존하지 않음
        • ❓ 1. 각 layer에 대한 입력의 분포가 안정화되므로 가중치 초기화에 대한 영향이 상대적으로 줄어듦     
      • overfitting을 억제함 (dropout등의 필요성 감소)
    • batch norm layer마다 scale, shift 변환이 필요함
      • ❓ 왜? 
        • 강제적인 batch norm은 레이어가 학습하는 함수의 표현력을 제한할 수 있으므로
        • 확대와 이동변환으로 각 레이어의 분포 조절 가능

    Drop out

    • 학습 시 뉴런을 임의로 삭제하면서 학습하는 방법
    • 각 뉴런의 output : (1-dropout 비율) == 앙상블처럼!
    반응형

    댓글