如何构建识别的神经网络?

摘要:import torch.nn as nn class Net(nn.Module): """ 定义一个简单点的神经网络,卷积,池化,激活,全连接 嗯.....够
import torch.nn as nn class Net(nn.Module): """ 定义一个简单点的神经网络,卷积,池化,激活,全连接 嗯.....够简单了! 输入的话就64*64的图片吧,通道数为3,卷积核为2,padding为1吧,这样的话就是 : (3, 64, 64) 卷积核为2,padding为1,输出通道数为64,这样的话就是 : (64, 64, 64) 池化核为2,输出通道数为64,这样的话就是 : (64, 32, 32) 全连接层的话就32*32*64=65536个神经元,输出10个类别的概率 """ def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=2, padding=1) self.pool = nn.MaxPool2d(kernel_size=2) self.relu = nn.ReLU() self.fc = nn.Linear(in_features=64*32*32, out_features=10) self.dropout = nn.Dropout(0.5) # 随机失活,防止过拟合 # 接下来的话就是定义前向传播了! def forward(self, x): x = self.conv1(x) x = self.pool(x) x = self.relu(x) x = x.view(-1, 64*32*32) # 这里的-1就是让Pytorch自动计算这个维度的值 x = self.fc(x) x = self.dropout(x) return x """ 这里就是定义了前向传播,这里就是将输入的图片进行卷积,然后进行池化,然后进行激活,然后进行全连接,然后返回结果 """ # 实例化模型,看看效果吧 net = Net() print(net) import torch # 创建一个简单的64*64的图片张量 array = torch.rand(64, 3, 64, 64) # 创建目标标签(假设是10分类问题) target = torch.randint(0, 10, (64,)) # 超参数定义 echo = 100 lr = 0.001 optimizer = torch.optim.SGD(net.parameters(), lr=lr) # 优化器 """ 简单的训练过程实现 : """ for i in range(echo): # 设置模型为训练模式 net.train() output = net(array) # 定义损失函数 criterion = nn.CrossEntropyLoss() # 损失函数 loss = criterion(output, target) # 计算损失 optimizer.zero_grad() # 梯度清零 loss.backward() # 反向传播 optimizer.step() # 更新参数 # 反向传播 print(f"第{i+1}轮训练,损失值: {loss.item():.4f}") print("反向传播完成,梯度已计算") # 保存模型 torch.save(net.state_dict(), 'model.pth') # 测试 net.eval() # 加载模型 model = Net() model.load_state_dict(torch.load('model.pth')) model.eval() # 测试数据 test_array = torch.rand(1, 3, 64, 64) with torch.no_grad(): output = model(test_array) print(output) print(f"当前模型预测的类别是: {torch.argmax(output, dim=1).item()}") # import torchvision.transforms as transforms # import torchvision.datasets as datasets # train_dataset = datasets.ImageFolder(root='./data/train', transform=transforms.ToTensor()) # train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True) # test_dataset = datasets.ImageFolder(root='./data/test', transform=transforms.ToTensor()) # test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False) # print(len(train_dataset)) # print(len(test_dataset)) # print(train_dataset.class_to_idx) # import matplotlib.pyplot as plt # plt.imshow(train_dataset[0][0].numpy().transpose(1, 2, 0)) # plt.title(train_dataset.classes[train_dataset[0][1]]) # plt.show()​ 核心组件详解 1. 卷积层 (nn.Conv2d) 作用: 提取图像特征 参数: in_channels=3: 输入通道数(RGB) out_channels=64: 输出特征图数量 kernel_size=2: 卷积核大小 padding=1: 边缘填充,保持尺寸 2. 池化层 (nn.MaxPool2d) 作用: 降维、防止过拟合 参数: kernel_size=2: 2×2最大池化 3. 激活函数 (nn.ReLU) 作用: 引入非线性,增强模型表达能力 4. 全连接层 (nn.Linear) 作用: 分类决策 参数: in_features=65536: 展平后的特征数量 out_features=10: 输出类别数 训练流程 基本设置 # 模型实例化 net = Net() # 优化器 optimizer = torch.optim.SGD(net.parameters(), lr=0.001) # 损失函数 criterion = nn.CrossEntropyLoss() 训练循环 for epoch in range(100): # 前向传播 output = net(input_tensor) # 计算损失 loss = criterion(output, target) # 反向传播三部曲 optimizer.zero_grad() # 梯度清零 loss.backward() # 反向传播 optimizer.step() # 参数更新 print(f"第{epoch+1}轮训练,损失值: {loss.item():.4f}") 关键要点 1. 反向传播原理 梯度清零: 防止梯度累积 loss.backward(): 自动计算所有参数的梯度 optimizer.step(): 根据梯度更新参数 2. 尺寸匹配规则 卷积输出尺寸: (输入尺寸 + 2×padding - kernel_size) / stride + 1 池化输出尺寸: 输入尺寸 / kernel_size 全连接层输入必须展平为一维 3. 常见问题解决 RuntimeError: grad can be implicitly created only for scalar outputs 原因: backward()只能对标量求导 解决: 使用损失函数(loss)而不是原始输出 快速构建模板 基础模板 import torch import torch.nn as nn class SimpleCNN(nn.Module): def __init__(self, input_channels, num_classes): super(SimpleCNN, self).__init__() self.conv1 = nn.Conv2d(input_channels, 64, 3, padding=1) self.pool = nn.MaxPool2d(2) self.relu = nn.ReLU() self.fc = nn.Linear(64*32*32, num_classes) # 根据实际尺寸调整 def forward(self, x): x = self.conv1(x) x = self.pool(x) x = self.relu(x) x = x.view(x.size(0), -1) # 自动展平 x = self.fc(x) return x # 使用示例 model = SimpleCNN(3, 10) optimizer = torch.optim.Adam(model.parameters(), lr=0.001) criterion = nn.CrossEntropyLoss() 数据加载模板 from torchvision import datasets, transforms # 数据预处理 transform = transforms.Compose([ transforms.Resize((64, 64)), transforms.ToTensor(), ]) # 数据集加载 train_dataset = datasets.ImageFolder('./data/train', transform=transform) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True) 进阶功能 1. 模型保存与加载 # 保存模型 torch.save(model.state_dict(), 'model.pth') # 加载模型 model = SimpleCNN(3, 10) model.load_state_dict(torch.load('model.pth')) 2. 训练验证分离 def train(model, dataloader, criterion, optimizer): model.train() for batch_idx, (data, target) in enumerate(dataloader): optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() def validate(model, dataloader, criterion): model.eval() total_loss = 0 with torch.no_grad(): for data, target in dataloader: output = model(data) total_loss += criterion(output, target).item() return total_loss / len(dataloader) 实用技巧 学习率调整: 使用torch.optim.lr_scheduler 早停机制: 监控验证集损失 数据增强: 使用torchvision.transforms GPU加速: 使用.to('cuda')迁移到GPU