3 분 소요

📌 인공 신경망에 층을 여러개 추가하여 데이터셋을 분류하면서 심층 신경망을 만들기 (디벨롬)

1️⃣ 데이터셋 가져오기

from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()

from sklearn.model_selection import train_test_split
train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28*28)
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)

인공 신경망 모델에 층을 2개 추가해 볼 것이다.

2️⃣ 은닉층 추가하기 => 심층 신경망 만들기

앞 장에서는 입력층 ~ 출력층 -> 활성화 함수 이런 식으로 훈련했었는데, 층을 추가하게 된다면 입력층과 출력층 사이에 은닉층 을 추가하게 되는 것이다.

출력층에 적용하는 활성화 함수의 종류는 시그모이드 함수와 소프트맥스 함수로 제한되어 있으나, 은닉층의 활성화 함수는 비교적 자유롭다.

📍 은닉층 추가하는 법 #1

dense1 = keras.layers.Dense(100, activation='sigmoid', input_shape=(784, )) # 은닉층, 100개의 뉴런 포함
dense2 = keras.layers.Dense(10, activation='softmax') # 은닉층, 10개의 뉴런 포함
model = keras.Sequential([dense1, dense2])
model.summary()

>>>
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #
=================================================================
 dense (Dense)               (None, 100)               78500

 dense_1 (Dense)             (None, 10)                1010

=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
  • Output Shape 부분 -> output이 None인 이유: output은 샘플 개수를 나타내는데 아직 케라스 모델의 fit() 메소드에 훈련 데이터를 주입하면 미니 배치 경사 하강법을 사용하기 때문에 샘플 개수를 고정하지 않고, 어떤 배치 크기에도 유연하게 대응할 수 있도록 None으로 설정

📍 은닉층 추가하는 법 #2

model = keras.Sequential([keras.layers.Dense(100, activation='sigmoid', input_shape=(784, ), name='hidden'),
keras.layers.Dense(10, activation='softmax', name='output')], name="패션 MNIST 모델")

-> 추가되는 층을 한눈에 쉽게 알아볼 수 있는 장점이 있다.

📍 은닉층 추가하는 법 #3

model = keras.Sequential()
model.add(keras.layers.Dense(100, activation='sigmoid', input_shape=(784, )))
model.add(keras.layers.Dense(10, activation='softmax'))

-> 한눈에 추가되는 층을 볼 수 있고, 프로그램 실행 시 동적으로 층을 선택하여 추가할 수 있다.

🔮 렐루 함수

시그모이드 함수 -> 0 또는 1로 수렴하는 함수이므로 올바른 출력을 만드는데 신속하게 대응하지 못함 -> sol. 렐루 함수

렐루 함수는 입력이 양수일 때는 활성화 함수가 없는 것처럼 그냥 입력을 통과시키고, 음수일 경우는 0으로 만든다.

  • max(0, z) : 같이 사용할 수 있는데, z가 0보다 크면 z를 출력, 아니면 0을 출력
  • 이미지 처리에서 좋은 성능을 나타낸다고 알려져 있다.

3️⃣ 렐루 함수를 사용하여서 심층 신경망 만들기

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28, 28)))
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
model.summary()

>>>
Model: "sequential_4"
_________________________________________________________________
 Layer (type)                Output Shape              Param #
=================================================================
 flatten (Flatten)           (None, 784)               0

 dense_8 (Dense)             (None, 100)               78500

 dense_9 (Dense)             (None, 10)                1010

=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
  • Flattern : 입력 차원을 모두 일렬로 펼치는 역할(앞 장에서는 reshape()를 통해서 1차원 배열로 픽셀들의 배치를 바꾸어줌)
(train_input, train_target), (test_input, test_train) = keras.datasets.fashion_mnist.load_data()
train_scaled = train_input / 255.0
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)

model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)

>>>
Epoch 1/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.5313 - accuracy: 0.8135
Epoch 2/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3905 - accuracy: 0.8596
Epoch 3/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3565 - accuracy: 0.8714
Epoch 4/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3364 - accuracy: 0.8781
Epoch 5/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3212 - accuracy: 0.8860
<keras.callbacks.History at 0x7fe62ecdb390>
model.evaluate(val_scaled, val_target)

>>>
375/375 [==============================] - 1s 1ms/step - loss: 0.3612 - accuracy: 0.8784
[0.3612439036369324, 0.8784166574478149]

❗ 지금까지는 에포크를 5로 지정을 해두었지만, 이 값을 늘려서 더 훈련을 시킬 수 있다. ❗

옵티마이저

케라스의 경우 기본 경사 하강법 알고리즘을 사용했지만, 이를 다양한 종류의 경사 하강법 알고리즘으로 바꿀 수 있다. 이런 알고리즘들을 옵티마이저 라고 부른다.

📍 SGD : 가장 기본 옵티마이저

SGD는 미니 배치 경사 하강법을 사용한다.

model.compile(optimizer='sgd', loss='sparse_categorical_crossentropy', metrics='accuracy')

SGD 클래스의 매개변수

  • momentum : 기본값 0, 0보다 큰 값인 경우 모멘텀 최적화를 사용, 일반적으로 0.9 이상 사용
  • nesterov : 기본값 False, True로 바꾸면 네스테로프 모멘텀 최적화를 사용.

📍 적응적 학습률을 사용하는 옵티마이저

적응적 학습률이란 모델이 최적점에 가까이 갈수록 학습률을 낮추는 것.

이를 사용하는 대표적 옵티마이저 : Adagrad , RMSprop , Adam (모멘텀 최적화와 RMSprop의 장점 접목)

-> 모두 learning_rate는 0.001을 사용


optimizer=’adam’ 사용하여 훈련해보기

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28, 28)))
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
model.evaluate(val_scaled, val_target)

>>>
Epoch 1/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.5258 - accuracy: 0.8150
Epoch 2/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.3928 - accuracy: 0.8580
Epoch 3/5
1500/1500 [==============================] - 2s 2ms/step - loss: 0.3555 - accuracy: 0.8697
Epoch 4/5
1500/1500 [==============================] - 2s 2ms/step - loss: 0.3284 - accuracy: 0.8806
Epoch 5/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.3083 - accuracy: 0.8882
375/375 [==============================] - 1s 1ms/step - loss: 0.3563 - accuracy: 0.8712

[0.3563465178012848, 0.8712499737739563]

87% 정도로 RMSprop보다는 조금 나은 성능을 나타냄

댓글남기기