首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Tensorflow 2中使用保存模型的推理:如何在/输出中控制?

Tensorflow 2中使用保存模型的推理:如何在/输出中控制?
EN

Stack Overflow用户
提问于 2022-01-11 01:04:50
回答 1查看 1.5K关注 0票数 11

将我的代码从TF1调整到TF2.6,我遇到了麻烦。我试图添加一些自定义层到一个初始resnet,保存模型,然后加载和运行它。

代码语言:javascript
运行
复制
from tensorflow.keras.layers import Dense                                                                                                                       
from tensorflow.keras.models import Model                                                                                                                       
from tensorflow.keras.applications.inception_resnet_v2 import InceptionResNetV2                                                                                 
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D                                                                                               
import tensorflow as tf                                                                                                                                         
import numpy as np                                                                                                                                              
from PIL import Image                                                                                                                                           
                                                                                                                                                                
export_path = "./save_test"                                                                                                                                     
                                                                                                                                                                
# Get model without top and add two layers                                                                                                                      
base_model = InceptionResNetV2(weights='imagenet', input_tensor=None, include_top=False)                                                                        
out = base_model.output                                                                                                                                         
out = GlobalAveragePooling2D()(out)                                                                                                                             
predictions = Dense(7, activation='softmax', name="output")(out)                                                                                                
                                                                                                                                                                
# Make new model using inputs from base model and custom outputs                                                                                                
model = Model(inputs=base_model.input, outputs=[predictions])                                                                                                   
                                                                                                                                                                
# save model                                                                                                                                                    
tf.saved_model.save(model, export_path)                                                                                                                         
                                                                                                                                                                
# load model and run                                                                                                                                            
with tf.compat.v1.Session(graph=tf.Graph()) as sess:                                                                                                            
    tf.compat.v1.saved_model.loader.load(sess, ['serve'], export_path)                                                                                          
    graph = tf.compat.v1.get_default_graph()                                                                                                                    
                                                                                                                                                                
    img = Image.new('RGB', (299, 299))                                                                                                                          
    x = tf.keras.preprocessing.image.img_to_array(img)                                                                                                          
    x = np.expand_dims(x, axis=0)                                                                                                                               
    x = x[..., :3]                                                                                                                                              
    x /= 255.0                                                                                                                                                  
    x = (x - 0.5) * 2.0                                                                                                                                         
                                                                                                                                                                
    y_pred = sess.run('output/Softmax:0', feed_dict={'serving_default_input_1:0': x})                                                                           

错误:KeyError: "The name 'output/Softmax:0' refers to a Tensor which does not exist. The operation, 'output/Softmax', does not exist in the graph."

我不明白的是:predictions.name'output/Softmax:0',但是graph.get_tensor_by_name('output/Softmax:0')告诉我它不存在!

注意:我知道我可以用TF2的tf.keras.models.savetf.keras.models.load_model保存和加载模型,然后用model(x)运行模型。但是,在我的应用程序中,我在内存中有多个模型,并且我发现推理所用的时间比使用TF1对象的session代码要长得多。因此,我希望在兼容模式下对TF1对象使用session方法。

如何在保存时控制输入/输出的名称?我遗漏了什么?

EN

回答 1

Stack Overflow用户

发布于 2022-01-14 17:49:20

在TF2.0、2.6和2.7上测试

如果您还没有这样做,您可以尝试如下所示,因为我认为您在SignatureDef中引用了错误的键

代码语言:javascript
运行
复制
from tensorflow.keras.layers import Dense                                                                                                                       
from tensorflow.keras.models import Model                                                                                                                       
from tensorflow.keras.applications.inception_resnet_v2 import InceptionResNetV2                                                                                 
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D                                                                                               
import tensorflow as tf                                                                                                                                         
import numpy as np                                                                                                                                              
from PIL import Image                                                                                                                                           
                                                                                                                                                                
export_path = "./save_test"                                                                                                                                     
                                                                                                                                                                
base_model = InceptionResNetV2(weights='imagenet', input_tensor=None, include_top=False)                                                                        
out = base_model.output                                                                                                                                         
out = GlobalAveragePooling2D()(out)                                                                                                                             
predictions = Dense(7, activation='softmax', name="output")(out)                                                                                                
model = Model(inputs=base_model.input, outputs=[predictions])                                                                                                   
                                                                                                                                                              
tf.saved_model.save(model, export_path)

with tf.compat.v1.Session(graph=tf.Graph()) as sess:                                                                                                            
    meta_graph = tf.compat.v1.saved_model.loader.load(sess, ["serve"], export_path)
    sig_def = meta_graph.signature_def[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
    input_key = list(dict(sig_def.inputs).keys())[0]
    input_name = sig_def.inputs[input_key].name
    output_name = sig_def.outputs['output'].name
    img = Image.new('RGB', (299, 299))                                                                                                                          
    x = tf.keras.preprocessing.image.img_to_array(img)                                                                                                          
    x = np.expand_dims(x, axis=0)                                                                                                                               
    x = x[..., :3]                                                                                                                                              
    x /= 255.0                                                                                                                                                  
    x = (x - 0.5) * 2.0   
    y_pred = sess.run(output_name, feed_dict={input_name: x})        
    print(y_pred)  
代码语言:javascript
运行
复制
INFO:tensorflow:Restoring parameters from ./save_test/variables/variables
[[0.14001141 0.13356228 0.14509581 0.22432518 0.16313255 0.11899492
  0.07487784]]

您还可以查看输入和输出信息的SignatureDef

代码语言:javascript
运行
复制
print(meta_graph.signature_def)
{'serving_default': inputs {
  key: "input_2"
  value {
    name: "serving_default_input_2:0"
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: -1
      }
      dim {
        size: -1
      }
      dim {
        size: -1
      }
      dim {
        size: 3
      }
    }
  }
}
outputs {
  key: "output"
  value {
    name: "StatefulPartitionedCall:0"
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: -1
      }
      dim {
        size: 7
      }
    }
  }
}
method_name: "tensorflow/serving/predict"
, '__saved_model_init_op': outputs {
  key: "__saved_model_init_op"
  value {
    name: "NoOp"
    tensor_shape {
      unknown_rank: true
    }
  }
}
}

如果删除base_model的第一层并添加新的Input层,则可以使用静态键名sig_def.inputs['input'].namesig_def.outputs['output'].name

代码语言:javascript
运行
复制
from tensorflow.keras.layers import Dense                                                                                                                       
from tensorflow.keras.models import Model                                                                                                                       
from tensorflow.keras.applications.inception_resnet_v2 import InceptionResNetV2                                                                                 
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D                                                                                               
import tensorflow as tf                                                                                                                                         
import numpy as np                                                                                                                                              
from PIL import Image                                                                                                                                           
                                                                                                                                                                
export_path = "./save_test"                                                                                                                                     
                                                                                                                                                                
base_model = InceptionResNetV2(weights='imagenet', input_tensor=None, include_top=False)
base_model.layers.pop(0)
new_input = tf.keras.layers.Input(shape=(299,299,3), name='input')
out = base_model(new_input)                                                                                                                                        
out = GlobalAveragePooling2D()(out)                                                                                                                             
predictions = Dense(7, activation='softmax', name="output")(out) 

model = Model(inputs=new_input, outputs=[predictions])                                                                                                   
tf.saved_model.save(model, export_path)

with tf.compat.v1.Session(graph=tf.Graph()) as sess:                                                                                                            
    meta_graph = tf.compat.v1.saved_model.loader.load(sess, ["serve"], export_path)
    sig_def = meta_graph.signature_def[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
    input_name = sig_def.inputs['input'].name
    output_name = sig_def.outputs['output'].name
    img = Image.new('RGB', (299, 299))                                                                                                                          
    x = tf.keras.preprocessing.image.img_to_array(img)                                                                                                          
    x = np.expand_dims(x, axis=0)                                                                                                                               
    x = x[..., :3]                                                                                                                                              
    x /= 255.0                                                                                                                                                  
    x = (x - 0.5) * 2.0   
    y_pred = sess.run(output_name, feed_dict={input_name: x})        
    print(y_pred)   
代码语言:javascript
运行
复制
INFO:tensorflow:Restoring parameters from ./save_test/variables/variables
[[0.21079363 0.10773096 0.07287834 0.06983061 0.10538215 0.09172108
  0.34166315]]

注意,更改base_model第一层的名称不适用于语法model.layers[0]._name = 'input',因为模型配置本身不会被更新。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70660544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档