Coverage for mlair/model_modules/probability_models.py: 0%
265 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-12-02 15:24 +0000
« prev ^ index » next coverage.py v6.4.2, created at 2022-12-02 15:24 +0000
1"""
2>>> MyCustomisedModel().model.compile(**kwargs) == MyCustomisedModel().compile(**kwargs)
3True
5"""
7import mlair.model_modules.keras_extensions
9__author__ = "Felix Kleinert"
10__date__ = '2022-07-08'
12import tensorflow as tf
13import tensorflow.keras as keras
14import tensorflow_probability as tfp
15tfd = tfp.distributions
16tfb = tfp.bijectors
17tfpl = tfp.layers
19import logging
20from mlair.model_modules import AbstractModelClass
21from mlair.model_modules.inception_model import InceptionModelBase
22from mlair.model_modules.flatten import flatten_tail
23from mlair.model_modules.advanced_paddings import PadUtils, Padding2D, SymmetricPadding2D
24from mlair.model_modules.loss import l_p_loss
27class MyUnetProb(AbstractModelClass):
28 def __init__(self, input_shape: list, output_shape: list, num_of_training_samples: int):
29 super().__init__(input_shape[0], output_shape[0])
30 self.first_filter_size = 16 # 16*2#self._input_shape[-1] # 16
31 self.lstm_units = 64 * 2 # * 2
32 self.kernel_size = (3, 1) # (3,1)
33 self.activation = "elu"
34 self.pool_size = (2, 1)
36 self.num_of_training_samples = num_of_training_samples
37 # self.divergence_fn = lambda q, p, _: tfd.kl_divergence(q, p) / input_shape[0][0]
38 self.divergence_fn = lambda q, p, _: tfd.kl_divergence(q, p) / num_of_training_samples
40 # self.loss_fn = lambda y_true, y_pred: -y_pred.log_prob(y_true)
41 # self.loss = nll
43 self.dropout = .15 # .2
44 self.k_mixed_components = 2
45 self.kernel_regularizer = keras.regularizers.l1_l2(l1=0.01, l2=0.01)
46 self.bias_regularizer = keras.regularizers.l1_l2(l1=0.01, l2=0.01)
48 self.kernel_initializer = 'he_normal'
50 self.dense_units = 32 * 2
51 self.initial_lr = 0.001
53 # apply to model
54 self.set_model()
55 self.set_compile_options()
56 self.set_custom_objects(SymmetricPadding2D=SymmetricPadding2D, loss=self.loss, divergence_fn=self.divergence_fn)
58 def set_model(self):
59 input_train = keras.layers.Input(shape=self._input_shape)
60 pad_size = PadUtils.get_padding_for_same(self.kernel_size)
62 c1 = Padding2D("SymPad2D")(padding=pad_size)(input_train)
63 c1 = tfpl.Convolution2DReparameterization(
64 self.first_filter_size, self.kernel_size, padding='valid',
65 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
66 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
67 kernel_divergence_fn=self.divergence_fn,
68 bias_prior_fn=tfpl.default_multivariate_normal_fn,
69 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
70 bias_divergence_fn=self.divergence_fn,
71 activation=self.activation,
72 )(c1)
73 #c1 = keras.layers.Conv2D(self.first_filter_size, self.kernel_size, activation=self.activation,
74 # kernel_initializer=self.kernel_initializer, kernel_regularizer=self.kernel_regularizer,
75 # bias_regularizer=self.bias_regularizer)(c1)
76 c1 = keras.layers.Dropout(self.dropout)(c1)
77 c1 = Padding2D("SymPad2D")(padding=pad_size)(c1)
78 c1 = tfpl.Convolution2DReparameterization(
79 self.first_filter_size, self.kernel_size, padding='valid',
80 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
81 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
82 kernel_divergence_fn=self.divergence_fn,
83 bias_prior_fn=tfpl.default_multivariate_normal_fn,
84 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
85 bias_divergence_fn=self.divergence_fn,
86 activation=self.activation,
87 name='c1'
88 )(c1)
89 #c1 = keras.layers.Conv2D(self.first_filter_size, self.kernel_size, activation=self.activation,
90 # kernel_initializer=self.kernel_initializer, name='c1',
91 # kernel_regularizer=self.kernel_regularizer,
92 # bias_regularizer=self.bias_regularizer)(c1)
93 p1 = c1
94 # p1 = keras.layers.MaxPooling2D(self.pool_size)(c1)
96 c2 = Padding2D("SymPad2D")(padding=pad_size)(p1)
97 c2 = tfpl.Convolution2DReparameterization(
98 self.first_filter_size * 2, self.kernel_size, padding='valid',
99 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
100 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
101 kernel_divergence_fn=self.divergence_fn,
102 bias_prior_fn=tfpl.default_multivariate_normal_fn,
103 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
104 bias_divergence_fn=self.divergence_fn,
105 activation=self.activation,
106 )(c2)
107 # c2 = keras.layers.Conv2D(self.first_filter_size * 2, self.kernel_size, activation=self.activation,
108 # kernel_initializer=self.kernel_initializer, kernel_regularizer=self.kernel_regularizer,
109 # bias_regularizer=self.bias_regularizer)(c2)
110 c2 = keras.layers.Dropout(self.dropout)(c2)
111 c2 = Padding2D("SymPad2D")(padding=pad_size)(c2)
112 c2 = tfpl.Convolution2DReparameterization(
113 self.first_filter_size * 2, self.kernel_size, padding='valid',
114 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
115 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
116 kernel_divergence_fn=self.divergence_fn,
117 bias_prior_fn=tfpl.default_multivariate_normal_fn,
118 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
119 bias_divergence_fn=self.divergence_fn,
120 activation=self.activation, name="c2"
121 )(c2)
122 # c2 = keras.layers.Conv2D(self.first_filter_size * 2, self.kernel_size, activation=self.activation,
123 # kernel_initializer=self.kernel_initializer, name='c2',
124 # kernel_regularizer=self.kernel_regularizer,
125 # bias_regularizer=self.bias_regularizer)(c2)
126 p2 = c2
127 # p2 = keras.layers.MaxPooling2D(self.pool_size)(c2)
129 c3 = Padding2D("SymPad2D")(padding=pad_size)(p2)
130 c3 = tfpl.Convolution2DReparameterization(
131 self.first_filter_size * 4, self.kernel_size, padding='valid',
132 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
133 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
134 kernel_divergence_fn=self.divergence_fn,
135 bias_prior_fn=tfpl.default_multivariate_normal_fn,
136 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
137 bias_divergence_fn=self.divergence_fn,
138 activation=self.activation
139 )(c3)
140 # c3 = keras.layers.Conv2D(self.first_filter_size * 4, self.kernel_size, activation=self.activation,
141 # kernel_initializer=self.kernel_initializer, kernel_regularizer=self.kernel_regularizer,
142 # bias_regularizer=self.bias_regularizer)(c3)
143 c3 = keras.layers.Dropout(self.dropout * 2)(c3)
144 c3 = Padding2D("SymPad2D")(padding=pad_size)(c3)
145 c3 = tfpl.Convolution2DReparameterization(
146 self.first_filter_size * 4, self.kernel_size, padding='valid',
147 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
148 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
149 kernel_divergence_fn=self.divergence_fn,
150 bias_prior_fn=tfpl.default_multivariate_normal_fn,
151 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
152 bias_divergence_fn=self.divergence_fn,
153 activation=self.activation, name="c3"
154 )(c3)
155 # c3 = keras.layers.Conv2D(self.first_filter_size * 4, self.kernel_size, activation=self.activation,
156 # kernel_initializer=self.kernel_initializer, name='c3',
157 # kernel_regularizer=self.kernel_regularizer,
158 # bias_regularizer=self.bias_regularizer)(c3)
159 # p3 = c3
160 p3 = keras.layers.MaxPooling2D(self.pool_size)(c3)
162 ### own LSTM Block ###
163 ls1 = keras.layers.Reshape((p3.shape[1], p3.shape[-1]))(p3)
164 ls1 = keras.layers.LSTM(self.lstm_units, return_sequences=True)(ls1)
165 ls1 = keras.layers.LSTM(self.lstm_units, return_sequences=True)(ls1)
166 c4 = keras.layers.Reshape((p3.shape[1], 1, -1))(ls1)
168 ### own 2nd LSTM Block ###
169 ls2 = keras.layers.Reshape((c3.shape[1], c3.shape[-1]))(c3)
170 ls2 = keras.layers.LSTM(self.lstm_units, return_sequences=True)(ls2)
171 ls2 = keras.layers.LSTM(self.lstm_units, return_sequences=True)(ls2)
172 c4_2 = keras.layers.Reshape((c3.shape[1], 1, -1))(ls2)
174 u7 = keras.layers.UpSampling2D(size=(3, 1))(c4)
175 cn3 = Padding2D("SymPad2D")(padding=pad_size)(c3)
176 # u7 = c4
177 u7 = keras.layers.concatenate([u7, cn3], name="u7_c3")
178 c7 = u7
179 # c7 = Padding2D("SymPad2D")(padding=pad_size)(u7)
180 c7 = tfpl.Convolution2DReparameterization(
181 self.first_filter_size * 4, self.kernel_size, padding='valid',
182 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
183 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
184 kernel_divergence_fn=self.divergence_fn,
185 bias_prior_fn=tfpl.default_multivariate_normal_fn,
186 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
187 bias_divergence_fn=self.divergence_fn,
188 activation=self.activation
189 )(c7)
190 # c7 = keras.layers.Conv2D(self.first_filter_size * 4, self.kernel_size, activation=self.activation,
191 # kernel_initializer=self.kernel_initializer, kernel_regularizer=self.kernel_regularizer,
192 # bias_regularizer=self.bias_regularizer)(c7)
193 c7 = keras.layers.concatenate([c7, c4_2], name="Concat_2nd_LSTM")
194 c7 = keras.layers.Dropout(self.dropout * 2)(c7)
195 c7 = Padding2D("SymPad2D")(padding=pad_size)(c7)
196 c7 = tfpl.Convolution2DReparameterization(
197 self.first_filter_size * 4, self.kernel_size, padding='valid',
198 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
199 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
200 kernel_divergence_fn=self.divergence_fn,
201 bias_prior_fn=tfpl.default_multivariate_normal_fn,
202 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
203 bias_divergence_fn=self.divergence_fn,
204 activation=self.activation, name='c7_to_u8'
205 )(c7)
206 # c7 = keras.layers.Conv2D(self.first_filter_size * 4, self.kernel_size, activation=self.activation,
207 # kernel_initializer=self.kernel_initializer, name='c7_to_u8',
208 # kernel_regularizer=self.kernel_regularizer,
209 # bias_regularizer=self.bias_regularizer)(c7)
212 # u8 = Padding2D("SymPad2D")(padding=pad_size)(c7)
213 # u8 = keras.layers.Conv2DTranspose(32, self.pool_size, strides=self.pool_size)(u8)
214 u8 = c7
215 # u8 = c3
216 u8 = keras.layers.concatenate([u8, c2], name="u8_c2")
217 c8 = Padding2D("SymPad2D")(padding=pad_size)(u8)
218 c8 = tfpl.Convolution2DReparameterization(
219 self.first_filter_size * 2, self.kernel_size, padding='valid',
220 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
221 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
222 kernel_divergence_fn=self.divergence_fn,
223 bias_prior_fn=tfpl.default_multivariate_normal_fn,
224 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
225 bias_divergence_fn=self.divergence_fn,
226 activation=self.activation
227 )(c8)
228 # c8 = keras.layers.Conv2D(self.first_filter_size * 2, self.kernel_size, activation=self.activation,
229 # kernel_initializer=self.kernel_initializer, kernel_regularizer=self.kernel_regularizer,
230 # bias_regularizer=self.bias_regularizer)(c8)
231 c8 = keras.layers.Dropout(self.dropout)(c8)
232 c8 = Padding2D("SymPad2D")(padding=pad_size)(c8)
233 c8 = tfpl.Convolution2DReparameterization(
234 self.first_filter_size * 2, self.kernel_size, padding='valid',
235 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
236 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
237 kernel_divergence_fn=self.divergence_fn,
238 bias_prior_fn=tfpl.default_multivariate_normal_fn,
239 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
240 bias_divergence_fn=self.divergence_fn,
241 activation=self.activation, name='c8_to_u9'
242 )(c8)
243 # c8 = keras.layers.Conv2D(self.first_filter_size * 2, self.kernel_size, activation=self.activation,
244 # kernel_initializer=self.kernel_initializer, name='c8_to_u9',
245 # kernel_regularizer=self.kernel_regularizer,
246 # bias_regularizer=self.bias_regularizer)(c8)
248 # u9 = Padding2D("SymPad2D")(padding=pad_size)(c8)
249 # u9 = keras.layers.Conv2DTranspose(16, self.pool_size, strides=self.pool_size)(u9)
250 u9 = c8
251 u9 = keras.layers.concatenate([u9, c1], name="u9_c1")
252 c9 = Padding2D("SymPad2D")(padding=pad_size)(u9)
253 c9 = tfpl.Convolution2DReparameterization(
254 self.first_filter_size, self.kernel_size, padding='valid',
255 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
256 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
257 kernel_divergence_fn=self.divergence_fn,
258 bias_prior_fn=tfpl.default_multivariate_normal_fn,
259 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
260 bias_divergence_fn=self.divergence_fn,
261 activation=self.activation,
262 )(c9)
263 # c9 = keras.layers.Conv2D(self.first_filter_size, self.kernel_size, activation=self.activation,
264 # kernel_initializer=self.kernel_initializer, kernel_regularizer=self.kernel_regularizer,
265 # bias_regularizer=self.bias_regularizer)(c9)
266 c9 = keras.layers.Dropout(self.dropout)(c9)
267 c9 = Padding2D("SymPad2D")(padding=pad_size)(c9)
268 c9 = tfpl.Convolution2DReparameterization(
269 self.first_filter_size, self.kernel_size, padding='valid',
270 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
271 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
272 kernel_divergence_fn=self.divergence_fn,
273 bias_prior_fn=tfpl.default_multivariate_normal_fn,
274 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
275 bias_divergence_fn=self.divergence_fn,
276 activation=self.activation,
277 )(c9)
278 # c9 = keras.layers.Conv2D(self.first_filter_size, self.kernel_size, activation=self.activation,
279 # kernel_initializer=self.kernel_initializer, name='c9',
280 # kernel_regularizer=self.kernel_regularizer,
281 # bias_regularizer=self.bias_regularizer)(c9)
283 # outputs = keras.layers.Conv2D(1, (1, 1), activation='sigmoid')(c9)
284 dl = keras.layers.Flatten()(c9)
285 dl = keras.layers.Dropout(self.dropout)(dl)
287 # outputs = tfpl.DenseVariational(tfpl.MultivariateNormalTriL.params_size(self._output_shape),
288 # make_posterior_fn=self.posterior,
289 # make_prior_fn=self.prior)(dl)
290 # outputs = tfpl.MultivariateNormalTriL(self._output_shape)(outputs)
291 # outputs = keras.layers.Dense(units=self._output_shape)(dl)
293 #outputs = keras.layers.Dense(tfpl.IndependentNormal.params_size(self._output_shape),
294 # )(dl)
295 #outputs = tfpl.DenseVariational(units=tfpl.IndependentNormal.params_size(self._output_shape),
296 # #make_prior_fn=self.prior,
297 # make_prior_fn=prior_trainable,
298 # make_posterior_fn=self.posterior,
299 # )(dl)
300 #outputs = VarDense(units=tfpl.IndependentNormal.params_size(self._output_shape),
301 # make_prior_fn=self.prior,
302 # make_posterior_fn=self.posterior,
303 # )(dl)
306 #outputs = tfpl.IndependentNormal(self._output_shape)(outputs)
307 params_size = tfpl.MixtureSameFamily.params_size(
308 self.k_mixed_components,
309 component_params_size=tfpl.MultivariateNormalTriL.params_size(self._output_shape)
310 )
312 pars = tf.keras.layers.Dense(params_size)(dl)
313 # pars = DenseVariationalCustom(
314 # units=params_size, make_prior_fn=prior, make_posterior_fn=posterior,
315 # kl_use_exact=True, kl_weight=1./self.x_train_shape)(dl)
317 outputs = tfpl.MixtureSameFamily(self.k_mixed_components,
318 tfpl.MultivariateNormalTriL(
319 self._output_shape,
320 convert_to_tensor_fn=tfp.distributions.Distribution.mode
321 )
322 )(pars)
324 self.model = keras.Model(inputs=input_train, outputs=outputs)
326 def set_compile_options(self):
327 # self.optimizer = keras.optimizers.Adam(lr=self.initial_lr,
328 # clipnorm=self.clipnorm,
329 # )
331 # loss = nll
332 # self.optimizer = tf.keras.optimizers.RMSprop(learning_rate=self.initial_lr)
333 self.optimizer = tf.keras.optimizers.Adam(learning_rate=self.initial_lr)
334 self.loss = nll
335 self.compile_options = {"metrics": ["mse", "mae"]}
337 # loss = keras.losses.MeanSquaredError()
338 # self.compile_options = {"loss": [loss]}
340 @staticmethod
341 def prior(kernel_size, bias_size, dtype=None):
342 n = kernel_size + bias_size
344 prior_model = tf.keras.Sequential([
346 tfpl.DistributionLambda(
347 # Note: Our prior is a non-trianable distribution
348 lambda t: tfd.MultivariateNormalDiag(loc=tf.zeros(n), scale_diag=tf.ones(n)))
349 ])
351 return prior_model
353 @staticmethod
354 def posterior(kernel_size, bias_size, dtype=None):
355 n = kernel_size + bias_size
357 posterior_model = tf.keras.Sequential([
359 tfpl.VariableLayer(tfpl.MultivariateNormalTriL.params_size(n), dtype=dtype),
360 tfpl.MultivariateNormalTriL(n)
361 ])
363 return posterior_model
368class MyCNNProb(AbstractModelClass):
369 """
370 Taken fromhttps://towardsdatascience.com/uncertainty-in-deep-learning-bayesian-cnn-tensorflow-probability-758d7482bef6
371 and modified to our data
372 """
373 def __init__(self, input_shape: list, output_shape: list):
374 super().__init__(input_shape[0], output_shape[0])
375 self.initial_lr = 0.001
377 self.divergence_fn = lambda q, p, q_tensor : self.approximate_kl(q, p, q_tensor) / 1000 # check how to get num of samples included here
378 # apply to model
379 self.set_model()
380 self.set_compile_options()
381 self.set_custom_objects(loss_fn=self.loss_fn )
384 @staticmethod
385 def loss_fn(y_true, y_pred):
386 return -y_pred.log_prob(y_true)
389 # For Reparameterization Layers
391 @staticmethod
392 def custom_normal_prior(dtype, shape, name, trainable, add_variable_fn):
393 distribution = tfd.Normal(loc = 0.1 * tf.ones(shape, dtype),
394 scale = 1.5 * tf.ones(shape, dtype))
395 batch_ndims = tf.size(distribution.batch_shape_tensor())
397 distribution = tfd.Independent(distribution,
398 reinterpreted_batch_ndims = batch_ndims)
399 return distribution
401 @staticmethod
402 def laplace_prior(dtype, shape, name, trainable, add_variable_fn):
403 distribution = tfd.Laplace(loc = tf.zeros(shape, dtype),
404 scale = tf.ones(shape, dtype))
405 batch_ndims = tf.size(distribution.batch_shape_tensor())
407 distribution = tfd.Independent(distribution,
408 reinterpreted_batch_ndims = batch_ndims)
409 return distribution
412 @staticmethod
413 def approximate_kl(q, p, q_tensor):
414 return tf.reduce_mean(q.log_prob(q_tensor) - p.log_prob(q_tensor))
417 def conv_reparameterization_layer(self, filters, kernel_size, activation):
418 # For simplicity, we use default prior and posterior.
419 # In the next parts, we will use custom mixture prior and posteriors.
420 return tfpl.Convolution2DReparameterization(
421 filters = filters,
422 kernel_size = kernel_size,
423 activation = activation,
424 padding = 'same',
425 kernel_posterior_fn = tfpl.default_mean_field_normal_fn(is_singular=False),
426 kernel_prior_fn = tfpl.default_multivariate_normal_fn,
428 bias_prior_fn = tfpl.default_multivariate_normal_fn,
429 bias_posterior_fn = tfpl.default_mean_field_normal_fn(is_singular=False),
431 kernel_divergence_fn = self.divergence_fn,
432 bias_divergence_fn = self.divergence_fn)
434 def set_model(self):
435 bayesian_cnn = tf.keras.Sequential([
436 tf.keras.layers.InputLayer(self._input_shape),
437 self.conv_reparameterization_layer(16, 3, 'swish'),
438 #tf.keras.layers.MaxPooling2D(2),
439 self.conv_reparameterization_layer(32, 3, 'swish'),
440 #tf.keras.layers.MaxPooling2D(2),
441 self.conv_reparameterization_layer(64, 3, 'swish'),
442 #tf.keras.layers.MaxPooling2D(2),
443 self.conv_reparameterization_layer(128, 3, 'swish'),
444 #tf.keras.layers.GlobalMaxPooling2D(),
445 tfpl.DenseReparameterization(
446 units=tfpl.IndependentNormal.params_size(self._output_shape), activation=None,
447 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(is_singular=False),
448 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
449 bias_prior_fn=tfpl.default_multivariate_normal_fn,
450 bias_posterior_fn=tfpl.default_mean_field_normal_fn(is_singular=False),
451 kernel_divergence_fn=self.divergence_fn,
452 bias_divergence_fn=self.divergence_fn),
453 tfpl.IndependentNormal(self._output_shape)
454 ])
456 input_train = keras.layers.Input(shape=self._input_shape)
457 x = self.conv_reparameterization_layer(16, 3, 'swish')(input_train)
458 # tf.keras.layers.MaxPooling2D(2),
459 x = self.conv_reparameterization_layer(32, 3, 'swish')(x)
460 # tf.keras.layers.MaxPooling2D(2),
461 x = self.conv_reparameterization_layer(64, 3, 'swish')(x)
462 # tf.keras.layers.MaxPooling2D(2),
463 x = self.conv_reparameterization_layer(128, 3, 'swish')(x)
464 x = tf.keras.layers.Flatten()(x)
465 # x = tfpl.DenseReparameterization(
466 # units=tfpl.IndependentNormal.params_size(self._output_shape), activation=None,
467 # kernel_posterior_fn=tfpl.default_mean_field_normal_fn(is_singular=False),
468 # kernel_prior_fn=tfpl.default_multivariate_normal_fn,
469 # bias_prior_fn=tfpl.default_multivariate_normal_fn,
470 # bias_posterior_fn=tfpl.default_mean_field_normal_fn(is_singular=False),
471 # kernel_divergence_fn=self.divergence_fn,
472 # bias_divergence_fn=self.divergence_fn)(x)
473 # outputs = tfpl.IndependentNormal(self._output_shape)(x)
474 x = tf.keras.layers.Dense(tfpl.IndependentNormal.params_size(event_shape=self._output_shape))(x)
475 outputs = tfpl.IndependentNormal(event_shape=self._output_shape)(x)
476 # outputs = tfpl.DistributionLambda(
477 # make_distribution_fn=lambda t: tfd.Normal(
478 # loc=t[..., 0], scale=tf.exp(t[..., 1])),
479 # convert_to_tensor_fn=lambda s: s.sample(30))(x)
482 bnn = keras.Model(inputs=input_train, outputs=outputs)
483 self.model = bnn
486 logging.info(f"model summary:\n{self.model.summary()}")
488 def set_compile_options(self):
489 self.optimizer = tf.keras.optimizers.Adam(lr=self.initial_lr,
490 # clipnorm=self.clipnorm,
491 )
493 loss = self.loss_fn
494 # self.compile_options = {"loss": [loss], "metrics": ["mse", "mae"]}
496 # loss = keras.losses.MeanSquaredError()
497 self.compile_options = {"loss": [loss]}
502class VarDense(tf.keras.layers.Layer):
504 def __init__(self,
505 units,
506 make_posterior_fn,
507 make_prior_fn,
508 kl_weight=None,
509 kl_use_exact=False,
510 activation=None,
511 use_bias=True,
512 activity_regularizer=None,
513 **kwargs
514 ):
515 super().__init__(**kwargs)
516 self.units = units
517 self.make_posterior_fn = make_posterior_fn
518 self.make_prior_fn = make_prior_fn
519 self.kl_weight = kl_weight,
520 self.kl_use_exact = kl_use_exact,
521 self.activation = activation,
522 self.use_bias = use_bias,
523 self.activity_regularizer = activity_regularizer
524 self.tfpllayer = tfpl.DenseVariational(units=self.units,
525 make_prior_fn=self.make_prior_fn,
526 make_posterior_fn=self.make_posterior_fn,
527 kl_weight=self.kl_weight,
528 kl_use_exact=self.kl_use_exact,
529 use_bias=self.use_bias,
530 activity_regularizer=self.activity_regularizer
531 )
533 def call(self, inputs):
534 return self.tfpllayer(inputs)
539 def get_config(self):
540 config = super().get_config().copy()
541 config.update({
542 "units": self.units,
543 "make_posterior_fn": self.make_posterior_fn,
544 "make_prior_fn": self.make_prior_fn,
545 "kl_weight": self.kl_weight,
546 "kl_use_exact": self.kl_use_exact,
547 "activation": self.activation,
548 "use_bias": self.use_bias,
549 "activity_regularizer": self.activity_regularizer,
550 })
551 return config
554def prior_trainable(kernel_size, bias_size=0, dtype=None):
555 n = kernel_size + bias_size
556 return tf.keras.Sequential([
557 tfp.layers.VariableLayer(n, dtype=dtype),
558 tfp.layers.DistributionLambda(lambda t: tfd.Independent(
559 tfd.Normal(loc=t, scale=1),
560 reinterpreted_batch_ndims=1)),
561 ])
564class ProbTestModel(AbstractModelClass):
565 def __init__(self, input_shape: list, output_shape: list):
566 super().__init__(input_shape[0], output_shape[0])
567 self.initial_lr = 0.001
568 self.loss = nll
570 self.set_model()
571 self.set_compile_options()
572 self.set_custom_objects(nll=nll)
574 def set_model(self):
576 x_in = keras.layers.Input(self._input_shape)
577 x = keras.layers.Conv2D(kernel_size=(3,1), filters=8,
578 activation='relu', padding="same")(x_in)
579 x = keras.layers.Flatten()(x)
580 x = keras.layers.Dense(tfpl.IndependentNormal.params_size(self._output_shape))(x)
581 out = tfpl.IndependentNormal(self._output_shape)(x)
582 model = keras.Model(inputs=x_in, outputs=out)
585 #model = tf.keras.Sequential([
586 # keras.layers.InputLayer(self._input_shape),
587 # keras.layers.Conv2D(kernel_size=(3,1), filters=8,
588 # activation='relu', padding="same"),
590 # keras.layers.Flatten(),
592 # keras.layers.Dense(tfpl.IndependentNormal.params_size(self._output_shape)),
593 # tfpl.IndependentNormal(self._output_shape,
594 # convert_to_tensor_fn=tfp.distributions.Distribution.sample
595 # )
597 #])
598 self.model = model
599 logging.info(self.model.summary())
601 def set_compile_options(self):
602 self.optimizer = tf.keras.optimizers.RMSprop(lr=self.initial_lr,
603 # clipnorm=self.clipnorm,
604 )
606class ProbTestModel2(AbstractModelClass):
607 def __init__(self, input_shape: list, output_shape: list):
608 super().__init__(input_shape[0], output_shape[0])
609 self.initial_lr = 0.001
610 self.loss = nll
611 self.divergence_fn = lambda q, p, _: tfd.kl_divergence(q, p) / input_shape[0][0]
613 self.set_model()
614 self.set_compile_options()
615 self.set_custom_objects(nll=nll)
617 def set_model(self):
618 model = tf.keras.Sequential([
619 tf.keras.layers.InputLayer(self._input_shape),
620 #tf.keras.layers.Conv2D(kernel_size=(3,1), filters=8,
621 # activation='relu', padding="same"),
622 Convolution2DReparameterizationCustom(
623 8, (3,1), padding='same',
624 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
625 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
626 kernel_divergence_fn=self.divergence_fn,
627 bias_prior_fn=tfpl.default_multivariate_normal_fn,
628 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
629 bias_divergence_fn=self.divergence_fn,
630 activation='relu'),
632 tf.keras.layers.Flatten(),
634 tf.keras.layers.Dense(tfpl.MultivariateNormalTriL.params_size(self._output_shape)),
635 tfpl.MultivariateNormalTriL(self._output_shape,
636 convert_to_tensor_fn=tfp.distributions.Distribution.mode
637 )
639 ])
640 self.model = model
641 logging.info(self.model.summary())
643 def set_compile_options(self):
644 self.optimizer = tf.keras.optimizers.RMSprop(lr=self.initial_lr,
645 # clipnorm=self.clipnorm,
646 )
651class ProbTestModel3(AbstractModelClass):
652 def __init__(self, input_shape: list, output_shape: list):
653 super().__init__(input_shape[0], output_shape[0])
655 self.x_train_shape=100.
656 self.set_model()
657 self.set_compile_options()
658 self.set_custom_objects(nll=nll)
660 def set_model(self):
661 model = tf.keras.Sequential([
662 keras.layers.Flatten(input_shape=self._input_shape),
663 # Epistemic uncertainty
664 tfpl.DenseVariational(units=8,
665 make_prior_fn=prior,
666 make_posterior_fn=posterior,
667 kl_weight=1/self.x_train_shape,
668 kl_use_exact=False,
669 activation='sigmoid'),
671 tfpl.DenseVariational(units=tfpl.IndependentNormal.params_size(1),
672 make_prior_fn=prior,
673 make_posterior_fn=posterior,
674 kl_use_exact=False,
675 kl_weight=1/self.x_train_shape),
677 # Aleatoric uncertainty
678 tfpl.IndependentNormal(1)
679 ])
680 logging.warning(model.summary())
681 self.model = model
683 def set_compile_options(self):
684 self.optimizer = tf.keras.optimizers.RMSprop()
687class ProbTestModel4(AbstractModelClass):
688 def __init__(self, input_shape: list, output_shape: list):
689 super().__init__(input_shape[0], output_shape[0])
691 self.x_train_shape = 100.
692 self.set_model()
693 self.set_compile_options()
694 self.set_custom_objects(nll=nll)
696 def set_model(self):
697 model = tf.keras.Sequential([
698 keras.layers.Flatten(input_shape=self._input_shape),
699 # Epistemic uncertainty
700 DenseVariationalCustom(units=8,
701 make_prior_fn=prior,
702 make_posterior_fn=posterior,
703 kl_weight=1 / self.x_train_shape,
704 kl_use_exact=False,
705 activation='sigmoid'),
707 DenseVariationalCustom(units=tfpl.IndependentNormal.params_size(self._output_shape),
708 make_prior_fn=prior,
709 make_posterior_fn=posterior,
710 kl_use_exact=False,
711 kl_weight=1 / self.x_train_shape),
713 # Aleatoric uncertainty
714 tfpl.IndependentNormal(self._output_shape)
715 ])
716 logging.warning(model.summary())
717 self.model = model
719 def set_compile_options(self):
720 self.optimizer = tf.keras.optimizers.RMSprop()
721 self.loss = nll
725class ProbTestModelMixture(AbstractModelClass):
726 def __init__(self, input_shape: list, output_shape: list):
727 super().__init__(input_shape[0], output_shape[0])
728 self.initial_lr = 0.001
729 self.loss = nll
730 self.divergence_fn = lambda q, p, _: tfd.kl_divergence(q, p) / input_shape[0][0]
731 self.k_mixed_components = 2
733 self.set_model()
734 self.set_compile_options()
735 self.set_custom_objects(nll=nll)
737 def set_model(self):
738 x_input = tf.keras.layers.Input(self._input_shape)
739 #tf.keras.layers.Conv2D(kernel_size=(3,1), filters=8,
740 # activation='relu', padding="same"),
741 x = Convolution2DReparameterizationCustom(
742 8, (3, 1), padding='same',
743 kernel_prior_fn=tfpl.default_multivariate_normal_fn,
744 kernel_posterior_fn=tfpl.default_mean_field_normal_fn(),
745 kernel_divergence_fn=self.divergence_fn,
746 bias_prior_fn=tfpl.default_multivariate_normal_fn,
747 bias_posterior_fn=tfpl.default_mean_field_normal_fn(),
748 bias_divergence_fn=self.divergence_fn,
749 activation='relu',
750 )(x_input)
752 x = tf.keras.layers.Flatten()(x)
754 params_size = tfpl.MixtureSameFamily.params_size(
755 self.k_mixed_components,
756 component_params_size=tfpl.MultivariateNormalTriL.params_size(self._output_shape)
757 )
759 x = tf.keras.layers.Dense(params_size)(x)
760 # tfpl.MultivariateNormalTriL(self._output_shape,
761 # convert_to_tensor_fn=tfp.distributions.Distribution.mode
762 # )
763 out = tfpl.MixtureSameFamily(self.k_mixed_components, tfpl.MultivariateNormalTriL(self._output_shape,
764 convert_to_tensor_fn=tfp.distributions.Distribution.mode
765 ))(x)
767 self.model = tf.keras.Model(inputs=[x_input], outputs=out)
768 logging.info(self.model.summary())
770 def set_compile_options(self):
771 self.optimizer = tf.keras.optimizers.RMSprop(lr=self.initial_lr,
772 # clipnorm=self.clipnorm,
773 )
777def nll(y_true, y_pred):
778 """
779 This function should return the negative log-likelihood of each sample
780 in y_true given the predicted distribution y_pred. If y_true is of shape
781 [B, E] and y_pred has batch shape [B] and event_shape [E], the output
782 should be a Tensor of shape [B].
783 """
784 return -y_pred.log_prob(y_true)
787# Posterior
788def posterior(kernel_size, bias_size, dtype=None):
790 n = kernel_size + bias_size
792 posterior_model = tf.keras.Sequential([
794 tfpl.VariableLayer(tfpl.MultivariateNormalTriL.params_size(n), dtype=dtype),
795 tfpl.MultivariateNormalTriL(n)
796 ])
798 return posterior_model
800# Prior - diagonal MVN ~ N(0, 1)
801def prior(kernel_size, bias_size, dtype=None):
803 n = kernel_size + bias_size
805 prior_model = tf.keras.Sequential([
807 tfpl.DistributionLambda(
808 # Note: Our prior is a non-trianable distribution
809 lambda t: tfd.MultivariateNormalDiag(loc=tf.zeros(n), scale_diag=tf.ones(n)))
810 ])
812 return prior_model
815class DenseVariationalCustom(tfpl.DenseVariational):
816 """
817 Trying to implement a DensVar that can be stored:
818 https://github.com/tensorflow/probability/commit/0ca065fb526b50ce38b68f7d5b803f02c78c8f16#
819 """
821 def get_config(self):
822 config = super().get_config().copy()
823 config.update({
824 'units': self.units,
825 'make_posterior_fn': self._make_posterior_fn,
826 'make_prior_fn': self._make_prior_fn
827 })
828 return config
831class Convolution2DReparameterizationCustom(tfpl.Convolution2DReparameterization):
832 def get_config(self):
833 config = super().get_config().copy()
834 config.update({
835 # 'units': self.units,
836 # 'make_posterior_fn': self._make_posterior_fn,
837 # 'make_prior_fn': self._make_prior_fn,
838 # 'kernel_divergence_fn': self.divergence_fn,
839 })
840 return config
843if __name__ == "__main__":
845 mylayer = DenseVariationalCustom(units=8,
846 make_prior_fn=prior,
847 make_posterior_fn=posterior,
848 kl_weight=1/100.,
849 kl_use_exact=False,
850 activation='sigmoid')
852 print(mylayer)
855#### How to access mixture model parameters:
856# https://stackoverflow.com/questions/65918888/mixture-parameters-from-a-tensorflow-probability-mixture-density-network
857# from MLAir perspective:
858#gm = self.model.model(input_data)
859#
860#mixing parameters
861#gm.mixture_distribution.probs_parameter()
862#
863#for parameters see keys and select
864#gm.components_distribution.parameters.keys()