输入层类型:在Windows Caffe CPP中使用ImageData提供空白输出

3

我正在使用Caffe在Windows上使用C++解决图像分割问题。我使用"Imagedata"输入类型来训练网络,但是测试时输出为空白。有没有人能帮助我分析这个问题。

**********  solver.prototxt  ***************

test_initialization: false
base_lr: 0.01
display: 51
max_iter: 50000
lr_policy: "step"
gamma: 0.1
momentum: 0.9
weight_decay: 0.0001
stepsize: 4069
snapshot: 10000
snapshot_prefix: "snapshot"
solver_mode: GPU
net: "train.prototxt"
solver_type: SGD

File_Triangle.txt和File_label_triangle.txt包含图像位置的绝对路径和虚拟标签。 例如:D:\00000032.png 0

****************  train.prototxt   ********************

layer {
  name: "data"
  type: "ImageData"
  top: "data"
  top: "xx"
  include {
    phase: TRAIN
  }
  image_data_param {
    source: "File_triangle.txt"
     batch_size: 1
     new_height: 32
     new_width: 32
     is_color: False
}

}

layer {
  name: "label"
  type: "ImageData"
  top: "label"
  top: "yy"
  image_data_param {
    source: "File_label_triangle.txt"
     batch_size: 1
     new_height: 32
     new_width: 32
     is_color: False
}
  include {
    phase: TRAIN
  }
}


layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1.0
  }
  param {
    lr_mult: 0.10000000149
  }
  convolution_param {
    num_output: 32
    pad: 1
    kernel_size: 3
    stride: 1
    weight_filler {
      type: "gaussian"
      std: 0.0010000000475
    }
    bias_filler {
      type: "constant"
      value: 0.0
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "conv1"
  top: "conv2"
  param {
    lr_mult: 1.0
  }
  param {
    lr_mult: 0.10000000149
  }
  convolution_param {
    num_output: 1024
    pad: 0
    kernel_size: 16
    stride: 16
    weight_filler {
      type: "gaussian"
      std: 0.0010000000475
    }
    bias_filler {
      type: "constant"
      value: 0.0
    }
  }
}
layer {
  name: "relu2"
  type: "ReLU"
  bottom: "conv2"
  top: "conv2"
}
layer {
  name: "upsample"
  type: "Deconvolution"
  bottom: "conv2"
  top: "upsample"
  param {
    lr_mult: 1.0
  }
  convolution_param {
    num_output: 1
    pad: 0
    kernel_size: 16
    stride: 16
    bias_filler {
      type: "constant"
      value: 128.0
    }
  }
}
layer {
  name: "lossL1"
  type: "SmoothL1Loss"
  bottom: "upsample"
  bottom: "label"
  top: "lossL1"
  loss_weight: 1.0
}

C++训练的代码片段

shared_ptr<Net<float> > net_;
net_.reset(new Net<float>("train.prototxt", caffe::Phase::TRAIN));
Caffe::set_mode(Caffe::GPU);
caffe::SolverParameter solver_param;
caffe::ReadSolverParamsFromTextFileOrDie("solver.prototxt", &solver_param);
boost::shared_ptr<caffe::Solver<float> > solver(caffe::SolverRegistry<float>::CreateSolver(solver_param));
solver->Solve();

在训练完成后,我使用 .caffemodel 来测试网络。

********************  test.prototxt  **********************

layer {
  name: "data"
  type: "Input"
  top: "data"
  input_param { shape: { dim: 1 dim: 1 dim: 32 dim: 32 } }
}

layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1.0
  }
  param {
    lr_mult: 0.10000000149
  }
  convolution_param {
    num_output: 32
    pad: 1
    kernel_size: 3
    stride: 1
    weight_filler {
      type: "gaussian"
      std: 0.0010000000475
    }
    bias_filler {
      type: "constant"
      value: 0.0
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "conv1"
  top: "conv2"
  param {
    lr_mult: 1.0
  }
  param {
    lr_mult: 0.10000000149
  }
  convolution_param {
    num_output: 1024
    pad: 0
    kernel_size: 16
    stride: 16
    weight_filler {
      type: "gaussian"
      std: 0.0010000000475
    }
    bias_filler {
      type: "constant"
      value: 0.0
    }
  }
}
layer {
  name: "relu2"
  type: "ReLU"
  bottom: "conv2"
  top: "conv2"
}
layer {
  name: "upsample"
  type: "Deconvolution"
  bottom: "conv2"
  top: "upsample"
  param {
    lr_mult: 1.0
  }
  convolution_param {
    num_output: 1
    pad: 0
    kernel_size: 16
    stride: 16
    bias_filler {
      type: "constant"
      value: 128.0
    }
  }
}

用于测试的代码片段。
Caffe::set_mode(Caffe::GPU);

boost::shared_ptr<caffe::Net<float> > net_;
net_.reset(new Net<float>("test.prototxt", caffe::TEST));

net_->CopyTrainedLayersFrom("snapshot_iter_50000.caffemodel");

cv::Mat matInput = cv::imread("input image path");

matInput.convertTo(matInput, CV_32F);
int height = matInput.rows;
int width = matInput.cols;

Blob<float>* input_layer = net_->input_blobs()[0];
float* input_data = input_layer->mutable_cpu_data();
int layer_index = height * width;
for (size_t i = 0; i < height; i++)
{
    for (size_t j = 0; j < width; j++)
    {
        input_data[i*width + j] = matInput.at<float>(i, j);
    }

}

net_->Forward();

const shared_ptr<Blob<float> >& concat_blob = net_->blob_by_name("upsample");
const float* concat_out = concat_blob->cpu_data();

cv::Mat matout(height, width, CV_8UC1);
for (size_t i = 0; i < height*width; i++)
{
    matout.data[i] = concat_out[i];
}

cv::imwrite(output_str, matout);
1个回答

1

我理解了问题。网络输出是正确的,但错误在于转储它。该网络在浮点数形式(即在上采样层)输出,并且不是规范化形式。下面的修改将提供正确的输出。

const shared_ptr<Blob<float> >& concat_blob = net_->blob_by_name("upsample");
const float* concat_out = concat_blob->cpu_data();

cv::Mat matout(height, width, CV_32FC1);
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
         matout.at<float>(i, j) = (float)(concat_out[i*width + j]);
    }
}
cv::normalize(matout, matout, 0, 255, CV_MINMAX);
cv::imwrite("output image path", matout);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接