找回密码
 立即注册
首页 业界区 安全 定义一个简单点的神经网络

定义一个简单点的神经网络

笙芝 2026-1-14 13:30:04
  1. import torch.nn as nn
  2. class Net(nn.Module):
  3.     """
  4.     定义一个简单点的神经网络,卷积,池化,激活,全连接  嗯.....够简单了!
  5.     输入的话就64*64的图片吧,通道数为3,卷积核为2,padding为1吧,这样的话就是
  6.     : (3, 64, 64)
  7.     卷积核为2,padding为1,输出通道数为64,这样的话就是
  8.     : (64, 64, 64)
  9.     池化核为2,输出通道数为64,这样的话就是
  10.     : (64, 32, 32)
  11.     全连接层的话就32*32*64=65536个神经元,输出10个类别的概率
  12.     """
  13.     def __init__(self):
  14.         super(Net, self).__init__()
  15.         self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=2, padding=1)
  16.         self.pool = nn.MaxPool2d(kernel_size=2)
  17.         self.relu = nn.ReLU()
  18.         self.fc = nn.Linear(in_features=64*32*32, out_features=10)
  19.         self.dropout = nn.Dropout(0.5)      # 随机失活,防止过拟合
  20.     # 接下来的话就是定义前向传播了!
  21.     def forward(self, x):
  22.         x = self.conv1(x)
  23.         x = self.pool(x)
  24.         x = self.relu(x)
  25.         x = x.view(-1, 64*32*32)    # 这里的-1就是让Pytorch自动计算这个维度的值
  26.         x = self.fc(x)
  27.         x = self.dropout(x)
  28.         return x
  29.     """
  30.     这里就是定义了前向传播,这里就是将输入的图片进行卷积,然后进行池化,然后进行激活,然后进行全连接,然后返回结果
  31.     """
  32. # 实例化模型,看看效果吧
  33. net = Net()
  34. print(net)
  35. import torch
  36. # 创建一个简单的64*64的图片张量
  37. array = torch.rand(64, 3, 64, 64)
  38. # 创建目标标签(假设是10分类问题)
  39. target = torch.randint(0, 10, (64,))
  40. # 超参数定义
  41. echo = 100
  42. lr = 0.001
  43. optimizer = torch.optim.SGD(net.parameters(), lr=lr)  # 优化器
  44. """
  45. 简单的训练过程实现
  46. :
  47. """
  48. for i in range(echo):
  49.     # 设置模型为训练模式
  50.     net.train()
  51.     output = net(array)
  52.     # 定义损失函数
  53.     criterion = nn.CrossEntropyLoss()   # 损失函数
  54.     loss = criterion(output, target)    # 计算损失
  55.     optimizer.zero_grad()               # 梯度清零
  56.     loss.backward()                     # 反向传播
  57.     optimizer.step()                    # 更新参数
  58.     # 反向传播
  59.     print(f"第{i+1}轮训练,损失值: {loss.item():.4f}")
  60.     print("反向传播完成,梯度已计算")
  61. # 保存模型
  62. torch.save(net.state_dict(), 'model.pth')
  63. # 测试
  64. net.eval()
  65. # 加载模型
  66. model = Net()
  67. model.load_state_dict(torch.load('model.pth'))
  68. model.eval()
  69. # 测试数据
  70. test_array = torch.rand(1, 3, 64, 64)
  71. with torch.no_grad():
  72.     output = model(test_array)
  73.     print(output)
  74.     print(f"当前模型预测的类别是: {torch.argmax(output, dim=1).item()}")
  75. # import torchvision.transforms as transforms
  76. # import torchvision.datasets as datasets
  77. # train_dataset = datasets.ImageFolder(root='./data/train', transform=transforms.ToTensor())
  78. # train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
  79. # test_dataset = datasets.ImageFolder(root='./data/test', transform=transforms.ToTensor())
  80. # test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
  81. # print(len(train_dataset))
  82. # print(len(test_dataset))
  83. # print(train_dataset.class_to_idx)
  84. # import matplotlib.pyplot as plt
  85. # plt.imshow(train_dataset[0][0].numpy().transpose(1, 2, 0))
  86. # plt.title(train_dataset.classes[train_dataset[0][1]])
  87. # 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: 输出类别数

训练流程

基本设置
  1. # 模型实例化
  2. net = Net()
  3. # 优化器
  4. optimizer = torch.optim.SGD(net.parameters(), lr=0.001)
  5. # 损失函数
  6. criterion = nn.CrossEntropyLoss()
复制代码
训练循环
  1. for epoch in range(100):
  2.     # 前向传播
  3.     output = net(input_tensor)
  4.    
  5.     # 计算损失
  6.     loss = criterion(output, target)
  7.    
  8.     # 反向传播三部曲
  9.     optimizer.zero_grad()  # 梯度清零
  10.     loss.backward()        # 反向传播
  11.     optimizer.step()       # 参数更新
  12.    
  13.     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)而不是原始输出

快速构建模板

基础模板
  1. import torch
  2. import torch.nn as nn
  3. class SimpleCNN(nn.Module):
  4.     def __init__(self, input_channels, num_classes):
  5.         super(SimpleCNN, self).__init__()
  6.         self.conv1 = nn.Conv2d(input_channels, 64, 3, padding=1)
  7.         self.pool = nn.MaxPool2d(2)
  8.         self.relu = nn.ReLU()
  9.         self.fc = nn.Linear(64*32*32, num_classes)  # 根据实际尺寸调整
  10.    
  11.     def forward(self, x):
  12.         x = self.conv1(x)
  13.         x = self.pool(x)
  14.         x = self.relu(x)
  15.         x = x.view(x.size(0), -1)  # 自动展平
  16.         x = self.fc(x)
  17.         return x
  18. # 使用示例
  19. model = SimpleCNN(3, 10)
  20. optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
  21. criterion = nn.CrossEntropyLoss()
复制代码
数据加载模板
  1. from torchvision import datasets, transforms
  2. # 数据预处理
  3. transform = transforms.Compose([
  4.     transforms.Resize((64, 64)),
  5.     transforms.ToTensor(),
  6. ])
  7. # 数据集加载
  8. train_dataset = datasets.ImageFolder('./data/train', transform=transform)
  9. train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
复制代码
进阶功能

1. 模型保存与加载
  1. # 保存模型
  2. torch.save(model.state_dict(), 'model.pth')
  3. # 加载模型
  4. model = SimpleCNN(3, 10)
  5. model.load_state_dict(torch.load('model.pth'))
复制代码
2. 训练验证分离
  1. def train(model, dataloader, criterion, optimizer):
  2.     model.train()
  3.     for batch_idx, (data, target) in enumerate(dataloader):
  4.         optimizer.zero_grad()
  5.         output = model(data)
  6.         loss = criterion(output, target)
  7.         loss.backward()
  8.         optimizer.step()
  9. def validate(model, dataloader, criterion):
  10.     model.eval()
  11.     total_loss = 0
  12.     with torch.no_grad():
  13.         for data, target in dataloader:
  14.             output = model(data)
  15.             total_loss += criterion(output, target).item()
  16.     return total_loss / len(dataloader)
复制代码
实用技巧


  • 学习率调整: 使用torch.optim.lr_scheduler
  • 早停机制: 监控验证集损失
  • 数据增强: 使用torchvision.transforms
  • GPU加速: 使用.to('cuda')迁移到GPU

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

2026-1-16 15:33:45

举报

2026-1-20 07:39:14

举报

2026-1-25 12:32:02

举报

6 天前

举报

您需要登录后才可以回帖 登录 | 立即注册