Allow EuclideanLossLayer to ignore labels#3677
Allow EuclideanLossLayer to ignore labels#3677xternalz wants to merge 4 commits intoBVLC:masterfrom xternalz:master
Conversation
|
As I am busy looking at ignore labels in #3653 as well, I was wondering if it does not make sense to move the |
| const int label_value = static_cast<int>(label_data[i]); | ||
| if (label_value == ignore_label_) { | ||
| label_data[i] = ignore_label_; | ||
| bottom_data[i] = ignore_label_; |
There was a problem hiding this comment.
Doesn't this violate the contract of layers? Layers should not be modifying the bottom data in the forward pass.
|
I don't quite understand the point of this layer. This appears to be a |
|
I have made some changes - it doesn't modify the |
|
Sorry, but I don't think this makes sense. The entire float range is valid for both inputs to EuclideanLossLayer (it doesn't make sense to have an integer point in that range which indicates the sample is ignored), and neither input is explicitly a label or prediction -- the layer is symmetric in the inputs, and this breaks that symmetry. I'd suggest doing something like this instead, assuming you have a binary indicator vector def euclidean_loss_with_ignore(ignore, label, pred):
# ignore is a batch length vector, shape (N) -- 1 for ignore, 0 for keep
# label and prediction are tops with shape (N, ...)
not_ignore = L.Power(ignore, scale=-1, shift=1) # not_ignore = 1 - ignore
masked_label = L.Scale(label, ignore, axis=0)
masked_pred = L.Scale(pred, not_ignore, axis=0)
ignored_pred = L.Eltwise(masked_label, masked_pred)
return L.EuclideanLoss(ignored_pred, label)
Edit: come to think of it I guess this is the point of |
|
I think you also need to ignore the samples with for (int i = 0; i < outer_num_; ++i) {
for (int j = 0; j < inner_num_; j++) {
const int label_value = static_cast<int>(label[i * inner_num_ + j]);
if (has_ignore_label_ && label_value == ignore_label_) {
continue;
}
DCHECK_GE(label_value, 0);
DCHECK_LT(label_value, prob_.shape(softmax_axis_));
loss -= log(std::max(prob_data[i * dim + label_value * inner_num_ + j],
Dtype(FLT_MIN)));
++count; // NOTE the way of computing normalization count
}
} |
|
Closing as the switch to int does not make sense and a mask approach is more general. However the motivation is right, so thanks for pointing out the need for ignore with regression @xternalz.
Ideally ignoring and normalizing would be handled once and in general in the base class, but right now the subclasses are doing it separately (and in some cases differently). |
Typecast the labels to
inttype and ignore the labels if they are equal toignore_label_.