@@ -98,108 +98,6 @@ def advi(vars=None, start=None, model=None, n=5000, accurate_elbo=False,
98
98
w [var ] = np .exp (w [var ])
99
99
return ADVIFit (u , w , elbos )
100
100
101
- def advi_minibatch (vars = None , start = None , model = None , n = 5000 , n_mcsamples = 1 ,
102
- minibatch_RVs = None , minibatch_tensors = None , minibatches = None , total_size = None ,
103
- learning_rate = .001 , epsilon = .1 , random_seed = 20090425 , verbose = 1 ):
104
- """Run mini-batch ADVI.
105
-
106
- minibatch_RVs, minibatch_tensors and minibatches should be in the
107
- same order.
108
-
109
- Parameters
110
- ----------
111
- vars : object
112
- Random variables.
113
- start : Dict or None
114
- Initial values of parameters (variational means).
115
- model : Model
116
- Probabilistic model.
117
- n : int
118
- Number of interations updating parameters.
119
- n_mcsamples : int
120
- Number of Monte Carlo samples to approximate ELBO.
121
- minibatch_RVs : list of ObservedRVs
122
- Random variables for mini-batch.
123
- minibatch_tensors : list of tensors
124
- Tensors used to create ObservedRVs in minibatch_RVs.
125
- minibatches : list of generators
126
- Generates minibatches when calling next().
127
- totalsize : int
128
- Total size of training samples.
129
- learning_rate: float
130
- Adagrad base learning rate.
131
- epsilon : float
132
- Offset in denominator of the scale of learning rate in Adagrad.
133
- random_seed : int
134
- Seed to initialize random state.
135
-
136
- Returns
137
- -------
138
- ADVIFit
139
- Named tuple, which includes 'means', 'stds', and 'elbo_vals'.
140
- """
141
-
142
- model = modelcontext (model )
143
- if start is None :
144
- start = model .test_point
145
-
146
- if vars is None :
147
- vars = model .vars
148
-
149
- vars = set (inputvars (vars )) - set (minibatch_RVs )
150
-
151
- check_discrete_rvs (vars )
152
-
153
- # Create variational gradient tensor
154
- grad , elbo , shared , uw = variational_gradient_estimate (
155
- vars , model , minibatch_RVs , minibatch_tensors , total_size ,
156
- n_mcsamples = n_mcsamples , random_seed = random_seed )
157
-
158
- # Set starting values
159
- for var , share in shared .items ():
160
- share .set_value (start [str (var )])
161
-
162
- order = ArrayOrdering (vars )
163
- bij = DictToArrayBijection (order , start )
164
- u_start = bij .map (start )
165
- w_start = np .zeros_like (u_start )
166
- uw_start = np .concatenate ([u_start , w_start ])
167
-
168
- shared_inarray = theano .shared (uw_start , 'uw_shared' )
169
- grad = theano .clone (grad , { uw : shared_inarray }, strict = False )
170
- elbo = theano .clone (elbo , { uw : shared_inarray }, strict = False )
171
- updates = adagrad (grad , shared_inarray , learning_rate = learning_rate , epsilon = epsilon , n = 10 )
172
-
173
- # Create in-place update function
174
- tensors , givens = replace_shared_minibatch_tensors (minibatch_tensors )
175
- f = theano .function (tensors , [shared_inarray , grad , elbo ],
176
- updates = updates , givens = givens )
177
-
178
- # Run adagrad steps
179
- elbos = np .empty (n )
180
- for i in range (n ):
181
- uw_i , g , e = f (* next (minibatches ))
182
- elbos [i ] = e
183
- if verbose and not i % (n // 10 ):
184
- if not i :
185
- print ('Iteration {0} [{1}%]: ELBO = {2}' .format (i , 100 * i // n , e .round (2 )))
186
- else :
187
- avg_elbo = elbos [i - n // 10 :i ].mean ()
188
- print ('Iteration {0} [{1}%]: Average ELBO = {2}' .format (i , 100 * i // n , avg_elbo .round (2 )))
189
-
190
- if verbose :
191
- avg_elbo = elbos [i - n // 10 :i ].mean ()
192
- print ('Finished [100%]: Average ELBO = {}' .format (avg_elbo .round (2 )))
193
-
194
- l = int (uw_i .size / 2 )
195
-
196
- u = bij .rmap (uw_i [:l ])
197
- w = bij .rmap (uw_i [l :])
198
- # w is in log space
199
- for var in w .keys ():
200
- w [var ] = np .exp (w [var ])
201
- return ADVIFit (u , w , elbos )
202
-
203
101
def replace_shared_minibatch_tensors (minibatch_tensors ):
204
102
"""Replace shared variables in minibatch tensors with normal tensors.
205
103
"""
@@ -326,9 +224,10 @@ def adagrad(grad, param, learning_rate, epsilon, n):
326
224
tt .sqrt (accu_sum + epsilon ))
327
225
return updates
328
226
329
- def sample_vp (vparams , draws = 1000 , model = None , random_seed = 20090425 ,
330
- hide_transformed = True ):
331
- """Draw samples from variational posterior.
227
+ def sample_vp (
228
+ vparams , draws = 1000 , model = None , local_RVs = None , random_seed = 20090425 ,
229
+ hide_transformed = True ):
230
+ """Draw samples from variational posterior.
332
231
333
232
Parameters
334
233
----------
@@ -356,17 +255,33 @@ def sample_vp(vparams, draws=1000, model=None, random_seed=20090425,
356
255
'stds' : vparams .stds
357
256
}
358
257
258
+ ds = model .deterministics
259
+ get_transformed = lambda v : v if v not in ds else v .transformed
260
+ rvs = lambda x : [get_transformed (v ) for v in x ] if x is not None else []
261
+
262
+ global_RVs = list (set (model .free_RVs ) - set (rvs (local_RVs )))
263
+
359
264
# Make dict for replacements of random variables
360
265
r = MRG_RandomStreams (seed = random_seed )
361
266
updates = {}
362
- for var in model . free_RVs :
363
- u = theano .shared (vparams ['means' ][str (var )]).ravel ()
364
- w = theano .shared (vparams ['stds' ][str (var )]).ravel ()
267
+ for v in global_RVs :
268
+ u = theano .shared (vparams ['means' ][str (v )]).ravel ()
269
+ w = theano .shared (vparams ['stds' ][str (v )]).ravel ()
365
270
n = r .normal (size = u .tag .test_value .shape )
366
- updates .update ({var : (n * w + u ).reshape (var .tag .test_value .shape )})
367
- vars = model .free_RVs
271
+ updates .update ({v : (n * w + u ).reshape (v .tag .test_value .shape )})
272
+
273
+ if local_RVs is not None :
274
+ ds = model .deterministics
275
+ get_transformed = lambda v : v if v not in ds else v .transformed
276
+ for v_ , (uw , _ ) in local_RVs .items ():
277
+ v = get_transformed (v_ )
278
+ u = uw [0 ].ravel ()
279
+ w = uw [1 ].ravel ()
280
+ n = r .normal (size = u .tag .test_value .shape )
281
+ updates .update ({v : (n * tt .exp (w ) + u ).reshape (v .tag .test_value .shape )})
368
282
369
283
# Replace some nodes of the graph with variational distributions
284
+ vars = model .free_RVs
370
285
samples = theano .clone (vars , updates )
371
286
f = theano .function ([], samples )
372
287
0 commit comments