【问题标题】:What I am doing wrong with this semantic segmentation?这个语义分割我做错了什么?
【发布时间】:2017-03-03 05:38:22
【问题描述】:

现在我在 FCN32 上研究单通道图像的语义分割已经有很长一段时间了(差不多两个月)。我尝试了不同的学习率,甚至添加了BatchNormalization 层。但是,我什至没有看到任何输出。除了立即在这里寻求帮助之外,我别无选择。我真的不知道我做错了什么。

我将一个图像作为一批发送到网络。这是训练损失曲线LR=1e-9 和lr_policy="fixed":

我将学习率提高到1e-4(下图)。损失似乎正在下降,但是,学习曲线并不正常。

我将原始 FCN 的层数减少如下: (1) Conv64 – ReLU – Conv64 – ReLU – MaxPool

(2) Conv128 – ReLU – Conv128 – ReLU – MaxPool

(3) Conv256 – ReLU – Conv256 – ReLU – MaxPool

(4) Conv4096 – ReLU – Dropout0.5

(5) Conv4096 – ReLU – Dropout0.5

(6)Conv2

(7) Deconv32x - 裁剪

(8) SoftmaxWithLoss

layer {
  name: "data"
  type: "Data"
  top: "data"
  include {
    phase: TRAIN
  }
  transform_param {
    mean_file: "/jjj/FCN32_mean.binaryproto"
  }

  data_param {
    source: "/jjj/train_lmdb/"
    batch_size: 1
    backend: LMDB
  }
}
layer {
  name: "label"
  type: "Data"
  top: "label"
  include {
    phase: TRAIN
  }
  data_param {
    source: "/jjj/train_label_lmdb/"
    batch_size: 1
    backend: LMDB
  }
}
layer {
  name: "data"
  type: "Data"
  top: "data"
  include {
    phase: TEST
  }
  transform_param {
    mean_file: "/jjj/FCN32_mean.binaryproto"
  }
  data_param {
    source: "/jjj/val_lmdb/"
    batch_size: 1
    backend: LMDB
  }
}
layer {
  name: "label"
  type: "Data"
  top: "label"
  include {
    phase: TEST
  }
  data_param {
    source: "/jjj/val_label_lmdb/"
    batch_size: 1
    backend: LMDB
  }
}

layer {
  name: "conv1_1"
  type: "Convolution"
  bottom: "data"
  top: "conv1_1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 64
    pad: 100
    kernel_size: 3
    stride: 1
  }
}
layer {
  name: "relu1_1"
  type: "ReLU"
  bottom: "conv1_1"
  top: "conv1_1"
}
layer {
  name: "conv1_2"
  type: "Convolution"
  bottom: "conv1_1"
  top: "conv1_2"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 64
    pad: 1
    kernel_size: 3
    stride: 1
  }
}
layer {
  name: "relu1_2"
  type: "ReLU"
  bottom: "conv1_2"
  top: "conv1_2"
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1_2"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv2_1"
  type: "Convolution"
  bottom: "pool1"
  top: "conv2_1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 128
    pad: 1
    kernel_size: 3
    stride: 1
  }
}
layer {
  name: "relu2_1"
  type: "ReLU"
  bottom: "conv2_1"
  top: "conv2_1"
}
layer {
  name: "conv2_2"
  type: "Convolution"
  bottom: "conv2_1"
  top: "conv2_2"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 128
    pad: 1
    kernel_size: 3
    stride: 1
  }
}
layer {
  name: "relu2_2"
  type: "ReLU"
  bottom: "conv2_2"
  top: "conv2_2"
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2_2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "conv3_1"
  type: "Convolution"
  bottom: "pool2"
  top: "conv3_1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
    stride: 1
  }
}
layer {
  name: "relu3_1"
  type: "ReLU"
  bottom: "conv3_1"
  top: "conv3_1"
}
layer {
  name: "conv3_2"
  type: "Convolution"
  bottom: "conv3_1"
  top: "conv3_2"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
    stride: 1
  }
}
layer {
  name: "relu3_2"
  type: "ReLU"
  bottom: "conv3_2"
  top: "conv3_2"
}
layer {
  name: "pool3"
  type: "Pooling"
  bottom: "conv3_2"
  top: "pool3"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {
  name: "fc6"
  type: "Convolution"
  bottom: "pool3"
  top: "fc6"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 4096
    pad: 0
    kernel_size: 7
    stride: 1
  }
}
layer {
  name: "relu6"
  type: "ReLU"
  bottom: "fc6"
  top: "fc6"
}
layer {
  name: "drop6"
  type: "Dropout"
  bottom: "fc6"
  top: "fc6"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc7"
  type: "Convolution"
  bottom: "fc6"
  top: "fc7"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 4096
    pad: 0
    kernel_size: 1
    stride: 1
  }
}
layer {
  name: "relu7"
  type: "ReLU"
  bottom: "fc7"
  top: "fc7"
}
layer {
  name: "drop7"
  type: "Dropout"
  bottom: "fc7"
  top: "fc7"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "score_fr"
  type: "Convolution"
  bottom: "fc7"
  top: "score_fr"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 5 #21
    pad: 0
    kernel_size: 1
    weight_filler {
        type: "xavier"
    }   
    bias_filler {
        type: "constant"
     } 
  }
}
layer {
  name: "upscore"
  type: "Deconvolution"
  bottom: "score_fr"
  top: "upscore"
  param {
    lr_mult: 0
  }
  convolution_param {
    num_output: 5 #21
    bias_term: false
    kernel_size: 64
    stride: 32
    group: 5 #2
    weight_filler: { 
         type: "bilinear" 
     }
  }
}
layer {
  name: "score"
  type: "Crop"
  bottom: "upscore"
  bottom: "data"
  top: "score"
  crop_param {
    axis: 2
    offset: 19
  }
}
layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "score"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TRAIN
  }
}

layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "score"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "score"
  bottom: "label"
  top: "loss"
  loss_param {
    ignore_label: 255
    normalize: true
  }
}

这是求解器的定义:

net: "train_val.prototxt"
#test_net: "val.prototxt"
test_iter: 736
# make test net, but don't invoke it from the solver itself
test_interval: 2000 #1000000
display: 50
average_loss: 50
lr_policy: "step" #"fixed"
stepsize: 2000  #+
gamma: 0.1  #+
# lr for unnormalized softmax
base_lr: 0.0001 
# high momentum
momentum: 0.99
# no gradient accumulation
iter_size: 1
max_iter: 10000
weight_decay: 0.0005
snapshot: 2000
snapshot_prefix: "snapshot/NET1"
test_initialization: false
solver_mode: GPU

一开始,损失开始下降,但经过一些迭代后,它又没有表现出良好的学习行为:

我是深度学习的初学者,caffe。我真的不明白为什么会这样。我真的很感激那些有专业知识的人,请看看模型定义,如果你能帮助我,我将非常感激。

【问题讨论】:

  • 您是使用预训练的权重开始,还是从头开始训练网络(随机权重)?
  • 我实际上是从零开始训练的。感谢您的帮助

标签: deep-learning caffe pycaffe matcaffe


【解决方案1】:

问题是你是从零开始训练的。

阅读FCN paper 会告诉你,他们总是使用在 ImageNet 上预训练的网络,如果你从头开始训练它不会工作,它必须从预训练的网络进行微调。如果您从随机权重进行训练,那么优化问题不会收敛。

【讨论】:

  • 感谢您的评论。通过在点号4 中引用这个link,就是说“新数据集很大并且与原始数据集非常不同。由于数据集非常大,我们可以预期我们可以负担得起从头开始训练ConvNet .",由于我的数据与预训练模型的原始数据集有很大不同,会发生什么?我想我很困惑。非常感谢。
  • 我能做什么?你的建议是什么?非常感谢
  • @S.EB 最简单的方法是在数据集上预训练您的网络,例如 ImageNet 用于图像分类,然后更改部分架构并对其进行微调。如果你不能做到这一点,那就不要使用自己的网络架构,而只需使用像 VGG/ResNet 这样的预训练网络。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-18
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
相关资源
最近更新 更多