Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Output accuracies per class. #2935

Merged
merged 1 commit into from
Aug 22, 2015
Merged

Output accuracies per class. #2935

merged 1 commit into from
Aug 22, 2015

Conversation

rmanor
Copy link
Contributor

@rmanor rmanor commented Aug 15, 2015

No description provided.

@@ -82,6 +90,11 @@ void AccuracyLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,

// LOG(INFO) << "Accuracy: " << accuracy;
top[0]->mutable_cpu_data()[0] = accuracy / count;
if (top.size() > 1) {
for (int i = 0; i < dim; ++i) {
top[1]->mutable_cpu_data()[i] = accuracies[i] / nums[i];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if you get 0/0 here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed.

@ronghanghu
Copy link
Member

You also need to address ignore_label https://github.com/BVLC/caffe/blob/master/src/caffe/proto/caffe.proto#L413-L414 and skip them in per-class accuracy.

int count = 0;
for (int i = 0; i < outer_num_; ++i) {
for (int j = 0; j < inner_num_; ++j) {
const int label_value =
static_cast<int>(bottom_label[i * inner_num_ + j]);
++nums[label_value];
if (has_ignore_label_ && label_value == ignore_label_) {
continue;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move ++nums[label_value]; (3 lines above) after this line.

@bhack
Copy link
Contributor

bhack commented Aug 15, 2015

@ronghanghu I've not read read this already but has it some overlap point with #759?

@ronghanghu
Copy link
Member

@bhack No. This PR is incremental enhancement while #759 involves extending the label format, which may involve many other things (e.g. extending loss layers to support them?) to be taken into consideration.

@bhack
Copy link
Contributor

bhack commented Aug 15, 2015

@ronghanghu Ok.. Thank you. So I leave it opened if somebody could be still interested.

@ronghanghu ronghanghu added the RH label Aug 17, 2015
@@ -38,6 +38,10 @@ void AccuracyLayer<Dtype>::Reshape(
<< "with integer values in {0, 1, ..., C-1}.";
vector<int> top_shape(0); // Accuracy is a scalar; 0 axes.
top[0]->Reshape(top_shape);
if (top.size() > 1) {
int dim = bottom[0]->count() / bottom[0]->num();
top[1]->Reshape(dim, 1, 1, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A note: in order to better align with ND-Array blob and to be compatible with accuracy axis, please change these two lines into

vector<int> top_shape_per_cls(1); // Per-class accuracy is a vector; 1 axes.
top_shape_per_cls[0] = bottom[0]->shape(label_axis_);
top[1]->Reshape(top_shape_per_cls);

And also reshape your buffer blob after here to have top_shape_per_cls. Thanks :)

@rmanor
Copy link
Contributor Author

rmanor commented Aug 22, 2015

Fixed comments, thanks.

@ronghanghu
Copy link
Member

Please run make lint and fix lint errors.

@rmanor
Copy link
Contributor Author

rmanor commented Aug 22, 2015

Fixed.

On Sat, Aug 22, 2015 at 11:32 PM Ronghang Hu notifications@github.com
wrote:

Please run make lint and fix lint errors.


Reply to this email directly or view it on GitHub
#2935 (comment).

: top[1]->cpu_data()[i] / nums_buffer_.cpu_data()[i];
++output_label;
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean here, but it seems confusing to shift label index in top[1] due to ignore_label.

Better to keep original index in top[1] and simply do

if (top.size() > 1) {
  int top_count = top[1]->count();
  for (int i = 0; i < top_count; ++i) {
    top[1]->mutable_cpu_data()[i] =
        nums_buffer_.cpu_data()[i] == 0 ? 0
        : top[1]->cpu_data()[i] / nums_buffer_.cpu_data()[i];
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks.

@ronghanghu
Copy link
Member

Looks good to me now. Please squash into one single commit :)

Fixed case where number of samples in class can be zero.

- Fixed ignore_label case, also added a test.
- Two other fixes.

Fixed lint errors.

Small fix.
@rmanor
Copy link
Contributor Author

rmanor commented Aug 22, 2015

Squashed :)

ronghanghu added a commit that referenced this pull request Aug 22, 2015
Output accuracies per class.
@ronghanghu ronghanghu merged commit 0dfc5da into BVLC:master Aug 22, 2015
ronghanghu added a commit to ronghanghu/caffe that referenced this pull request Sep 4, 2015
Fix AccuracyLayerTest for per-class accuracy. Previously in BVLC#2935, it crashes since the test accuracy is nan (0/0) when a class never appear.
wangyida pushed a commit to wangyida/caffe that referenced this pull request Sep 14, 2015
Fix AccuracyLayerTest for per-class accuracy. Previously in BVLC#2935, it crashes since the test accuracy is nan (0/0) when a class never appear.
wangyida pushed a commit to wangyida/caffe that referenced this pull request Sep 15, 2015
Fix AccuracyLayerTest for per-class accuracy. Previously in BVLC#2935, it crashes since the test accuracy is nan (0/0) when a class never appear.
wangyida pushed a commit to wangyida/caffe that referenced this pull request Sep 15, 2015
Fix AccuracyLayerTest for per-class accuracy. Previously in BVLC#2935, it crashes since the test accuracy is nan (0/0) when a class never appear.
aidangomez pushed a commit to aidangomez/caffe that referenced this pull request Sep 15, 2015
Fix AccuracyLayerTest for per-class accuracy. Previously in BVLC#2935, it crashes since the test accuracy is nan (0/0) when a class never appear.
wangyida pushed a commit to wangyida/caffe that referenced this pull request Sep 16, 2015
Fix AccuracyLayerTest for per-class accuracy. Previously in BVLC#2935, it crashes since the test accuracy is nan (0/0) when a class never appear.
wangyida pushed a commit to wangyida/caffe that referenced this pull request Sep 22, 2015
Fix AccuracyLayerTest for per-class accuracy. Previously in BVLC#2935, it crashes since the test accuracy is nan (0/0) when a class never appear.
@chensiqin
Copy link

@rmanor Hi, rmanor! Now I use your code to output the accuracy per class. My train_val.prototxt is:

layer {
name: "accuracy"
type: "Accuracy"
bottom: "loss3_animal/classifier"
bottom: "label"
top: "accuracy"
top: "class"
include {
phase: TEST
}
}

and I use the ImageData layer:

layer {
name: "data"
type: "ImageData"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
mirror: true
crop_size: 224
mean_file: "animal_mean.binaryproto"
}
image_data_param {
source: "/str/users/chensq/experiments/network/caffe/data/39/val_animal_0-37.txt"
batch_size: 50
shuffle: true
new_height: 256
new_width: 256
}
}

I am doing 38 animal classes classification problem. In my log file, I find something strange:
I1128 15:04:30.611277 5720 solver.cpp:415] Test net output #0: accuracy = 0.842105
I1128 15:04:30.611333 5720 solver.cpp:415] Test net output #1: class = 0.723684
I1128 15:04:30.611343 5720 solver.cpp:415] Test net output #2: class = 0.559649
I1128 15:04:30.611358 5720 solver.cpp:415] Test net output #3: class = 0.482456
I1128 15:04:30.611367 5720 solver.cpp:415] Test net output #4: class = 0.616228
I1128 15:04:30.611374 5720 solver.cpp:415] Test net output #5: class = 0.679825
I1128 15:04:30.611382 5720 solver.cpp:415] Test net output #6: class = 0.744737
I1128 15:04:30.611389 5720 solver.cpp:415] Test net output #7: class = 0.708333
I1128 15:04:30.611397 5720 solver.cpp:415] Test net output #8: class = 0.629386
I1128 15:04:30.611405 5720 solver.cpp:415] Test net output #9: class = 0.815789
I1128 15:04:30.611418 5720 solver.cpp:415] Test net output #10: class = 0.688597
I1128 15:04:30.611428 5720 solver.cpp:415] Test net output #11: class = 0.330702
I1128 15:04:30.611436 5720 solver.cpp:415] Test net output #12: class = 0.564912
I1128 15:04:30.611445 5720 solver.cpp:415] Test net output #13: class = 0.679825
I1128 15:04:30.611454 5720 solver.cpp:415] Test net output #14: class = 0.379386
I1128 15:04:30.611462 5720 solver.cpp:415] Test net output #15: class = 0.491228
I1128 15:04:30.611471 5720 solver.cpp:415] Test net output #16: class = 0.673684
I1128 15:04:30.611480 5720 solver.cpp:415] Test net output #17: class = 0.701754
I1128 15:04:30.611490 5720 solver.cpp:415] Test net output #18: class = 0.600877
I1128 15:04:30.611497 5720 solver.cpp:415] Test net output #19: class = 0.561404
I1128 15:04:30.611506 5720 solver.cpp:415] Test net output #20: class = 0.701754
I1128 15:04:30.611515 5720 solver.cpp:415] Test net output #21: class = 0.469298
I1128 15:04:30.611522 5720 solver.cpp:415] Test net output #22: class = 0.627193
I1128 15:04:30.611531 5720 solver.cpp:415] Test net output #23: class = 0.665789
I1128 15:04:30.611538 5720 solver.cpp:415] Test net output #24: class = 0.618421
I1128 15:04:30.611546 5720 solver.cpp:415] Test net output #25: class = 0.583333
I1128 15:04:30.611554 5720 solver.cpp:415] Test net output #26: class = 0.574561
I1128 15:04:30.611562 5720 solver.cpp:415] Test net output #27: class = 0.542982
I1128 15:04:30.611570 5720 solver.cpp:415] Test net output #28: class = 0.569298
I1128 15:04:30.611578 5720 solver.cpp:415] Test net output #29: class = 0.58114
I1128 15:04:30.611588 5720 solver.cpp:415] Test net output #30: class = 0.705263
I1128 15:04:30.611595 5720 solver.cpp:415] Test net output #31: class = 0.649123
I1128 15:04:30.611603 5720 solver.cpp:415] Test net output #32: class = 0.434211
I1128 15:04:30.611611 5720 solver.cpp:415] Test net output #33: class = 0.736842
I1128 15:04:30.611619 5720 solver.cpp:415] Test net output #34: class = 0.701754
I1128 15:04:30.611627 5720 solver.cpp:415] Test net output #35: class = 0.682018
I1128 15:04:30.611635 5720 solver.cpp:415] Test net output #36: class = 0.605263
I1128 15:04:30.611644 5720 solver.cpp:415] Test net output #37: class = 0.684211
I1128 15:04:30.611651 5720 solver.cpp:415] Test net output #38: class = 0.710526
I1128 15:04:30.611663 5720 solver.cpp:415] Test net output #39: loss = 0.811343 (* 1 = 0.811343 loss)

The all per-class accuracy(Test net output #(1-38)) is smaller than the accuracy in the all 38 classes test data(Test net output #0: accuracy). I wonder whether there is something wrong.

@rmanor
Copy link
Contributor Author

rmanor commented Nov 28, 2015

@chensiqin remember that the final accuracy also depends on how many samples you have from each class, e.g. a class can have zero accuracy, but if it has very little samples then it won't affect much the total accuracy.

@chensiqin
Copy link

@rmanor Sorry to bother you again. My test data has 38 classes, each class has 50 test samples. Look at my log file output, all per-class accuracy is smaller than the final total accuracy, so I am wonder how can the final total accuracy is so high and it should be at least one class accuracy is higher than the final total accuracy.

@volgy
Copy link

volgy commented Feb 11, 2016

@chensiqin I guess the discrepancy comes from the behavior of the class-specific accuracy calculation, when there are zero test samples belonging to the particular class in the current batch. In that case, the class-accuracy is explicitly set to zero. Since the reported test accuracy values are averaged across the batches (test_iter), these (somewhat arbitrary) zero values skew the final results. Very misleading, indeed.

@laotao
Copy link

laotao commented Mar 29, 2016

How to use this feature in prototxt/python code?

@tsungjenh
Copy link

Does anyone know how to use this PR? what should i do after i pull this PR???please help!!

acmiyaguchi pushed a commit to acmiyaguchi/caffe that referenced this pull request Nov 13, 2017
Fix AccuracyLayerTest for per-class accuracy. Previously in BVLC#2935, it crashes since the test accuracy is nan (0/0) when a class never appear.
@wlf52520
Copy link

Hi,i wonder to know which caffe version you used for Output accuracies per class? I tried to change relevant codes you modified,but failed. could you provide all the caffe codes? Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants