使用 cuda 而不是 cudnn 测试 caffe 时的未知池方法

Unknown pooling method when testing caffe with cuda but not cudnn

我在 windows 中构建了 caffe 深度学习库,如下所示 link:

https://initialneil.wordpress.com/2015/07/15/caffe-vs2013-opencv-in-windows-tutorial-i/

我停用了 cuDNN,因为我的 nvidia 卡不支持它,并将目标架构更改为费米架构。

我将 caffe 构建为静态库,以便在如下所示的测试项目中使用它:

int main(int argc, char** argv)
{
// get a testing image and display
Mat img = imread(CAFFE_ROOT + "/examples/images/mnist_5.png");
cvtColor(img, img, CV_BGR2GRAY);
imshow("img", img);
waitKey(1);

// Set up Caffe
Caffe::set_mode(Caffe::GPU);
int device_id = 0;
Caffe::SetDevice(device_id);
LOG(INFO) << "Using GPU";

// Load net
Net<float> net(CAFFE_ROOT + "/examples/mnist/lenet_test-memory-1.prototxt");
string model_file = CAFFE_ROOT + "/examples/mnist/lenet_iter_10000.caffemodel";
net.CopyTrainedLayersFrom(model_file);

// set the patch for testing
vector<Mat> patches;
patches.push_back(img);

// push vector<Mat> to data layer
float loss = 0.0;
boost::shared_ptr<MemoryDataLayer<float> > memory_data_layer;
memory_data_layer = boost::static_pointer_cast<MemoryDataLayer<float>>(net.layer_by_name("data"));

vector<int> labels(patches.size());
memory_data_layer->AddMatVector(patches, labels);

// Net forward

 //ERROR IN THE LINE BELOW
const vector<Blob<float>*> & results = net.ForwardPrefilled(&loss);// HERE THE ERROR
float *output = results[1]->mutable_cpu_data();

// Display the output
for (int i = 0; i < 10; i++) {
    printf("Probability to be Number %d is %.3f\n", i, output[i]);
}
waitKey(0);
}

但是访问文件时出现错误:pooling_layer.cu 在下面描述的函数中:

template <typename Dtype>
 void PoolingLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
  vector<Blob<Dtype>*>* top) {
  const Dtype* bottom_data = bottom[0]->gpu_data();
 Dtype* top_data = (*top)[0]->mutable_gpu_data();
int count = (*top)[0]->count();
 // We'll output the mask to top[1] if it's of size >1.
 const bool use_top_mask = top->size() > 1;
 int* mask = NULL;
 Dtype* top_mask = NULL;
 switch (this->layer_param_.pooling_param().pool()) {
case PoolingParameter_PoolMethod_MAX:
   if (use_top_mask) {
  top_mask = (*top)[1]->mutable_gpu_data();
  } else {
   mask = max_idx_.mutable_gpu_data();
  }
  // NOLINT_NEXT_LINE(whitespace/operators)
  MaxPoolForward<Dtype><<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS>>>       (
    count, bottom_data, bottom[0]->num(), channels_,
    height_, width_, pooled_height_, pooled_width_, kernel_h_,
    kernel_w_, stride_h_, stride_w_, pad_h_, pad_w_, top_data,
    mask, top_mask);
break;
  case PoolingParameter_PoolMethod_AVE:
   // NOLINT_NEXT_LINE(whitespace/operators)
   AvePoolForward<Dtype><<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS>>>(
      count, bottom_data, bottom[0]->num(), channels_,
    height_, width_, pooled_height_, pooled_width_, kernel_h_,
    kernel_w_, stride_h_, stride_w_, pad_h_, pad_w_, top_data);
  break;
   case PoolingParameter_PoolMethod_STOCHASTIC:
   if (Caffe::phase() == Caffe::TRAIN) {
   // We need to create the random index as well.
   caffe_gpu_rng_uniform(count, Dtype(0), Dtype(1),
                        rand_idx_.mutable_gpu_data());
    // NOLINT_NEXT_LINE(whitespace/operators)
    StoPoolForwardTrain<Dtype><<<CAFFE_GET_BLOCKS(count),
                               CAFFE_CUDA_NUM_THREADS>>>(
      count, bottom_data, bottom[0]->num(), channels_,
      height_, width_, pooled_height_, pooled_width_, kernel_h_,
      kernel_w_, stride_h_, stride_w_,
      rand_idx_.mutable_gpu_data(), top_data);
   } else {
    // NOLINT_NEXT_LINE(whitespace/operators)
     StoPoolForwardTest<Dtype><<<CAFFE_GET_BLOCKS(count),
                              CAFFE_CUDA_NUM_THREADS>>>(
      count, bottom_data, bottom[0]->num(), channels_,
      height_, width_, pooled_height_, pooled_width_, kernel_h_,
      kernel_w_, stride_h_, stride_w_, top_data);
  }
  break;
  default:
    LOG(FATAL) << "Unknown pooling method.";
   }
   CUDA_POST_KERNEL_CHECK;
}

并得到消息"Unknown pooling method.",如下面的window所示:

我的项目正常执行情况如下图所示: 有人可以告诉我可能的解决方案吗?

默认情况下应为 max pooling 的池化层已转换为其他一些层。您可以在 pooling_layer.cu (line 163) 处添加一个断点或在该行之前添加 cout << this->layer_param_.pooling_param().pool() << endl; 以查看它使用的是哪个池化层。我猜这里不等于PoolingParameter_PoolMethod_MAX

我不确定为什么会这样,也许 prototxt 文件或 protobuf 中有一些错误。一个 残酷的技巧 line 206line 165-176 重叠,以强制使用 max pooling.