You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于TF-slim训练的模型Python推理正常,C++推理结果异常

Hey there! Let's break down what's going on and fix this step by step—since you're new to lower-level TensorFlow stuff, I'll keep things straightforward and avoid jargon where possible.

The Core Problem

When you trained with TF-slim, it likely used a queue-based input pipeline (like tf.train.string_input_producer or TF Dataset queues) to load training data efficiently. When you froze the model directly, those queue-related nodes were kept in the graph. But tools like label_image feed image data directly as tensors, not through queues—so the model couldn't get valid input, leading to it spitting out the same default prediction every time. Manually swapping input layers caused resource mismatches because the queue nodes were still tangled up in the graph.

Step 1: Re-Export the Model with a Direct Tensor Input

We need to create a new graph that replaces the queue pipeline with a simple placeholder tensor for input, then load your trained weights into this graph and freeze it. Here's a complete, copy-paste-able script (adjust paths and parameters to match your setup):

import tensorflow as tf
from nets import mobilenet_v1  # Import your MobileNet_v1 definition (match your training code)

# 1. Define a direct input tensor (no queues!)
INPUT_HEIGHT = 224  # Replace with your training image height
INPUT_WIDTH = 224   # Replace with your training image width
input_tensor = tf.placeholder(
    tf.uint8, 
    shape=[None, INPUT_HEIGHT, INPUT_WIDTH, 3], 
    name='input_image'  # This name will be our input layer for deployment
)

# 2. Replicate your training preprocessing EXACTLY
# This is critical! If your training code used mean subtraction, scaling, etc., copy it here.
# Example (adjust to match your training preprocessing):
processed_input = tf.cast(input_tensor, tf.float32)
processed_input = tf.image.per_image_standardization(processed_input)
# Alternative example if you used simple scaling:
# processed_input = processed_input / 255.0
# processed_input = processed_input - tf.constant([0.485, 0.456, 0.406])  # ImageNet mean, adjust if you used custom means

# 3. Build the MobileNet model in inference mode
with tf.contrib.slim.arg_scope(mobilenet_v1.mobilenet_v1_arg_scope()):
    logits, _ = mobilenet_v1.mobilenet_v1(
        processed_input,
        num_classes=2,  # Your number of classes
        is_training=False  # Disable training-only layers like dropout/BN updates
    )

# 4. Add usable output nodes (name them for easy access later)
predictions = tf.argmax(logits, axis=1, name='predictions')
probabilities = tf.nn.softmax(logits, name='probabilities')

# 5. Load your trained weights and freeze the graph
saver = tf.train.Saver()
with tf.Session() as sess:
    # Restore weights from your training checkpoint
    saver.restore(sess, '/path/to/your/trained/model.ckpt')  # Replace with your .ckpt path
    
    # Freeze the graph (convert variables to constants)
    frozen_graph_def = tf.graph_util.convert_variables_to_constants(
        sess,
        sess.graph_def,
        ['predictions', 'probabilities']  # Keep these output nodes
    )
    
    # Save the frozen model
    with open('/path/to/save/frozen_mobilenet.pb', 'wb') as f:
        f.write(frozen_graph_def.SerializeToString())

Step 2: Verify the New Model's Input/Output

Use summarize_graph to confirm the queue nodes are gone and our new input is present:

summarize_graph --in_graph=/path/to/save/frozen_mobilenet.pb

You should see input_image as the input layer, and predictions/probabilities as outputs—no queue-related nodes like input_producer or queue_runner.

Step 3: Test with label_image

Call label_image with the correct parameters matching your new model:

label_image \
  --graph=/path/to/save/frozen_mobilenet.pb \
  --input_layer=input_image \
  --input_height=224 \
  --input_width=224 \
  --output_layer=probabilities \
  --image=/path/to/your/test/image.jpg
  • Double-check input_height/input_width match your training dimensions
  • If you adjusted preprocessing in the export script, make sure label_image doesn't apply conflicting preprocessing (or better yet, include all preprocessing in the export script so label_image just feeds raw pixels)

Key Takeaways for Future Deployments

  • Training pipelines (queues/Datasets) are great for efficiency but don't play nice with deployment tools that feed direct tensors
  • Always replicate training preprocessing exactly when exporting for deployment—mismatched data distribution is a top cause of weird model outputs
  • For TF-slim models, building a fresh inference graph with placeholders is simpler than trying to patch the training graph

内容的提问来源于stack exchange,提问作者szm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:23:00