首页 > 解决方案 > Keras 相当于 Caffe 的“cpu_data()”方法?

问题描述

例子

我试图了解用 C++ 版本的 Caffe 编写的特定代码,以便将其移植到 Python 版本的 Keras 中。

显然,Caffe 中的 layer 可以定义为如下示例:

template <typename Dtype>
void ROIPoolingLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {

其中bottom是一个接受输入的一维数组,top是一个产生输出的一维数组。

不久之后,已经使用bottom向量设置了几个参数:

template <typename Dtype>
void ROIPoolingLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  ROIPoolingParameter roi_pool_param = this->layer_param_.roi_pooling_param();
  CHECK_GT(roi_pool_param.pooled_h(), 0)
      << "pooled_h must be > 0";
  CHECK_GT(roi_pool_param.pooled_w(), 0)
      << "pooled_w must be > 0";
  pooled_height_ = roi_pool_param.pooled_h();
  pooled_width_ = roi_pool_param.pooled_w();
  spatial_scale_ = roi_pool_param.spatial_scale();
  LOG(INFO) << "Spatial scale: " << spatial_scale_;
}

template <typename Dtype>
void ROIPoolingLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  channels_ = bottom[0]->channels();
  height_ = bottom[0]->height();
  width_ = bottom[0]->width();
  top[0]->Reshape(bottom[1]->num(), channels_, pooled_height_,
      pooled_width_);
  max_idx_.Reshape(bottom[1]->num(), channels_, pooled_height_,
      pooled_width_);
}

如果我们进一步扩展代码,他们使用cpu_data方法:

template <typename Dtype>
void ROIPoolingLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  const Dtype* bottom_rois = bottom[1]->cpu_data();

参考完整代码


问题

来自 Caffe 文档:

由于我们经常对 blob 的值和梯度感兴趣,因此 Blob 存储了两个内存块,即数据和差异。前者是我们传递的正常数据,后者是网络计算的梯度。

此外,由于实际值可以存储在 CPU 和 GPU 上,因此有两种不同的访问方式:不更改值的 const 方式和更改值的 mutable 方式:

const Dtype* cpu_data() const; Dtype* mutable_cpu_data();

那么根据上面的描述,bottom_data[0].cpu_data()在最近的代码块中定义的只是一个存储在 CPU 寄存器中的数组,其中包含输入数据和关于错误的偏导数?如果是这样,我怎么能在 Keras 中复制这样的代码?它在 Keras 中是否重要(层已经被评估或只是一个空形状)?

谢谢!

标签: pythonc++kerascaffe

解决方案


bottom_data[0].cpu_data()是返回一个指向第一个输入 blob 内存的常量指针的方法。如有必要,将首先从 GPU 内存中复制数据。

您不需要在 Keras 中对这样的低级概念进行操作。

查看Keras 示例中的这段代码:

def call(self, x):
    return K.dot(x, self.kernel)

在这里,您返回输入张量和层内核之间的点积结果。

与 Caffe 不同,在 Keras 中,您(主要)定义对tensors的操作,而不是在内存数组上。运行会话时,张量将填充有关执行时间的实际数据。Keras 后端将处理执行操作所需的所有内存操作K.dot(也返回一个张量)。

此外,您可以选择用于放置张量的设备:FAQ。同样,Keras 将在后台执行所有必要的操作。


推荐阅读