Caffe display all kinds of accuracy (including accuracy_layer source modification)
This article mainly includes the following content:
Caffe Show all kinds of accuracy containing Accuracy_layer source code modification prototxt File mode Two directly modify the Accuracy_layercpp source Accuracy_layercpp source code Accuracy_laye Rcpp Source Code Modification
This blog is designed to teach you to train the classification network, with a number of simple operations to further show the exact rate of each category, you can further adjust the network mode based on this information : Modify the Prototxt file
Here, we need to edit the prototxt:deploy.prototxt of the test to add a top: "Class".
Layer {
name: ' Data ' type: ' Data ' top
: ' Data ' top
: ' label '
include {
phase:test
}
Transform_param {
mean_file: "/home/kb539/yh/work/behavior_recognition/lmdb/imagenet_mean.binaryproto"
Mirror:false
crop_size:224
}
data_param {
Source: "/home/kb539/yh/work/behavior_recognition/ Lmdb/test_lmdb "
batch_size:128 # Note Batch_size settings (which are related to the validation set size
)
Backend:lmdb
}
Layer {
name: "Accuracy"
type: "Accuracy"
bottom: "Fc8_score"
Bottom: "Label" Top
: " accuracy@1 "Top
: Class" # There is a top[0]/top[1 in the source code, where top[1] corresponds to the label for each category
include: {phase:test}
accuracy _param {
top_k:1
}
}
Next, using the Caffe test, the test code appears as follows:
#!/usr/bin/env sh
set-e
/home/kb539/yh/caffe-master/build/tools/caffe test--gpu=0--model=/home/kb539/yh/ Work/behavior_recognition/vgg_16/deploy.prototxt--weights=/home/kb539/yh/work/behavior_recognition/vgg_16/ Output/case_two.caffemodel--iterations=21 # iterations*batch_size>= Authentication Set Number
You can get the following results: (Note: My category is 12 classes)
Test results: I0503 15:50:23.471802 12256 caffe.cpp:325] accuracy@1 = 0.857887 I0503 15:50:23.471859 12256 caffe.cpp:325] Loss_fc8 = 0.603455 (* 1 = 0.603455 loss) I0503 15:50:23.471871 12256 caffe.cpp:325] Perclass = 0.845 I0503 15:50:23.471881 12256 caffe.cpp:325] perclass = 0.847117 I0503 15:50:23.471891 12256 caffe.cpp:325] perclass = 0 481 .786423 I0503 15:50:23.471900 12256 caffe.cpp:325] perclass = 0.782536 I0503 15:50:23.471909 12256 caffe.cpp:325] Perclass = 0.85791 I0503 15:50:23.471920 12256 caffe.cpp:325] perclass = 0.944581 I0503 15:50:23.471928 12256 caffe.cpp:325] Percl Ass = 0.891931 I0503 15:50:23.471938 12256 caffe.cpp:325] perclass = 0.926242 I0503 15:50:23.471947 12256 caffe.cpp:325] P Erclass = 0.919357 I0503 15:50:23.471956 12256 caffe.cpp:325] perclass = 0.909317 I0503 15:50:23.471966 12256 5] Perclass = 0.912399 I0503 15:50:23.471976 12256 caffe.cpp:325] Perclass = 0.704083
mode two: Directly modify Accuracy_layer.cpp source code
Accuracy_layer.cpp Source
First, we can read the source accuracy_layer.cpp: The source of the idea is to construct a top[0]/top[1] blob, where top[0] stores the accuracy of the validation set, Top[1] stores the accuracy of each category in the validation set.
#include <functional> #include <utility> #include <vector> #include "caffe/layers/accuracy_ Layer.hpp "#include" caffe/util/math_functions.hpp "namespace Caffe {Template <typename dtype> void Accuracylayer <dtype>::layersetup (const vector<blob<dtype>*>& Bottom, const vector<blob<dtype>*
>& top) {top_k_ = This->layer_param_.accuracy_param (). Top_k ();
Has_ignore_label_ = This->layer_param_.accuracy_param (). Has_ignore_label ();
if (has_ignore_label_) {ignore_label_ = This->layer_param_.accuracy_param (). Ignore_label (); } template <typename dtype> void Accuracylayer<dtype>::reshape (const VECTOR<BLOB<DTYPE>*>&A mp Bottom, const vector<blob<dtype>*>& top) {check_le (Top_k_, Bottom[0]->count ()/bottom[1]->
Count ()) << "Top_k must is less than or equal to the number of classes."; Label_axis_ = Bottom[0]->canonicalaxisindex (this->layer_param_.accuracy_param (). axis ()); outer_num_ = Bottom[0]->count (0, Label_axis_); Outer_num_ is the number of images, inner_num_ = Bottom[0]->count (Label_axis_ + 1); Inner_num_ for each image, 1 check_eq (outer_num_ * inner_num_, Bottom[1]->count ()) << "Number of labels Mu St match number of predictions; "<<" e.g., if label axis = = 1 and Prediction shape is (N, C, H, W), "<<" label count (number of
Labels) must is N*h*w, "<<" with the integer values in {0, 1, ..., C-1}. " Vector<int> top_shape (0); accuracy is a scalar; 0 axes.
The accuracy rate of the overall test set Top[0]->reshape (Top_shape);
if (Top.size () > 1) {//Per-class accuracy is a vector; 1 axes.
Vector<int> Top_shape_per_class (1);
Top_shape_per_class[0] = Bottom[0]->shape (Label_axis_); Top[1]->reshape (Top_shape_per_class); Corresponds to the accuracy of each category: 10 D nums_buffer_. Reshape (Top_shape_per_class); Total images corresponding to each category: 10 D}} template <typename Dtype> void accuracylayer<dtype>::forward_cpu (const vector<blob<dtype>*>& Bottom, const vector<blob<dtype>*>& top) {Dtype accuracy = 0; The accuracy rate is initialized to 0 const dtype* Bottom_data = Bottom[0]->cpu_data (); Input image 100 sheets, each corresponding to 10 output categories 100*10 const dtype* Bottom_label = Bottom[1]->cpu_data (); Image label, each image corresponds to a label 100*1 const int Dim = Bottom[0]->count ()/outer_num_; Dim = 10,outer_num_ = + Const int num_labels = Bottom[0]->shape (Label_axis_);
Number of categories = Vector<dtype> maxval (top_k_+1);
Vector<int> max_id (top_k_+1);
if (Top.size () > 1) {caffe_set (Nums_buffer_.count (), Dtype (0), Nums_buffer_.mutable_cpu_data ());
Caffe_set (Top[1]->count (), Dtype (0), Top[1]->mutable_cpu_data ());
int count = 0;
for (int i = 0; i < outer_num_. ++i) {for (int j = 0; j < inner_num_; ++j) {//Inner_num_ the number of categories for each image, so =1 const int label_value = static_cast<int> (bOttom_label[i * inner_num_ + j]);
if (has_ignore_label_ && label_value = = Ignore_label_) {continue; if (Top.size () > 1) ++nums_buffer_.mutable_cpu_data () [Label_value]; Record the total number of images per category Dcheck_ge (Label_value, 0); Label_value (0~9) is greater than or equal to 0 dcheck_lt (Label_value, num_labels); Label_value (0~9) is certainly less than num_labels (a)//top-k accuracy//Top_k for the top K score (forecast label) STD::VECTOR<STD::p air<
;D type, int> > bottom_data_vector; for (int k = 0; k < num_labels; ++k) {Bottom_data_vector.push_back Std::make_pair (///Record Forecast: Dim = 10;inner
_num = 1,num_labels = Ten Bottom_data[i * Dim + k * Inner_num_ + j], K));
std::p artial_sort (///Bottom_data_vector.begin by Forecast result (), bottom_data_vector.begin () + Top_k_,
Bottom_data_vector.end (), STD::GREATER<STD::p air<dtype, Int> > ()); Check if True label is in top K predictions for (int k = 0; K &Lt Top_k_; k++) {///only Top_k results if (Bottom_data_vector[k].second = = Label_value) {//If there is a label, the exact value is increased ++accuracy
; if (Top.size () > 1) ++top[1]->mutable_cpu_data () [Label_value];
corresponding to each category accuracy rate count + 1 break; }} ++count;
Total statistics}//LOG (INFO) << "accuracy:" << accuracy; Top[0]->mutable_cpu_data () [0] = Accuracy/count; Total Accuracy if (top.size () > 1) {for (int i = 0; i < Top[1]->count (); ++i) {//corresponds to the accuracy rate of each category top[1]-& Gt;mutable_cpu_data () [I] = Nums_buffer_.cpu_data () [i] = = 0?
0:top[1]->cpu_data () [i]/nums_buffer_.cpu_data () [i];
}//Accuracy layer should is used as a loss function.
} instantiate_class (Accuracylayer);
Register_layer_class (accuracy); }//Namespace Caffe
accuracy_layer.cpp Source Code modification
Next: We modify the source code: a blob that only constructs top[0], where top[0] stores the accuracy of the validation set and the accuracy of each category in the validation set.
#include <functional> #include <utility> #include <vector> #include "caffe/layers/accuracy_ Layer.hpp "#include" caffe/util/math_functions.hpp "namespace Caffe {Template <typename dtype> void Accuracylayer <dtype>::layersetup (const vector<blob<dtype>*>& Bottom, const vector<blob<dtype>*
>& top) {top_k_ = This->layer_param_.accuracy_param (). Top_k ();
Has_ignore_label_ = This->layer_param_.accuracy_param (). Has_ignore_label ();
if (has_ignore_label_) {ignore_label_ = This->layer_param_.accuracy_param (). Ignore_label (); } template <typename dtype> void Accuracylayer<dtype>::reshape (const VECTOR<BLOB<DTYPE>*>&A mp Bottom, const vector<blob<dtype>*>& top) {check_le (Top_k_, Bottom[0]->count ()/bottom[1]->
Count ()) << "Top_k must is less than or equal to the number of classes."; Label_axis_ = Bottom[0]->canonicalaxisindex (this->layer_param_.accuracy_param (). axis ()); outer_num_ = Bottom[0]->count (0, Label_axis_); Outer_num_ is the number of images, inner_num_ = Bottom[0]->count (Label_axis_ + 1); Inner_num_ for each image, 1 check_eq (outer_num_ * inner_num_, Bottom[1]->count ()) << "Number of labels Mu St match number of predictions; "<<" e.g., if label axis = = 1 and Prediction shape is (N, C, H, W), "<<" label count (number of
Labels) must is N*h*w, "<<" with the integer values in {0, 1, ..., C-1}. " int Dim = Bottom[0]->count ()/outer_num_;
Dim = Ten Top[0]->reshape (1 + Dim, 1, 1, 1); } template <typename dtype> void accuracylayer<dtype>::forward_cpu (const vector<blob<dtype>* >& Bottom, const vector<blob<dtype>*>& top) {Dtype accuracy = 0; The accuracy rate is initialized to 0 const dtype* Bottom_data = Bottom[0]->cpu_data (); Input image 100, each corresponding to 10 output categories 100*10 const dtype* Bottom_label = BOTTOM[1]->CPU_data (); Image label, each image corresponds to a label 100*1 int num = outer_num_; Total Images: Const int Dim = Bottom[0]->count ()/outer_num_;
Dim = 10,outer_num_ = Vector<dtype> maxval (top_k_+1);
Vector<int> max_id (top_k_+1); Vector<dtype> accuracies (Dim, 0); Record the accuracy rate of each category Vector<dtype> Nums (Dim, 0); Record the total number of each category image for (int i = 0; i < outer_num_ ++i) {const int label_value = static_cast<int> (Bottom_lab El[i]);
tags for each image std::vector<std::p air<dtype, int> > Bottom_data_vector; for (int k = 0; k < Dim; ++k) {Bottom_data_vector.push_back (Std::make_pair) (///Record Forecast: Dim = 10;inner_num =
1,num_labels = Bottom_data[i * Dim + K], k);
std::p artial_sort (///Bottom_data_vector.begin by Forecast result (), bottom_data_vector.begin () + Top_k_,
Bottom_data_vector.end (), STD::GREATER<STD::p air<dtype, Int> > ()); Check if True label is in top K preDictions for (int k = 0; k < top_k_; k++) {//Only look forward top_k results ++nums[label_value];
if (Bottom_data_vector[k].second = = Label_value) {//If there is a label, the exact value increases ++accuracy; ++accuracies[label_value];
corresponding to each category accuracy rate count + 1 break;
}}//LOG (INFO) << "accuracy:" << accuracy; Top[0]->mutable_cpu_data () [0] = Accuracy/num; Total accuracy for (int i = 0; i < Dim; ++i) {//corresponding to the accuracy rate of each category Top[0]->mutable_cpu_data () [i + 1] = Accuracies[i ]/nums[i];
Outputs the accuracy rate of each category}//accuracy layer should is used as a loss function.
} instantiate_class (Accuracylayer);
Register_layer_class (accuracy); }//Namespace Caffe
Finally, in the Caffe root make, you can get the following results: (Note: My category is 12 classes, get 13 output)
I0503 21:29:25.707322 14206 caffe.cpp:325] accuracy@1 = 0.857887 I0503 21:29:25.707332 14206-
caffe.cpp:325] accuracy@1 = 0.845481
I0503 21:29:25.707340 14206 caffe.cpp:325] accuracy@1 = 0.847117 I0503 21:29:25.707346
14206 caffe.cpp:325] accuracy@1 = 0.786423 I0503 21:29:25.707353 14206 caffe.cpp:325
] accuracy@1 = 0.782536
I0503 21:29:25.707361 14206 caffe.cpp:325] accuracy@1 = 0.85791 I0503 21:29:25.707370 14206-
caffe.cpp:325] accuracy@1 = 0.944581
I0503 21:29:25.707378 14206 caffe.cpp:325] accuracy@1 = 0.891931 I0503 21:29:25.707386
14206 caffe.cpp:325] accuracy@1 = 0.926242 I0503 21:29:25.707392 14206 caffe.cpp:325
] accuracy@1 = 0.919357
I0503 21:29:25.707399 14206 caffe.cpp:325] accuracy@1 = 0.909317 I0503 21:29:25.707406 14206-
caffe.cpp:325] accuracy@1 = 0.912399
I0503 21:29:25.707414 14206 caffe.cpp:325] accuracy@1 = 0.704083 I0503 21:29:25.707427
14206 caffe.cpp:325