void LogLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int count = bottom[0]->count(); const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); if (input_scale_ == Dtype(1) && input_shift_ == Dtype(0)) { caffe_log(count, bottom_data, top_data); } else { caffe_cpu_copy(count, bottom_data, top_data); if (input_scale_ != Dtype(1)) { caffe_scal(count, input_scale_, top_data); } if (input_shift_ != Dtype(0)) { caffe_add_scalar(count, input_shift_, top_data); } caffe_log(count, top_data, top_data); } if (base_scale_ != Dtype(1)) { caffe_scal(count, base_scale_, top_data); } }
void CRFWithLossLayer<Dtype>::Reshape( const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { CHECK_EQ(bottom.size(), 2) << "CRFWithLossLayer need both feature table and labels as inputs"; CHECK_EQ(bottom[0]->count(1, 2), feature_num_) << "The state num of input feature table doesn't match the state-feature" << "number of the CRF"; CHECK_EQ(bottom[0]->count(2), max_seq_length_) << "The input feature table must have a length of max_seq_length_ as defined in crf layer" << "for a requirement of alignment in blobs"; CHECK_EQ(bottom[1]->count(2), max_seq_length_) << "The input label sequence should be of the same length as the input feature table"; CHECK_EQ(bottom[1]->count(1, 2), 1) << "The label sequence is a one dimensional vector with each element of it referring to a class number"; // Training top: (nbest label, nbest prob); Test top: (-logProb) if (!for_training_) { CHECK_EQ(top.size(), 2) << "The Top should have two blobs: pred labels, predictive probability"; vector<int> output_seq_shape = bottom[0]->shape(); output_seq_shape[1] = nbest_; top[0]->Reshape(output_seq_shape); vector<int> output_prob_shape = bottom[0]->shape(); output_prob_shape[1] = nbest_; output_prob_shape[2] = 1; output_prob_shape[3] = 1; top[1]->Reshape(output_prob_shape); } else { vector<int> loss_shape(1); loss_shape[0] = bottom[0]->count(0,1); top[0]->Reshape(loss_shape); } // Do The Transpose operation input bottom , which is important for the RowMajor routine Dtype* ptr_buf = buf_bottom_transposed_.mutable_cpu_data(); // Table size ( each matrix size) int ts = bottom[0]->count(1); // Transpose to a buffer and make a log energy transition of each element // for following matrix multiplication of LogSumExp version for (int i = 0; i < num_; ++i) { caffe_cpu_transpose(feature_num_, max_seq_length_, bottom[0]->cpu_data() + i * ts, ptr_buf + i * ts); caffe_log(ts, buf_bottom_transposed_.cpu_data() + i * ts, ptr_buf); } }