1
我正在CNN工作,最後一層應該是一個交叉熵層,我在這裏比較兩幅圖像。我被強制使用Caffe。我檢查了圖層目錄。沒有交叉熵層,只有Sigmoid交叉熵。我問我的主管誰說使用不會。我如何去了解Caffe中的交叉熵層?
所以這是我的問題。香草跨熵隱藏在什麼地方?
我正在CNN工作,最後一層應該是一個交叉熵層,我在這裏比較兩幅圖像。我被強制使用Caffe。我檢查了圖層目錄。沒有交叉熵層,只有Sigmoid交叉熵。我問我的主管誰說使用不會。我如何去了解Caffe中的交叉熵層?
所以這是我的問題。香草跨熵隱藏在什麼地方?
不,到目前爲止,沒有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;
}
}
}
}
謝謝。我還讀到SoftmaxWithLoss實際上是softmax + MultinomialLogisticLossLayer。有沒有辦法使用SoftmaxWithLoss來做softmax + CE? –
@AlperenAYDIN是的,SoftmaxWithLoss是softmax + MultinomialLogisticLoss,所以softmax + CE的解決方案是修改SoftmaxWithLossLayer的MultinomialLogisticLoss計算部分。 – Dale
非常感謝。你一直在幫助很大。現在有如何修改MultinomialLogisticLoss –