Python

[Python] Keras.initailizers(초기화 함수)

SangRok Jung 2022. 10. 31. 22:03
반응형

초기화 함수


▶ Keras.initailizers

Keras가 기본으로 제공하는 초기화 함수.

Keras layer의 초기값을 어떤 방식으로 생성할 것인지를 결정합니다. 

Dense(2, activation='relu', kernel_initializer=initializer1)(ip)

 

initializer1 = keras.initializers.RandomNormal(mean=0, stddev=1.)
initializer2 = keras.initializers.RandomUniform(minval=0, maxval=1.)
initializer3 = keras.initializers.TruncatedNormal(mean=0., stddev=1.)
initializer4 = keras.initializers.Zeros()
initializer5 = keras.initializers.Ones()
initializer6 = keras.initializers.GlorotNormal()
initializer7 = keras.initializers.GlorotUniform()
initializer8 = keras.initializers.HeNormal()
initializer9 = keras.initializers.HeUniform()
  • Ones
    • 지정한 파라미터 값을 모두 1로 생성합니다.
  • Constant
    • 지정한 파라미터를 특정한 상수 값으로 생성합니다.
  • RandomNormal(mean=0.0, stddev=0.05, seed=None)
    • 지정한 평균 및 표준 편차를 따르는 정규 분포로 부터 대상 파라미터 값을 무작위로 생성합니다.
    • mean : int혹은 float형식의 스칼라 값 또는 같은 형식의 스칼라 텐서, 파라미터 생성에 사용할 정규분포의 평균을 정합니다.
    • stddev : int 혹은 float형식의 스칼라 값 또는 같은 형식의 스칼라 텐서, 파라미터 생성에 사용할 정규 분포의 표준편차를 정합니다 기본값은 0.05.
    • seed : int 무작위 생성에 사용할 시드를 정합니다. 기본값 None
  • RandomUniform(minval=-0.05, maxval = 0.05, seed=None)
    • 지정한 범위의 균등분포로 부터 대상 파라미터 값을 무작귀로 생성.
    • minval: int 혹은 float형식의 스칼라 값 또는 같은 형식의 스칼라 텐서. 무작위 생성에 사용할 수치 범위의 최솟값입니다. 기-0.05입니다.
    • maxval: int 혹은 float형식의 스칼라 값 또는 같은 형식의 스칼라 텐서. 무작위 생성에 사용할 수치 범위의 최댓값입니다. 기본값은 0.05입니다.
    • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
  • TruncateedNorae(mean=0.0, stddev=0.05, seed=None)
    • initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None)
    • mean: int 혹은 float형식의 스칼라 값 또는 같은 형식의 스칼라 텐서. 파라미터 생성에 사용할 정규분포의 평균을 정합니다. 기본값은 0입니다.
    • stddev: int 혹은 float형식의 스칼라 값 또는 같은 형식의 스칼라 텐서. 파라미터 생성에 사용할 정규분포의 표준편차를 정합니다. 기본값은 0.05입니다.
    • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
  • VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)
    • 가중치 텐서의 규모에 따라 초기값 생성에 사용할 분포를 조정합니다.
    • 먼저 정규분포(distribution='normal')를 선택할 경우, 0을 평균으로 sqrt(scale / n)의 표준편차를 가진 절단 정규분포의 범위 안에서 값을 선택합니다. 이때 n값은 mode인자에 따라 다음과 같이 달라집니다.
    • 'fan_in': 가중치 텐서의 입력 차원 크기.
    • 'fan_out': 가중치 텐서의 출력 차원 크기.
    • 'fan_avg': 입력 차원, 출력 차원 크기의 평균값.
    • 또는 균등분포(distribution="uniform")를 선택할 경우 [-limit, limit]의 범위를 가진 균등분포로부터 값이 선택됩니다. 여기서 limit은 sqrt(3 * scale / n)으로 정의됩니다. 위와 마찬가지로 n값은 mode인자에 따라 정해집니다.
    • 인자
      • scale: 스케일링 값. 양의 float를 입력해야 하며 기본값은 1.0입니다.
      • mode: 'fan_in', 'fan_out', 'fan_avg'. 기본값은 'fan_in'입니다.
      • distribution: 'normal', 'uniform'. 기본값은 'normal'입니다.
      • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
    • 오류
      • ValueError: scale, mode 혹은 distribution 인자에 잘못된 값을 전달한 경우 발생합니다.
  • Orthogonal(gain=1.0, seed=None)
    • 무작위 직교행렬orthogonal matrix을 파라미터의 초기값으로 생성합니다. 먼저 평균 0 표준편차 1의 정규분포로부터 무작위 텐서를 생성한 뒤, 해당 텐서를 특이값분해singular value decomposition하여 얻은 직교행렬을 원하는 파라미터의 형태에 맞게 변형하여 사용합니다. 직교행렬의 가중치 초기값 활용에 대해서는 다음의 논문을 참고하십시오.
    • 인자
      • gain: 생성될 직교행렬에 곱할 배수입니다. 기본값은 1.입니다.
      • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
  • Identity(gain=1.0)
    • 지정한 파라미터를 단위행렬로 생성합니다. 단위행렬의 특성상 2D 행렬에만 사용할 수 있습니다. 만약 사용하고자 하는 행렬이 정사각형이 아니라면 0을 채운 행 또는 열을 추가하여 형태를 맞춥니다.
    • 인자
      • gain: 생성할 단위행렬에 곱할 배수입니다. 기본값은 1.입니다.
  • glorot_normal(seed=None)
    • Glorot 정규분포 방식으로 파라미터의 초기값을 생성합니다. Xavier 정규분포 방식이라고도 불리며, 가중치 텐서의 크기에 따라 값을 조절하는 방식의 하나입니다.
    • 가중치 텐서의 입력 차원 크기를 fan_in, 출력 차원 크기를 fan_out이라고 할 때, 평균 0과 sqrt(2 / (fan_in + fan_out))의 표준편차를 가진 정규분포의 +-2표준편차 범위 안에서 무작위로 값을 추출합니다.
    • 인자
      • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
    • 반환값
      • Glorot 정규분포 방식을 따르는 초기화 함수.
  • glorot_uniform(seed=None)
    • Glorot 균등분포 방식으로 파라미터의 초기값을 생성합니다. Xavier 균등분포 방식이라고도 불리며, 가중치 텐서의 크기에 따라 값을 조절하는 방식의 하나입니다.
    • [-limit, limit]의 범위를 가진 균등분포로부터 값이 선택됩니다. 가중치 텐서의 입력 차원 크기를 fan_in, 출력 차원 크기를 fan_out이라고 할 때, limit은 sqrt(6 / (fan_in + fan_out))으로 구합니다.
    • 인자
      • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
    • 반환값
      • Glorot 균등분포 방식을 따르는 초기화 함수.
  • he_normal(seed=None)
    • He 정규분포 방식으로 파라미터의 초기값을 생성합니다. 가중치 텐서의 크기에 따라 값을 조절하는 방식의 하나입니다.
    • 가중치 텐서의 입력 차원 크기를 fan_in이라고 할 때, 평균 0과 sqrt(2 / fan_in)의 표준편차를 가진 정규분포의 +-2표준편차 범위 안에서 무작위로 값을 추출합니다.
    • 인자
      • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
    • 반환값
      • He 정규분포 방식을 따르는 초기화 함수.
  • he_uniform(seed=None)
    • He 정규분포 방식으로 파라미터의 초기값을 생성합니다. 가중치 텐서의 크기에 따라 값을 조절하는 방식의 하나입니다.
    • [-limit, limit]의 범위를 가진 균등분포로부터 값이 선택됩니다. 가중치 텐서의 입력 차원 크기를 fan_in이라고 할 때, limit은 sqrt(6 / fan_in)으로 구합니다.
    • 인자
      • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
    • 반환값
      • He 균등분포 방식을 따르는 초기화 함수.
  • lecun_normal(seed=None)
    • LeCun 정규분포 방식으로 파라미터의 초기값을 생성합니다. 가중치 텐서의 크기에 따라 값을 조절하는 방식의 하나입니다.
    • 가중치 텐서의 입력 차원 크기를 fan_in이라고 할 때, 평균 0과 sqrt(1 / fan_in)의 표준편차를 가진 정규분포의 +-2표준편차 범위 안에서 무작위로 값을 추출합니다.
    • 인자
      • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
    • 반환값
      • LeCun 정규분포 방식을 따르는 초기화 함수.
  • lecun_uniform(seed=None)
    • LeCun 정규분포 방식으로 파라미터의 초기값을 생성합니다. 가중치 텐서의 크기에 따라 값을 조절하는 방식의 하나입니다.
    • [-limit, limit]의 범위를 가진 균등분포로부터 값이 선택됩니다. 가중치 텐서의 입력 차원 크기를 fan_in이라고 할 때, limit은 sqrt(3 / fan_in)으로 구합니다.
    • 인자
      • seed: int. 무작위 생성에 사용할 시드를 정합니다. 기본값은 None입니다.
    • 반환값
      • LeCun 균등분포 방식을 따르는 초기화 함수.

 

 

 

▶ Keras 각 모델층 함수 적용

 

방법 1. 케라스가 제공하는 함수인 경우 인자에 초기화 함수의 이름과 동일한 문자열을 지정한다.

방법 2. 문자열 대신 호출 가능한 함수의 형태로 직접 지정한다.

 

from keras import initializers

model.add(Dense(64, kernel_initializer=initializers.random_normal(stddev=0.01))) # 함수 호출로 지정합니다.

# also works; will use the default parameters.
model.add(Dense(64, kernel_initializer='random_normal'))                         # 문자열로 지정합니다.

 

 

 

 

▶ 사용자 정의 초기화 함수

사용자 정의 함수를 만들어 사용하는 경우, 인자로 shape(초기값을 생성할 파라미터의 형태)와 dtype을 전달받아야합니다.

from keras import backend as K

def my_init(shape, dtype=None):                 # 형태와 자료형 인자를 명시합니다.
    return K.random_normal(shape, dtype=dtype)

model.add(Dense(64, kernel_initializer=my_init))

 

 

 

 

 

 

 

▶ 초기화 함수 별 성능 차이

▷ 인자값을 받아 시각화 그래프를 생성하는 함수 생성

from tensorflow.keras import initializers
import matplotlib.pyplot as plt
def xor_practice(initializer, activation, epochs, optimizer):
    xor = {'x1':[0,0,1,1], 'x2':[0,1,0,1], 'y':[0,1,1,0]}
    XOR = pd.DataFrame(xor)
    X = XOR.drop('y', axis=1)
    y = XOR.y
    
    initializer = initializers.RandomNormal()
    ip = Input(shape=(2,))
    n = Dense(2, activation=activation, kernel_initializer=initializer)(ip)
    n = Dense(1, activation='linear', kernel_initializer=initializer)(n)
    model = Model(inputs=ip, outputs=n)
    model.compile(loss='mse', optimizer=optimizer, metrics='accuracy')
    hist = model.fit(X, y, epochs=epochs, verbose=0)
    fig, loss_ax = plt.subplots()
    loss_ax.plot(hist.history['loss'], 'y', label='train loss', c='blue')
    loss_ax.plot(hist.history['accuracy'], 'y', label='train accuracy', c='red')
    plt.plot(range(epochs), [0.15 for _ in range(epochs)], linestyle='--')
    loss_ax.set_xlabel('epoch')
    loss_ax.set_ylabel('loss')
    loss_ax.legend(loc='upper left')
    loss_ax.set_ylim(0, 1)
    plt.show()
    
    return model.predict(X)

▷ 함수 실행

initializer = keras.initializers.TruncatedNormal(mean=0, stddev=1.)
activation = 'elu'
epochs = 1900
optimizer = 'rmsprop'

for _ in range(5) : 
    xor_practice(initializer, activation, epochs, optimizer)

결론 : 큰차이가 없다.

 

 

▷ 9개 그래프 생성.

initializer1 = keras.initializers.RandomNormal(mean=0, stddev=1.)
initializer2 = keras.initializers.RandomUniform(minval=0,maxval=1.)
initializer3 = keras.initializers.TruncatedNormal(mean=0, stddev=1.)
initializer4 = keras.initializers.Zeros()
initializer5 = keras.initializers.Ones()
initializer6 = keras.initializers.GlorotNormal() #Xavier
initializer7 = keras.initializers.GlorotUniform() #Xavier
initializer8 = keras.initializers.HeNormal() #He
initializer9 = keras.initializers.HeUniform() #He
from tensorflow.keras import initializers
import matplotlib.pyplot as plt
def xor_practice2(activation, epochs, optimizer):
    fig = plt.figure(figsize=(30, 15))
    for i in range(9):
        globals()[f'ax{i+1}'] = fig.add_subplot(3, 3, i+1)
    for i in range(9):
        xor = {'x1':[0,0,1,1], 'x2':[0,1,0,1], 'y':[0,1,1,0]}
        XOR = pd.DataFrame(xor)
        X = XOR.drop('y', axis=1)
        y = XOR.y
        ip = Input(shape=(2,))
        n = Dense(2, activation=activation, kernel_initializer=globals()[f'initializer{i+1}'])(ip)
        n = Dense(1, activation='linear', kernel_initializer=globals()[f'initializer{i+1}'])(n)
        model = Model(inputs=ip, outputs=n)
        model.compile(loss='mse', optimizer=optimizer, metrics='accuracy')
        hist = model.fit(X, y, epochs=epochs, verbose=0)
        globals()[f'ax{i+1}'].plot(hist.history['loss'], 'y', label='train loss', c='blue')
        globals()[f'ax{i+1}'].plot(hist.history['accuracy'], 'y', label='train accuracy', c='red')
        plt.plot(range(epochs), [0.15 for _ in range(epochs)], linestyle='--')
        globals()[f'ax{i+1}'].set_xlabel('epoch')
        globals()[f'ax{i+1}'].set_ylabel('loss')
        globals()[f'ax{i+1}'].legend(loc='upper left')
        globals()[f'ax{i+1}'].set_ylim(0, 1)
    plt.show()

 

 

 

 

 

반응형

'Python' 카테고리의 다른 글

[Python] Regression  (0) 2022.11.10
[Python] Deep Learning  (0) 2022.11.03
[Python] Functional API  (0) 2022.10.31
[Python] 빅데이터 분석 4 : 평가 및 적용(Evaluation & Application)  (0) 2022.10.23
[Python] Coding Test (팩토리얼)  (0) 2022.10.13