You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MNIST图像分类错误排查:如何可视化神经网络的感知内容?

Got it, let's fix this misclassification visualization step by step. You’ve got a MNIST model that’s labeling a '1' as a '2', and you want to see what the network is actually "perceiving" by turning activated nodes into images, then compare that to your test image. Here’s how to extend your existing code to make this happen:

First, Tweak Your Network Class to Capture Hidden Layer Activations

Right now, your query method only returns the final output. We need to grab the hidden layer’s activation values too, since those are key to seeing what the network picks up from your image:

import numpy as np

class Network():
    def __init__(self, inn, hidd, outt, lr):
        self.InNodes = inn
        self.HiddenNodes = hidd
        self.OutNodes = outt
        self.LearningRate = lr
        self.wih = np.random.normal(0.0, pow(self.InNodes,-0.5), (self.HiddenNodes,self.InNodes))
        self.woh = np.random.normal(0.0, pow(self.OutNodes,-0.5), (self.OutNodes,self.HiddenNodes))
        
    def train(self, inputs_list, targets_list):
        inputs = np.array(inputs_list, ndmin=2).T
        targets = np.array(targets_list, ndmin=2).T
        hidden_inputs = np.dot(self.wih, inputs)
        hidden_outputs = sigmoid(hidden_inputs)
        final_inputs = np.dot(self.woh, hidden_outputs)
        final_outputs = sigmoid(final_inputs)
        output_errors = targets - final_outputs
        hidden_errors = np.dot(self.woh.T, output_errors)
        self.woh += self.LearningRate * np.dot((output_errors * final_outputs * (1 - final_outputs)), np.transpose(hidden_outputs))
        self.wih += self.LearningRate * np.dot((hidden_errors * hidden_outputs * (1 - hidden_outputs)), np.transpose(inputs))
        
    def query(self, inputs_list):
        inputs = np.array(inputs_list, ndmin=2).T
        hidden_inputs = np.dot(self.wih, inputs)
        hidden_outputs = sigmoid(hidden_inputs)
        final_inputs = np.dot(self.woh, hidden_outputs)
        final_outputs = sigmoid(final_inputs)
        return final_outputs, hidden_outputs  # Return both outputs and hidden activations

def sigmoid(z):
    """The sigmoid function."""
    return 1.0/(1.0+np.exp(-z))

Preprocess Your Test Image to Match Training Data

Your raw image needs to be normalized the same way as the MNIST training data (0.01 to 1.0 range) — mismatched preprocessing is a common cause of weird predictions, so don’t skip this:

import imageio
import matplotlib.pyplot as plt

# Load and prep your test image
img_array = imageio.imread(r"\IMG\output-onlinepngtools.png", as_gray=True)
# Reverse colors if your image is white-on-black (MNIST uses black-on-white)
img_data = 255.0 - img_array.reshape(784)
# Normalize to match MNIST's input range
img_data = (img_data / 255.0 * 0.99) + 0.01

Run the Query and Grab Activation Data

Now get the model’s prediction and the hidden layer activations we need for visualization:

# Load training data (assuming mnist_loader is the standard Nielsen implementation)
import mnist_loader
training_data, validation_data, test_data = mnist_loader.load_data_wrapper()

# Initialize and train the network (you'll want to train it properly first!)
input_nodes = 784
hidden_nodes = 10
output_nodes = 10
learning = 0.1
Net = Network(input_nodes, hidden_nodes, output_nodes, learning)

# Train for a few epochs (adjust based on your needs)
for epoch in range(5):
    for x, y in training_data:
        Net.train(x, y)

# Get model outputs and hidden layer activations
outputs, hidden_outputs = Net.query(img_data)
predicted_label = np.argmax(outputs)
print(f"Predicted Label: {predicted_label} | Actual Label: 1")

Visualize: Test Image vs. Network's "Perception"

We’ll plot three things: your original test image, the hidden layer’s learned features (with their activation levels), and what the network associates with the incorrect label ('2').

Full Visualization Code

plt.figure(figsize=(14, 6))

# Plot your original test image
plt.subplot(2, 6, 1)
plt.imshow(img_array, cmap='gray')
plt.title("Test Image\n(Actual: 1)")
plt.axis('off')

# Plot each hidden node's learned feature + activation level
for i in range(Net.HiddenNodes):
    plt.subplot(2, 6, i+2)
    # Reshape the hidden node's weights into a 28x28 image
    weight_img = Net.wih[i].reshape(28, 28)
    plt.imshow(weight_img, cmap='gray')
    # Show how active this node was for your test image
    plt.title(f"Hidden Node {i}\nActivation: {hidden_outputs[i][0]:.2f}")
    plt.axis('off')

plt.tight_layout()
plt.show()

# Now plot what the network associates with the incorrect label ('2')
plt.figure(figsize=(6, 6))
# Combine output layer weights (for label 2) with hidden layer weights to see the "perceived" image
perceived_img = np.dot(Net.woh[2], Net.wih).reshape(28, 28)
plt.imshow(perceived_img, cmap='gray')
plt.title(f"Network's Perception of '2'")
plt.axis('off')
plt.show()

What This Shows You

  • The hidden node images reveal the low-level features the network learned (like edges, curves, or stroke patterns).
  • The activation values tell you which of those features the network detected in your test image. If nodes tied to "2"-like features are highly activated, that’s exactly why the model misclassified your '1'.
  • The "perceived '2'" image shows the composite feature the network uses to identify a '2' — you’ll probably see it matches some part of your test image that tricked the model.

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

火山引擎 最新活动