Пример #1
0
def channel_pruning_manual_mode():

    sess = tf.compat.v1.Session()

    # Construct graph
    with sess.graph.as_default():
        _ = VGG16(weights=None, input_shape=(224, 224, 3))
        init = tf.compat.v1.global_variables_initializer()
    sess.run(init)

    # Create random dataset
    batch_size = 1
    input_data = np.random.rand(100, 224, 224, 3)
    dataset = tf.data.Dataset.from_tensor_slices(input_data)
    dataset = dataset.batch(batch_size=batch_size)

    #  Pick two convs to compress as examples
    block1_conv2_op = sess.graph.get_operation_by_name('block1_conv2/Conv2D')
    block2_conv2_op = sess.graph.get_operation_by_name('block2_conv2/Conv2D')

    list_of_module_comp_ratio_pairs = [
        ModuleCompRatioPair(block1_conv2_op, 0.5),
        ModuleCompRatioPair(block2_conv2_op, 0.5)
    ]

    manual_params = ChannelPruningParameters.ManualModeParams(
        list_of_module_comp_ratio_pairs=list_of_module_comp_ratio_pairs)

    params = ChannelPruningParameters(
        input_op_names=['input_1'],
        output_op_names=['predictions/Softmax'],
        data_set=dataset,
        batch_size=32,
        num_reconstruction_samples=50,
        allow_custom_downsample_ops=False,
        mode=ChannelPruningParameters.Mode.manual,
        params=manual_params,
        multiplicity=8)

    # Single call to compress the model
    results = ModelCompressor.compress_model(
        sess,
        working_dir=None,
        eval_callback=evaluate_model,
        eval_iterations=10,
        input_shape=(32, 224, 224, 3),
        compress_scheme=CompressionScheme.channel_pruning,
        cost_metric=CostMetric.mac,
        parameters=params)

    compressed_model, stats = results
    print(compressed_model)
    print(stats)  # Stats object can be pretty-printed easily
def compress_session(sess, compressible_ops):
    """
    Compressed TF session
    :param sess: Tf session
    :param compressible_ops: layers to compress
    :return: compressed session
    """
    layer_a = sess.graph.get_operation_by_name(compressible_ops[0])
    list_of_module_comp_ratio_pairs = [ModuleCompRatioPair(layer_a, 0.5)]
    manual_params = SpatialSvdParameters.ManualModeParams(
        list_of_module_comp_ratio_pairs=list_of_module_comp_ratio_pairs)
    params = SpatialSvdParameters(input_op_names=['input_1'], output_op_names=['act_softmax/Softmax'],
                                  mode=SpatialSvdParameters.Mode.manual, params=manual_params)
    scheme = CompressionScheme.spatial_svd
    metric = CostMetric.mac

    # pylint: disable=unused-argument
    def evaluate(sess, iterations, use_cuda):
        return 1

    sess, _ = ModelCompressor.compress_model(sess=sess,
                                             working_dir="./",
                                             eval_callback=evaluate,
                                             eval_iterations=None,
                                             input_shape=(1, 3, 224, 224),
                                             compress_scheme=scheme,
                                             cost_metric=metric,
                                             parameters=params)
    return sess
Пример #3
0
def spatial_svd_manual_mode():

    sess = tf.compat.v1.Session()
    # Construct graph
    with sess.graph.as_default():
        _ = VGG16(weights=None, input_shape=(224, 224, 3))
        init = tf.compat.v1.global_variables_initializer()
    sess.run(init)

    # Pick two convs to compress as examples
    conv2d = sess.graph.get_operation_by_name('block1_conv1/Conv2D')
    conv2d_1 = sess.graph.get_operation_by_name('block1_conv2/Conv2D')

    # Specify the necessary parameters
    manual_params = SpatialSvdParameters.ManualModeParams([
        ModuleCompRatioPair(module=conv2d, comp_ratio=0.5),
        ModuleCompRatioPair(module=conv2d_1, comp_ratio=0.4)
    ])

    params = SpatialSvdParameters(input_op_names=['input_1'],
                                  output_op_names=['predictions/Softmax'],
                                  mode=SpatialSvdParameters.Mode.manual,
                                  params=manual_params)

    input_shape = (1, 3, 224, 224)

    # Single call to compress the model
    compr_model_sess, stats = ModelCompressor.compress_model(
        sess=sess,
        working_dir=str('./'),
        eval_callback=evaluate_model,
        eval_iterations=10,
        input_shape=input_shape,
        compress_scheme=CompressionScheme.spatial_svd,
        cost_metric=CostMetric.mac,
        parameters=params,
        trainer=None)

    print(stats)  # Stats object can be pretty-printed easily
Пример #4
0
    def test_channel_pruning_manual_resnet50_keras(self):
        """
        Manual mode test for Keras Resnet50
        """
        AimetLogger.set_level_for_all_areas(logging.INFO)

        graph = tf.Graph()

        with graph.as_default():

            _ = ResNet50(weights=None, input_shape=(224, 224, 3))
            init = tf.compat.v1.global_variables_initializer()

        # Grow GPU memory as needed at the cost of fragmentation.
        config = tf.compat.v1.ConfigProto()
        config.gpu_options.allow_growth = True  # pylint: disable=no-member

        sess = tf.compat.v1.Session(graph=graph, config=config)

        # predicted value of the model
        y_hat = sess.graph.get_tensor_by_name('probs/Softmax:0')

        with sess.graph.as_default():
            # place holder for the labels
            y = tf.compat.v1.placeholder(tf.int64,
                                         shape=[None, 1000],
                                         name='labels')
            # prediction Op
            correct_prediction = tf.equal(tf.argmax(y_hat, axis=1),
                                          tf.argmax(y, axis=1))
            # accuracy Op
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32),
                                      name='accuracy')

        # initialize all the variables
        sess.run(init)

        batch_size = 32
        input_data = np.random.rand(100, 224, 224, 3)
        dataset = tf.data.Dataset.from_tensor_slices(input_data)
        dataset = dataset.batch(batch_size=batch_size)

        conv2_block1_1_conv = sess.graph.get_operation_by_name(
            'conv2_block1_1_conv/Conv2D')
        conv2_block1_2_conv = sess.graph.get_operation_by_name(
            'conv2_block1_2_conv/Conv2D')

        conv3_block1_1_conv = sess.graph.get_operation_by_name(
            'conv3_block1_1_conv/Conv2D')
        conv3_block1_2_conv = sess.graph.get_operation_by_name(
            'conv3_block1_2_conv/Conv2D')

        list_of_module_comp_ratio_pairs = [
            ModuleCompRatioPair(conv2_block1_2_conv, 0.5),
            ModuleCompRatioPair(conv3_block1_2_conv, 0.5)
        ]

        input_op_names = ['input_1']
        output_op_names = ['probs/Softmax']

        manual_params = aimet_tensorflow.defs.ChannelPruningParameters.ManualModeParams(
            list_of_module_comp_ratio_pairs=list_of_module_comp_ratio_pairs)

        params = aimet_tensorflow.defs.ChannelPruningParameters(
            input_op_names=input_op_names,
            output_op_names=output_op_names,
            data_set=dataset,
            batch_size=32,
            num_reconstruction_samples=50,
            allow_custom_downsample_ops=True,
            mode=aimet_tensorflow.defs.ChannelPruningParameters.Mode.manual,
            params=manual_params,
            multiplicity=8)
        # channels_last data format
        input_shape = (32, 224, 224, 3)

        mocked_eval = unittest.mock.MagicMock()
        mocked_eval.side_effect = [70.123, 70.124]

        compr_model_sess, stats = ModelCompressor.compress_model(
            sess=sess,
            working_dir=None,
            eval_callback=mocked_eval,
            eval_iterations=1,
            input_shape=input_shape,
            compress_scheme=aimet_common.defs.CompressionScheme.
            channel_pruning,
            cost_metric=aimet_common.defs.CostMetric.mac,
            parameters=params)

        print(stats)
        all_ops = compr_model_sess.graph.get_operations()
        for op in all_ops:
            if op.type == 'Conv2D':
                print(op.name)

        # conv2_block1_2_conv
        reduced_conv2_block1_1_conv = compr_model_sess.graph.get_operation_by_name(
            'reduced_conv2_block1_1_conv/Conv2D')
        reduced_conv2_block1_2_conv = compr_model_sess.graph.get_operation_by_name(
            'reduced_conv2_block1_2_conv/Conv2D')

        # conv3_block1_2_conv
        reduced_conv3_block1_1_conv = compr_model_sess.graph.get_operation_by_name(
            'reduced_conv3_block1_1_conv/Conv2D')
        reduced_conv3_block1_2_conv = compr_model_sess.graph.get_operation_by_name(
            'reduced_conv3_block1_2_conv/Conv2D')

        # conv2_block1_1_conv after and before compression weight shapes
        self.assertEqual(
            compr_model_sess.run(reduced_conv2_block1_1_conv.inputs[1]).shape,
            (1, 1, 64, 32))
        self.assertEqual(
            sess.run(conv2_block1_1_conv.inputs[1]).shape, (1, 1, 64, 64))

        # conv2_block1_1_conv after and before compression weight shapes
        self.assertEqual(
            compr_model_sess.run(reduced_conv2_block1_2_conv.inputs[1]).shape,
            (3, 3, 32, 64))
        self.assertEqual(
            sess.run(conv2_block1_2_conv.inputs[1]).shape, (3, 3, 64, 64))

        # conv3_block1_1_conv after and before compression weight shapes
        self.assertEqual(
            compr_model_sess.run(reduced_conv3_block1_1_conv.inputs[1]).shape,
            (1, 1, 256, 64))
        self.assertEqual(
            sess.run(conv3_block1_1_conv.inputs[1]).shape, (1, 1, 256, 128))

        # conv3_block1_2_conv after and before compression weight shapes
        self.assertEqual(
            compr_model_sess.run(reduced_conv3_block1_2_conv.inputs[1]).shape,
            (3, 3, 64, 128))
        self.assertEqual(
            sess.run(conv3_block1_2_conv.inputs[1]).shape, (3, 3, 128, 128))

        # Test forward pass through the model with random data and labels
        new_input_data = np.random.rand(32, 224, 224, 3)
        labels = np.random.randint(low=2, size=(32, 1000))
        accuracy_tensor = compr_model_sess.graph.get_tensor_by_name(
            'accuracy:0')
        input_tensor = compr_model_sess.graph.get_tensor_by_name('input_1:0')
        label_tensor = compr_model_sess.graph.get_tensor_by_name('labels:0')
        compr_model_sess.run(accuracy_tensor,
                             feed_dict={
                                 input_tensor: new_input_data,
                                 label_tensor: labels
                             })

        # close original session
        sess.close()

        # close compressed model session
        compr_model_sess.close()

        # delete temp directory
        shutil.rmtree(str('./temp_meta/'))
Пример #5
0
    def test_spatial_svd_compress_manual(self):
        """
        End to end manual mode spatial SVD using Resnet50 Keras model
        :return:
        """
        np.random.seed(1)
        AimetLogger.set_level_for_all_areas(logging.INFO)

        graph = tf.Graph()

        with graph.as_default():

            _ = ResNet50(weights=None, input_shape=(224, 224, 3))
            init = tf.compat.v1.global_variables_initializer()

        # Grow GPU memory as needed at the cost of fragmentation.
        config = tf.compat.v1.ConfigProto()
        config.gpu_options.allow_growth = True  # pylint: disable=no-member

        sess = tf.compat.v1.Session(graph=graph, config=config)

        with sess.graph.as_default():

            # predicted value of the model
            y_hat = sess.graph.get_tensor_by_name('probs/Softmax:0')
            # place holder for the labels
            y = tf.compat.v1.placeholder(tf.int64,
                                         shape=[None, 1000],
                                         name='labels')
            # prediction Op
            correct_prediction = tf.equal(tf.argmax(y_hat, axis=1),
                                          tf.argmax(y, axis=1))
            # accuracy Op
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32),
                                      name='accuracy')

        sess.run(init)
        writer = tf.compat.v1.summary.FileWriter('./', sess.graph)
        # make sure the learning_phase flag is False (inference mode)
        learning_phase = sess.graph.get_tensor_by_name(
            'keras_learning_phase/input:0')
        self.assertFalse(sess.run(learning_phase))

        input_shape = (1, 224, 224, 3)

        conv2_block1_2_conv = sess.graph.get_operation_by_name(
            'conv2_block1_2_conv/Conv2D')
        conv3_block1_2_conv = sess.graph.get_operation_by_name(
            'conv3_block1_2_conv/Conv2D')

        list_of_module_comp_ratio_pairs = [
            ModuleCompRatioPair(conv2_block1_2_conv, 0.5),
            ModuleCompRatioPair(conv3_block1_2_conv, 0.4)
        ]

        manual_params = aimet_tensorflow.defs.SpatialSvdParameters.ManualModeParams(
            list_of_module_comp_ratio_pairs=list_of_module_comp_ratio_pairs)

        params = aimet_tensorflow.defs.SpatialSvdParameters(
            input_op_names=['input_1'],
            output_op_names=['probs/Softmax'],
            mode=aimet_tensorflow.defs.SpatialSvdParameters.Mode.manual,
            params=manual_params,
            multiplicity=8)

        mocked_eval = unittest.mock.MagicMock()
        mocked_eval.side_effect = [87, 64]

        results = ModelCompressor.compress_model(
            sess=sess,
            working_dir=None,
            eval_callback=mocked_eval,
            eval_iterations=5,
            input_shape=input_shape,
            compress_scheme=aimet_common.defs.CompressionScheme.spatial_svd,
            cost_metric=aimet_common.defs.CostMetric.mac,
            parameters=params,
            trainer=None)

        compr_model_sess, stats = results
        print(stats)

        # split ops for res2a_branch2b_Conv2D op
        conv2_block1_2_conv_a = compr_model_sess.graph.get_operation_by_name(
            'conv2_block1_2_conv_a/Conv2D')
        conv2_block1_2_conv_b = compr_model_sess.graph.get_operation_by_name(
            'conv2_block1_2_conv_b/Conv2D')

        # split ops for res3a_branch2b_Conv2D op
        conv3_block1_2_conv_a = compr_model_sess.graph.get_operation_by_name(
            'conv3_block1_2_conv_a/Conv2D')
        conv3_block1_2_conv_b = compr_model_sess.graph.get_operation_by_name(
            'conv3_block1_2_conv_b/Conv2D')

        # res2a_branch2b_Conv2D
        self.assertEqual(
            compr_model_sess.run(conv2_block1_2_conv_a.inputs[1]).shape,
            (3, 1, 64, 48))
        self.assertEqual(
            compr_model_sess.run(conv2_block1_2_conv_b.inputs[1]).shape,
            (1, 3, 48, 64))

        self.assertEqual(
            compr_model_sess.run(conv3_block1_2_conv_a.inputs[1]).shape,
            (3, 1, 128, 80))
        self.assertEqual(
            compr_model_sess.run(conv3_block1_2_conv_b.inputs[1]).shape,
            (1, 3, 80, 128))

        # forward pass to the model with random data and labels
        input_data = np.random.rand(32, 224, 224, 3)
        labels = np.random.randint(low=2, size=(32, 1000))
        accuracy_tensor = compr_model_sess.graph.get_tensor_by_name(
            'accuracy:0')
        input_tensor = compr_model_sess.graph.get_tensor_by_name('input_1:0')
        label_tensor = compr_model_sess.graph.get_tensor_by_name('labels:0')

        # make sure the learning_phase flag is False (inference mode)
        learning_phase = compr_model_sess.graph.get_tensor_by_name(
            'keras_learning_phase/input:0')
        self.assertFalse(compr_model_sess.run(learning_phase))

        compr_model_sess.run(accuracy_tensor,
                             feed_dict={
                                 input_tensor: input_data,
                                 label_tensor: labels
                             })

        # close original session
        sess.close()
        # close compressed model session
        compr_model_sess.close()

        # delete temp directory
        shutil.rmtree(str('./temp_meta/'))
Пример #6
0
    def test_svd_followed_by_channel_pruning(self):
        """ Test that a model can be run through spatial svd and then channel pruning """
        sess = tf.compat.v1.Session()
        with sess.graph.as_default():
            _ = model_with_three_convs()
            init = tf.compat.v1.global_variables_initializer()
        sess.run(init)

        conv2d_1 = sess.graph.get_operation_by_name('conv2d_1/Conv2D')

        list_of_module_comp_ratio_pairs = [ModuleCompRatioPair(conv2d_1, 0.5)]

        manual_params = aimet_tensorflow.defs.SpatialSvdParameters.ManualModeParams(
            list_of_module_comp_ratio_pairs=list_of_module_comp_ratio_pairs)

        input_op_names = ['input_1']
        output_op_names = ['three_convs/Softmax']
        params = aimet_tensorflow.defs.SpatialSvdParameters(
            input_op_names=input_op_names,
            output_op_names=output_op_names,
            mode=aimet_tensorflow.defs.SpatialSvdParameters.Mode.manual,
            params=manual_params,
            multiplicity=1)

        mocked_eval = unittest.mock.MagicMock()
        mocked_eval.side_effect = [87, 87]

        input_shape = (1, 8, 8, 3)
        sess, _ = ModelCompressor.compress_model(
            sess=sess,
            working_dir=None,
            eval_callback=mocked_eval,
            eval_iterations=5,
            input_shape=input_shape,
            compress_scheme=aimet_common.defs.CompressionScheme.spatial_svd,
            cost_metric=aimet_common.defs.CostMetric.mac,
            parameters=params,
            trainer=None)

        # Check that svd added these ops
        _ = sess.graph.get_operation_by_name('conv2d_1_a/Conv2D')
        _ = sess.graph.get_operation_by_name('conv2d_1_b/Conv2D')

        greedy_params = aimet_common.defs.GreedySelectionParameters(
            target_comp_ratio=Decimal(0.5),
            num_comp_ratio_candidates=4,
            use_monotonic_fit=True,
            saved_eval_scores_dict=None)

        conv_to_ignore = sess.graph.get_operation_by_name('conv2d/Conv2D')
        auto_params = aimet_tensorflow.defs.ChannelPruningParameters.AutoModeParams(
            greedy_select_params=greedy_params,
            modules_to_ignore=[conv_to_ignore])

        dataset = np.random.rand(1, 1, 8, 8, 3)
        dataset = tf.convert_to_tensor(dataset)
        dataset = tf.data.Dataset.from_tensor_slices(dataset)

        params = aimet_tensorflow.defs.ChannelPruningParameters(
            input_op_names=input_op_names,
            output_op_names=output_op_names,
            data_set=dataset,
            batch_size=32,
            num_reconstruction_samples=50,
            allow_custom_downsample_ops=False,
            mode=aimet_tensorflow.defs.ChannelPruningParameters.Mode.auto,
            params=auto_params,
            multiplicity=1)

        mocked_eval = unittest.mock.MagicMock()
        mocked_eval.side_effect = [0, .5, 1, 0, .5, 1, 0, .5, 1, 0, 1]

        sess, _ = ModelCompressor.compress_model(
            sess=sess,
            working_dir=None,
            eval_callback=mocked_eval,
            eval_iterations=1,
            input_shape=input_shape,
            compress_scheme=aimet_common.defs.CompressionScheme.
            channel_pruning,
            cost_metric=aimet_common.defs.CostMetric.mac,
            parameters=params)

        # Check that these ops were added by cp
        _ = sess.graph.get_operation_by_name(
            'reduced_reduced_conv2d_1_a/Conv2D')
        _ = sess.graph.get_operation_by_name(
            'reduced_reduced_conv2d_1_b/Conv2D')
        _ = sess.graph.get_operation_by_name('reduced_conv2d_2/Conv2D')