2016-06-28 45 views
1

我正在CNN工作,最後一層應該是一個交叉熵層,我在這裏比較兩幅圖像。我被強制使用Caffe。我檢查了圖層目錄。沒有交叉熵層,只有Sigmoid交叉熵。我問我的主管誰說使用不會。我如何去了解Caffe中的交叉熵層?

所以這是我的問題。香草跨熵隱藏在什麼地方?

回答

1

不,到目前爲止,沒有vanilla cross-entropy咖啡。 caffe中只有一些特殊的交叉熵實例,例如SigmoidCrossEntropyLossLayer和MultinomialLogisticLossLayer。

但是,您可以通過簡單地模擬 MultinomialLogisticLosser來獲得香草交叉熵。因爲這個層計算交叉熵,假設目標概率分佈是單熱矢量的形式,所以通過修改其計算公式,通過假定目標概率分佈爲一般概率分佈,可以得到香草交叉熵。希望這會幫助你。

一部開拓創新MultinomialLogisticLossLayer在CAFFE:

template <typename Dtype> 
void MultinomialLogisticLossLayer<Dtype>::Forward_cpu(
     const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { 
    const Dtype* bottom_data = bottom[0]->cpu_data(); 
    const Dtype* bottom_label = bottom[1]->cpu_data(); 
    int num = bottom[0]->num(); 
    int dim = bottom[0]->count()/bottom[0]->num(); 
    Dtype loss = 0; 
    for (int i = 0; i < num; ++i) { 
     int label = static_cast<int>(bottom_label[i]); 
     Dtype prob = std::max(bottom_data[i * dim + label], Dtype(kLOG_THRESHOLD)); 
     loss -= log(prob); 
    } 
    top[0]->mutable_cpu_data()[0] = loss/num; 
} 

假設底部[1]包含目標/真實分佈,然後交叉EntropyLossLayer應該是這樣的現:

void CrossEntropyLossLayer<Dtype>::Forward_cpu(
     const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { 
    const Dtype* bottom_data = bottom[0]->cpu_data(); 
    const Dtype* bottom_label = bottom[1]->cpu_data(); 
    int num = bottom[0]->num(); 
    int dim = bottom[0]->count()/bottom[0]->num(); 
    Dtype loss = 0; 
    for (int i = 0; i < num; ++i) { 
     for (int j = 0; j < dim; ++j){ 
      Dtype prob = std::max(bottom_data[i * dim + j], Dtype(kLOG_THRESHOLD)); 
      loss -= bottom_label[i * dim + j] * log(prob); 
     } 
    } 
    top[0]->mutable_cpu_data()[0] = loss/num; 
} 

同樣,用於反傳的相應的backward_cpu函數將是:

template <typename Dtype> 
void CrossEntropyLossLayer<Dtype>::Backward_cpu(
const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, 
     const vector<Blob<Dtype>*>& bottom) { 
    if (propagate_down[1]) { 
     LOG(FATAL) << this->type() 
      << " Layer cannot backpropagate to label inputs."; 
    } 
    if (propagate_down[0]) { 
     const Dtype* bottom_data = bottom[0]->cpu_data(); 
     const Dtype* bottom_label = bottom[1]->cpu_data(); 
     Dtype* bottom_diff = bottom[0]->mutable_cpu_diff(); 
     int num = bottom[0]->num(); 
     int dim = bottom[0]->count()/bottom[0]->num(); 
     caffe_set(bottom[0]->count(), Dtype(0), bottom_diff); 
     const Dtype scale = -top[0]->cpu_diff()[0]/num; 
     for (int i = 0; i < num; ++i) { 
      for (int j = 0; j < dim; ++j){ 
       Dtype prob = std::max(bottom_data[i * dim + j], Dtype(kLOG_THRESHOLD)); 
       bottom_diff[i * dim + j] = scale * bottom_label[i * dim + j]/prob; 
      } 
     } 
    } 
} 
+0

謝謝。我還讀到SoftmaxWithLoss實際上是softmax + MultinomialLogisticLossLayer。有沒有辦法使用SoftmaxWithLoss來做softmax + CE? –

+0

@AlperenAYDIN是的,SoftmaxWithLoss是softmax + MultinomialLogisticLoss,所以softmax + CE的解決方案是修改SoftmaxWithLossLayer的MultinomialLogisticLoss計算部分。 – Dale

+0

非常感謝。你一直在幫助很大。現在有如何修改MultinomialLogisticLoss –