基于FCN训练-测试自己的数据集

本文介绍如何基于FCN-32s网络简化版,针对工业缺陷数据进行训练和测试。通过减少网络层深度,调整卷积核大小,适应256*256的图像输入。样本制作涉及图像和标签转换,使用labelme工具生成标注,并创建train、val列表。训练完成后,使用C++动态库进行测试,注意图像预处理和通道顺序。

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

前言

都9102年了,语义分割网络层出不穷,不过作为鼻祖,FCN还是有必要了解下,这里就不在记录其原理,直接基于原始FCN-32s精简网络,对工业缺陷数据进行训练和测试。

简化网络

相对于工业缺陷数据,sift-flow,pascal数据算是及其复杂的数据,直接用原始的FCN网络进行训练,先不说效果,效率上就过不去,因此需要对网络进行简化,原始网络有以下特点:

  1. 卷积层kernel size均为3,stride为1,pooling层为size2,stride2;
  2. 第一个卷积层pad100;
  3. 上采样不学习,在python代码中,用双线性插值初始化后直接固定住。

由以上第一点以及公式w' = (w + 2*pad - kernel) / stride + 1可知,卷积层输出特征图是不会缩小的,只在每个pooling层缩小一倍,由于工业数据不用做太深的网络,因此会减少层深度,只保留3个pooling层,最后一层特征图相比与原图缩小8倍,为了在减少层深度的同时不要使感受野减小太多,将第一个卷积kernel size改为11,pad为5;
针对第二点,由于训练的图是256*256,可以缩小8倍,因此并不用pad100;
简化后的网络结构如下:
简化的FCN

在设计上采样时,要注意:

  • crop层 的参数,也是根据公式计算出来,目的是让裁剪从中间进行裁的。上采样输出图的大小,然后移动到offset进行裁剪的,裁剪是根据输入图像大小;
  • 反卷积层 上采样的参数,根据公式output = (input - 1) * s + k - 2 * p;计算,设置步长和核大小,参照标准设置,核尺寸设64,32等,stride作为公式中乘除比例因子,设8.
layer {
  name: "upscore"
  type: "Deconvolution"
  bottom: "conv5"
  top: "upscore"
  param {
    lr_mult: 0
  }
  convolution_param {
    num_output: 2
    bias_term: false
    kernel_size: 32
    stride: 8
  }
}
layer {
  name: "score"
  type: "Crop"
  bottom: "upscore"
  bottom: "data"
  top: "score"
  crop_param {
    axis: 2   #axis(决定从第2个轴(h,w)开始裁剪)
    offset: 12 #决定裁剪位置的偏移,保证截的图是重心区域
  }
}

样本制作

fcn源码训练的数据输

### PyTorch FCN 训练自定义数据集教程 #### 数据准备 为了使用PyTorch中的全卷积网络(FCN训练自定义数据集,首先需要准备好数据并创建适合的数据加载器。这可以通过继承`torch.utils.data.Dataset`类来自定义数据集处理逻辑[^1]。 ```python from torch.utils.data import Dataset, DataLoader class CustomDataset(Dataset): def __init__(self, data_dir, transform=None): self.data_dir = data_dir self.transform = transform # 加载文件列表或其他初始化操作 def __len__(self): return total_number_of_samples def __getitem__(self, idx): sample = load_sample(idx) # 实现读取单个样本的方法 if self.transform: sample = self.transform(sample) return sample ``` #### 构建模型结构 接着定义用于语义分割任务的FCN架构。可以基于现有的预训练模型如VGG或ResNet进行修改以适应特定的应用场景[^2]。 ```python import torchvision.models as models import torch.nn as nn def make_fcn_model(pretrained=True): vgg = models.vgg16_bn(pretrained=pretrained).features for param in vgg.parameters(): param.requires_grad_(False) fcns = [] conv_layers_to_copy = [0,7,14,24,34] for i,l in enumerate(conv_layers_to_copy[:-1]): layers = list(vgg.children())[conv_layers_to_copy[i]:conv_layers_to_copy[i+1]] fcns += layers + [nn.ConvTranspose2d(512, 512, kernel_size=2, stride=2)] classifier = nn.Sequential( nn.Conv2d(in_channels=512,out_channels=n_classes,kernel_size=1), nn.Sigmoid() ) model = nn.Sequential(*fcns,classifier) return model ``` #### 定义损失函数与优化算法 对于图像分类或者像素级别的预测问题,常用的损失函数有交叉熵损失等;而Adam通常是较为推荐的选择之一作为优化方法[^3]。 ```python criterion = nn.BCELoss() optimizer = optim.Adam(model.parameters(), lr=learning_rate) ``` #### 开始训练过程 最后一步就是编写循环来进行批量前向传播、计算误差以及反向更新权重参数的过程了。记得定期保存最佳性能下的模型状态以便后续评估测试阶段调用。 ```python for epoch in range(num_epochs): running_loss = 0.0 for inputs, labels in dataloader: optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() print(f'Epoch [{epoch}/{num_epochs}], Loss: {running_loss:.4f}') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值