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