不一定从零开始的CNN分类项目(数据集、训练、分类、混淆矩阵)

本文档详细记录了一个CNN图像分类项目的全过程,包括数据集制作、网络结构定义、训练与测试函数的编写,以及如何利用混淆矩阵评估模型性能。作者提醒注意数据集格式,并分享了完整代码,旨在帮助初学者避免常见问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先声明,本人菜狗,做毕设第一次接触相关项目,代码也是多处缝合,发帖纯为经验分享,防止走过的坑别人再走一遍,有错误欢迎大佬评论区指正
该项目数据集为灰度图,训练RGB图的得改代码

CNN算法文档

一、训练

1、数据集制作

对于文件存放格式为:

|dataset

|-------|class1

|-----------------|111.jpg

|-----------------|222.jpg

|-------|class2

|-----------------|112.jpg

|-----------------|212.jpg

这种的数据集,可以使用ImageFolder函数加载,不是这样的数据集的话,可以自己写Dataset,或者把数据集处理一下成上述形式

from torch.utils.data import DataLoader
from torchvision import transforms as T
# 需要做的变换方式,上述做了个灰度、转化为tensor、归一化
transform  = T.Compose([
        T.Grayscale(),
        T.ToTensor(),
        T.Normalize(mean,std),
])
# 训练集测试集分开加载(预处理?)
dataset_train = ImageFolder('D:\CNN_TEST\\train_dataset', transform=transform)
dataset_test = ImageFolder('D:\CNN_TEST\\test_dataset', transform=transform)

#再用Dataloader函数加载预处理好的数据集
train_loader = DataLoader(dataset_train, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(dataset_test, batch_size=batch_size, shuffle=False)
#batch_size自己设置,shuffle是是否随机加载

2、定义网络结构

class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5, padding=(2, 2), stride=1)
        self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5, padding=(2, 2), stride=1)
        self.pooling = torch.nn.MaxPool2d(2)
        self.fc1 = torch.nn.Linear(5120, 1280)
        self.fc2 = torch.nn.Linear(1280, 240)
        self.fc3 = torch.nn.Linear(240, 10)

    def forward(self, x):


        batch_size = x.size(0)
        x = F.relu(self.pooling(self.conv1(x)))
        x = F.relu(self.pooling(self.conv2(x)))
        x = x.view(batch_size, -1)  # -1 此处自动算出的是320
        # print("x.shape",x.shape)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

不多说,我的结构如图(分几类最后全连接层就是几),根据不同的分类任务可以自己写相应网络

在这里插入图片描述

3、定义训练函数

# 载入模型,使用GPU
model = Net()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

# 损失函数和优化器设置,注意学习率在这里设,也
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

def train(epoch):
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader, 0):
        inputs, target = data
        # inputs = Variable(torch.unsqueeze(inputs, dim=0).float(), requires_grad=False)
        # inputs.reshape(64, 1, 64, 64)
        # print(inputs.shape)
        # print(target, batch_idx)
        inputs, target = inputs.to(device), target.to(device)
        optimizer.zero_grad()

        outputs = model(inputs)
        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()


        running_loss += loss.item()
        if batch_idx % 118 == 117:
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 118))
            #上面几行不对可以优化但不影响训练我懒得改了
            running_loss = 0.0

4、定义测试函数

def test():
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            images, labels = images.to(device), labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, dim=1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print('accuracy on test set: %d %% ' % (100 * correct / total))
    return correct / total

5、主函数

if __name__ == '__main__':
    epoch_list = []
    acc_list = []

    for epoch in range(50):
        train(epoch)
        acc = test()
        epoch_lis
<think>好的,用户现在想用深度学习算法来训练一个多分类模型,但刚开始训练时不知道如何确立模型。我需要先理清楚用户的需求和可能的背景。 首先,用户可能对深度学习有一定的基础,但缺乏实际项目经验,特别是在模型搭建的初期阶段。他们可能已经了解过一些基本概念,比如softmax函数,但具体如何开始构建模型还不清楚。需要从零开始指导他们如何一步步建立模型。 接下来,要确定用户的具体任务是什么。多分类任务有很多种,比如图像分类、文本分类或者其他类型的数据。不同的数据类型会影响模型的选择。比如图像通常用CNN,文本可能用RNN或Transformer,表格数据可能用全连接网络。用户没有具体说明数据类型,所以需要给出通用的建议,并提醒根据数据类型调整模型结构。 然后,用户可能需要了解数据预处理的重要性。数据质量直接影响模型效果,所以需要强调数据清洗、标准化、类别平衡等步骤。另外,数据集的划分也是关键,比如训练集、验证集和测试集的比例,以及交叉验证的应用。 模型结构方面,用户可能不知道如何选择层数、每层的神经元数量,以及激活函数的使用。需要给出常见的结构示例,比如全连接网络的结构,CNN的典型层组合,以及如何处理不同数据类型的输入。同时,需要提醒输出层的设计,比如使用softmax激活函数和合适的损失函数,如交叉熵损失。 优化器和学习率的选择也是用户可能不太清楚的地方。需要介绍常用的优化器,如Adam,以及学习率调整的策略,比如学习率衰减。正则化方法如Dropout和L2正则化也需要提到,以防止过拟合。 训练过程中的监控和调参同样重要。用户需要知道如何通过验证集来调整超参数,使用早停法防止过拟合,以及如何可视化训练过程来诊断问题。此外,代码示例可以帮助用户更快地上手,比如用PyTorch或Keras搭建模型的示例。 可能用户还有一些隐藏的需求,比如如何选择评估指标,如何处理类别不平衡,或者计算资源不足时该怎么办。需要简要提及这些方面,给出实用的建议,比如使用F1分数、数据增强、迁移学习等。 最后,总结整个模型确立的步骤,强调迭代优化的重要性,鼓励用户从简单模型开始,逐步调整。同时提醒注意数据质量、模型评估和调参策略,确保用户有一个全面的认识。</think>以下是构建多分类深度学习模型的**核心步骤与建议**,适用于初期模型设计: --- ### **1. 明确任务与数据** - **任务类型**:确定分类类别数量(如10类、100类)、数据形式(图像、文本、表格等)。 - **数据准备**: - **数据清洗**:处理缺失值、异常值、重复样本。 - **类别平衡**:检查类别分布是否均衡,必要时通过过采样(Oversampling)、欠采样(Undersampling)或数据增强(Data Augmentation)调整。 - **数据标准化**:归一化(如Min-Max缩放)或标准化(Z-Score)输入数据,加速模型收敛。 - **数据集划分**: - 训练集(60-80%)、验证集(10-20%)、测试集(10-20%)。 - 小数据集可使用**交叉验证**(如5折交叉验证)。 --- ### **2. 选择模型架构** 根据数据类型选择合适的**基础模型结构**: #### **(1) 图像数据** - **基础架构**:卷积神经网络CNN),如: - **轻量级模型**:自定义CNN(例如:`Conv2D → MaxPool → Flatten → Dense`)。 - **预训练模型**:使用ResNet、VGG、EfficientNet等作为特征提取器(迁移学习)。 - **输入层**:与图像尺寸匹配的卷积层(如224x224x3)。 - **示例代码(PyTorch)**: ```python import torch.nn as nn class SimpleCNN(nn.Module): def __init__(self, num_classes): super().__init__() self.features = nn.Sequential( nn.Conv2d(3, 16, kernel_size=3, padding=1), # 输入通道3,输出通道16 nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(16, 32, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2), nn.Flatten() ) self.classifier = nn.Sequential( nn.Linear(32 * 56 * 56, 128), # 根据实际输入尺寸调整 nn.ReLU(), nn.Linear(128, num_classes) ) def forward(self, x): x = self.features(x) x = self.classifier(x) return x ``` #### **(2) 文本数据** - **基础架构**:循环神经网络(RNN/LSTM/GRU)或Transformer。 - **词嵌入层**:使用预训练词向量(如Word2Vec、GloVe)或随机初始化。 - **序列模型**:LSTM处理长文本依赖。 - **注意力机制**:Transformer(如BERT微调)。 - **输入层**:文本需转换为词向量序列(如长度固定为512)。 - **示例代码(Keras)**: ```python from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, LSTM, Dense model = Sequential() model.add(Embedding(input_dim=10000, output_dim=128, input_length=200)) # 词汇量1万,句子长度200 model.add(LSTM(128)) model.add(Dense(64, activation='relu')) model.add(Dense(num_classes, activation='softmax')) ``` #### **(3) 表格数据** - **基础架构**:全连接网络(DNN)。 - **输入层**:神经元数量等于特征维度。 - **隐藏层**:逐步降低维度(如512 → 256 → 128)。 - **示例结构**: ```python model = Sequential([ Dense(256, activation='relu', input_shape=(input_dim,)), Dropout(0.5), # 防止过拟合 Dense(128, activation='relu'), Dense(num_classes, activation='softmax') ]) ``` --- ### **3. 输出层设计** - **激活函数**:使用`softmax`函数将输出转换为概率分布。 - **损失函数**:分类任务常用**交叉熵损失**: - **PyTorch**:`nn.CrossEntropyLoss()`(自动结合LogSoftmax)。 - **TensorFlow/Keras**:`loss='categorical_crossentropy'`(需对标签One-Hot编码)。 --- ### **4. 优化器与超参数** - **优化器**: - **通用选择**:`Adam`(自适应学习率,适合大多数任务)。 - **进阶调整**:`SGD` + 动量(需手动调学习率)。 - **学习率**:初始值常设为`1e-3`(Adam)或`0.01`(SGD),根据训练动态调整。 - **批次大小(Batch Size)**:根据GPU显存选择(如32、64、128)。 - **训练轮次(Epochs)**:初始可设50-100轮,配合早停法(Early Stopping)。 --- ### **5. 正则化与防过拟合** - **方法**: - **Dropout**:在全连接层后添加(如`Dropout(0.5)`)。 - **权重正则化**:L2正则化(如`kernel_regularizer=l2(0.01)`)。 - **数据增强**:如图像旋转、裁剪,文本同义词替换。 - **早停法**:监控验证集损失,若连续N轮不下降则停止训练。 --- ### **6. 训练与调参策略** 1. **初始验证**: - 使用简单模型(如1-2个隐藏层)快速验证数据可行性。 - 检查训练集和验证集的初始损失是否下降。 2. **逐步复杂化**: - 若欠拟合(训练准确率低):增加层数、神经元数量或使用更复杂模型。 - 若过拟合(验证集准确率远低于训练集):加强正则化或减少参数量。 3. **超参数搜索**: - 工具:使用`GridSearchCV`或`Optuna`自动化搜索学习率、批次大小等。 4. **可视化监控**: - 绘制损失和准确率曲线(如TensorBoard、Matplotlib)。 --- ### **7. 评估与迭代** - **评估指标**: - **分类准确率**(Accuracy):适用于类别均衡的任务。 - **F1 Score**:适用于类别不平衡的任务。 - **混淆矩阵**:分析各类别的分类错误模式。 - **迭代优化**: - 根据评估结果调整模型结构或超参数。 - 尝试集成学习(如模型融合)或更高级架构(如注意力机制)。 --- ### **总结:模型确立流程** 1. **数据预处理** → 2. **选择基础架构** → 3. **设计输出层** → 4. **设置优化策略** → 5. **添加正则化** → 6. **训练与调参** → 7. **评估迭代**。 **关键原则**:从简单模型开始,逐步增加复杂度,优先保证数据质量和模型泛化能力。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值