人工智能例子汇总:AI常见的算法和例子-CSDN博客 

下面是一个简单的卷积神经网络(CNN)用于区分实心圆方形圆的二分类任务。数据集是人工生成的图像

CNN 是专门用于处理图像等具有空间结构数据的神经网络。其核心组成部分如下:

  1. 输入层(Input Layer):接受原始图像数据,如 28×28×3 的彩色图片(RGB 三通道)。
  2. 卷积层(Convolutional Layer):提取图像特征,如边缘、纹理、形状。
  3. 激活函数(ReLU):引入非线性,提高模型表达能力。
  4. 池化层(Pooling Layer):减少计算量,提高模型对位置变化的鲁棒性。
  5. 全连接层(Fully Connected Layer, FC):将特征映射到最终的分类任务。
  6. 输出层(Output Layer):使用 Softmax(分类)或回归输出
  • 数据生成

    • generate_circle_image(shape, size=28): 生成 28×28 的灰度图像,包含实心圆方形圆
    • generate_dataset(num_samples=1000): 生成包含 num_samples 个样本的数据集,每个样本由 28×28 的图像和标签(0:实心圆,1:方形圆)组成。
  • 模型

    • CNN(): 一个简单的 3 层卷积神经网络,包含 ReLU 激活和最大池化层。
  • 训练

    • train(): 训练模型,使用二元交叉熵损失(BCEWithLogitsLoss)和 Adam 优化器。
  • 测试

    • test(): 评估模型准确率,并可视化预测结果。

完整代码:

import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as Data
import matplotlib.pyplot as plt
import random

# 生成实心圆或方形圆的 28×28 图像
def generate_circle_image(shape, size=28):
    """生成 28x28 的灰度图像,包含实心圆或方形圆"""
    image = torch.ones((size, size), dtype=torch.float32)  # 初始化背景为 1(白色)

    y, x = torch.meshgrid(torch.arange(size), torch.arange(size), indexing='ij')  # 确保未来 PyTorch 版本兼容
    center = (size // 2, size // 2)  # 圆心坐标
    radius = size // 4  # 圆的半径

    if shape == 'circle':
        mask = (x - center[1]) ** 2 + (y - center[0]) ** 2 <= radius ** 2  # 圆的方程
    elif shape == 'square':
        half_size = radius
        mask = (abs(x - center[1]) <= half_size) & (abs(y - center[0]) <= half_size)  # 方形范围

    image[mask] = 0  # 图形部分设为 0(黑色)
    return image

# 生成训练和测试数据
def generate_dataset(num_samples=1000):
    """生成数据集,包含 num_samples 个样本,每个样本是 28x28 图像和标签"""
    images = []
    labels = []
    for _ in range(num_samples):
        shape = random.choice(['circle', 'square'])  # 随机选择类别
        label = 0 if shape == 'circle' else 1  # 圆: 0,方形圆: 1
        img = generate_circle_image(shape)
        images.append(img.unsqueeze(0))  # 增加通道维度 (1, 28, 28)
        labels.append(label)
    
    images = torch.stack(images)  # 转换为张量 (num_samples, 1, 28, 28)
    labels = torch.tensor(labels, dtype=torch.float32)  # 标签张量
    return images, labels

# 卷积神经网络
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 8, kernel_size=3, padding=1)  # 1 输入通道 -> 8 输出通道
        self.conv2 = nn.Conv2d(8, 16, kernel_size=3, padding=1) # 8 -> 16 输出通道
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  # 2x2 最大池化层
        self.fc1 = nn.Linear(16 * 7 * 7, 32)  # 全连接层
        self.fc2 = nn.Linear(32, 1)  # 最终输出 1 维(用于二分类)
    
    def forward(self, x):
        x = self.pool(torch.relu(self.conv1(x)))  # 28x28 -> 14x14
        x = self.pool(torch.relu(self.conv2(x)))  # 14x14 -> 7x7
        x = x.view(-1, 16 * 7 * 7)  # 扁平化张量
        x = torch.relu(self.fc1(x))  # 全连接层
        x = self.fc2(x)  # 输出层
        return x.squeeze(1)  # 去除多余维度,保证输出形状一致

# 训练模型
def train(model, train_loader, criterion, optimizer, num_epochs=5):
    """训练模型"""
    model.train()
    for epoch in range(num_epochs):
        total_loss = 0
        for images, labels in train_loader:
            optimizer.zero_grad()
            outputs = model(images)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            total_loss += loss.item()
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss/len(train_loader):.4f}')

# 评估模型
def test(model, test_loader):
    """测试模型,并可视化部分预测结果"""
    model.eval()
    correct = 0
    total = 0
    images_list, preds, labels_list = [], [], []
    
    with torch.no_grad():
        for images, labels in test_loader:
            outputs = model(images)
            predicted = (torch.sigmoid(outputs) > 0.5).float()  # 通过 sigmoid 得到二分类结果
            correct += (predicted == labels).sum().item()
            total += labels.size(0)

            images_list.extend(images.cpu())
            preds.extend(predicted.cpu())
            labels_list.extend(labels.cpu())

    print(f'Accuracy: {100 * correct / total:.2f}%')

    # 显示部分预测结果
    fig, axes = plt.subplots(1, 5, figsize=(12, 3))
    for i in range(5):
        axes[i].imshow(images_list[i].squeeze(), cmap='gray')
        axes[i].set_title(f"Pred: {int(preds[i].item())} - True: {int(labels_list[i].item())}")
        axes[i].axis('off')
    plt.show()

# 运行训练和测试
def main():
    # 生成数据集
    X_train, y_train = generate_dataset(1000)
    X_test, y_test = generate_dataset(200)

    # 创建数据加载器
    train_dataset = Data.TensorDataset(X_train, y_train)
    test_dataset = Data.TensorDataset(X_test, y_test)
    train_loader = Data.DataLoader(train_dataset, batch_size=32, shuffle=True)
    test_loader = Data.DataLoader(test_dataset, batch_size=32, shuffle=False)

    # 初始化模型、损失函数和优化器
    model = CNN()
    criterion = nn.BCEWithLogitsLoss()  # 二元交叉熵损失
    optimizer = optim.Adam(model.parameters(), lr=0.001)

    # 训练模型
    train(model, train_loader, criterion, optimizer, num_epochs=5)

    # 测试模型
    test(model, test_loader)

if __name__ == "__main__":
    main()

CNN 在 计算机视觉、医学影像、自动驾驶、遥感、NLP 和语音处理 等领域有广泛应用。其主要优势在于:

  • 局部连接和权重共享,减少计算量。
  • 池化层降维,增强特征提取能力。
  • 适用于 2D/3D 结构数据(如图像、视频、遥感影像)
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐