-
[HandsOn]10. 케라스를 사용한 인공 신경망- 연습문제[도서완독]Hands On Machine Learning 2022. 1. 12. 12:09
신년 목표로 '핸즈온 머신러닝' 책을 완독하기로 결심했다.
https://book.naver.com/bookdb/book_detail.nhn?bid=16328592
핸즈온 머신러닝
컬러판으로 돌아온 아마존 인공지능 분야 부동의 1위 도서이 책은 지능형 시스템을 구축하려면 반드시 알아야 할 머신러닝, 딥러닝 분야 핵심 개념과 이론을 이해하기 쉽게 설명한다. 사이킷런,
book.naver.com
엄청나게 두껍다!
전에 보던 '머신러닝 완벽 가이드'보다 더 깊고 방대한 내용을 담고 있다.
이제 겨우 1장 끝냈지만... 천리 길도 한 걸음부터! 이니깐 열심히 해봐야지.
해당 책은 연습문제에서 한 문제 정도를 코딩을 직접 해 볼수 있도록 하고 있다.
같이 풀어보자!
10. 심층 다층 퍼셉트론을 MNIST 데이터셋에 훈련해보세요. 98% 이상의 정확도를 얻을 수 있는지 확인해보세요. 이 장 에서 소개한 방법을 사용해 최적의 학습률을 찾아보세요(즉 학습률을 지수적으로 증가시키면서 손실을 그래프로 그립니다. 그다음 손실이 다시 증가하는 지점을 찾습니다.) 모든 부가기능을 추가해보세요. 즉, 체크포인트를 저장하고, 조기 종료를 사용하고, 텐서보드를 사용해 학습 곡선을 그려보세요.
답안: https://github.com/rickiepark/handson-ml2 를 참고하였다.
import tensorflow as tf from tensorflow import keras import matplotlib.pyplot as plt import math from sklearn.datasets import fetch_openml (X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data() X_valid = X_train[:5000]/255.0 X_train = X_train[5000:]/255.0 X_test = X_test/255.0 y_valid = y_train[:5000] y_train = y_train[5000:]
mnist 데이터를 불러오고, train,valid, test 셋으로 나누고 표준화 해준다. sgd에서 표준화는 필수이다.
class ExponentialLearningRate(keras.callbacks.Callback): def __init__(self,factor): self.factor=factor self.rates=[] self.losses=[] def on_batch_end(self,batch,logs): self.rates.append(keras.backend.get_value(self.model.optimizer.lr)) self.losses.append(logs['loss']) keras.backend.set_value(self.model.optimizer.lr, self.model.optimizer.lr * self.factor)
답안에는 이 코드에 대한 설명은 없다. 이 코드가 핵심 같다. 간단한..(나는 잘 모르는) 서브클래싱 코드인데, 일단 상속과 오버라이딩을 알면 쉽게 이해는 가능하다.
먼저 첫 줄 괄호 안에 keras.callbacks.Callback을 상속받는다. callback에는 많은 함수가 있다.
https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/Callback 를 참조하자.
tf.keras.callbacks.Callback | TensorFlow Core v2.7.0
Abstract base class used to build new callbacks.
www.tensorflow.org
그리고 두개의 def를 오버라이딩한다. 두번째 on_batch_end는 이미 callback 안에 있는 함수이고, 미니배치가 끝날때 마다 학습률을 바꿔서 증가시킨다.
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() sgd = tf.keras.optimizers.SGD(learning_rate=0.001) model.compile(loss='sparse_categorical_crossentropy', optimizer=sgd, metrics=['accuracy']) expon_lr=ExponentialLearningRate(factor=1.005)
반복마다 0.5%씩 증가하는 걸로 한다.
checkpoint_cb=keras.callbacks.ModelCheckpoint(r"어쩌구\문서\my_keras_model.h5",save_best_only=True) early_stopping_cb=keras.callbacks.EarlyStopping(patience=10,restore_best_weights=True) #tensorboard_cb=keras.callbacks.TensorBoard(r'어쩌구\문서\tensor_log') history=model.fit(X_train,y_train, # batch_size=10,(128,256,512) epochs=1, validation_data=(X_valid,y_valid), callbacks=[expon_lr, checkpoint_cb, early_stopping_cb, tensorboard_cb])
체크포인트와 조기 종료를 피팅에 추가 해준다. 텐서보드는 어려워서... 하지 않겠습니다. (ㅜㅜ)
아! 에포크를 1로 한 이유는, 에포크가 '모든 데이터를 다 학습'한 걸 뜻하는데, 그 안에서 미니배치로 학습률을 변경시켰기 때문인 것 같다.
plt.plot(expon_lr.rates, expon_lr.losses) plt.gca().set_xscale('log') plt.hlines(min(expon_lr.losses), min(expon_lr.rates), max(expon_lr.rates)) plt.axis([min(expon_lr.rates), max(expon_lr.rates), 0, expon_lr.losses[0]]) plt.grid() plt.xlabel("Learning rate") plt.ylabel("Loss")
학습률 1 직전에 loss가 솟구치는 걸 볼 수 있다. 그럼 직전의 학습률인 0.5 정도로 할 수 있겠다.
model = keras.models.load_model("my_mnist_model.h5") # rollback to best model model.evaluate(X_test, y_test)
코드엔 안 적었는데 모델 주소를 적어줘야 된다! (너무기초.. 다들아시리라믿음)
이러면 best 모델로 롤백 가능하다.
그리고 test데이터로 평가하면 98% 정확도를 얻을 수 있다.
이제 시작했는데 너무 힘들다... 힘내서 11장으로 가부자!
코드전체는 여기! https://깃허브
'[도서완독]Hands On Machine Learning' 카테고리의 다른 글
[HandsOn]10. 케라스를 사용한 인공 신경망 - 내용 정리 3 (0) 2022.07.01 [HandsOn]10. 케라스를 사용한 인공 신경망 - 내용 정리2 (0) 2022.07.01 [HandsOn]10. 케라스를 사용한 인공 신경망 - 내용 정리1 (0) 2022.06.28 [HandsOn]12. 텐서플로를 사용한 사용자 정의 모델과 훈련 - 연습문제 (0) 2022.02.15 [HandsOn]11.심층 신경망 훈련하기- 연습문제 (0) 2022.01.19