07-1 인공 신경망¶
☆ 신경망은 기존의 머신러닝 알고리즘으로 다루기 어려웠던 이미지, 음성, 텍스트 분야에서 뛰어난 성능을 발휘하면서 크게 주목을 받고 있으며 딥러닝이라고도 부른다.
from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
# 데이터 크기 확인하기
print(train_input.shape, train_target.shape)
print(test_input.shape, test_target.shape)
(60000, 28, 28) (60000,)
(10000, 28, 28) (10000,)
# 데이터 이미지 확인해 보기
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 10, figsize=(10,10))
for i in range(10):
axs[i].imshow(train_input[i], cmap='gray_r')
axs[i].axis('off')
plt.show()
# target값 확인
print([train_target[i] for i in range(10)])
[9, 0, 0, 3, 0, 2, 7, 2, 5, 5]
# 각 인덱스별 데이터 수
import numpy as np
print(np.unique(train_target, return_counts=True))
# 6000개의 데이터가 각각의 인덱스에 존재하는 것을 확인할 수 있다.
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8), array([6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000],
dtype=int64))
로지스틱 회귀로 패션 아이템 분류하기¶
# 전체 데이터를 한꺼번에 사용하여 모델을 훈련하는 것보다 샘플 하나씩 꺼내서 모델을 훈련하는 방법 확률적 경사 하강법(SGDClassifier)를 시행
train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28*28)
from sklearn.model_selection import cross_validate
from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss='log', max_iter=5, random_state=42)
scores = cross_validate(sc, train_scaled, train_target)
print(np.mean(scores['test_score']))
# 정확도 : 0.8192833333333333
C:\work\envs\datascience\lib\site-packages\sklearn\linear_model\_stochastic_gradient.py:574: ConvergenceWarning: Maximum number of iteration reached before convergence. Consider increasing max_iter to improve the fit.
warnings.warn("Maximum number of iteration reached before "
C:\work\envs\datascience\lib\site-packages\sklearn\linear_model\_stochastic_gradient.py:574: ConvergenceWarning: Maximum number of iteration reached before convergence. Consider increasing max_iter to improve the fit.
warnings.warn("Maximum number of iteration reached before "
C:\work\envs\datascience\lib\site-packages\sklearn\linear_model\_stochastic_gradient.py:574: ConvergenceWarning: Maximum number of iteration reached before convergence. Consider increasing max_iter to improve the fit.
warnings.warn("Maximum number of iteration reached before "
C:\work\envs\datascience\lib\site-packages\sklearn\linear_model\_stochastic_gradient.py:574: ConvergenceWarning: Maximum number of iteration reached before convergence. Consider increasing max_iter to improve the fit.
warnings.warn("Maximum number of iteration reached before "
0.8192833333333333
C:\work\envs\datascience\lib\site-packages\sklearn\linear_model\_stochastic_gradient.py:574: ConvergenceWarning: Maximum number of iteration reached before convergence. Consider increasing max_iter to improve the fit.
warnings.warn("Maximum number of iteration reached before "
인공 신경망¶
☆ 텐서플로 : 구글이 만들 딥러닝 라이브러리, 케라스를 핵심 API로 채택
☆ 딥러닝 라이브러리는 GPU를 사용하여 인공 신경망을 훈련
☆ 케라스는 GPU 연산을 수행하지 않고 GPU 연산을 수행하는 다른 라이브러리를 백엔드로 사용한다.
import tensorflow as tf
from tensorflow import keras
# 데이터 분류
from sklearn.model_selection import train_test_split
train_scaled, val_scaled, train_target, val_target = train_test_split(
train_scaled, train_target, test_size=0.2, random_state=42)
print(train_scaled.shape, train_target.shape)
print(val_scaled.shape, val_target.shape)
(48000, 784) (48000,)
(12000, 784) (12000,)
인공 신경망에서는 교차 검증을 사용하지 않는다.¶
- 이유 1 : 데이터셋은 충분히 크기 때문에 검증 점수가 안정적
- 이유 2 : 교차 검증을 수행하면 훈련 시간이 너무 오래 걸리기 때문
dense = keras.layers.Dense(10, activation='softmax', input_shape=(784,))
# 뉴런 개수, 뉴런의 출력에 적용할 함수, 입력의 크기
model = keras.Sequential(dense)
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
# loss='sparse_categorical_crossentropy' = 정수로 된 타깃값을 원-핫 인코딩하지 않고 바로 사용할 수 있게 해주는 함수
model.fit(train_scaled, train_target, epochs=5)
# 정확도 : 0.8553
Epoch 1/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.6083 - accuracy: 0.7964
Epoch 2/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.4776 - accuracy: 0.8396
Epoch 3/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.4563 - accuracy: 0.8484
Epoch 4/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.4437 - accuracy: 0.8521
Epoch 5/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.4364 - accuracy: 0.8556
<keras.callbacks.History at 0x1950a2fef10>
model.evaluate(val_scaled, val_target)
# 정확도 : 0.8526666760444641
375/375 [==============================] - 1s 1ms/step - loss: 0.4405 - accuracy: 0.8518
[0.4405025243759155, 0.8517500162124634]
로지스틱 회귀 분석에 의한 분류보다는 정확도가 높다.
07-2 신층 신경망¶
☆ 은닉층 : 입력층과 출력층 사이에 있는 모든 층
회귀를 축력하는 신경망은 활성화 함수를 사용할 필요가 없다.
# 심층 신경망 만들기
dense1 = keras.layers.Dense(100, activation='sigmoid', input_shape=(784,))
dense2 = keras.layers.Dense(10, activation='softmax')
model = keras.Sequential([dense1, dense2])
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 100) 78500
_________________________________________________________________
dense_2 (Dense) (None, 10) 1010
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
# 층 추가하기 방법 1
model = keras.Sequential([
keras.layers.Dense(100, activation='sigmoid', input_shape=(784,), name='hidden'),
keras.layers.Dense(10, activation='softmax', name='output')
], name='패션 MNIST 모델')
# 층 추가하기 방법 2
model = keras.Sequential()
model.add(keras.layers.Dense(100, activation='sigmoid', input_shape=(784,)))
model.add(keras.layers.Dense(10, activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
# 층이 추가되어 정확도가 높아졌다.
Epoch 1/5
1500/1500 [==============================] - 4s 3ms/step - loss: 0.5604 - accuracy: 0.8069
Epoch 2/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.4088 - accuracy: 0.8533
Epoch 3/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3753 - accuracy: 0.8648
Epoch 4/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3521 - accuracy: 0.8707
Epoch 5/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3362 - accuracy: 0.8785
<keras.callbacks.History at 0x195159dfa90>
렐루 함수¶
☆ 시그모이드 함수의 단점 : 오른쪽과 왼쪽 끝으로 갈수록 그래프가 누워있기 때문에 올바른 출력을 못한다.
☆ 시그모이드 함수의 단점을 보완하고자 렐루 함수 사용 (max(0,z)를 사용)
☆ 렐루 함수 : 이미지 처리에 좋은 성능
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_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten (Flatten) (None, 784) 0
_________________________________________________________________
dense_5 (Dense) (None, 100) 78500
_________________________________________________________________
dense_6 (Dense) (None, 10) 1010
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
(train_input, train_target), (test_input, test_target) = 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)
# 렐루 함수 fit
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
Epoch 1/5
1500/1500 [==============================] - 4s 2ms/step - loss: 0.5339 - accuracy: 0.8121
Epoch 2/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3919 - accuracy: 0.8594
Epoch 3/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3541 - accuracy: 0.8724
Epoch 4/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3333 - accuracy: 0.8802
Epoch 5/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3189 - accuracy: 0.8862
<keras.callbacks.History at 0x1951ea65970>
model.evaluate(val_scaled, val_target)
# 렐루 함수를 사용해 좀더 높은 정화도 도출
375/375 [==============================] - 1s 1ms/step - loss: 0.3628 - accuracy: 0.8792
[0.3627806007862091, 0.8791666626930237]
옵티마이저¶
옵티마이저 : 신경망의 가중치와 절편을 학습하기 위한 알고리즘 또는 방법
sgd = keras.optimizers.SGD()
model.compile(optimizer=sgd, loss='sparse_categorical_crossentropy', metrics='accuracy')
# 여러가지 설정도 가능
sgd = keras.optimizers.SGD(learning_rate=0.1)
sgd = keras.optimizers.SGD(momentum=0.9, nesterov=True)
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'))
☆ 옵티마이저 클래스 종류
- Adagrad : 그레이디언트 제곱을 누적하여 학습률을 나눔
- RMSprop : 최근의 그레이디언트를 사용하기 dnlgo 지수 감소를 사용
- Adam
# adam으로 학습하기
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
Epoch 1/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.5315 - accuracy: 0.8150
Epoch 2/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3950 - accuracy: 0.8580
Epoch 3/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3574 - accuracy: 0.8702: 0s - loss: 0.3578 - accuracy
Epoch 4/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3314 - accuracy: 0.8778
Epoch 5/5
1500/1500 [==============================] - 4s 2ms/step - loss: 0.3093 - accuracy: 0.8858
<keras.callbacks.History at 0x1950717e850>
model.evaluate(val_scaled, val_target)
375/375 [==============================] - 1s 2ms/step - loss: 0.3396 - accuracy: 0.8769
[0.33964309096336365, 0.8769166469573975]
07-3 신경망 모델 훈련¶
(train_input, train_target), (test_input, test_target) = \
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)
def model_fn(a_layer=None):
model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28, 28)))
model.add(keras.layers.Dense(100, activation='relu'))
if a_layer:
model.add(a_layer)
model.add(keras.layers.Dense(10, activation='softmax'))
return model
# 이전 모델 사용
model = model_fn()
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=5, verbose=0)
# history 딕셔너리 사용
print(history.history.keys())
dict_keys(['loss', 'accuracy'])
history에는 손실과 정확도가 포함
history는 에포크마다 계산한 값이 순서대로 나열된 단순한 리스트
# 에폭시별 손실함수 값 출력
import matplotlib.pyplot as plt
plt.plot(history.history['loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.savefig('7_3-01', dpi=300)
plt.show()
# 에포크 20으로 증가
model = model_fn()
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0)
import matplotlib.pyplot as plt
plt.plot(history.history['loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
#plt.savefig('7_3-01', dpi=300) # 파일 저장 코드
plt.show()
# 훈련 데이터와 검증 데이터들의 검증 손실 비교
model = model_fn()
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0,
validation_data=(val_scaled, val_target))
print(history.history.keys())
dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
# 검증 데이터와 비교를 통해 최적의 epoch값 도출 가능
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
#plt.savefig('7_3-04', dpi=300) # 파일 저장 코드
plt.show()
드롭아웃¶
일부 뉴런을 랜덤하게 꺼서(즉 뉴런의 출력을 0으로 만들어) 과대적합을 막아주는 것을 드롭아웃이라고 부릅니다.
드롭아웃을 통해 특정 뉴런에 과대하게 의존하는 것을 줄일 수 있다.
# 드롭아웃 코드
model = model_fn(keras.layers.Dropout(0.3))
model.summary()
# 드롭아웃은 일부 뉴런의 출력을 0으로 만들지만 전체 출력 배열의 크기를 바꾸지 않는다.
Model: "sequential_8"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten_5 (Flatten) (None, 784) 0
_________________________________________________________________
dense_15 (Dense) (None, 100) 78500
_________________________________________________________________
dropout (Dropout) (None, 100) 0
_________________________________________________________________
dense_16 (Dense) (None, 10) 1010
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',
metrics='accuracy')
history = model.fit(train_scaled, train_target, epochs=20, verbose=0,
validation_data=(val_scaled, val_target))
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
# plt.savefig('7_3-06', dpi=300)
plt.show()
# 과대적합이 많이 줄은것을 확인할 수 있다.
# 훈련된 모델의 파라미터를 저장하는 메서드
model.save_weights('model-weights.h5')
# 모델 구조와 모델 파라미터를 함께 저장하는 메서드
model.save('model-whole.h5')
model = model_fn(keras.layers.Dropout(0.3))
# 동일한 구조를 가져야 실행 가능
model.load_weights('model-weights.h5')
# 검증
import numpy as np
val_labels = np.argmax(model.predict(val_scaled),axis=-1)
print(np.mean(val_labels == val_target))
0.886
# 검증 2
model = keras.models.load_model('model-whole.h5')
model.evaluate(val_scaled,val_target)
375/375 [==============================] - 1s 3ms/step - loss: 0.3272 - accuracy: 0.8860
[0.32715699076652527, 0.8859999775886536]
콜백¶
fit() 메서드의 callbacks 매개변수에 리스트로 전달하여 사용
자동으로 최상의 모델 유지 가능
model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',
metrics='accuracy')
checkpoint_cb = keras.callbacks.ModelCheckpoint('best-model.h5',
save_best_only=True) # 최상의 검증 점수를 낸 모델 저장
model.fit(train_scaled, train_target, epochs=20, verbose=0,
validation_data=(val_scaled, val_target),
callbacks=[checkpoint_cb])
<keras.callbacks.History at 0x1950a2ddac0>
# 최상의 검증 점수를 낸 모델 읽기
model = keras.models.load_model('best-model.h5')
model.evaluate(val_scaled, val_target)
375/375 [==============================] - 1s 2ms/step - loss: 0.3183 - accuracy: 0.8882
[0.3183283805847168, 0.8881666660308838]
조기 종료 : 과대적합이 시작되기 전에 훈련을 미리 중지하는 것
에포크 횟수를 제한하는 역할이지만 모델이 과대적합되는 것을 막아 주기 때문에 규제 방법 중 하나
# 조기 종료 실행 코드
model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',
metrics='accuracy')
checkpoint_cb = keras.callbacks.ModelCheckpoint('best-model.h5',
save_best_only=True)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2,
restore_best_weights=True)
# patience=2 는 2연속 검증 점수가 향상되지 않으면 훈련 중지
# restore_best_weights=True 가장 낮은 검증 손실 낸 모델 파라미터 반환
history = model.fit(train_scaled, train_target, epochs=20, verbose=0,
validation_data=(val_scaled, val_target),
callbacks=[checkpoint_cb, early_stopping_cb])
# 훈련 중지 에포크
print(early_stopping_cb.stopped_epoch)
# patience=2 이므로 6에서 에포크 훈련 중지이다.
8
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.savefig('7_3-07', dpi=300)
plt.show()
model.evaluate(val_scaled, val_target)
375/375 [==============================] - 1s 1ms/step - loss: 0.3351 - accuracy: 0.8799
[0.3350639343261719, 0.8799166679382324]
from IPython.core.display import display, HTML
display(HTML("<style>.container {width:80% !important;}</style>"))
'Book report > 혼자 공부하는 머신러닝 + 딥러닝' 카테고리의 다른 글
[혼자 공부하는 머신러닝 + 딥러닝] Chapter 9 텍스트를 위한 인공 신경망 (0) | 2021.09.29 |
---|---|
[혼자 공부하는 머신러닝 + 딥러닝] Chapter 8 이미지를 위한 인공 신경망 (0) | 2021.09.27 |
[혼자 공부하는 머신러닝 + 딥러닝] Chapter 6 비지도 학습 (0) | 2021.09.03 |
[혼자 공부하는 머신러닝 + 딥러닝] Chapter 5 트리 알고리즘 (0) | 2021.09.01 |
[혼자 공부하는 머신러닝 + 딥러닝] Chapter 4 다양한 분류 알고리즘 (0) | 2021.08.31 |