본문 바로가기

딥러닝

밑바닥부터 시작하는 딥러닝 5장-9 렐루함수 (p.165)

 

목차 

1. 렐루 함수란 p.165

2.렐루함수 클래스 생성하기 위한 문법

 

3.copy모듈 

 

4. x[x<=0] 의 코드


5. 렐루함수 클래스 코드 

1. 렐루함수란?

입력 신호가 0보다 큰 값이 입력되면 그 값을 그대로 출력하고, 0보다 작거나 같은 값이 입력이 되면 0을 출력하는 함수

그림 (5-18) 렐루함수의 순전파와 역전파 모습(x>0 ,x<=0의 모습이 다르다)

순전파일때 신호가 흐르면(즉, x>0 ,y=x) 역전파일때 그 값의 기울기를 보내고,

순전파일때 신호가 흐르지 않으면(즉, x<=0,y=0) 역전파일때 기울기를 보내지 않고, 0을 보낸다.

 

2. 렐루 함수 클래스 생성하기 위한 필수 파이썬 문법 2가지 

(1) copy 모듈 사용법 : 역전파할 때 순전파의 입력값을 기억하여 신호가 흘렀는지 유무 파악

(2) x[x<=0] 의 의미 : 역전파할 때 순전파의 신호가 흐르지 않을 때 필요(즉, x<=0,y=0) 

 

3. copy 모듈 코드

from copy import copy
a=[1,2,3]
b=a.copy()  # copy 했기 때문에 b는 별도의 객체가 됩니다.

a[1]=6
print(a)
print(b) # a[1]=6으로 변경되기 이전에 copy 했기 때문에 [1,2,3]

#[1, 6, 3]
#[1, 2, 3]

b=a.copy() :a를 카피하여 b라는 변수에 담아 별도의 b 객체 생성

b는 별도의 객체이므로 a가 변경되도 b는 copy한 당시의 a값과 같다.

 

이 copy 모듈은 역전파할 때 순전파의 입력값을 기억하여 신호를 보냈는지 보내지 않았는지 알기 위해 필요하다.

 

4. x[x≤0] 의 의미 (p.166) 

역전파할때 순전파의 신호가 흐르지 않을 때 필요(즉, x<=0,y=0) 

import numpy as np
x=np.array( [ [ 1, -0.5], [-2,3]]) #2x2 행렬
print(x)
#[[ 1.  -0.5]
 #[-2.   3. ]]

mask = (x<=0)
print(mask)
#[[False  True]   # x<=0인 경우만 mask를 출력했을 때 True로 나오고 있다. 
 #[ True False]] # 즉 , mask 에 x<=0 이면 True인 것을 변수에 넣은 것 

out=x.copy()
out[mask]=0 # True 인 자리에 0이 할당됩니다
print(out)
#[[1. 0.]
 #[0. 3.]]

 

순전파 때의 입력 값이 0 이하면 역전파 때의 값은 0이 돼야 합니다. 그래서 역전파 때는 순전파 때 만들어둔 mask를 써서 mask 의 원소가 True인 곳에는 상류에서 전파된 dout을 0으로 설정합니다.

 

5. 렐루 클래스 생성 코드 

class Relu:
    def __init__(self):
        self.mask=None
    
    def forward(self,x):
        self.mask = (x<=0)  # 순전파로 신호를 보낼 때 어느자리에 값이 흘러갔는지 유무 저장 
        out=x.copy()        # 입력값 행렬을 복사해서 out 에 담고
        out[self.mask] = 0  # out 행렬에서 신호가 흘러가지 않은 True에 해당하는 부분에 
        
        return out          # 0을 할당. 즉, x값이 음수면 신호를 보내지 않는다. 
    
    def backward(self, dout):  #dout: 오차함수의 기울기 
        dout[self.mask]=0  # 순전파일때 신호를 안보낸 자리가 self.mask에 True로
        dx=dout            # 기억되고 있어서 그 자리에 0을 할당 
        
        return dx

 

코드 객체화 

relu=Relu()
x=np.array([ [1.0, -0.5] ,[-2.0 ,3.0]] )
relu.forward(x)  # 순전파 
dout=np.array( [[ 35,73],[92,83]])  # 상류층 기울기 
print(relu.backward(dout)) # 역전파