-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmultiPred3.cpp
executable file
·117 lines (98 loc) · 3.79 KB
/
multiPred3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "multi.h"
#include <omp.h>
#include <cassert>
int main(int argc, char** argv){
if( argc < 1+3 ){
cerr << "multiPred3 [testfile] [model] [num_thread]" << endl;
cerr << "\tcompute top-1,2,3,4,5 accuracy" << endl;
exit(0);
}
char* testFile = argv[1];
char* modelFile = argv[2];
int num_thread = atoi(argv[3]);
omp_set_num_threads(num_thread);
char* outFname;
bool is_binary = !isFile(modelFile);
cerr << "is_binary=" << is_binary << endl;
StaticModel* model = readModel(modelFile, is_binary);
Problem* prob = new Problem();
readData( testFile, prob, true );
cerr << "Ntest=" << prob->N << endl;
//compute accuracy
vector<SparseVec*>* data = &(prob->data);
vector<Labels>* labels = &(prob->labels);
Float** top_k_hit = new Float*[num_thread];
for(int i=0;i<num_thread;i++){
top_k_hit[i] = new Float[5];
memset(top_k_hit[i], 0.0, sizeof(Float)*5);
}
Float** prod = new Float*[num_thread];
for(int i=0;i<num_thread;i++){
prod[i] = new Float[model->K];
for(int k=0;k<model->K;k++)
prod[i][k] = -1e300;
}
vector<int>* touched_index = new vector<int>[num_thread];
double start = omp_get_wtime();
#pragma omp parallel for
for(int i=0;i<prob->N;i++){
int thd_num = omp_get_thread_num();
if( i % (prob->N/100) == 0 )
cerr << ".";
SparseVec* xi = data->at(i);
Labels* yi = &(labels->at(i));
//compute scores
for(SparseVec::iterator it=xi->begin(); it!=xi->end(); it++){
int j= it->first;
Float xij = it->second;
if( j >= model->D )
continue;
SparseVec* wj = &(model->w[j]);
for(SparseVec::iterator it2=wj->begin(); it2!=wj->end(); it2++){
int k = it2->first;
if( prod[thd_num][k] == -1e300 ){
touched_index[thd_num].push_back(k);
prod[thd_num][k] = 0.0;
}
prod[thd_num][k] += it2->second*xij;
}
}
//find k1, k2, k3, k4, k5
nth_element(touched_index[thd_num].begin(), touched_index[thd_num].begin()+5, touched_index[thd_num].end(), ScoreComp(prod[thd_num]));
int size = min( 5, (int)touched_index[thd_num].size() );
sort(touched_index[thd_num].begin(), touched_index[thd_num].begin()+size, ScoreComp(prod[thd_num]));
//compute top-1,2,3,4,5 precision
for(int t=0;t<5&&t<touched_index[thd_num].size();t++){
int k = touched_index[thd_num][t];
bool flag = false;
for (int j = 0; j < yi->size(); j++){
if( yi->at(j) >= prob->label_name_list.size() )
continue;
if (prob->label_name_list[yi->at(j)] == model->label_name_list->at(k)){
flag = true;
}
}
if (flag){
for(int j=4;j>=t;j--)
top_k_hit[thd_num][j] += 1.0;
}
}
//clear earse prod values touched index
for(vector<int>::iterator it=touched_index[thd_num].begin(); it!=touched_index[thd_num].end(); it++)
prod[thd_num][*it] = -1e300;
touched_index[thd_num].clear();
}
cerr << endl;
double end = omp_get_wtime();
Float* top_k_hit_sum = new Float[5];
for(int j=0;j<5;j++)
top_k_hit_sum[j] = 0.0;
for(int i=0;i<num_thread;i++){
for(int j=0;j<5;j++)
top_k_hit_sum[j] += top_k_hit[i][j];
}
for(int t=0;t<5;t++){
cerr << "Top " << t+1 << " Acc=" << ((Float)top_k_hit_sum[t]/(prob->N*(t+1))) << endl;
}
cerr << "pred time=" << (end-start) << " s" << endl;
}