caffe中如何实现rnn的结构

rnn结构的特点是,上一次的forward的输出会作为这次forward的输入,这种反馈结构在目前的layer设计要体现,同时rnn也存在很多变种,内部结构多种多样,比如GRU LSTM

如何在保证反馈结构的同时,容许更加容易的实现内部结构?

caffe中使用net去代替了layer,因为net内部又能用layer表述更加细致的结构变化,在net层面上实现反馈的输入即可,因此源码设计上,RecurrentLayer是个虚类,

LSTM是个子类,在RecurrentLayer中

  /// @brief A Net to implement the Recurrent functionality.
  shared_ptr<Net<Dtype> > unrolled_net_;

同时为了反馈计算,定义了:

  vector<Blob<Dtype>* > recur_input_blobs_;
  vector<Blob<Dtype>* > recur_output_blobs_;

在forword之前:

      const Dtype* timestep_T_data = recur_output_blobs_[i]->cpu_data();
      Dtype* timestep_0_data = recur_input_blobs_[i]->mutable_cpu_data();
      caffe_copy(count, timestep_T_data, timestep_0_data);

将net top的数据拷贝到net bottom上来,也就是output到input的反馈

然后再前向计算:

unrolled_net_->ForwardTo(last_layer_index_);


在RecurrentLayer<Dtype>::LayerSetUp中,指定了

  T_ = bottom[0]->shape(0);
  N_ = bottom[0]->shape(1);

T_表示序列的长度 N_表示通道的数量。


LSTM都是2个输入吗?

从代码来看,必须是

  CHECK_EQ(bottom[1]->num_axes(), 2)
      << "bottom[1] must have exactly 2 axes -- (#timesteps, #streams)";
  CHECK_EQ(T_, bottom[1]->shape(0));
  CHECK_EQ(N_, bottom[1]->shape(1));


在每一次前向计算,都会传递

template <typename Dtype>
void RecurrentLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  CHECK_EQ(top.size(), output_blobs_.size());
  for (int i = 0; i < top.size(); ++i) {
    top[i]->ReshapeLike(*output_blobs_[i]);
    output_blobs_[i]->ShareData(*top[i]);
    output_blobs_[i]->ShareDiff(*top[i]);
  }
  x_input_blob_->ShareData(*bottom[0]);
  x_input_blob_->ShareDiff(*bottom[0]);
  cont_input_blob_->ShareData(*bottom[1]);
  if (static_input_) {
    x_static_input_blob_->ShareData(*bottom[2]);
    x_static_input_blob_->ShareDiff(*bottom[2]);
  }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值