def testSVD_BreaksDownLayerWeights(self):
        model = _build_model()

        first_conv_layer = model.layers[2]
        self.assertLen(first_conv_layer.weights, 2)

        model_for_inference = svd.SVD(rank=16).compress_model(model)

        first_conv_layer = model_for_inference.layers[2]

        self.assertLen(first_conv_layer.weights, 3)
    def testSVD_HasReasonableAccuracy_TFLite(self):
        model = _build_model()
        _train_model(model)

        model_for_inference = svd.SVD(rank=16).compress_model(model)

        saved_model_dir = _save_as_saved_model(model_for_inference)
        compressed_tflite_file = _convert_to_tflite(saved_model_dir)

        accuracy = _test_tflite(compressed_tflite_file)

        self.assertGreater(accuracy, 0.60)
    def testSVD_ReducesSavedModelSize(self):
        model = _build_model()

        original_saved_model_dir = _save_as_saved_model(model)

        model_for_inference = svd.SVD(rank=16).compress_model(model)

        saved_model_dir = _save_as_saved_model(model_for_inference)

        original_size = _get_directory_size_in_bytes(original_saved_model_dir)
        compressed_size = _get_directory_size_in_bytes(saved_model_dir)

        self.assertLess(compressed_size, original_size / 3)
    def testSVD_ReducesTFLiteModelSize(self):
        model = _build_model()

        original_saved_model_dir = _save_as_saved_model(model)
        original_tflite_file = _convert_to_tflite(original_saved_model_dir)

        model_for_inference = svd.SVD(rank=16).compress_model(model)

        saved_model_dir = _save_as_saved_model(model_for_inference)
        compressed_tflite_file = _convert_to_tflite(saved_model_dir)

        original_size = os.path.getsize(original_tflite_file)
        compressed_size = os.path.getsize(compressed_tflite_file)

        self.assertLess(compressed_size, original_size / 6)
    def testSVD_HasReasonableAccuracy_TF(self):
        model = _build_model()
        _train_model(model)

        model_for_inference = svd.SVD(rank=16).compress_model(model)

        _, (x_test, y_test) = _get_dataset()

        loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(
            from_logits=True)

        model_for_inference.compile(optimizer='adam',
                                    loss=loss_fn,
                                    metrics=['accuracy'])

        results = model_for_inference.evaluate(x_test, y_test)

        self.assertGreater(results[1], 0.60)
    def testSVD_PreservesPretrainedWeights(self):
        i = tf.keras.layers.Input(shape=(2), name='input')
        output = tf.keras.layers.Dense(3, name='fc1')(i)
        model = tf.keras.Model(inputs=[i], outputs=[output])

        dense_layer_weights = model.layers[1].get_weights()

        algorithm = svd.SVD(rank=1)
        model_for_inference = algorithm.compress_model(model)

        dense_layer_compressed_weights = model_for_inference.layers[
            1].get_weights()

        # kernel
        w1, w2 = algorithm.compress_training_weights(
            tf.constant(dense_layer_weights[0]))
        assert (w1 == dense_layer_compressed_weights[0]).numpy().all()
        assert (w2 == dense_layer_compressed_weights[1]).numpy().all()

        # bias
        assert (
            dense_layer_weights[1] == dense_layer_compressed_weights[2]).all()