인공 신경망
퍼셉트론(perceptron), 다층 퍼셉트론 (MLP)
이전 내용
모델 저장과 복원하기
◆ 훈련된 케라스 모델 저장하는 방법
model.save('my_keras_model.keras')
※ 이전에는 model.save('my_keras_model', save_format='tf')로 저장 형식을 지정해야 했으나, 케라스 3.부터는 보다 간소화되었다.
The `save_format` argument is deprecated in Keras 3. Please remove this argument and pass a file path with either `.keras` or `.h5` extension.Received: save_format=tf
◆ 모델 로드하는 방법 (에러 발생)
# 모델 로드
model = tf.keras.models.load_model("my_keras_model.keras")
y_pred_main, y_pred_aux = model.predict((X_new_wide, X_new_deep))
◆ 코드 수정하여 저장 및 로드 재수행
만약 하단의 에러가 발생할 경우
TypeError: Could not locate class 'WideAndDeepModel'. Make sure custom classes are decorated with `@keras.saving.register_keras_serializable()`. Full object config: {'module': None, 'class_name': 'WideAndDeepModel', 'config': {'name': 'my_cool_model', 'trainable': True, 'dtype': {'module': 'keras', 'class_name': 'DTypePolicy', 'config': {'name': 'float32'}, 'registered_name': None}}, 'registered_name': 'WideAndDeepModel', 'build_config': {'input_shape': [[None, 5], [None, 6]]}, 'compile_config': {'optimizer': {'module': 'keras.optimizers', 'class_name': 'Adam', 'config': {'name': 'adam', 'learning_rate': 0.0010000000474974513, 'weight_decay': None, 'clipnorm': None, 'global_clipnorm': None, 'clipvalue': None, 'use_ema': False, 'ema_momentum': 0.99, 'ema_overwrite_frequency': None, 'loss_scale_factor': None, 'gradient_accumulation_steps': None, 'beta_1': 0.9, 'beta_2': 0.999, 'epsilon': 1e-07, 'amsgrad': False}, 'registered_name': None}, 'loss': 'mse', 'loss_weights': [0.9, 0.1], 'metrics': ['RootMeanSquaredError', 'RootMeanSquaredError'], 'weighted_metrics': None, 'run_eagerly': False, 'steps_per_execution': 1, 'jit_compile': False}}
주어진 코드에서 커스텀 모델 클래스를 저장하고 다시 불러올 때 발생하는 오류를 해결하기 위해, 해당 모델 클래스를 @tf.keras.utils.register_keras_serializable() 데코레이터로 등록해야 한다. 이 데코레이터는 텐서플로우가 모델을 저장할 때 커스텀 클래스를 직렬화해주는 역할을 한다.
이전에 했던 WideAndDeepModel 클래스 상단에 @tf.keras.utils.register_keras_serializable() 데코레이터 코드를 추가
@tf.keras.utils.register_keras_serializable()
class WideAndDeepModel(tf.keras.Model):
def __init__(self, units=30, activation='relu', **kwargs):
super().__init__(**kwargs) # 모델에 이름 부여 위해 필요
self.norm_layer_wide = tf.keras.layers.Normalization()
self.norm_layer_deep = tf.keras.layers.Normalization()
self.hidden1 = tf.keras.layers.Dense(units, activation=activation)
self.hidden2 = tf.keras.layers.Dense(units, activation=activation)
self.main_output = tf.keras.layers.Dense(1)
self.aux_output = tf.keras.layers.Dense(1)
def call(self, inputs):
input_wide, input_deep = inputs
norm_wide = self.norm_layer_wide(input_wide)
norm_deep = self.norm_layer_deep(input_deep)
hidden1 = self.hidden1(norm_deep)
hidden2 = self.hidden2(hidden1)
concat = tf.keras.layers.concatenate([norm_wide, hidden2])
output = self.main_output(concat)
aux_output = self.aux_output(hidden2)
return output, aux_output
# 모델 인스턴스 생성 및 컴파일
model = WideAndDeepModel(30, activation='relu', name='my_cool_model')
코드를 재실행하고, 생성한 모델을 컴파일, 정규화 측 적용, 훈련, 평가, 예측 하는 코드를 재실행하고 모델을 저장한 뒤,
모델을 다시 로드해보면
경고메시지가 뜨긴 했지만, 어쨌든 로드는 되었다.
◆ 파라미터 값만 저장하고 로드
save_weights()와 load_weight()를 사용하여 파라미터 값만 저장하고 로드할 수 있으며, 여기에는 연결 가중치, 편향, 전처리 통계치, 옵티마이저 상태 등이 포함된다.
가중치만 저장하는 것이 전체 모델을 저장하는 것보다 더 빠르고 디스크 공간을 덜 사용하므로 훈련 중에 체크포인트를 빠르게 저장하는 데 적합하다. 큰 모델을 훈련하는 데 몇 시간 또는 며칠이 걸리는 경우 컴퓨터가 다운되는 경우를 대비해 체크포인트를 정기적으로 저장해야 한다.
model.save_weights("my_weights.weights.h5")
model.load_weights("my_weights.weights.h5")
콜백 사용하기
fit() 메서드에 callbacks 매개변수를 사용하여 케라스가 훈련의 시작 전이나 후에 호출할 객체 리스트를 저장할 수 있거나, 에포크의 시작 전후, 각 배치 처리 전후에 호출할 수도 있다.
아래의 ModelCheckpoint는 훈련하는 동안 일정한 간격으로 모델의 체크포인트를 저장한다. (기본적으로 매 에포크의 끝에서 호출)
checkpoint_cb = tf.keras.callbacks.ModelCheckpoint("my_checkpoints.weights.h5",
save_weights_only=True)
history = model.fit(
(X_train_wide, X_train_deep), (y_train, y_train), epochs=10,
validation_data=((X_valid_wide, X_valid_deep), (y_valid, y_valid)),
callbacks=[checkpoint_cb])
훈련하는 동안 검증 세트를 사용하면 ModelCheckpoint를 만들 때 save_best_only=True로 지정할 수 있는데,
이렇게 하면 최상의 검증 세트 점수에서만 모델을 저장하여 오랜 훈련 시간으로 훈련 세트에 과대적합될 걱정을 하지 않아도 되며 훈련이 끝난 후 마지막에 저장된 모델을 복원하면 된다. 그 모델이 검증 세트에서 최상의 점수를 낸 모델이며, 이것이 조기 종료를 구현하는 한 가지 방법이다. (실제로 훈련을 종료시키지는 않음.)
또 다른 방법은 EarlyStopping 콜백을 사용하는 것으로, patience 매개변수로 지정하는 일정 에포크 동안 검증 세트에 대한 점수가 향상되지 않으면 훈련을 멈춘다. restore_best_weights=True 로 지정하면 훈련이 끝난 후 최상의 모델을 복원한다. 컴퓨터가 문제를 일으키는 경우를 대비해서 체크포인트 저장 콜백과 시간이나 자원을 낭비하지 않고 과대적합을 막기 위해 진전이 없는 경우 훈련을 일찍 멈추는 콜백을 함께 사용할 수 있다.
early_stopping_cb = tf.keras.callbacks.EarlyStopping(patience=10,
restore_best_weights=True)
history = model.fit(
(X_train_wide, X_train_deep), (y_train, y_train), epochs=100,
validation_data=((X_valid_wide, X_valid_deep), (y_valid, y_valid)),
callbacks=[checkpoint_cb, early_stopping_cb])
모델이 향상되지 않으면 훈련이 자동으로 중지되므로 에포크의 숫자를 크게 지정해도 된다. (100 에포크 중 28에서 훈련이 중지되었다)
학습률이 너무 작으면 끝까지 느리게 진행될 수 있다.
조기 종료 콜백은 최적의 모델 가중치를 메모리에 저장하고 훈련이 끝나면 이를 복원한다.
더 많은 제어를 원한다면 사용자 정의 콜백을 만들 수 있다.
아래와 같은 사용자 정의 콜백은 훈련하는 동안 검증 손실과 훈련 손실의 비율을 출력하여 과대적합을 감지한다.
class PrintValTrainRatioCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self, eopch, logs):
ratio = logs['val_loss'] / logs['loss']
print(f'Epoch={epoch}, val/train={ratio:.2f}')
콜백 관련 더 자세한 내용은 하단의 링크 참고
텐서보드로 시각화하기
텐서보드는 매우 좋은 인터랙티브 시각화 도구이다.
훈련하는 동안 학습 곡선을 그리거나 여러 실행 간의 학습 곡선을 비교하고 계산 그래프 시각화와 훈련 통계 분석을 수행할 수 있다. 또한 모델이 생성한 이미지를 확인하거나 3D 에 투영된 복잡한 다차원 데이터를 시각화하고 자동으로 클러스터링하며 네트워크 프로파일 등에 사용할 수 있는 훌륭한 대화형 시각화 도구이다.
텐서보드 홈페이지
텐서보드는 텐서플로를 설치할 때 자동으로 설치된다. 그러나 프로파일링 데이터를 시각화하려면 텐서보드 로그인이 필요하다. 텐서보드를 사용하려면 프로그램을 수정하여 이벤트 파일이라는 특별한 이진 로그 파일에 시각화하려는 데이터를 출력해야 하며, 각각의 이진 데이터 레코드를 'summary' 라고 부른다.
텐서보드 서버는 로그 디렉터리를 모니터링하고 자동으로 변경 사항을 읽어 그래프를 업데이트 한다. 훈련하는 중간에 학습 곡선 같이 실시간 데이터를 시각화할 수 있다.
일반적으로 텐서보드 서버가 루트 로그 디렉터리를 가리키고 프로그램은 실행할 때마다 다른 서브디렉터리에 이벤트를 기록한다. 이렇게 하면 복잡하지 않게 하나의 텐서보드 서버가 여러 번 실행한 프로그램의 결과를 시각화하고 비교할 수 있다.
루트 로그 디렉터리의 이름을 my_logs 로 지정하고, 현재 날짜와 시간을 기준으로 서브디렉터리의 경로를 생성하는 함수를 정의하여 실행할 때마다 다른 경로 생성
from pathlib import Path
from time import strftime
def get_run_logdir(root_logdir='my_logs'):
return Path(root_logdir) / strftime('run_%Y_%m_%d_%H_%M_%S')
run_logdir = get_run_logdir()
케라스는 로그 디렉터리를 생성하고, 훈련 중에 이벤트 파일을 만들어 요약 정보를 기록하는 편리한 TensorBoard() 콜백을 제공한다. 모델의 훈련 및 검증 손실과 측정 지표(MSE, RMSE) 를 계산하고 신경망의 프로파일링도 수행한다.
tensorboard_cb = tf.keras.callbacks.TensorBoard(run_logdir,
profile_batch=(100, 200))
history = model.fit(
(X_train_wide, X_train_deep), (y_train, y_train), epochs=20,
validation_data=((X_valid_wide, X_valid_deep), (y_valid, y_valid)),
callbacks=[tensorboard_cb])
▶ 이 예에서는 첫 번째 에포크 동안 배치 100과 200 사이의 신경망을 프로파일링한다.
학습률 등을 변경하고 코드 등을 재실행 할 때마다 하나의 디렉터리가 생성되고, 그 아래 훈련 로그를 위한 서브디렉터리와 검증 로그를 위한 서브디렉터리가 포함된다. 둘 다 이벤트 파일을 담고 있고, 훈련 로그에는 프로파일링 트레이스 파일도 포함된다.
print("my_logs")
for path in sorted(Path("my_logs").glob("**/*")):
print(" " * (len(path.parts) - 1) + path.parts[-1])
◆ 텐서보드 서버 시작하기
텐서보드 서버는 텐서보드 라이브러리와 함께 설치되는 주피터 확장 프로그램을 사용하여 주피터 또는 코랩 내에서 직접 수행할 수 있다.
%load_ext tensorboard
%tensorboard --logdir=./my_logs
- 첫 번째 줄: 텐서보드용 주피터 확장 프로그램 로드
- 두 번째 줄: my_logs 디렉터리로 텐서보드 서버를 시작하고 주피터에서 이 서버에 연결하여 바로 사용자 인터페이스를 표시
학습 곡선을 보려면 SCALARS 탭을 클릭하고, 왼쪽 하단에서 시각화하려는 로그를 선택하고 원하는 스칼라를 클릭한다.
(GRAPHS 탭: 전체 계산 그래프 시각화 가능)
오른쪽 상단의 새로 고침 버튼을 클릭하면 텐서보드가 데이터를 새로 갱신할 수 있다.
텐서플로에서는 tf.summary 페키지에 저수준의 API를 제공한다.
아래 코드는 create_file_writer() 함수를 사용하여 SummaryWriter를 생성하고, 이를 파이썬 콘텍스트로 사용하여 스칼라, 히스토그램, 이미지, 오디오 및 텍스트를 기록한다. 이런 데이터는 모두 텐서보드를 사용하여 시각화할 수 있다.
test_logdir = get_run_logdir()
writer = tf.summary.create_file_writer(str(test_logdir))
with writer.as_default():
for step in range(1, 1000 +1):
tf.summary.scalar('my_scalar', np.sin(step / 10), step=step)
data = (np.random.randn(100) + 2) * step / 100 # 점점 커짐
tf.summary.histogram('my_hist', data, buckets=50, step=step)
images = np.random.rand(2, 32, 32, 3) * step / 1000 # 점점 밝아짐
tf.summary.image('my_images', images, step=step)
texts = ['The step is ' + str(step), 'Its squar is ' + str(step ** 2)]
tf.summary.text('my_text', texts, step=step)
sine_wave = tf.math.sin(tf.range(12000) / 48000 * 2 * np.pi * step)
audio = tf.reshape(tf.cast(sine_wave, tf.float32), [1, -1, 1])
tf.summary.audio('my_audio', audio, sample_rate=48000, step=step)
코드를 실행하고 텐서보드에서 새로고침 버튼을 누르면 코드에서 생성한 새로운 탭들이 나타난다.
이 주피터 커널(런타임이라고도 함)을 중지하면 텐서보드 서버도 자동으로 중지된다.
다음 내용
[출처]
핸즈 온 머신러닝
텐서플로
'[파이썬 Projects] > <파이썬 딥러닝, 신경망>' 카테고리의 다른 글
[딥러닝] 심층 신경망 훈련 - 1 (0) | 2024.11.23 |
---|---|
[딥러닝] 신경망 하이퍼파라미터 튜닝하기 (1) | 2024.11.21 |
[딥러닝] 케라스로 다층 퍼셉트론 구현하기 - 2 (0) | 2024.11.20 |
[딥러닝] 케라스로 다층 퍼셉트론 구현하기 - 1 (0) | 2024.11.19 |
[딥러닝] 인공 신경망: 퍼셉트론, 다층 퍼셉트론 (1) | 2024.11.19 |