Skip to content

Commit d5c50e4

Browse files
committed
fixing sklearn binary classifiers
1 parent 0fbc851 commit d5c50e4

File tree

2 files changed

+95
-49
lines changed

2 files changed

+95
-49
lines changed

embml/sklearnModels/embml_sklearn_LinearSVC.py

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@ def process(self, model, opts):
77
self.coef = model.coef_.tolist()
88
self.intercept = model.intercept_.tolist()
99
self.classes = list(map(int, model.classes_.tolist()))
10+
self.input_size = len(self.coef[0])
1011

1112
if opts['useFxp']:
1213
self.coef = [[utils.toFxp(self.coef[_i][_j], opts) \
1314
for _j in range(len(self.coef[_i]))] \
1415
for _i in range(len(self.coef))]
1516
self.intercept = [utils.toFxp(_i, opts)\
1617
for _i in self.intercept]
18+
19+
if len(self.classes) == 2:
20+
self.coef = self.coef[0]
21+
self.intercept = self.intercept[0]
1722

1823
def write_output(classifier, opts):
1924
funcs = '\n'
@@ -24,47 +29,65 @@ def write_output(classifier, opts):
2429
decType = ("FixedNum" if opts['useFxp'] else "float")
2530

2631
# Classify function
27-
funcs += utils.write_func_init("int", "classify") + \
28-
utils.write_dec("int", "indMax", initValue="0", tabs=1) + \
29-
utils.write_dec(decType, "scores[NUM_CLASSES]", tabs=1)
32+
funcs += utils.write_func_init("int", "classify")
33+
34+
if len(classifier.classes) == 2:
35+
funcs += utils.write_dec(decType, "score", tabs=1)
36+
else:
37+
funcs += utils.write_dec("int", "indMax", initValue="0", tabs=1) + \
38+
utils.write_dec(decType, "scores[NUM_CLASSES]", tabs=1)
3039

3140
if opts['C']:
3241
funcs += utils.write_dec("int", "i", tabs=1) + \
3342
utils.write_dec("int", "j", tabs=1)
34-
35-
funcs += utils.write_for("i = 0", "i < NUM_CLASSES", "i++", tabs=1, inC=opts['C']) + \
36-
utils.write_attribution("scores[i]", "intercept[i]", tabs=2) + \
37-
utils.write_for("j = 0", "j < INPUT_SIZE", "j++", tabs=2, inC=opts['C']) + \
38-
utils.write_attribution("scores[i]", \
39-
("fxp_sum(scores[i], fxp_mul(coef[i][j], instance[j]))" \
40-
if opts['useFxp'] else \
41-
"(coef[i][j] * instance[j])"), \
42-
op=('' if opts['useFxp'] else '+'), tabs=3) + \
43-
utils.write_end(tabs=2) + \
44-
utils.write_if("scores[i] " + \
45-
("<" if len(classifier.classes) == 2 else ">") + \
46-
" scores[indMax]", tabs=2) + \
47-
utils.write_attribution("indMax", "i", tabs=3) + \
48-
utils.write_end(tabs=2) + \
49-
utils.write_end(tabs=1) + \
50-
utils.write_ret("classes[indMax]", tabs=1) + \
51-
utils.write_end(tabs=0)
43+
44+
if len(classifier.classes) == 2:
45+
funcs += utils.write_attribution("score", "intercept", tabs=1) + \
46+
utils.write_for("i = 0", "i < INPUT_SIZE", "i++", tabs=1, inC=opts['C']) + \
47+
utils.write_attribution("score", \
48+
("fxp_sum(score, fxp_mul(coef[i], instance[i]))" \
49+
if opts['useFxp'] else \
50+
"(coef[i] * instance[i])"), \
51+
op=('' if opts['useFxp'] else '+'), tabs=2) + \
52+
utils.write_end(tabs=1) + \
53+
utils.write_ret("classes[((score > 0) ? 1 : 0)]", tabs=1) + \
54+
utils.write_end(tabs=0)
55+
else:
56+
funcs += utils.write_for("i = 0", "i < NUM_CLASSES", "i++", tabs=1, inC=opts['C']) + \
57+
utils.write_attribution("scores[i]", "intercept[i]", tabs=2) + \
58+
utils.write_for("j = 0", "j < INPUT_SIZE", "j++", tabs=2, inC=opts['C']) + \
59+
utils.write_attribution("scores[i]", \
60+
("fxp_sum(scores[i], fxp_mul(coef[i][j], instance[j]))" \
61+
if opts['useFxp'] else \
62+
"(coef[i][j] * instance[j])"), \
63+
op=('' if opts['useFxp'] else '+'), tabs=3) + \
64+
utils.write_end(tabs=2) + \
65+
utils.write_if("scores[i] " + \
66+
("<" if len(classifier.classes) == 2 else ">") + \
67+
" scores[indMax]", tabs=2) + \
68+
utils.write_attribution("indMax", "i", tabs=3) + \
69+
utils.write_end(tabs=2) + \
70+
utils.write_end(tabs=1) + \
71+
utils.write_ret("classes[indMax]", tabs=1) + \
72+
utils.write_end(tabs=0)
5273

5374
# Declaration of global variables
5475
decls += utils.write_dec(decType, "instance[INPUT_SIZE + 1]") + '\n' + \
5576
utils.write_dec("const " + decType, \
56-
"coef[NUM_CLASSES][INPUT_SIZE]", \
77+
("coef[INPUT_SIZE]"
78+
if len(classifier.classes) == 2 else
79+
"coef[NUM_CLASSES][INPUT_SIZE]"), \
5780
initValue=utils.toStr(classifier.coef)) + '\n' + \
5881
utils.write_dec("const " + decType, \
59-
"intercept[NUM_CLASSES]", \
82+
"intercept" + ("[NUM_CLASSES]" if len(classifier.classes) != 2 else ""), \
6083
initValue=utils.toStr(classifier.intercept)) + '\n' + \
6184
utils.write_dec("const " + utils.chooseDataType(classifier.classes), \
6285
"classes[NUM_CLASSES]", \
6386
initValue=utils.toStr(classifier.classes)) + '\n'
6487

6588
# Definition of constant values
6689
defs += utils.write_define("NUM_CLASSES", str(len(classifier.classes))) + \
67-
utils.write_define("INPUT_SIZE", str(len(classifier.coef[0])))
90+
utils.write_define("INPUT_SIZE", str(classifier.input_size))
6891

6992
# Include of libraries
7093
if opts['useFxp']:

embml/sklearnModels/embml_sklearn_LogisticRegression.py

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@ def process(self, model, opts):
77
self.coef = model.coef_.tolist()
88
self.intercept = model.intercept_.tolist()
99
self.classes = list(map(int, model.classes_.tolist()))
10-
10+
self.input_size = len(self.coef[0])
11+
1112
if opts['useFxp']:
1213
self.coef = [[utils.toFxp(self.coef[_i][_j], opts) \
1314
for _j in range(len(self.coef[_i]))] \
1415
for _i in range(len(self.coef))]
1516
self.intercept = [utils.toFxp(_i, opts)\
1617
for _i in self.intercept]
18+
19+
if len(self.classes) == 2:
20+
self.coef = self.coef[0]
21+
self.intercept = self.intercept[0]
1722

1823
def write_output(classifier, opts):
1924
funcs = '\n'
@@ -24,47 +29,65 @@ def write_output(classifier, opts):
2429
decType = ("FixedNum" if opts['useFxp'] else "float")
2530

2631
# Classify function
27-
funcs += utils.write_func_init("int", "classify") + \
28-
utils.write_dec("int", "indMax", initValue="0", tabs=1) + \
29-
utils.write_dec(decType, "scores[NUM_CLASSES]", tabs=1)
32+
funcs += utils.write_func_init("int", "classify")
33+
34+
if len(classifier.classes) == 2:
35+
funcs += utils.write_dec(decType, "score", tabs=1)
36+
else:
37+
funcs += utils.write_dec("int", "indMax", initValue="0", tabs=1) + \
38+
utils.write_dec(decType, "scores[NUM_CLASSES]", tabs=1)
3039

3140
if opts['C']:
3241
funcs += utils.write_dec("int", "i", tabs=1) + \
3342
utils.write_dec("int", "j", tabs=1)
34-
35-
funcs += utils.write_for("i = 0", "i < NUM_CLASSES", "i++", tabs=1, inC=opts['C']) + \
36-
utils.write_attribution("scores[i]", "intercept[i]", tabs=2) + \
37-
utils.write_for("j = 0", "j < INPUT_SIZE", "j++", tabs=2, inC=opts['C']) + \
38-
utils.write_attribution("scores[i]", \
39-
("fxp_sum(scores[i], fxp_mul(coef[i][j], instance[j]))" \
40-
if opts['useFxp'] else \
41-
"(coef[i][j] * instance[j])"), \
42-
op=('' if opts['useFxp'] else '+'), tabs=3) + \
43-
utils.write_end(tabs=2) + \
44-
utils.write_if("scores[i] " + \
45-
("<" if len(classifier.classes) == 2 else ">") + \
46-
" scores[indMax]", tabs=2) + \
47-
utils.write_attribution("indMax", "i", tabs=3) + \
48-
utils.write_end(tabs=2) + \
49-
utils.write_end(tabs=1) + \
50-
utils.write_ret("classes[indMax]", tabs=1) + \
51-
utils.write_end(tabs=0)
43+
44+
if len(classifier.classes) == 2:
45+
funcs += utils.write_attribution("score", "intercept", tabs=1) + \
46+
utils.write_for("i = 0", "i < INPUT_SIZE", "i++", tabs=1, inC=opts['C']) + \
47+
utils.write_attribution("score", \
48+
("fxp_sum(score, fxp_mul(coef[i], instance[i]))" \
49+
if opts['useFxp'] else \
50+
"(coef[i] * instance[i])"), \
51+
op=('' if opts['useFxp'] else '+'), tabs=2) + \
52+
utils.write_end(tabs=1) + \
53+
utils.write_ret("classes[((score > 0) ? 1 : 0)]", tabs=1) + \
54+
utils.write_end(tabs=0)
55+
else:
56+
funcs += utils.write_for("i = 0", "i < NUM_CLASSES", "i++", tabs=1, inC=opts['C']) + \
57+
utils.write_attribution("scores[i]", "intercept[i]", tabs=2) + \
58+
utils.write_for("j = 0", "j < INPUT_SIZE", "j++", tabs=2, inC=opts['C']) + \
59+
utils.write_attribution("scores[i]", \
60+
("fxp_sum(scores[i], fxp_mul(coef[i][j], instance[j]))" \
61+
if opts['useFxp'] else \
62+
"(coef[i][j] * instance[j])"), \
63+
op=('' if opts['useFxp'] else '+'), tabs=3) + \
64+
utils.write_end(tabs=2) + \
65+
utils.write_if("scores[i] " + \
66+
("<" if len(classifier.classes) == 2 else ">") + \
67+
" scores[indMax]", tabs=2) + \
68+
utils.write_attribution("indMax", "i", tabs=3) + \
69+
utils.write_end(tabs=2) + \
70+
utils.write_end(tabs=1) + \
71+
utils.write_ret("classes[indMax]", tabs=1) + \
72+
utils.write_end(tabs=0)
5273

5374
# Declaration of global variables
5475
decls += utils.write_dec(decType, "instance[INPUT_SIZE + 1]") + '\n' + \
5576
utils.write_dec("const " + decType, \
56-
"coef[NUM_CLASSES][INPUT_SIZE]", \
77+
("coef[INPUT_SIZE]"
78+
if len(classifier.classes) == 2 else
79+
"coef[NUM_CLASSES][INPUT_SIZE]"), \
5780
initValue=utils.toStr(classifier.coef)) + '\n' + \
5881
utils.write_dec("const " + decType, \
59-
"intercept[NUM_CLASSES]", \
82+
"intercept" + ("[NUM_CLASSES]" if len(classifier.classes) != 2 else ""), \
6083
initValue=utils.toStr(classifier.intercept)) + '\n' + \
6184
utils.write_dec("const " + utils.chooseDataType(classifier.classes), \
6285
"classes[NUM_CLASSES]", \
6386
initValue=utils.toStr(classifier.classes)) + '\n'
6487

6588
# Definition of constant values
6689
defs += utils.write_define("NUM_CLASSES", str(len(classifier.classes))) + \
67-
utils.write_define("INPUT_SIZE", str(len(classifier.coef[0])))
90+
utils.write_define("INPUT_SIZE", str(classifier.input_size))
6891

6992
# Include of libraries
7093
if opts['useFxp']:

0 commit comments

Comments
 (0)