일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- hadoop
- session 유지
- login crawling
- flask
- UDF
- Airflow
- tensorflow text
- XAI
- airflow subdag
- top_k
- gather_nd
- integrated gradient
- 상관관계
- 공분산
- GenericGBQException
- spark udf
- API
- subdag
- youtube data
- GCP
- Retry
- API Gateway
- 유튜브 API
- grad-cam
- BigQuery
- correlation
- requests
- chatGPT
- TensorFlow
- Counterfactual Explanations
- Today
- Total
데이터과학 삼학년
[TF.2.x] Keras 모델의 predict output을 사용자가 커스텀하는 방법 본문
TF.2.x Keras 모델의 predict output을 사용자가 커스텀하는 방법
1. 배경 및 필요성
-
tf.2.X tf.keras를 이용하여 예측시 예측결과를 커스텀하는 것의 어려움이 있었음
-
예측결과에 tf.estimator의 경우, estimatorspec의 predictoutput을 이용해 info_column 을 커스텀 할 수 있음
-
tf.keras에서도 predict output을 커스텀하게 만들 방법 모색 필요
2. 방법론
-
tf.keras.Model 의 다중 input, 다중 output을 받는 방식으로, info_column을 output까지 그대로 가져오는 방법
-
-
tf.keras.Model 을 상속받아 custom Keras model을 만들어 predict 메서드를 overriding하여 모델을 저장하는 방법
-
학습된 keras model을 저장하고, 저장된 모델을 다시 불러와 signature의 serving_default 함수를 custom하여 재저장하는 방법
3. 실험 분석
-
1번의 경우, input으로 받은 string 데이터를 Lambda를 이용해 그대로 output까지 가져왔지만, output을 표출하는 부분에서 에러가 발생
-
무엇보다 모델의 학습과정을 그대로 계속 타고 내려와야한다는 단점이 있었음
- info_column을 tf.string 으로 싸서 가지고 내려오면 성공했을 것 같음
-
2번의 경우, predict 함수를 오버라이딩해 원하는 info_column을 결과에 실었지만 해당 모델을 저장한 후 다시 실행하면 동작하지 않음
-
원인 : 모델 저장시 메서드가 함께 저장되는 것이 아니라 graph와 weight가 저장된 것을 다시 불러와 원래 정의된 serving 함수를 실행시킴
-
수정 : 원인을 해결하려 메서드를 tf.function으로 싸서 모델을 저장하려 했지만, predict 메서드를 오버라이딩한 함수를 tf.function 데커레이터를 싸려는 과정에서 에러 발생
-
3번의 경우, keras 모델을 저장해야 signature로 serving이 생겨, 해당 serving signature를 다시 변경할 수 있었음. 또한 serving_default 함수를 저장하기 위해 tf.function을 데커레이터로 싸서 저장함. 매우 잘 동작함.
info_column을 tf.string으로 싸서 그대로 가져왔으면 성공했을 것 같음
info_column을 tf.string으로 싸서 그대로 가져왔으면 성공했을 것 같음
4. 결과
-
keras model 학습후 해당 모델을 저장한 후 다시 로드한 loaded model의 serving 함수를 custom하는 방법을 써서 ai-platform까지 잘 동작하도록 할 수 있었음
-
ai-platform에서 predict 를 실행시 파라미터로 signature-name을 custom함수로 지정한 serving_default 를 입력해줘야함
5. 기타
방법론 1번 샘플 코드
import tensorflow as tf
input_data = Input(shape=(30,), name="input_data", dtype=tf.int32)
embed = Embedding(40 + 1, 32, input_length=30, mask_zero=True, dtype=tf.float32,name='Embedding')(input_data)
conv1d = Conv1D(filters=3, kernel_size=2, strides=2, activation='relu')(embed)
flat = Flatten()(conv1d)
output = Dense(2, activation=tf.nn.softmax, name="output")(flat)
info_col = Input(shape=(2,), name="info_column", dtype=tf.string)
output1 = Lambda(lambda x:x,name='output1')(info_col)
model = Model(inputs=[input_data,info_col], outputs=[output,output1])
tf.keras.utils.plot_model(model, show_shapes=True, dpi=90)
방법론 2번 샘플 코드
class MyKerasRNN(tf.keras.Model):
def __init__(self, info_cols, vocab_size, embed_dim, max_len, units, n_classes):
super().__init__()
self.info_cols = info_cols
self.embed = Embedding(vocab_size + 1, embed_dim, input_shape=[max_len])
self.gru = SimpleRNN(units)
self.output_class = Dense(n_classes, activation='softmax')
print('if you have any problems or issue, ask bdh for solution')
@tf.function
def call(self, inputs, training=False):
embed = self.embed(inputs)
gru = self.gru(embed)
return self.output_class(gru)
# method overiding
@tf.function
def predict(self, x, batch_size=None, verbose=0, steps=None, callbacks=None, max_queue_size=10, workers=1,use_multiprocessing=False):
print('predict method of keras overiding')
infos, pred_data = preprocess_for_predict_info(x, self.info_cols)
outputs = super().predict(pred_data, batch_size, verbose, steps, callbacks, max_queue_size, workers,use_multiprocessing)
result = get_result_with_info(infos, outputs)
return result
방법론 3번 샘플 코드
MODEL_EXPORT_PATH = os.path.join(args.job_dir, 'keras_export')
print(f'Model exported to: {MODEL_EXPORT_PATH}')
tf.saved_model.save(keras_model, MODEL_EXPORT_PATH)
time.sleep(120)
loaded_model_bdh = tf.keras.models.load_model(MODEL_EXPORT_PATH)
print('completed load saved model')
input_signature = [tf.TensorSpec([None], dtype=tf.string, name=str(i)) for i in args.info_columns]
input_signature.append(tf.TensorSpec([None, MAX_LEN], dtype=tf.int32))
## serving으로 쓸 인자는 정해져 있어야 함
@tf.function(input_signature=input_signature)
def keyed_prediction(pid, logkey, data):
pred = loaded_model_bdh(data, training=False)
return {
'output': pred,
'pid': pid,
'logkey':logkey
}
KEYED_EXPORT_PATH = os.path.join(args.job_dir, 'keras_export', 'keyed_model')
loaded_model_bdh.save(KEYED_EXPORT_PATH, signatures={'serving_default': keyed_prediction})
print(f'Model with keys exported to: {KEYED_EXPORT_PATH}')`
[GCP ai-platform prediction]
gcloud ai-platform jobs submit prediction predict_text_model_pactice_20200709_b \
--model-dir gs://model/custom_keras_model_20200709_b/keras_export/keyed_model \
--runtime-version 2.1 \
--data-format text \
--region us-central1 \
--input-paths gs://preprocess/predict/sequence_predict.json \
--output-path gs://predict/20200709_b/output \
--signature-name serving_default
'Machine Learning' 카테고리의 다른 글
[TF 2.2] tf.keras.layers.experimental.preprocessing.TextVectorization 한계와 해결 방법 (0) | 2020.07.17 |
---|---|
Keras API 간단 정리 (From. Google Developers ) (0) | 2020.07.16 |
[TF 2.x] tf.keras prediction 결과 custom하기(feat. GCP ai-platform) (0) | 2020.07.08 |
Text classification using GCP ai-platform (0) | 2020.06.26 |
tf.keras.callbacks.LearningRateScheduler (1) | 2020.06.24 |