@@ -66,114 +66,100 @@ def partial_fit(self, train_main, train_appliances, **load_kwargs):
66
66
67
67
print ("{}: Finished training" .format (self .MODEL_NAME ))
68
68
69
- def disaggregate_thread (self , test_mains ,index ,d ):
70
- means_vector = self .means_vector
71
- pi_s_vector = self .pi_s_vector
72
- means_vector = self .means_vector
73
- transmat_vector = self .transmat_vector
74
-
75
- sigma = 100 * np .ones ((len (test_mains ),1 ))
76
- flag = 0
77
-
78
- for epoch in range (6 ):
79
- # The alernative minimization
80
- if epoch % 2 == 1 :
81
- usage = np .zeros ((len (test_mains )))
82
- for appliance_id in range (self .num_appliances ):
83
- app_usage = np .sum (s_ [appliance_id ]@means_vector [appliance_id ],axis = 1 )
84
- usage += app_usage
85
- sigma = (test_mains .flatten () - usage .flatten ()).reshape ((- 1 ,1 ))
86
- sigma = np .where (sigma < 1 ,1 ,sigma )
69
+ def setup_cvx_constraints (self , n_samples , n_appliances ):
70
+ cvx_state_vectors = [
71
+ cvx .Variable (
72
+ shape = ( n_samples , self .default_num_states ),
73
+ name = "state_vec-{}" .format (i )
74
+ )
75
+ for i in range (n_appliances )
76
+ ]
77
+ constraints = []
78
+ for stv in cvx_state_vectors :
79
+ # State vector values are ranged.
80
+ constraints += [ stv >= 0 , stv <= 1 ]
81
+ # Sum of states equals 1.
82
+ for t in range (n_samples ):
83
+ constraints .append (cvx .sum (stv [t ]) == 1 )
84
+ # Create variable matrices for each appliance, for each sample.
85
+ cvx_variable_matrices = [
86
+ [
87
+ cvx .Variable (
88
+ shape = ( self .default_num_states , self .default_num_states ),
89
+ name = "variable_matrix-{}-{}" .format (i , t )
90
+ )
91
+ for t in range (n_samples )
92
+ ]
93
+ for i in range (n_appliances )
94
+ ]
95
+ for i , appli_varmats in enumerate (cvx_variable_matrices ):
96
+ for t , varmat in enumerate (appli_varmats ):
97
+ # Assign range constraints to variable matrices.
98
+ constraints += [ varmat >= 0 , varmat <= 1 ]
99
+ # Assign equality constraints with state vectors.
100
+ constraints += [
101
+ cvx .sum (varmat [l ]) == cvx_state_vectors [i ][t - 1 ][l ]
102
+ for l in range (self .default_num_states )
103
+ ]
104
+ constraints += [
105
+ cvx .sum ((varmat .T )[l ]) == cvx_state_vectors [i ][t ][l ]
106
+ for l in range (self .default_num_states )
107
+ ]
108
+
109
+ return cvx_state_vectors , constraints , cvx_variable_matrices
110
+
111
+ def disaggregate_thread (self , test_mains ):
112
+ n_epochs = 6 # don't put in __init__, those are inference epochs!
113
+ n_samples = len (test_mains )
114
+ sigma = 100 * np .ones (( n_samples , 1 ))
115
+ cvx_state_vectors , constraints , cvx_varmats = self .setup_cvx_constraints (
116
+ n_samples , len (self .means_vector ))
117
+ # Preparing first terms of the objective function.
118
+ term_1 = 0
119
+ term_2 = 0
120
+ total_appli_energy = np .zeros_like (test_mains )
121
+ for i , (appli_name , means ) in enumerate (self .means_vector .items ()):
122
+ total_appli_energy += cvx_state_vectors [i ]@means
123
+ appli_varmats = cvx_varmats [i ]
124
+ transmat = self .transmat_vector [appli_name ]
125
+ for varmat in appli_varmats :
126
+ term_1 -= cvx .sum (cvx .multiply (varmat , np .log (transmat )))
127
+
128
+ first_hot_state = cvx_state_vectors [i ][0 ]
129
+ transition_p = self .pi_s_vector [appli_name ]
130
+ term_2 -= cvx .sum (cvx .multiply (first_hot_state , np .log (transition_p )))
131
+
132
+ for epoch in range (n_epochs ):
133
+ if epoch % 2 :
134
+ # Alernative minimization on odd epochs.
135
+ usage = np .zeros (( n_samples , ))
136
+ for i , (appli_name , means ) in enumerate (self .means_vector .items ()):
137
+ usage += np .sum (s_ [i ]@means , axis = 1 )
138
+ sigma = (test_mains .flatten () - usage .flatten ()).reshape (( - 1 , 1 ))
139
+ sigma = np .where (sigma < 1 , 1 , sigma )
87
140
else :
88
- if flag == 0 :
89
- constraints = []
90
- cvx_state_vectors = []
91
- cvx_variable_matrices = []
92
- delta = cvx .Variable (shape = (len (test_mains ),1 ), name = 'delta_t' )
93
- for appliance_id in range (self .num_appliances ):
94
- state_vector = cvx .Variable (
95
- shape = (len (test_mains ), self .default_num_states ),
96
- name = 'state_vec-%s' % (appliance_id )
97
- )
98
- cvx_state_vectors .append (state_vector )
99
- # Enforcing that their values are ranged
100
- constraints += [cvx_state_vectors [appliance_id ]>= 0 ]
101
- constraints += [cvx_state_vectors [appliance_id ]<= 1 ]
102
- # Enforcing that sum of states equals 1
103
- for t in range (len (test_mains )): # 6c
104
- constraints += [cvx .sum (cvx_state_vectors [appliance_id ][t ])== 1 ]
105
- # Creating Variable matrices for every appliance
106
- appliance_variable_matrix = []
107
- for t in range (len (test_mains )):
108
- matrix = cvx .Variable (
109
- shape = (self .default_num_states , self .default_num_states ),
110
- name = 'variable_matrix-%s-%d' % (appliance_id ,t )
111
- )
112
- appliance_variable_matrix .append (matrix )
113
- cvx_variable_matrices .append (appliance_variable_matrix )
114
- # Enforcing that their values are ranged
115
- for t in range (len (test_mains )):
116
- constraints += [cvx_variable_matrices [appliance_id ][t ]>= 0 ]
117
- constraints += [cvx_variable_matrices [appliance_id ][t ]<= 1 ]
118
- # Constraint 6e
119
- for t in range (0 ,len (test_mains )): # 6e
120
- for i in range (self .default_num_states ):
121
- constraints += [cvx .sum (((cvx_variable_matrices [appliance_id ][t ]).T )[i ]) == cvx_state_vectors [appliance_id ][t ][i ]]
122
- # Constraint 6d
123
- for t in range (1 ,len (test_mains )): # 6d
124
- for i in range (self .default_num_states ):
125
- constraints += [
126
- cvx .sum (cvx_variable_matrices [appliance_id ][t ][i ]) == cvx_state_vectors [appliance_id ][t - 1 ][i ]
127
- ]
128
-
129
- total_observed_reading = np .zeros ((test_mains .shape ))
130
- # Total observed reading equals the sum of each appliance
131
- for appliance_id in range (self .num_appliances ):
132
- total_observed_reading += cvx_state_vectors [appliance_id ]@means_vector [appliance_id ]
133
-
134
- # Loss function to be minimized
135
- term_1 = 0
136
- term_2 = 0
137
- for appliance_id in range (self .num_appliances ):
138
- # First loop is over appliances
139
- variable_matrix = cvx_variable_matrices [appliance_id ]
140
- transmat = transmat_vector [appliance_id ]
141
- # Next loop is over different time-stamps
142
- for matrix in variable_matrix :
143
- term_1 -= cvx .sum (cvx .multiply (matrix ,np .log (transmat )))
144
- one_hot_states = cvx_state_vectors [appliance_id ]
145
- pi = pi_s_vector [appliance_id ]
146
- # The expression involving start states
147
- first_one_hot_states = one_hot_states [0 ]
148
- term_2 -= cvx .sum (cvx .multiply (first_one_hot_states ,np .log (pi )))
149
- flag = 1
150
-
151
- expression = 0
141
+ # Primary minimization on even epochs.
152
142
term_3 = 0
153
143
term_4 = 0
144
+ for t in range (n_samples ):
145
+ term_3 += .5 * (np .log (sigma [t ]** 2 ))
146
+ term_4 += .5 * ((test_mains [t ][0 ] - total_appli_energy [t ][0 ])** 2 / (sigma [t ]** 2 ))
154
147
155
- for t in range (len (test_mains )):
156
- term_4 += .5 * ((test_mains [t ][0 ] - total_observed_reading [t ][0 ])** 2 / (sigma [t ]** 2 ))
157
- term_3 += .5 * (np .log (sigma [t ]** 2 ))
158
-
159
- expression = term_1 + term_2 + term_3 + term_4
160
- expression = cvx .Minimize (expression )
161
- prob = cvx .Problem (expression , constraints ,)
162
- prob .solve (solver = cvx .SCS ,verbose = False ,warm_start = True )
148
+ objective = cvx .Minimize (term_1 + term_2 + term_3 + term_4 )
149
+ prob = cvx .Problem (objective , constraints )
150
+ prob .solve (solver = cvx .SCS , verbose = False , warm_start = True )
163
151
s_ = [
164
- np .zeros ((len ( test_mains ) , self .default_num_states )) if i .value is None
152
+ np .zeros ((n_samples , self .default_num_states )) if i .value is None
165
153
else i .value
166
154
for i in cvx_state_vectors
167
155
]
168
156
169
157
prediction_dict = {}
170
- for appliance_id in range (self .num_appliances ):
171
- app_name = self .appliances [appliance_id ]
172
- app_usage = np .sum (s_ [appliance_id ]@means_vector [appliance_id ],axis = 1 )
173
- prediction_dict [app_name ] = app_usage .flatten ()
158
+ for i , (appli_name , means ) in enumerate (self .means_vector .items ()):
159
+ app_usage = np .sum (s_ [i ]@means , axis = 1 )
160
+ prediction_dict [appli_name ] = app_usage .flatten ()
174
161
175
- # Store the result in the index corresponding to the thread.
176
- d [index ] = pd .DataFrame (prediction_dict ,dtype = 'float32' )
162
+ return pd .DataFrame (prediction_dict , dtype = "float32" )
177
163
178
164
@nilmtk .docinherit .doc_inherit
179
165
def disaggregate_chunk (self , test_mains ):
0 commit comments