Tensorflow 1.13 Serving搭建心得on Docker(三)把keras或tf model改寫成serving格式
目錄-本系列緩慢更新中
一、Docker的安裝與配置
1、Docker的安裝
2、配置非sudo許可權賬號運行docker
以上內容收錄在:Tensorflow 1.13 Serving搭建心得on Docker(一)Docker的安裝與配置
二、Python2.7+Tensorflow-GPU+Tensor_Serving的docker搭建
1、利用Nvidia-docker,將本地GPU傳入Docker
2、Tensorflow官方鏡像直接利用
3、Bazel和Tensor_Serving配置安裝
以上內容收錄在:Tensorflow 1.13 Serving搭建心得on Docker(二)Python2.7+Tensorflow1.13.0-GPU+Tensor_Serving的docker
三、Tensorflow-Serving自己的網路
1、把模型寫成serving格式
以上內容收錄在:
三、Tensorflow-Serving自己的網路
官方文檔對於這塊只有一個example,缺乏具體的解釋。我在這裡儘可能和大家分享一下我的理解。
Tensorflow的源代碼結構如下,主要分為三個部分
a)model_build: 把現有模型存成serving格式
b)serve:把模型在後台運行起來
c)client:向模型里輸出任務
1、把模型寫成serving格式
def main(_): export_path_base = FLAGS.output_path model_vision = FLAGS.model_vision export_path = os.path.join( tf.compat.as_bytes(export_path_base), tf.compat.as_bytes(str(model_vision))) img_input = Input(shape=(224,224,3)) x = Conv2D(32, kernel_size=(3, 3), activation=relu, name=conv2d_1)(img_input) x = MaxPooling2D(pool_size=(2, 2), name=max_pool_1)(x) x = Conv2D(32, kernel_size=(3, 3), activation=relu, name=conv2d_2)(x) x = MaxPooling2D(pool_size=(2, 2), name=max_pool_2)(x) x = Conv2D(64, kernel_size=(3, 3), activation=relu, name=conv2d_3)(x) x = MaxPooling2D(pool_size=(2, 2), name=max_pool_3)(x) # Classification block x = Flatten(name=Flatten)(x) x = Dense(64, activation=relu, name=fc_1)(x) # x = Dropout(0.5)(x) output = Dense(2, activation=sigmoid, name=pred)(x) model = Model(img_input, output, name=ifeye_model) model.load_weights(FLAGS.weights_file) model.summary() if (model.uses_learning_phase): raise ValueError(Model using learning phase.) config = model.get_config() weights = model.get_weights() new_model = Model.from_config(config) new_model.set_weights(weights) signature = predict_signature_def(inputs={images_name: new_model.input}, outputs={outputs_name: new_model.output}) builder = tf.saved_model.builder.SavedModelBuilder(export_path) with K.get_session() as sess: builder.add_meta_graph_and_variables( sess,[tf.saved_model.tag_constants.SERVING], signature_def_map={predict: signature}) builder.save(True) print(Finished export, export_path)
上面是我自己寫的一個,最簡單的model_build程序。幾個要點:
a)model.uses_learning_phase需要設置為0,表明這個model不再進行訓練
b)這個模型訓練的時候用的是keras,所以用以下四行,把模型變成tensorflow形式
config = model.get_config() weights = model.get_weights() new_model = Model.from_config(config) new_model.set_weights(weights)
c)predict_signature_def,用於定義輸入和輸出的『名稱』,這樣client往裡輸入的時候,變數名能夠對應的上。其中「images_name」是我的輸入,「outputs_name」是我的輸出,
d)用tf.saved_model.builder.SavedModelBuilder(export_path)創建一個輸出器,這個輸出器會自動管理版本(多次輸出的時候,可以用版本號控制,存成export_path/1,export_path/2等多個版本文件夾)
e)signature_def_map={predict: signature}用於控制讓model做什麼,不同的命令可以對應不同的signature組合。比如「predict1」可以預測等級,「predict2」可以輸出概率,兩個的signature不一樣
下面一段代碼的signature更複雜一些,但是其實核心是一樣的:
serialized_tf_example = tf.placeholder( tf.string, name=input_image) feature_configs = { image / encoded: tf.FixedLenFeature( shape=[], dtype=tf.string),} tf_example = tf.parse_example(serialized_tf_example, feature_configs) jpegs = tf_example[image / encoded] images = tf.map_fn(preprocess_image, jpegs, dtype=tf.float32) with slim.arg_scope(inception_v3_arg_scope()): logits, end_points = inception_v3(images, num_classes=20, is_training=False) values, indices = tf.nn.top_k(logits, 1) class_probs = tf.nn.softmax(logits[:5]) class_descriptions = [A級,B級,C級,D級,E級] for s in range(15): class_descriptions.append(unused background) class_tensor = tf.constant(class_descriptions) table = tf.contrib.lookup.index_to_string_table_from_tensor(class_tensor) classes = table.lookup(tf.to_int64(indices)) # Restore variables from training checkpoint. saver = tf.train.Saver() with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess: saver.restore(sess, FLAGS.weights_file) print("Inception_V3 Model Restored") export_path = os.path.join( tf.compat.as_bytes(export_path_base), tf.compat.as_bytes(str(model_vision))) print(Exporting trained model to, export_path) builder = tf.saved_model.builder.SavedModelBuilder(export_path) # Build the signature_def_map. classify_inputs_tensor_info = tf.saved_model.utils.build_tensor_info( serialized_tf_example) probs_output_tensor_info = tf.saved_model.utils.build_tensor_info(class_probs) classes_output_tensor_info = tf.saved_model.utils.build_tensor_info( classes) scores_output_tensor_info = tf.saved_model.utils.build_tensor_info(values) classification_signature = ( tf.saved_model.signature_def_utils.build_signature_def( inputs={ tf.saved_model.signature_constants.CLASSIFY_INPUTS: classify_inputs_tensor_info }, outputs={ tf.saved_model.signature_constants.CLASSIFY_OUTPUT_CLASSES: classes_output_tensor_info, tf.saved_model.signature_constants.CLASSIFY_OUTPUT_SCORES: scores_output_tensor_info }, method_name=tf.saved_model.signature_constants. CLASSIFY_METHOD_NAME)) predict_inputs_tensor_info = tf.saved_model.utils.build_tensor_info(jpegs) prediction_signature = ( tf.saved_model.signature_def_utils.build_signature_def( inputs={images: predict_inputs_tensor_info}, outputs={ probs: probs_output_tensor_info, classes: classes_output_tensor_info, scores: scores_output_tensor_info }, method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME )) legacy_init_op = tf.group(tf.tables_initializer(), name=legacy_init_op) builder.add_meta_graph_and_variables( sess, [tf.saved_model.tag_constants.SERVING], signature_def_map={ predict_images: prediction_signature, tf.saved_model.signature_constants. DEFAULT_SERVING_SIGNATURE_DEF_KEY: classification_signature, }, legacy_init_op=legacy_init_op) builder.save() print(Done exporting!)def preprocess_image(image_buffer): """Preprocess JPEG encoded bytes to 3D float Tensor.""" image = tf.image.decode_png(image_buffer, channels=3) image = tf.image.convert_image_dtype(image, dtype=tf.float32) image = np.multiply(image, 1.0 / 255.0) image = tf.image.resize_images(image, [FLAGS.image_size, FLAGS.image_size], method=0) return image
這裡的新要點如下:
a)輸出變成了3個:probs, classes, scores
b)輸入進來的圖片格式是tfrecord格式;如果想在serving過程中進行圖片預處理,需要使用處理tf格式圖片的方法進行處理,保證輸入輸出都是張量
c)classification_signature其實可以沒有(見第一段),目前還沒看出用處,大神可以來解答一下
以上就是如何把model輸出成tensor-serving格式的改寫方法,如果有任何疑問,歡迎隨時留言!
推薦閱讀:
TAG:TensorFlow | 深度學習DeepLearning |