简单图像分类器#

本笔记本将向您展示如何使用预训练的神经网络对图像进行分类。

您将学习:

  • 如何加载和使用预训练模型
  • 图像预处理
  • 对图像进行预测
  • 理解置信度分数

使用场景: 识别图像中的物体(例如“猫”、“狗”、“汽车”等)


第一步:导入所需的库#

让我们导入所需的工具。如果你还不完全理解这些也不用担心!

In [ ]:
# Core libraries
import numpy as np
from PIL import Image
import requests
from io import BytesIO

# TensorFlow for deep learning
try:
    import tensorflow as tf
    from tensorflow.keras.applications import MobileNetV2
    from tensorflow.keras.applications.mobilenet_v2 import preprocess_input, decode_predictions
    print("✅ TensorFlow loaded successfully!")
    print(f"   Version: {tf.__version__}")
except ImportError:
    print("❌ Please install TensorFlow: pip install tensorflow")

第2步:加载预训练模型#

我们将使用 MobileNetV2,这是一个已经在数百万张图片上训练过的神经网络。

这被称为 迁移学习 - 使用别人训练好的模型!

In [ ]:
print("📦 Loading pre-trained MobileNetV2 model...")
print("   This may take a minute on first run (downloading weights)...")

# Load the model
# include_top=True means we use the classification layer
# weights='imagenet' means it was trained on ImageNet dataset
model = MobileNetV2(weights='imagenet', include_top=True)

print("✅ Model loaded!")
print(f"   The model can recognize 1000 different object categories")

第 3 步:辅助函数#

让我们创建一些函数,用于加载和准备模型所需的图像。

In [ ]:
def load_image_from_url(url):
    """
    Load an image from a URL.
    
    Args:
        url: Web address of the image
        
    Returns:
        PIL Image object
    """
    response = requests.get(url)
    img = Image.open(BytesIO(response.content))
    return img


def prepare_image(img):
    """
    Prepare an image for the model.
    
    Steps:
    1. Resize to 224x224 (model's expected size)
    2. Convert to array
    3. Add batch dimension
    4. Preprocess for MobileNetV2
    
    Args:
        img: PIL Image
        
    Returns:
        Preprocessed image array
    """
    # Resize to 224x224 pixels
    img = img.resize((224, 224))
    
    # Convert to numpy array
    img_array = np.array(img)
    
    # Add batch dimension (model expects multiple images)
    img_array = np.expand_dims(img_array, axis=0)
    
    # Preprocess for MobileNetV2
    img_array = preprocess_input(img_array)
    
    return img_array


def classify_image(img):
    """
    Classify an image and return top predictions.
    
    Args:
        img: PIL Image
        
    Returns:
        List of (class_name, confidence) tuples
    """
    # Prepare the image
    img_array = prepare_image(img)
    
    # Make prediction
    predictions = model.predict(img_array, verbose=0)
    
    # Decode predictions to human-readable labels
    # top=5 means we get the top 5 most likely classes
    decoded = decode_predictions(predictions, top=5)[0]
    
    # Convert to simpler format
    results = [(label, float(confidence)) for (_, label, confidence) in decoded]
    
    return results


print("✅ Helper functions ready!")

第四步:在样本图像上进行测试#

让我们尝试对一些来自互联网的图像进行分类吧!

In [ ]:
# Sample images to classify
# These are from Unsplash (free stock photos)
test_images = [
    {
        "url": "https://images.unsplash.com/photo-1514888286974-6c03e2ca1dba?w=400",
        "description": "A cat"
    },
    {
        "url": "https://images.unsplash.com/photo-1552053831-71594a27632d?w=400",
        "description": "A dog"
    },
    {
        "url": "https://images.unsplash.com/photo-1511919884226-fd3cad34687c?w=400",
        "description": "A car"
    },
]

print(f"🧪 Testing on {len(test_images)} images...")
print("=" * 70)

分类每张图片#

In [ ]:
for i, img_data in enumerate(test_images, 1):
    print(f"\n📸 Image {i}: {img_data['description']}")
    print("-" * 70)
    
    try:
        # Load image
        img = load_image_from_url(img_data['url'])
        
        # Display image
        display(img.resize((200, 200)))  # Show smaller version
        
        # Classify
        results = classify_image(img)
        
        # Show predictions
        print("\n🎯 Top 5 Predictions:")
        for rank, (label, confidence) in enumerate(results, 1):
            # Create a visual bar
            bar_length = int(confidence * 50)
            bar = "█" * bar_length
            
            print(f"  {rank}. {label:20s} {confidence*100:5.2f}% {bar}")
        
    except Exception as e:
        print(f"❌ Error: {e}")

print("\n" + "=" * 70)

第五步:尝试使用自己的图片!#

将下面的 URL 替换为您想要分类的任何图片 URL。

In [ ]:
# Try your own image!
# Replace this URL with any image URL
custom_image_url = "https://images.unsplash.com/photo-1472491235688-bdc81a63246e?w=400"  # A flower

print("🖼️  Classifying your custom image...")
print("=" * 70)

try:
    # Load and show image
    img = load_image_from_url(custom_image_url)
    display(img.resize((300, 300)))
    
    # Classify
    results = classify_image(img)
    
    # Show results
    print("\n🎯 Top 5 Predictions:")
    print("-" * 70)
    for rank, (label, confidence) in enumerate(results, 1):
        bar_length = int(confidence * 50)
        bar = "█" * bar_length
        print(f"  {rank}. {label:20s} {confidence*100:5.2f}% {bar}")
    
    # Highlight top prediction
    top_label, top_confidence = results[0]
    print("\n" + "=" * 70)
    print(f"\n🏆 Best guess: {top_label} ({top_confidence*100:.2f}% confident)")
    
except Exception as e:
    print(f"❌ Error: {e}")
    print("   Make sure the URL points to a valid image!")

💡 刚刚发生了什么?#

  1. 我们加载了一个预训练模型 - MobileNetV2 已经在数百万张图片上完成了训练
  2. 我们对图片进行了预处理 - 调整大小并格式化以适配模型
  3. 模型进行了预测 - 输出了1000个物体类别的概率
  4. 我们解码了结果 - 将数字转换为人类可读的标签

理解置信度分数#

  • 90-100%:非常有信心(几乎肯定正确)
  • 70-90%:有信心(可能正确)
  • 50-70%:信心一般(可能正确)
  • 低于50%:信心不足(不确定)

为什么预测可能会出错?#

  • 不寻常的角度或光线 - 模型是在典型照片上训练的
  • 多个物体 - 模型预期只有一个主要物体
  • 罕见物体 - 模型只识别1000个类别
  • 低质量图片 - 模糊或像素化的图片更难识别

🚀 下一步#

  1. 尝试不同的图片:

    • Unsplash 上寻找图片
    • 右键点击 → “复制图片地址” 获取 URL
  2. 进行实验:

    • 抽象艺术会有什么效果?
    • 它能识别不同角度的物体吗?
    • 它如何处理多个物体?
  3. 深入学习:

    • 探索 计算机视觉课程
    • 学习如何训练自己的图像分类器
    • 理解 CNN(卷积神经网络)的工作原理

🎉 恭喜!#

你刚刚使用最先进的神经网络构建了一个图像分类器!

这种技术同样驱动了:

  • Google Photos(整理你的照片)
  • 自动驾驶汽车(识别物体)
  • 医学诊断(分析 X 光片)
  • 质量控制(检测缺陷)

继续探索和学习吧!🚀


免责声明
本文档使用AI翻译服务 Co-op Translator 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。