반응형

 

케라스를 사용한 인공 신경망 소개

  • 뇌에 있는 생물학적 뉴런의 네트워크에서 영감을 받은 머신러닝 모델

 

생물학적 뉴런에서 인공 뉴런까지

  • 신경망을 훈련하기 위한 데이터가 많아짐, 인공 신경망은 규모가 크고 복잡한 문제에서 다른 머신러닝 기법보다 좋은 성능을 발휘
  • 컴퓨터 하드웨어 발전으로 대규모 신경망 훈련이 가능, 훈련 알고리즘이 향상

 
뉴런을 사용한 논리 연산

  • 하나 이상의 이진 입력과 이진 출력을 가지는 형태

  • 인공 뉴런은 단순히 입력이 일정 개수만큼 활성화되었을 때 출력을 생성

    • 왼쪽 첫 번째 네트워크는 항등 함수
      • 뉴런 A 가 활성화 되면 뉴런 C도 활성화, 뉴런 A가 꺼지면 뉴런 C도 꺼짐
    • 두 번째 네트워크는 논리곱 연산을 수행
      • 뉴런 A와 B 모두 활성화될 때만 뉴런 C가 활성화
    • 세 번째 네트워크는 논리합 연산을 수행
      • 뉴런 A와 B중 하나가 활성화되면 뉴런 C가 활성호하

    어떤 입력이 뉴런의 활성화를 억제할 수 있다고 가정하면 네 번째 네트워크는 조금 더 복잡한 논리 명제를 계산할 수 있음, 뉴런 A가 활성화되고 뉴런 B가 비활성화될 때 뉴런 C가 활성화

    만약 뉴런 A가 항상 활성화되어 있다면 이 네트워크는 논리 부정 연산이 됨 (뉴런 B가 비활성화될 때 뉴런 C가 활성화되고 반대로 B가 활성화 일때 뉴런C가 비활성화 됨)

 

퍼셉트론

  • 퍼셉트론은 TLU 또는 이따금 LTU라고 불리는 조금 다른 형태의 인공 뉴런을 기반으로 함

  • 입력과 출력이 어떤 숫자이고, 각각의 입력 연결은 가중치와 연결되어 있음

  • TLU는 입력의 가중치 합을 계산한 뒤 계산된 합에 계단 함수를 적용하여 결과물을 출력

  • 퍼셉트론에서 가장 널리 사용되는 계단 함수는 헤비사이드 계단 함수, 부호 함수를 대신 사용하기도 함

  • 하나의 TLU는 간단한 선형 이진 분류 문제에 사용할 수 있음, 입력의 선형 조합을 계산해서 그 결과가 임계값을 넘으면 양성 클래스를 출력, 아닌경우에는 음성 클래스를 출력

  • 퍼셉트론은 층이 하나뿐인 TLU로 구성, 각 TLU는 모든 입력에 연결되어 있음, 한 층에 있는 모든 뉴런이 이전 층의 모든 뉴런과 연결되어 있을 때 이를 완전 연결 층 또는 밀집 층이라고 함

  • 퍼셉트론의 입력은 입력뉴런

    • 어떤 입력이 주입되도 출력으로 통과시키는 역할
  • 입력층은 모든 입력 뉴런으로 구성됨, 여기에 편향 특성이 더해짐

    • 전형적으로 이 편향 특성은 항상 1을 출력하는 특별한 종류의 뉴런인 편향 뉴런으로 표현

    • 아래 이미지는 샘플을 세 개의 다른 이진 클래스로 동시로 분류할 수 있으므로 다중 출력 분류기 이미지

  • 완전 연결 층의 출력 계산식

    • X는 입력 특성의 행렬을 의미, 행은 샘플 열은 특성
    • 가중치 행렬 W는 편향 뉴런을 제외한 모든 연결 가중치를 포함. 이 행렬의 행은 입력 뉴런에 해당하고 열은 출력층에 있는 인공 뉴런에 해당
    • 편향 벡터 b는 편향 뉴런과 인공 뉴런 사이의 모든 연결 가중치를 포함, 인공 뉴런마다 하나의 편향 존재
    • Ø를 활성화 함수라고 함, 인공 뉴런이 TLU일 경우 이 함수는 계단 함수
  • 퍼셉트론

    • 한 번에 한 개의 샘플이 주입되면 각 샘플에 대해 예측이 생성됨

    • 퍼셉트론 학습 규칙

- 
는 i번째 입력 뉴런과 j번째 출력 뉴런 사이를 연결하는 가중치 -
는 현재 훈련 샘플의 i번째 뉴런의 입력값 -
는 현재 훈련 샘플의 j번째 뉴런의 타깃값 -
는 학습률
  • 각 출력 뉴런의 결정 경계는 선형이므로 복잡한 패턴을 학습하기 어려움, 하지만 훈련 샘플이 선형적으로 구분될 수 있다면 알고리즘이 정답에 수렴 이를 퍼셉트론 수렴 이론이라고 함

  • sklearn에서 하나의 TLU 네트워크를 구현한 Perceptron 클래스를 제공

    • 파이썬 클래스도 동일한 방식으로 사용할 수 있음

    • 예제

      import numpy as np
      from sklearn.datasets import load_iris
      from sklearn.linear_model import Perceptron
      
      iris = load_iris()
      X = iris.data[:, (2, 3)]  # 꽃잎 길이, 꽃잎 너비
      y = (iris.target == 0).astype(np.int)
      
      per_clf = Perceptron(max_iter=1000, tol=1e-3, random_state=42)
      per_clf.fit(X, y)
      
      y_pred = per_clf.predict([[2, 0.5]])
      y_pred
      >> array([1])
  • 퍼셉트론은 클래스 확률을 제공하지 않으며 고정된 임곗값을 기준으로 예측을 수행, 이 때문에 퍼셉트론보다 로지스틱 회귀가 더 선호됨

 

다층 퍼셉트론과 역전파

  • 다층 퍼셉트론은 입력 층 하나와 은닉 층 이라 불리는 하나 이상의 TLU층과 마지막 출력 층으로 구성
  • 입력층과 가까운 층을 보통 하위 층이라 부르고 출력에 가까운 층을 상위 층 이라고 부름
  • 출력층을 제외하고 모든 층은 편향 뉴런을 포함하여 다음 층과 완전히 연결되어 있음

  • 은닉층을 여러 개 쌓아 올린 인공 신경망을 심층 신경망(DNN)이라고 함
  • 반복하는 과정 에포크, 마지막 출력층의 출력을 계산하는 것을 정방향 계산, 마지막으로 알고리즘의 경사 하강법을 수행하여 계산한 오차 그레이디언트를 사용해 네트워크에 있는 모든 연결 가중치 수정을 역전파

 

케라스로 다층 퍼셉트론 구현하기

 

케라스를 사용하여 데이터셋 적재하기

  • 이미지 크기는 28x28
fashion_mnist = keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()
  • 이미지 정규화
X_valid, X_train = X_train_full[:5000] / 255., X_train_full[5000:] / 255.
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
X_test = X_test / 255.
  • 클래스 이름의 리스트 생성
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat",
               "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]

 

시퀀셜 API를 사용하여 모델 만들기

  • 두 개의 은닉층으로 이루어진 분류용 다층 퍼셉트론
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
model.add(keras.layers.Dense(300, activation="relu"))
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dense(10, activation="softmax"))
  • model.summary()를 통한 모델 요약

 

모델 컴파일

  • 모델 작성후 compile() 메서드를 호출하여 사용할 함수와 옵티마이저를 지정해야 함
  • 훈련과 평가 시에 계산할 지표를 추가로 지정할 수 있음
    • class가 배타적인 정수 임으로 loss를 sparse_categorical_crossentropy
    • 샘플마다 클래스별 타깃 확률을 가지고 있다면 categorical_crossentropy
    • 이진 분류시 soft-max 대신 sigmoid 사용하고 binary_crossentropy 사용
model.compile(loss="sparse_categorical_crossentropy",
              optimizer="sgd",
              metrics=["accuracy"])

 

모델 훈련과 평가

  • class_weight 매개변수를 지정하면 적게 등장하는 클래스에 높은 가중치, 많이 나오는 클래스에 적은 가중치 부여
  • 샘플별로 가중치를 부여하고 싶다면 sample_weight 매개변수를 지정
history = model.fit(X_train, y_train, epochs=30,
                    validation_data=(X_valid, y_valid))
  • history 객체에 훈련 파라미터, 에포크등 다양한 정보를 가지고 있음

 

모델을 사용해 예측을 만들기

  • 모델의 predict()를 사용해 새로운 예측을 생성할 수 있음
X_new = X_test[:3]
y_proba = model.predict(X_new)
y_proba.round(2)

# y_pred = model.predict_classes(X_new)
y_pred = np.argmax(model.predict(X_new), axis=-1)
y_pred
>> array([9, 2, 1])

np.array(class_names)[y_pred]
>> array(['Ankle boot', 'Pullover', 'Trouser'], dtype='<U11')

 

시퀀셜 API를 사용하여 회귀용 다층 퍼셉트론 만들기

  • 사용할 데이터 적제하기
    • 데이터셋 로드후 스케일 조정
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

housing = fetch_california_housing()

X_train_full, X_test, y_train_full, y_test = train_test_split(housing.data, housing.target, random_state=42)
X_train, X_valid, y_train, y_valid = train_test_split(X_train_full, y_train_full, random_state=42)

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_valid = scaler.transform(X_valid)
X_test = scaler.transform(X_test)
  • 모델 생성및 훈련
model = keras.models.Sequential([
    keras.layers.Dense(30, activation="relu", input_shape=X_train.shape[1:]),
    keras.layers.Dense(1)
])
model.compile(loss="mean_squared_error", optimizer=keras.optimizers.SGD(learning_rate=1e-3))
history = model.fit(X_train, y_train, epochs=20, validation_data=(X_valid, y_valid))
mse_test = model.evaluate(X_test, y_test)
X_new = X_test[:3]
y_pred = model.predict(X_new)

y_pred
>>   array([[0.38856643],
           [1.6792021 ],
           [3.1022797 ]], dtype=float32)

 

함수형 API를 사용해 복잡한 모델 만들기

  • 신경망의 복잡한 패턴과 간단한 규칙을 모두 학습할 수 있음

  • 대조적으로 일반적인 MLP는 네트워크에 있는 층 전체에 모든 데이터를 통과시킴

  • 데이터에 있는 간단한 패턴이 연속된 변환으로 인해 왜곡될수 있음

  • 예제 (입력과 은닉층 concat)

    input_ = keras.layers.Input(shape=X_train.shape[1:])
    hidden1 = keras.layers.Dense(30, activation="relu")(input_)
    hidden2 = keras.layers.Dense(30, activation="relu")(hidden1)
    concat = keras.layers.concatenate([input_, hidden2])
    output = keras.layers.Dense(1)(concat)
    model = keras.models.Model(inputs=[input_], outputs=[output])
    • input 객체를 통해 shape과 dtype을 포함하여 모델의 입력을 정의, 한 모델은 여러 개의 입력을 가질수 있음
    • 30개의 뉴런과 Relu를 가진 dense층, concatenate()를 통한 두번째 은닉층의 출력과 입력을 연결
    • 마지막으로 입력과 출력을 지정하여 keras model 생성
  • 예제 (5개 특성 , 6개 특성 심층 concat)

    input_A = keras.layers.Input(shape=[5], name="wide_input")
    input_B = keras.layers.Input(shape=[6], name="deep_input")
    hidden1 = keras.layers.Dense(30, activation="relu")(input_B)
    hidden2 = keras.layers.Dense(30, activation="relu")(hidden1)
    concat = keras.layers.concatenate([input_A, hidden2])
    output = keras.layers.Dense(1, name="output")(concat)
    model = keras.models.Model(inputs=[input_A, input_B], outputs=[output])
    
    

model.compile(loss="mse", optimizer=keras.optimizers.SGD(learning_rate=1e-3))

X_train_A, X_train_B = X_train[:, :5], X_train[:, 2:]
X_valid_A, X_valid_B = X_valid[:, :5], X_valid[:, 2:]
X_test_A, X_test_B = X_test[:, :5], X_test[:, 2:]
X_new_A, X_new_B = X_test_A[:3], X_test_B[:3]

history = model.fit((X_train_A, X_train_B), y_train, epochs=20,
validation_data=((X_valid_A, X_valid_B), y_valid))
mse_test = model.evaluate((X_test_A, X_test_B), y_test)
y_pred = model.predict((X_new_A, X_new_B))


  - input이 결과적으로 2개, inputs=[input_A, input_B]

    - fit() 학습시  x_train은 (x_train_A, x_train_B)와 같은 형태가 되어야 함
    - x_valid도 같은 형태

  - 위와 같은 모델 형상은 여러개의 출력이 필요한 경우에 사용

    - 그림에 있는 주요 물체를 분류하고 위치를 알아야하는 작업 (회귀와 분류를 동시에 수행)

    - 동일한 데이터에서 독립적인 여러 작업을 수행할 때, 사람의 표정을 통한 감정 분류

    - 규제 기법으로 사용하는 경우,  신경망 구조안에 보조 출력을 추가할 수 있음

      - 보조출력을 사용해 네트워크가 나머지 네트워크에 의존하지 않고 그 자체로 유용한 것을 학습하는지 확인할 수 있음

      - 보조출력을 추가하는 것은 적절한 층에 연결하고 모델의 출력 리스트에 추가하는 방식으로 수행

      - 보조출력 예제

        ```python
        input_A = keras.layers.Input(shape=[5], name="wide_input")
        input_B = keras.layers.Input(shape=[6], name="deep_input")
        hidden1 = keras.layers.Dense(30, activation="relu")(input_B)
        hidden2 = keras.layers.Dense(30, activation="relu")(hidden1)
        concat = keras.layers.concatenate([input_A, hidden2])
        output = keras.layers.Dense(1, name="main_output")(concat)
        aux_output = keras.layers.Dense(1, name="aux_output")(hidden2)
        model = keras.models.Model(inputs=[input_A, input_B],
                                   outputs=[output, aux_output])

        model.compile(loss=["mse", "mse"], loss_weights=[0.9, 0.1], optimizer=keras.optimizers.SGD(learning_rate=1e-3))

        history = model.fit([X_train_A, X_train_B], [y_train, y_train], epochs=20,
                      validation_data=([X_valid_A, X_valid_B], [y_valid, y_valid]))

        total_loss, main_loss, aux_loss = model.evaluate(
                                         [X_test_A, X_test_B], [y_test, y_test])
        y_pred_main, y_pred_aux = model.predict([X_new_A, X_new_B])
        ```

        - 각 출력은 자신만의 손실함수가 필요
        - 보조출력보다 주 출력에 더 큰 관심을 부여하려면 가중치를 부여해 조절

&nbsp;

### 서브클래싱 API로 동적 모델 만들기

- 시퀀셜 API와 함수형 API는 모두 선언적인 특성을 가짐

  - 사용할 층과 연결 방식을 먼저 정의할 필요성이 있음
  - 그 후에 모델에 데이터를 입력하여 훈련이나 추론을 시작할수 있음

- 장점

  - 모델의 저장 및 복사, 공유하기가 쉬움, 모델의 구조를 출력하거나 분석하기 좋음
  - 프레임워크가 크기를 짐작하고 타입을 확인하여 에러를 일찍 발견 할 수 있음
  - 전체 모델이 층으로 구성된 정적 그래프이므로 디버깅 용이

- 단점

  - 여러 가지 동적인 구조를 수행하기 어려움
  - 이런 경우 서브클래싱 API가 좋음

- model 클래스를 상속한 다음 생성자 안에서 필요한 층을 생성, 그 다음 call() 메서드 안에 수행하려는 연산을 기술

  - WideAndDeepModel 예제

    ```python
    class WideAndDeepModel(keras.models.Model):
        def __init__(self, units=30, activation="relu", **kwargs):
            super().__init__(**kwargs)
            self.hidden1 = keras.layers.Dense(units, activation=activation)
            self.hidden2 = keras.layers.Dense(units, activation=activation)
            self.main_output = keras.layers.Dense(1)
            self.aux_output = keras.layers.Dense(1)

        def call(self, inputs):
            input_A, input_B = inputs
            hidden1 = self.hidden1(input_B)
            hidden2 = self.hidden2(hidden1)
            concat = keras.layers.concatenate([input_A, hidden2])
            main_output = self.main_output(concat)
            aux_output = self.aux_output(hidden2)
            return main_output, aux_output

    model = WideAndDeepModel(30, activation="relu")

    model.compile(loss="mse", loss_weights=[0.9, 0.1], optimizer=keras.optimizers.SGD(learning_rate=1e-3))
    history = model.fit((X_train_A, X_train_B), (y_train, y_train), epochs=10,
                        validation_data=((X_valid_A, X_valid_B), (y_valid, y_valid)))
    total_loss, main_loss, aux_loss = model.evaluate((X_test_A, X_test_B), (y_test, y_test))
    y_pred_main, y_pred_aux = model.predict((X_new_A, X_new_B))
    ```

    - 해당 방법을 통하면 함수형 API와 다르게 input 클래스의 객체를 생성할 필요가 없음
    - 대신 call() 메서드의 input 매개변수를 사용, 생성자에 있는 층 구성과 call() 메서드에 있는 정방향 계산을 분리
      - call() 안에서 원하는 연산을 자체적으로 생성하여 수행가능
    - 단점으로는 모델을 저장하거나 복사할 수 없음
      - summary()를 통한 각 층간의 연결 정보를 얻을수 없음
    - 높은 유연성이 필요하지 않는다면 API와 함수형 API를 사용하는 것이 좋음

  &nbsp;

### 모델 저장과 복원

- 시퀀셜 API와 함수형 API를 사용하면 훈련된 케라스 모델을 저장하는 것은 쉬워짐

- 저장 예제

  ```python
  model = keras.models.Sequential([
      keras.layers.Dense(30, activation="relu", input_shape=[8]),
      keras.layers.Dense(30, activation="relu"),
      keras.layers.Dense(1)
  ])    

  model.compile(loss="mse", optimizer=keras.optimizers.SGD(learning_rate=1e-3))
  history = model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
  mse_test = model.evaluate(X_test, y_test)

  model.save("my_keras_model.h5")
  model = keras.models.load_model("my_keras_model.h5")

  model.save_weights("my_keras_weights.ckpt")
  model.load_weights("my_keras_weights.ckpt")
  • keras는 HDF5 포멧을 사용하여 모델구조와 층의 모든 모델 파라미터를 저장, 옵티마저도 저장
  • 일반적으로 하나의 python script에서 모델을 훈련하고 저장한 다음 하나 이상의 script에서 모델을 로드하고 예측을 만드는 데 활용
  • 시퀀셜, 함수형 API만 가능하고 서브클래싱에서는 불가능

 

콜백 사용하기

  • fit() 메서드의 callbacks 매개변수를 사용하여 케라스가 훈련의 시작이나 끝에 호출할 객체 리스트를 지정할 수 있음 또는 에포크의 시작이나 끝, 각 배치 처리 전후에 호출할 수도 있음

  • 콜백 예제

    model = keras.models.Sequential([
        keras.layers.Dense(30, activation="relu", input_shape=[8]),
        keras.layers.Dense(30, activation="relu"),
        keras.layers.Dense(1)
    ])    
    
    model.compile(loss="mse", optimizer=keras.optimizers.SGD(learning_rate=1e-3))
    checkpoint_cb = keras.callbacks.ModelCheckpoint("my_keras_model.h5", save_best_only=True)
    history = model.fit(X_train, y_train, epochs=10,
                        validation_data=(X_valid, y_valid),
                        callbacks=[checkpoint_cb])
    model = keras.models.load_model("my_keras_model.h5") # 최상의 모델로 롤백
    mse_test = model.evaluate(X_test, y_test)
    • 'save_best_only=True' 를 통해서 최상의 검증 세트 점수에서만 모델을 저장

      • 오랜 훈련 시간으로 훈련 세트에 과대적합될 걱정을 하지 않아도 됨
    • 조기종료 예제

      model.compile(loss="mse", optimizer=keras.optimizers.SGD(learning_rate=1e-3))
      early_stopping_cb = keras.callbacks.EarlyStopping(patience=10,
                                                        restore_best_weights=True)
      history = model.fit(X_train, y_train, epochs=100,
                          validation_data=(X_valid, y_valid),
                          callbacks=[checkpoint_cb, early_stopping_cb])
      mse_test = model.evaluate(X_test, y_test)
      • EarlyStopping 이 훈련이 끝날때 최상의 가중치를 복원
    • 사용자 정의 콜백 예제

      class PrintValTrainRatioCallback(keras.callbacks.Callback):
          def on_epoch_end(self, epoch, logs):
              print("\nval/train: {:.2f}".format(logs["val_loss"] / logs["loss"]))
      • 필요시 콜백을 검증과 예측 단계에서도 사용할 수 있음

 

텐서보드를 사용해 시각화하기

  • 텐서보드를 사용하려면 프로그램을 수정하여 이벤트 파일이라는 이진 로그 파일에 시각화하려는 데이터를 출력해야 함

  • 텐서보드 예제

    def get_run_logdir():
        import time
        run_id = time.strftime("run_%Y_%m_%d-%H_%M_%S")
        return os.path.join(root_logdir, run_id)
    
    run_logdir = get_run_logdir()
    
    model = keras.models.Sequential([
        keras.layers.Dense(30, activation="relu", input_shape=[8]),
        keras.layers.Dense(30, activation="relu"),
        keras.layers.Dense(1)
    ])    
    model.compile(loss="mse", optimizer=keras.optimizers.SGD(learning_rate=1e-3))
    
    checkpoint_cb = keras.callbacks.ModelCheckpoint("my_keras_model.h5", save_best_only=True)
    tensorboard_cb = keras.callbacks.TensorBoard(run_logdir)
    
    history = model.fit(X_train, y_train, epochs=30,
                        validation_data=(X_valid, y_valid),
                        callbacks=[checkpoint_cb, tensorboard_cb])
    
    %load_ext tensorboard
    %tensorboard --logdir=./my_logs --port=6006

    • 실행마다 하나의 디렉터리가 생성, 텐서보드가 전체 디바이스에 걸쳐서 모델의 각 부분에서 시간소요 및 성능 병목 지점을 찾는데 큰 도움이 됨

 

신경망 하이퍼파라미터 튜닝하기

  • 많은 하이퍼파라미터 조합을 시도해보고 어떤 것이 검증 세트에서 가장 좋은 점수를 내는지 확인하는 방법

  • KerasRegressor 예제

    def build_model(n_hidden=1, n_neurons=30, learning_rate=3e-3, input_shape=[8]):
        model = keras.models.Sequential()
        model.add(keras.layers.InputLayer(input_shape=input_shape))
        for layer in range(n_hidden):
            model.add(keras.layers.Dense(n_neurons, activation="relu"))
        model.add(keras.layers.Dense(1))
        optimizer = keras.optimizers.SGD(learning_rate=learning_rate)
        model.compile(loss="mse", optimizer=optimizer)
        return model
    
    keras_reg = keras.wrappers.scikit_learn.KerasRegressor(build_model)
    
    keras_reg.fit(X_train, y_train, epochs=100,
                  validation_data=(X_valid, y_valid),
                  callbacks=[keras.callbacks.EarlyStopping(patience=10)])
    
    mse_test = keras_reg.score(X_test, y_test)
    y_pred = keras_reg.predict(X_new)
    • KerasRegressor 객체는 build_model() 함수로 만들어진 케라스 모델을 감싸는 간단한 래퍼 형태
    • 일반적인 sklearn 회귀 추정기처럼 이 객체를 사용할 수 있음
  • RandomizedSearchCV 파라미터 튜닝 예제

    from scipy.stats import reciprocal
    from sklearn.model_selection import RandomizedSearchCV
    
    param_distribs = {
        "n_hidden": [0, 1, 2, 3],
        "n_neurons": np.arange(1, 100).tolist(),
        "learning_rate": reciprocal(3e-4, 3e-2).rvs(1000).tolist(),
    }
    
    rnd_search_cv = RandomizedSearchCV(keras_reg, param_distribs, n_iter=10, cv=3, verbose=2)
    rnd_search_cv.fit(X_train, y_train, epochs=100,
                      validation_data=(X_valid, y_valid),
                      callbacks=[keras.callbacks.EarlyStopping(patience=10)])
    
    rnd_search_cv.best_params_
    >> {'learning_rate': 0.005803602934201024, 'n_hidden': 3, 'n_neurons': 74}
    rnd_search_cv.best_score_
    >> -0.3189570407072703
    
    model = rnd_search_cv.best_estimator_.model
    • RandomizedSearchCV는 k-겹 교차 검증을 사용하기 때문에 X_valid와 y_valid를 사용하지 않음
      • 해당 데이터는 조기 종료에만 사용 됨
    • 랜덤 탐색은 하드웨어와 데이터셋의 크기, 모델의 복잡도, n_iter, cv 매개변수에 따라 및 시간이 걸릴 수 있습니다.
      • 실행 완료되면 랜덤 탐색이 찾은 최상의 하이퍼파라미터와 훈련된 케라스 모델을 얻을수 있음
  • 추가적인 하이퍼파라미터 튜닝 패키지

    • Hyperopt

      • 모든 종류의 복잡한 탐색 공간에 대해 최적화를 수행할 수 있는 라이브러리
    • Hyperas, Kopt, Talos

      • 케라스 모델을 위한 하이퍼파라미터 최적화 라이브러리
    • kears tuner

      • 사용하기 쉬운 케라스 하이퍼파라미터 최적화 하이브러리
    • scikit-optimize

      • 범용 최적화 라이브러리, BayesSerachCV 클래스는 GridSearchCV와 빕슷한 인터페이스를 사용하여 베이즈 최적화를 수행
    • Spearminit

      • 베이즈 최적화 라이브러리
    • Hyperband

      • 빠른 하이퍼파라미터 튜닝 라이브러리 입니다.
    • Sklearn-Deep

      • GridSearchCV와 비슷한 인터페이스를 가진 evolutionary algorithm 기반의 하이퍼파라미터 최적화 라이브러리

 

은닉층 개수

  • 복잡한 문제에서는 심층 신경망이 얕은 신경망보다 파라미터 효율성이 훨씬 좋음
  • 심층 신경망은 복잡한 함수를 모델링하는 데 얕은 신경망보다 훨씬 적은 수의 뉴런을 사용하므로 동일한 양의 훈련 데이터에서 더 높은 성능을 낼 수 있음
  • 계층 구조는 심층 신경망이 좋은 솔루션으로 빨리 수렴하게끔 도화줄 뿐만 아니라 새로운 데이터에 일반화되는 능력도 향상시켜줌
  • 새로운 신경망에서 처음 몇 개 층의 가중치와 편향을 난수로 초기화하는 대신 첫 번째 신경망의 층에 있는 가중치와 편향값으로 초기화할 수 있음, 이를 전이 학습이라고 함

 

은닉층의 뉴런 개수

  • 입력층과 출력층의 뉴런 개수는 해당 작업에 필요한 입력과 출력의 형태에 따라 결정 됨

  • 은닉층의 구성 방식은 일반적으로 각 층의 뉴런을 점점 줄여서 깔때기처럼 구성

    • 저수준의 많은 특성이 고수준의 적은 특성으로 합쳐질 수 있기 때문
    • 대부분의 경우 모든 은닉층에 같은 크기를 사용해도 동일하거나 더 나은 성능을 냄
    • 튜닝할 하이퍼파라미터가 층마다 한 개씩이 아니라 전체를 통틀어 한 개가 됨, 데이터셋에 따라 다르지만 다른 은닉층보다 첫 번째 은닉층을 크게 하는 것이 도움이 됨
  • 층의 개수와 마찬가지로 네트워크가 과대적합이 시작되기 전까지 점진적으로 뉴런 수를 늘릴수 있음

    • 실전에서는 필요한 것보다 더 많은 층과 뉴런을 가진 모델을 선택하고, 그런 다음 과대적합되지 않도록 조기 종료나 규제 기법을 사용하는 것이 간단하고 효과적임

 

학습률, 배치 크기 그리고 다른 하이퍼파라미터

  • 학습률
    • 가장 중요한 하이퍼파라미터
    • 일반적으로 최적의 학습률은 최대 학습률의 절반
      • 좋은 학습률을 찾는 한 가지 방법은 매우 낮은 학습률에서 시작해서 점진적으로 매우 큰 학습률까지 수백 번 반 반복하여 모델을 훈련하는 방식이 제일 좋음
  • 옵티마이저
    • 데이터와 학습 상황을 통해 경사 하강법보다 더 좋은 옵티마이저를 선택하는 것도 중요합니다.
  • 배치 크기
    • 배치 크기는 모델 성능과 훈련 시간에 큰 영향을 미칠 수 있음
    • 큰 배치 크기를 사용하는 것의 주요 장점은 GPU와 같은 하드웨어 가속기를 효율적으로 활용할 수 있다는 점, 훈련 알고리즘이 초당 더 많은 샘플을 처리할 수 있음
  • 활성화 함수
    • 일반적으로 ReLU 활성화 함수가 모든 은닉층에 좋은 기본값임
    • 출력층의 활성화 함수는 수행하는 작업에 따라 달라짐
  • 반복 횟수
    • 대부분의 경우 훈련 반복 횟수는 튜닝할 필요가 없음, 대신 조기 종료를 사용
    • 최적의 학습률은 다른 하이퍼파라미터에 의존적, 배치 크기에 영향을 많이 받음, 따라서 다른 하이퍼파라미터를 수정하면 학습률도 반드시 튜닝해야 함
반응형

'Study > Self Education' 카테고리의 다른 글

핸즈온 머신러닝 - 12  (0) 2024.06.19
핸즈온 머신러닝 - 11  (0) 2024.06.19
핸즈온 머신러닝 - 9  (0) 2024.06.18
핸즈온 머신러닝 - 8  (0) 2024.06.18
핸즈온 머신러닝 - 7  (0) 2024.06.18