TensorFlow技术求助:恢复模型并传入单图执行引导反向传播
Let's walk through fixing your code to restore the checkpoint, process a single image, and run guided backpropagation properly. Here's a complete, corrected implementation tailored to your use case:
Step 1: Fix Checkpoint Restoration
Your current code creates a new placeholder alongside the imported meta graph, which can cause disconnects between the input and the saved network. Instead, import the meta graph first, then retrieve the existing input/output tensors directly from the graph. Don't forget to restore the actual checkpoint weights:
import tensorflow as tf import numpy as np import PIL.Image import matplotlib.pyplot as plt import cv2 # Initialize graph and session graph = tf.Graph() with graph.as_default(): sess = tf.Session(graph=graph) # Import the meta graph and restore trained weights saver = tf.train.import_meta_graph('flat-3000.meta') # Use latest checkpoint in the directory (removes need to hardcode the checkpoint number) saver.restore(sess, tf.train.latest_checkpoint('./')) # Retrieve input placeholder and output tensor from the saved graph # Replace these names with your actual tensor names (check your network code for exact names) images = graph.get_tensor_by_name('images:0') # Example placeholder name logits = graph.get_tensor_by_name('logits:0') # Example output tensor name
Step 2: Preprocess Single Input Image
Your placeholder shape (None, 1, 418400, 3) suggests each input is a flattened 3-channel image (418400 elements per channel). Let's load and preprocess an image to match this shape:
def preprocess_image(image_path): # Load image with PIL img = PIL.Image.open(image_path).convert('RGB') # Resize to the original dimensions that flatten to 418400 (adjust based on your network's input size) # Example: If your network expects a 646x646 image (646*646=417316, adjust to match 418400 exactly) target_size = (int(np.sqrt(418400)), int(np.sqrt(418400))) img = img.resize(target_size) # Convert to numpy array and apply training-time normalization img_array = np.array(img).astype(np.float32) / 255.0 # Adjust scaling if you used mean subtraction etc. # Reshape to match placeholder shape: (1, 1, 418400, 3) flattened_img = img_array.reshape(1, 1, -1, 3) return flattened_img, img_array # Load and preprocess your single image processed_img, original_img = preprocess_image('your_image.jpg')
Step 3: Implement Guided Backpropagation
Guided backprop modifies ReLU gradients to only pass positive gradients from both the input and output sides. We'll register a custom gradient for ReLU and reimport the graph with this override:
# Define the guided ReLU gradient function @tf.RegisterGradient("GuidedRelu") def guided_relu_grad(op, grad): # Only keep gradients where both the input and output are positive return grad * tf.cast(grad > 0, tf.float32) * tf.cast(op.outputs[0] > 0, tf.float32) # Create a dedicated graph for guided backprop guided_graph = tf.Graph() with guided_graph.as_default(): with tf.Session(graph=guided_graph) as sess_guided: # Override ReLU gradients during graph import with tf.get_default_graph().gradient_override_map({"Relu": "GuidedRelu"}): saver_guided = tf.train.import_meta_graph('flat-3000.meta') saver_guided.restore(sess_guided, tf.train.latest_checkpoint('./')) # Retrieve tensors for the guided graph images_guided = guided_graph.get_tensor_by_name('images:0') logits_guided = guided_graph.get_tensor_by_name('logits:0') # Get the predicted class for your input image pred_class = sess_guided.run(tf.argmax(logits_guided, axis=1), feed_dict={images_guided: processed_img})[0] # Compute gradients of the predicted class output with respect to the input image grads = tf.gradients(logits_guided[:, pred_class], images_guided)[0] # Run the gradient computation guided_grads = sess_guided.run(grads, feed_dict={images_guided: processed_img})
Step 4: Visualize the Guided Backpropagation Results
Reshape the gradients back to the original image shape and visualize the results:
# Reshape gradients to match the original image dimensions guided_grads_reshaped = guided_grads.reshape(original_img.shape) # Normalize gradients for proper visualization guided_grads_reshaped = (guided_grads_reshaped - np.min(guided_grads_reshaped)) / (np.max(guided_grads_reshaped) - np.min(guided_grads_reshaped)) # Plot original image and guided gradients side by side plt.figure(figsize=(12, 6)) plt.subplot(121) plt.imshow(original_img) plt.title('Original Image') plt.axis('off') plt.subplot(122) plt.imshow(guided_grads_reshaped) plt.title('Guided Backpropagation Heatmap') plt.axis('off') plt.show()
Key Tips:
- Tensor Names: Replace
'images:0'and'logits:0'with the exact names from your saved graph. You can list all tensor names with:[tensor.name for tensor in graph.as_graph_def().node]. - Input Dimensions: Double-check that the resized image flattens to exactly 418400 elements per channel to match your placeholder shape.
- Normalization: Ensure the preprocessing matches what was used during training (e.g., if you subtracted the dataset mean, apply that here).
内容的提问来源于stack exchange,提问作者user7241499

