pytorch卷积神经网络实现二分类

embedded/2025/2/2 9:26:56/

 人工智能例子汇总: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 = radiusmask = (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,方形圆: 1img = 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 -> 14x14x = self.pool(torch.relu(self.conv2(x)))  # 14x14 -> 7x7x = 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 = 0for 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 = 0total = 0images_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 结构数据(如图像、视频、遥感影像)

http://www.ppmy.cn/embedded/158869.html

相关文章

计算机网络之应用层

计算机网络的应用层是网络体系结构中的最高层&#xff0c;它直接面向用户&#xff0c;为用户提供各种网络应用服务。以下是关于计算机网络应用层的详细介绍&#xff1a; 一、应用层的功能 1. 提供用户接口 • 应用层是用户与网络之间的接口。它通过各种应用程序&#xff08;如…

C++模板初识

文章目录 一、函数模板1. 函数模板2. 函数模板、模板的特例化、非模板函数的重载关系3. 外部调用4. 模板的非类型参数5. 代码示例 二、类模板 一、函数模板 1. 函数模板 模板函数&#xff1a;在函数调用点&#xff0c;编译器用用户指定的类型&#xff0c;从原模板实例化一份函…

学习Python编程,需要哪些编程语言基础?如何开始学习Python?

一、编程语言基础 学习Python编程&#xff0c;虽然并不严格要求具备其他编程语言的先验知识&#xff0c;但拥有一些基本的编程概念和理解会对学习过程产生积极影响。以下是一些建议的编程语言基础&#xff0c;它们将帮助你更快地掌握Python&#xff1a; 基本编程概念&#xf…

MySQL知识点总结(十二)

请说明EXPLAIN语句的作用 EXPLAIN语句能够生成SQL语句的执行计划&#xff0c;显示出优化器如何执行该SQL语句的最优路径。可以用来检查SELECT,INSERT,REPLCAE,UPDATE和DELETE语句。 为什么使用索引会比全表扫描提供更好的查询性能&#xff1f; 索引是一个方案对象&#xff0…

c++ list

1.构造函数 构造函数 // list<T> lst; // list(beg, end); // 区间构造 // list(n, elem); // 元素构造 // list(const list &lst); // 拷贝构造#include <iostream> #include <fstream> #include <string> #include <list> using name…

快速启动与休眠唤醒的区分

留着备查&#xff0c;写驱动的方式可以判断真假S4&#xff1b; 链接

G. XOUR

题目链接&#xff1a;Problem - G - Codeforces 题目大意&#xff1a;给你一个n长的序列&#xff0c; 其中你可以将a[i] XOR a[j] 的值 严格小于4的数对进行交换。 你可以操作任何几次&#xff0c; 让最后的数列最小。如果在 x 和 y 不同的第一个位置&#xff0c; xi<yi &…

软件测试 —— jmeter(2)

软件测试 —— jmeter&#xff08;2&#xff09; HTTP默认请求头&#xff08;元件&#xff09;元件作用域和取样器作用域HTTP Cookie管理器同步定时器jmeter插件梯度压测线程组&#xff08;Stepping Thread Group&#xff09;参数解析总结 Response Times over TimeActive Thre…