본문 바로가기
인공지능 개발하기/Machine Learning

[Tensorflow] 23. 모델(Model) 구조와 가중치(Weights) 저장하기, 불러오기

by 선의공 2024. 1. 20.
반응형

 

 

이번 포스팅에서는

모델의 구조와 가중치를 저장하고 불러오는 방식에 대해서

학습해보겠습니다.

 

 

 


 

1.  model.save(), load_model()

모델의 구조와 가중치 모두 저장

 

 

keras의 model 모듈의 save() 함수를 사용하면 쉽게

모델의 구조와 가중치를 저장할 수 있습니다.

https://keras.io/api/models/model_saving_apis/model_saving_and_loading/#save-method

 

Keras documentation: Whole model saving & loading

Whole model saving & loading [source] save method Model.save(filepath, overwrite=True, **kwargs) Saves a model as a .keras file. Arguments filepath: str or pathlib.Path object. Path where to save the model. Must end in .keras. overwrite: Whether we should

keras.io

 

 

사용방법은 간단합니다.

모델을 구성하고 나서

model.save(경로)

를 적어주면 해당 경로에 h5 파일이 저장됩니다.

 

단, fit() 전에 저장된건 모델의 구조만 들어있고

가중치가 없는 h5파일이 생성됩니다.

#save model only
model = Sequential()
model.add(Dense(64, input_dim=30)) 
model.add(Dense(32))
model.add(Dense(16))
model.add(Dense(8))
model.add(Dense(4))
model.add(Dense(2))
model.add(Dense(1, activation="sigmoid")) 

model.save("../_data/_save/save_test/model01.h5")

 

 

fit() 후에 저장을 해야 모델과 가중치가

모두 들어간 파일이 저장됩니다.

#save model with weights
model = Sequential()
model.add(Dense(64, input_dim=30)) 
model.add(Dense(32))
model.add(Dense(16))
model.add(Dense(8))
model.add(Dense(4))
model.add(Dense(2))
model.add(Dense(1, activation="sigmoid")) 

model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["acc"])
history = model.fit(x_train, y_train, epochs=76, batch_size=1000, validation_split=0.3)

model.save("../_data/_save/save_test/model_with_weight01.h5")

 

저장한 모델을 불러올때는

keras의  models 모듈의 

load_model() 함수를 사용합니다.

 

마찬가지로 모델의 구조만 저장된 파일을 가져온다면

불러온 이후 fit() 훈련을 진행해야 가중치가 생성됩니다.

from keras.models import load_model

# load model only
model = load_model("../_data/_save/save_test/model01.h5")


# 컴파일 , 훈련
model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["acc"])
history = model.fit(x_train, y_train, epochs=76, batch_size=1, validation_split=0.3)

# 평가 예측
loss = model.evaluate(x_test, y_test)
y_predict = np.round(model.predict(x_test))

acc = accuracy_score(y_test, y_predict)
print("loss : ", loss[0])
print("acc :",loss[1])

 

 

모델의 구조와 가중치를 모두 저장한

파일을 불러오면 훈련 없이

모델로 예측을 뽑아낼 수 있습니다.

from keras.models import load_model

#load model with weights
model = load_model("../_data/_save/save_test/model_with_weight01.h5")

# 컴파일 , 훈련
# model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["acc"])
# history = model.fit(x_train, y_train, epochs=76, batch_size=1, validation_split=0.3)

# 평가 예측
loss = model.evaluate(x_test, y_test)
y_predict = np.round(model.predict(x_test))

acc = accuracy_score(y_test, y_predict)
print("loss : ", loss[0])
print("acc :",loss[1])

 

 

 


 

 

2. model.to_json(), model_from_json,

// save_weights(), load_weights()

 

 

model.to_json()을 사용하면

모델의 구조를 json파일 형태로 저장이 가능합니다.

(유사한 형태로 yaml파일 형태로 저장하는

model.to_yaml() 함수도 있습니다.)

 

save_weights() 함수를 이용해 가중치만

저장하는 것도 가능합니다.

# 모델 구성
model = Sequential()
model.add(Dense(64, input_dim=30)) 
model.add(Dense(32))
model.add(Dense(16))
model.add(Dense(8))
model.add(Dense(4))
model.add(Dense(2))
model.add(Dense(1, activation="sigmoid")) 

# save model to json
json_string = model.to_json()
with open('../_data/_save/save_test/json_model.json', 'w') as f:
    f.write(json_string)
    
#save weights
model.save_weights("../_data/_save/save_test/weight_test01.h5")

 

json viewer로 확인해보니

모델과 레이어 정보가 들어가 있습니다.

 

 

json 파일을 불러올 수도 있습니다.

models모듈의 model_from_json() 함수를 이용해서

json 구조로 저장된 모델을 불러오겠습니다.

(마찬가지로 yaml 로 저장했다면

model_from_yaml()로 불러올 수 있습니다 )

 

저장된 가중치 파일은

model.load_weights() 함수로

가져올 수 있습니다.

from keras.models import model_from_json
# load model to json
with open('../_data/_save/save_test/json_model.json', 'r') as f:
    model = model_from_json(f.read())
    
#load weights
model.load_weights("../_data/_save/save_test/weight_test01.h5")

# 평가 예측
loss = model.evaluate(x_test, y_test)
y_predict = np.round(model.predict(x_test))

acc = accuracy_score(y_test, y_predict)
print("loss : ", loss[0])
print("acc :",loss[1])

 

 

 

 


 

3. ModelCheckPoint() 콜백 함수

 

3번째 방법으로는

keras의 callbacks 함수에 있는

ModelCheckPoint()함수를 사용하는 것입니다.

 

https://keras.io/api/callbacks/model_checkpoint/

 

Keras documentation: ModelCheckpoint

ModelCheckpoint [source] ModelCheckpoint class keras.callbacks.ModelCheckpoint( filepath, monitor="val_loss", verbose=0, save_best_only=False, save_weights_only=False, mode="auto", save_freq="epoch", initial_value_threshold=None, ) Callback to save the Ker

keras.io

 

이 방식은 앞선 방식과 다르게 

 model.fit() 함수의  callbacks 로서 

1에포크마다 저장이됩니다.

 

파라미터를 살펴보겠습니다.

 

filepath : 저장할 파일 경로를 지정한다고 합니다.

충돌을 피하기 위해 각 경로는 에포크마다 달라야한다고 하네요. 

"{epoch:02d}-{val_loss:.2f}.hdf5"로 사용하면 epock, val_loss의 값이 

디렉토리명에 들어가나 봅니다.

monitor : 모니터링 대상입니다.

verbose: 정보 표시 모드입니다. 0은 silence모드,  1은 정보 표시 모드인듯합니다.

save_best_only: 모델이 최고라고 간주될떄만 저장이 된다고 합니다.

mode : 모니터 대상의 감지 모드입니다. min, max, auto 가 있습니다. 

 save_weights_only : True인 경우 가중치만 저장된다고 하네요.

save_freq : "epoch" 아니면 정수형을 써줄 수 있습니다. 정해준 사이즈의

에포크 마다 저장되는 듯 합니다.

initial_value_threshold : save_best_only = True인 경우만 적용된다고 합니다.

이 값에 설정된 것 보다 monitor 대상이 좋아야 파일이 저장되는 것 같네여.?

 

 

한번 사용해보겠습니다!

 

저는 파일명은 에포크, 로스값을 유동적으로 줘서 도큐먼트에서 권장하는

덮어쓰기를 피했습니다.

감지 대상은 val_loss입니다.

val_loss가 낮아야 좋기 때문에 mode는 min이구요

save_best_only를 줘서 val_loss 가 갱신될때만 저장되게 설정했습니다.

initial_value_threshold를 0.083로 줘서

val_loss가 0.083보다 내려간 경우만 파일 저장을 하게 했습니다.

생성한 ModelCheckpoint 콜백은

fit()함수의 callbacks에 넣어주었습니다.

from keras.callbacks import ModelCheckpoint

#ModelCheckpoint save
mch = ModelCheckpoint(
    filepath="../_data/_save/save_test/mcp/mcp_test_{epoch:02d}-{val_loss:2f}.h5",
    monitor="val_loss",
    mode="min",
    save_best_only=True,
    initial_value_threshold=0.083 #저장의 기준 수치
)


model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["acc"])
history = model.fit(
    x_train, y_train, epochs=76, batch_size=1000, validation_split=0.3, callbacks=[mch]
)

 

 val_loss가 0.083이하 일때

값이 갱신될때마다

저장이 되었네요.

그리고 모델을 불러오는 것은

 앞에서 학습했던

load_model()함수를 사용하면 됩니다.

 

#ModelCheckpoint load
model = load_model('../_data/_save/save_test/mcp/mcp_test_76-0.079240.h5')

# 평가 예측
loss = model.evaluate(x_test, y_test)
y_predict = np.round(model.predict(x_test))

acc = accuracy_score(y_test, y_predict)
print("loss : ", loss[0])
print("acc :",loss[1])

 

 


 

이상으로 모델의 구조와 가중치를

저장하는 방식을 학습해봤습니다.

 

코드와 모델의 구조도 중요하겠지만

모델의 가중치를 뺴내는게 결국 목표이니

좋은 가중치를 잘 저장해서 관리해야겠습니다!

 

틀린부분이 있으면 지적 부탁드립니다!

 

반응형