예제 #1
0
    def testCrossEntropyCustomLoop(self, loss):
        model_layers = [
            layers.Conv2D(7, 5, input_shape=(32, 32, 3)),
            layers.Activation('relu'),
            layers.Conv2D(10, (3, 3), kernel_regularizer='l2'),
            layers.GlobalMaxPool2D()
        ]
        model = tf.keras.Sequential(model_layers)
        model.compile('sgd', loss)
        loss_fn = utils.get_loss_fn(model=model, loss=loss)

        x = np.random.random((11, 32, 32, 3)).astype(np.float32)
        y = np.random.random((11, 10)).astype(np.float32)
        tf_x = tf.constant(x)
        tf_y = tf.constant(y)

        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            model_loss = sess.run(model.total_loss,
                                  feed_dict={
                                      'conv2d_input:0': x,
                                      'global_max_pooling2d_target:0': y
                                  })
            fn_loss = sess.run(loss_fn((tf_x, tf_y)))
            fn_loss_w_pred = sess.run(
                loss_fn((tf_x, tf_y), prediction=model(tf_x)))
        self.assertAlmostEqual(model_loss, fn_loss, fn_loss_w_pred)
예제 #2
0
    def testCrossEntropy(self, loss, label_shape, is_logits,
                         use_regularization):
        conv_kwargs = {
            'kernel_regularizer': 'l2'
        } if use_regularization else {}
        model_layers = [
            layers.Conv2D(7, 5, input_shape=(32, 32, 3), **conv_kwargs),
            layers.Activation('relu'),
            layers.Conv2D(10, (3, 3), activation='relu', **conv_kwargs),
            layers.GlobalMaxPool2D()
        ]
        if is_logits:
            model_layers.append(layers.Activation('softmax'))
        model = tf.keras.Sequential(model_layers)
        model.compile('sgd', loss)
        loss_fn = utils.get_loss_fn(model=model, loss=loss)

        x = tf.constant(np.random.random((11, 32, 32, 3)).astype(np.float32))
        y = tf.constant(np.random.random(label_shape).astype(np.float32))
        model_loss = model.evaluate(x, y, steps=1)
        fn_loss = tf.keras.backend.get_value(loss_fn((x, y)))
        fn_loss_w_pred = tf.keras.backend.get_value(
            loss_fn((x, y), prediction=model(x)))
        self.assertAlmostEqual(model_loss, fn_loss, fn_loss_w_pred)

        model.train_on_batch(np.random.random((11, 32, 32, 3)),
                             np.random.random(label_shape))

        x = tf.constant(np.random.random((11, 32, 32, 3)).astype(np.float32))
        y = tf.constant(np.random.random(label_shape).astype(np.float32))
        model_loss = model.test_on_batch(x, y)
        fn_loss = tf.keras.backend.get_value(loss_fn((x, y)))
        fn_loss_w_pred = tf.keras.backend.get_value(
            loss_fn((x, y), prediction=model(x)))
        self.assertAlmostEqual(model_loss, fn_loss, fn_loss_w_pred)
예제 #3
0
    def _create_optimizer(self):
        """Initializes the hyperparameters and sets the self._optimizer property."""
        if self._optimizer:
            return
        if not self._layer_collection:
            self.register_layers(self._model, self._loss)

        if self._config['adapt_damping']:
            if 'train_batch' not in self._kfac_kwargs:
                raise ValueError(
                    'Must provide a train_batch tuple to use adaptive '
                    'damping. Use register_train_batch or pass it in '
                    'during optimizer construction.')
            if 'loss_fn' not in self._kfac_kwargs:
                self._kfac_kwargs['loss_fn'] = utils.get_loss_fn(
                    self._model,
                    self._loss,
                    loss_weights=self._config['loss_weights'])

        with tf.name_scope(self._name):
            with tf.init_scope():
                # "iterations" property will create iterations if necessary.
                _ = self.iterations
                self._create_hypers()

        self._kfac_kwargs.update(self._hyper)
        try:
            # We use the TF 1 variable_scope instead of the TF 2 recommended
            # name_scope because we need to recover the variables created in this
            # scope, which is not possible with name_scope.
            with tf.variable_scope(self._tf_var_scope):
                self._optimizer = _KFAC_OPT_CLASS(
                    layer_collection=self._layer_collection,
                    **self._kfac_kwargs)
        except ValueError as e:
            msg = str(e)
            if re.search('Variable .* already exists', msg):
                raise ValueError(
                    'You may have instantiated a KFAC Optimizer with the same name as '
                    'an existing one. Try resetting the default graph, instantiating '
                    'the optimizer with a different name, or changing the optimizer\'s '
                    'name.\nHere is the original ValueError:\n ' + msg)
            elif re.search(
                    'Found the following errors with variable registration'
                    '.*gamma.*registered with wrong number of uses.*', msg):
                # We don't regex the name batch_normalization because the user could
                # have renamed the layer. We don't regex beta because they could have
                # used BatchNorm without the shift.
                raise ValueError(
                    'There may have been an issue registering BatchNormalization. Try '
                    'using tf.keras.backend.set_learning_phase before model '
                    'construction. An alternative solution is to use the unfused '
                    'batchnorm implementation (pass the argument fused=False to '
                    'BatchNormalization).\nHere is the original ValueError:\n '
                    + msg)
            else:
                raise e
예제 #4
0
    def testMSE(self, loss):
        model = _mlp()
        model.compile('sgd', loss)
        loss_fn = utils.get_loss_fn(model=model, loss=loss)

        x = tf.constant(np.random.random((23, 1)).astype(np.float32))
        y = tf.constant(np.random.random((23, 1)).astype(np.float32))
        model_loss = model.test_on_batch(x, y)
        fn_loss = tf.keras.backend.get_value(loss_fn((x, y)))
        fn_loss_w_pred = tf.keras.backend.get_value(
            loss_fn((x, y), prediction=model(x)))
        self.assertAlmostEqual(model_loss, fn_loss, fn_loss_w_pred)
예제 #5
0
    def testMultiLoss(self, multi_loss, loss_weights):
        inps, outs = _two_loss_model()
        model = tf.keras.Model(inputs=inps, outputs=outs)
        model.compile('sgd', multi_loss, loss_weights=loss_weights)
        loss_fn = utils.get_loss_fn(model=model,
                                    loss=multi_loss,
                                    loss_weights=loss_weights)

        x = tf.constant(np.random.random((11, 28, 28, 1)).astype(np.float32))
        y_1 = tf.constant(np.random.random((11, 1)).astype(np.float32))
        y_2 = tf.constant(np.random.random((11, 9)).astype(np.float32))
        # test_on_batch returns the total loss and the two individual losses.
        # We just want the total, so we use model_loss[0].
        model_loss = model.test_on_batch(x, [y_1, y_2])[0]
        fn_loss = tf.keras.backend.get_value(loss_fn((x, [y_1, y_2])))
        fn_loss_w_pred = tf.keras.backend.get_value(
            loss_fn((x, [y_1, y_2]), prediction=model(x)))
        self.assertAlmostEqual(model_loss, fn_loss, fn_loss_w_pred)