@@ -25,7 +25,7 @@ def __init__(self, meta_info,
25
25
lr_bp = 0.001 ,
26
26
l1_proj = 0.001 ,
27
27
l1_subnet = 0.001 ,
28
- smooth_lambda = 0.00001 ,
28
+ l2_smooth = 0.00001 ,
29
29
batch_size = 1000 ,
30
30
training_epochs = 2000 ,
31
31
tuning_epochs = 500 ,
@@ -38,7 +38,6 @@ def __init__(self, meta_info,
38
38
super (BaseNet , self ).__init__ ()
39
39
40
40
# Parameter initiation
41
- self .meta_info = meta_info
42
41
self .subnet_num = subnet_num
43
42
self .subnet_arch = subnet_arch
44
43
self .task_type = task_type
@@ -49,7 +48,7 @@ def __init__(self, meta_info,
49
48
self .lr_bp = lr_bp
50
49
self .l1_proj = l1_proj
51
50
self .l1_subnet = l1_subnet
52
- self .smooth_lambda = smooth_lambda
51
+ self .l2_smooth = l2_smooth
53
52
self .batch_size = batch_size
54
53
self .beta_threshold = beta_threshold
55
54
self .tuning_epochs = tuning_epochs
@@ -63,43 +62,52 @@ def __init__(self, meta_info,
63
62
np .random .seed (random_state )
64
63
tf .random .set_seed (random_state )
65
64
66
- self .categ_variable_num = 0
67
- self .numerical_input_num = 0
68
- self .categ_variable_list = []
69
- self .categ_index_list = []
70
- self .noncateg_index_list = []
71
- self .noncateg_variable_list = []
72
- self .variables_names = list (self .meta_info .keys ())
73
- for i , (key , item ) in enumerate (self .meta_info .items ()):
74
- if item ['type' ] == "target" :
65
+ self .dummy_values_ = {}
66
+ self .nfeature_scaler_ = {}
67
+ self .cfeature_num_ = 0
68
+ self .nfeature_num_ = 0
69
+ self .cfeature_list_ = []
70
+ self .nfeature_list_ = []
71
+ self .cfeature_index_list_ = []
72
+ self .nfeature_index_list_ = []
73
+
74
+ self .feature_list_ = []
75
+ self .feature_type_list_ = []
76
+ for idx , (feature_name , feature_info ) in enumerate (meta_info .items ()):
77
+ if feature_info ["type" ] == "target" :
75
78
continue
76
- if item ['type' ] == "categorical" :
77
- self .categ_variable_num += 1
78
- self .categ_variable_list .append (key )
79
- self .categ_index_list .append (i )
79
+ if feature_info ["type" ] == "categorical" :
80
+ self .cfeature_num_ += 1
81
+ self .cfeature_list_ .append (feature_name )
82
+ self .cfeature_index_list_ .append (idx )
83
+ self .feature_type_list_ .append ("categorical" )
84
+ self .dummy_values_ .update ({feature_name :meta_info [feature_name ]["values" ]})
80
85
else :
81
- self .numerical_input_num += 1
82
- self .noncateg_index_list .append (i )
83
- self .noncateg_variable_list .append (key )
86
+ self .nfeature_num_ += 1
87
+ self .nfeature_list_ .append (feature_name )
88
+ self .nfeature_index_list_ .append (idx )
89
+ self .feature_type_list_ .append ("continuous" )
90
+ self .nfeature_scaler_ .update ({feature_name :meta_info [feature_name ]["scaler" ]})
91
+ self .feature_list_ .append (feature_name )
84
92
85
- self .subnet_num = min (self .subnet_num , self .numerical_input_num )
86
93
# build
87
- self .proj_layer = ProjectLayer (index_list = list (self .noncateg_index_list ),
88
- subnet_num = self .subnet_num ,
89
- l1_proj = self .l1_proj ,
90
- method = self .proj_method )
94
+ self .subnet_num = min (self .subnet_num , self .nfeature_num_ )
95
+ self .proj_layer = ProjectLayer (index_list = self .nfeature_index_list_ ,
96
+ subnet_num = self .subnet_num ,
97
+ l1_proj = self .l1_proj ,
98
+ method = self .proj_method )
91
99
92
- self .categ_blocks = CategNetBlock (meta_info = self .meta_info ,
93
- categ_variable_list = self .categ_variable_list ,
94
- categ_index_list = self .categ_index_list ,
95
- bn_flag = self .bn_flag )
100
+ self .categ_blocks = CategNetBlock (feature_list = self .feature_list_ ,
101
+ cfeature_index_list = self .cfeature_index_list_ ,
102
+ dummy_values = self .dummy_values_ ,
103
+ bn_flag = self .bn_flag )
96
104
97
105
self .subnet_blocks = SubnetworkBlock (subnet_num = self .subnet_num ,
98
- subnet_arch = self .subnet_arch ,
99
- activation_func = self .activation_func ,
100
- smooth_lambda = self .smooth_lambda ,
101
- bn_flag = self .bn_flag )
102
- self .output_layer = OutputLayer (subnet_num = self .subnet_num + self .categ_variable_num , l1_subnet = self .l1_subnet )
106
+ subnet_arch = self .subnet_arch ,
107
+ activation_func = self .activation_func ,
108
+ l2_smooth = self .l2_smooth ,
109
+ bn_flag = self .bn_flag )
110
+ self .output_layer = OutputLayer (subnet_num = self .subnet_num + self .cfeature_num_ , l1_subnet = self .l1_subnet )
103
111
104
112
self .optimizer = tf .keras .optimizers .Adam (learning_rate = self .lr_bp )
105
113
if self .task_type == "Regression" :
@@ -116,9 +124,9 @@ def call(self, inputs, training=False):
116
124
self .subnet_outputs = self .subnet_blocks (self .proj_outputs , training = training )
117
125
118
126
concat_list = []
119
- if self .numerical_input_num > 0 :
127
+ if self .nfeature_num_ > 0 :
120
128
concat_list .append (self .subnet_outputs )
121
- if self .categ_variable_num > 0 :
129
+ if self .cfeature_num_ > 0 :
122
130
concat_list .append (self .categ_outputs )
123
131
124
132
if self .task_type == "Regression" :
@@ -157,7 +165,7 @@ def get_active_subnets(self, beta_threshold=0):
157
165
beta = self .output_layer .output_weights .numpy ()
158
166
else :
159
167
subnet_norm = [self .subnet_blocks .subnets [i ].moving_norm .numpy ()[0 ] for i in range (self .subnet_num )]
160
- categ_norm = [self .categ_blocks .categnets [i ].moving_norm .numpy ()[0 ]for i in range (self .categ_variable_num )]
168
+ categ_norm = [self .categ_blocks .categnets [i ].moving_norm .numpy ()[0 ]for i in range (self .cfeature_num_ )]
161
169
beta = self .output_layer .output_weights .numpy () * np .hstack ([subnet_norm , categ_norm ]).reshape ([- 1 , 1 ])
162
170
beta = beta * self .output_layer .output_switcher .numpy ()
163
171
subnets_scale = (np .abs (beta ) / np .sum (np .abs (beta ))).reshape ([- 1 ])
@@ -169,7 +177,7 @@ def get_active_subnets(self, beta_threshold=0):
169
177
for i in active_index :
170
178
if i in range (self .subnet_num ):
171
179
active_me_index .append (i )
172
- elif i in range (self .subnet_num , self .subnet_num + self .categ_variable_num ):
180
+ elif i in range (self .subnet_num , self .subnet_num + self .cfeature_num_ ):
173
181
active_categ_index .append (i )
174
182
return active_me_index , active_categ_index , beta , subnets_scale
175
183
@@ -228,7 +236,7 @@ def fit(self, train_x, train_y):
228
236
229
237
self .evaluate (tr_x , tr_y , training = True ) # update the batch normalization using all the training data
230
238
active_me_index , active_categ_index , _ , _ = self .get_active_subnets (self .beta_threshold )
231
- scal_factor = np .zeros ((self .subnet_num + self .categ_variable_num , 1 ))
239
+ scal_factor = np .zeros ((self .subnet_num + self .cfeature_num_ , 1 ))
232
240
scal_factor [active_me_index ] = 1
233
241
scal_factor [active_categ_index ] = 1
234
242
self .output_layer .output_switcher .assign (tf .constant (scal_factor , dtype = tf .float32 ))
@@ -270,8 +278,8 @@ def fit(self, train_x, train_y):
270
278
self .subnet_input_max = []
271
279
self .evaluate (tr_x , tr_y , training = True ) # update the batch normalization using all the training data
272
280
for i in range (self .subnet_num ):
273
- min_ = np .dot (train_x [:,self .noncateg_index_list ], self .proj_layer .get_weights ()[0 ])[:, i ].min ()
274
- max_ = np .dot (train_x [:,self .noncateg_index_list ], self .proj_layer .get_weights ()[0 ])[:, i ].max ()
281
+ min_ = np .dot (tr_x [:,self .noncateg_index_list ], self .proj_layer .get_weights ()[0 ])[:, i ].min ()
282
+ max_ = np .dot (tr_x [:,self .noncateg_index_list ], self .proj_layer .get_weights ()[0 ])[:, i ].max ()
275
283
self .subnet_input_min .append (min_ )
276
284
self .subnet_input_max .append (max_ )
277
285
@@ -328,21 +336,21 @@ def visualize(self, folder="./results/", name="demo", save_png=False, save_eps=F
328
336
ax1 .set_title ("Ridge Functions" , fontsize = 24 )
329
337
ax2 .set_title ("Projection Indices" , fontsize = 24 )
330
338
331
- if self .categ_variable_num > 0 :
339
+ if self .cfeature_num_ > 0 :
332
340
for indice in active_categ_index :
333
- dummy_name = self .categ_variable_list [indice - self .numerical_input_num ]
341
+ feature_name = self .cfeature_list_ [indice - self .numerical_input_num ]
334
342
dummy_gamma = self .categ_blocks .categnets [indice - self .numerical_input_num ].categ_bias .numpy ()
335
343
norm = self .categ_blocks .categnets [indice - self .numerical_input_num ].moving_norm .numpy ()
336
344
ax3 = f .add_subplot (np .int (max_ids ), 1 , np .int (max_ids ))
337
- ax3 .bar (np .arange (len (self .meta_info [ dummy_name ][ 'values' ])), np .sign (beta [indice ]) * dummy_gamma [:, 0 ] / norm )
338
- ax3 .set_xticks (np .arange (len (self .meta_info [ dummy_name ][ 'values' ])))
339
- ax3 .set_xticklabels (self .meta_info [ self . categ_variable_list [ indice - self . numerical_input_num ]][ 'values' ], fontsize = 14 )
345
+ ax3 .bar (np .arange (len (self .dummy_values_ [ feature_name ])), np .sign (beta [indice ]) * dummy_gamma [:, 0 ] / norm )
346
+ ax3 .set_xticks (np .arange (len (self .dummy_values_ [ feature_name ])))
347
+ ax3 .set_xticklabels (self .dummy_values_ [ feature_name ], fontsize = 14 )
340
348
341
349
yint = np .round (np .linspace (np .min (np .sign (beta [indice ]) * dummy_gamma [:, 0 ] / norm ),
342
350
np .max (np .sign (beta [indice ]) * dummy_gamma [:, 0 ] / norm ), 6 ), 2 )
343
351
ax3 .set_yticks (yint )
344
352
ax3 .set_yticklabels (["{0: .2f}" .format (j ) for j in yint ], fontsize = 14 )
345
- ax3 .set_title (dummy_name + " (" + str (np .round (100 * subnets_scale [indice ], 1 )) + "%)" , fontsize = 20 )
353
+ ax3 .set_title (feature_name + " (" + str (np .round (100 * subnets_scale [indice ], 1 )) + "%)" , fontsize = 20 )
346
354
347
355
if max_ids > 0 :
348
356
if save_png :
0 commit comments