예제 #1
0
def test_delete_all_channels_in_long_branch():
    input_1 = Input(shape=(20, 20, 3))
    conv_1 = Conv2D(2, [3, 3], name='conv_1')
    conv_2 = Conv2D(3, [3, 3], name='conv_2')
    conv_3 = Conv2D(4, [1, 1], name='conv_3')
    cat_1 = Concatenate(name='cat_1')

    x = conv_1(input_1)
    x = conv_3(x)
    y = conv_2(input_1)
    output_1 = cat_1([x, y])
    model_1 = utils.clean_copy(Model(input_1, output_1))

    surgeon = Surgeon(model_1, copy=True)
    surgeon.add_job('delete_channels',
                    model_1.get_layer('conv_1'),
                    channels=[0, 1])
    model_2 = surgeon.operate()

    output_1 = conv_2(input_1)
    model_2_exp = utils.clean_copy(Model(input_1, output_1))

    config_1 = model_2.get_config()
    config_2 = model_2_exp.get_config()
    config_2['name'] = config_1['name']  # make the config names identical
    assert config_1 == config_2
예제 #2
0
def layer_test_helper_flatten_1d(layer, channel_index):
    # This should test that the output is the correct shape so it should pass
    # into a Dense layer rather than a Conv layer.
    # The weighted layer is the previous layer,
    # Create model
    main_input = Input(shape=list(random.randint(10, 20, size=2)))
    x = Conv1D(3, 3)(main_input)
    x = layer(x)
    x = Flatten()(x)
    main_output = Dense(5)(x)
    model = Model(inputs=main_input, outputs=main_output)

    # Delete channels
    del_layer_index = 1
    next_layer_index = 4
    del_layer = model.layers[del_layer_index]
    surgeon = Surgeon(model)
    surgeon.add_job('delete_channels', del_layer, channels=channel_index)
    new_model = surgeon.operate()
    new_w = new_model.layers[next_layer_index].get_weights()

    # Calculate next layer's correct weights
    flat_sz = np.prod(layer.get_output_shape_at(0)[1:])
    channel_count = getattr(del_layer, utils.get_channels_attr(del_layer))
    channel_index = [i % channel_count for i in channel_index]
    delete_indices = [
        x + i for i in range(0, flat_sz, channel_count) for x in channel_index
    ]

    correct_w = model.layers[next_layer_index].get_weights()
    correct_w[0] = np.delete(correct_w[0], delete_indices, axis=0)

    assert weights_equal(correct_w, new_w)
예제 #3
0
def test_rebuild_submodel(model_2):
    output_nodes = []
    for output in model_2.outputs:
        layer, node_index, tensor_index = output._keras_history
        output_nodes.append(get_inbound_nodes(layer)[node_index])
    surgeon = Surgeon(model_2)
    outputs, _ = surgeon._rebuild_graph(model_2.inputs, output_nodes)
    new_model = Model(model_2.inputs, outputs)
    assert compare_models(model_2, new_model)
예제 #4
0
def test_delete_channels_merge_concatenate(channel_index, data_format):
    # This should test that the output is the correct shape so it should pass
    # into a Dense layer rather than a Conv layer.
    # The weighted layer is the previous layer,
    # Create model
    if data_format == 'channels_first':
        axis = 1
    elif data_format == 'channels_last':
        axis = -1
    else:
        raise ValueError

    input_shape = list(random.randint(10, 20, size=3))
    input_1 = Input(shape=input_shape)
    input_2 = Input(shape=input_shape)
    x = Conv2D(3, [3, 3], data_format=data_format, name='conv_1')(input_1)
    y = Conv2D(3, [3, 3], data_format=data_format, name='conv_2')(input_2)
    x = Concatenate(axis=axis, name='cat_1')([x, y])
    x = Flatten()(x)
    main_output = Dense(5, name='dense_1')(x)
    model = Model(inputs=[input_1, input_2], outputs=main_output)
    old_w = model.get_layer('dense_1').get_weights()

    # Delete channels
    layer = model.get_layer('cat_1')
    del_layer = model.get_layer('conv_1')
    surgeon = Surgeon(model, copy=True)
    surgeon.add_job('delete_channels', del_layer, channels=channel_index)
    new_model = surgeon.operate()
    new_w = new_model.get_layer('dense_1').get_weights()

    # Calculate next layer's correct weights
    flat_sz = np.prod(layer.get_output_shape_at(0)[1:])
    channel_count = getattr(del_layer, utils.get_channels_attr(del_layer))
    channel_index = [i % channel_count for i in channel_index]
    if data_format == 'channels_first':
        delete_indices = [
            x * flat_sz // 2 // channel_count + i for x in channel_index
            for i in range(
                0,
                flat_sz // 2 // channel_count,
            )
        ]
    elif data_format == 'channels_last':
        delete_indices = [
            x + i for i in range(0, flat_sz, channel_count * 2)
            for x in channel_index
        ]
    else:
        raise ValueError
    correct_w = model.get_layer('dense_1').get_weights()
    correct_w[0] = np.delete(correct_w[0], delete_indices, axis=0)

    assert weights_equal(correct_w, new_w)
예제 #5
0
파일: random.py 프로젝트: csxeba/Verres
 def prune(self, keep_ratio):
     surgeon = Surgeon(self.model, copy=True)
     filter_masks = self._produce_filter_pruning_mask(keep_ratio)
     for filter_mask, layer in zip(filter_masks, self.model.layers):
         drop_indices = np.argwhere(filter_mask)[:, 0]
         if drop_indices.size == filter_mask.size:
             drop_indices = drop_indices[1:]
         if drop_indices.size:
             surgeon.add_job("delete_channels",
                             layer,
                             channels=drop_indices)
     return surgeon.operate()
def prune_model(model, apoz_df, n_channels_delete):
    # Identify 5% of channels with the highest APoZ in model
    sorted_apoz_df = apoz_df.sort_values('apoz', ascending=False)
    high_apoz_index = sorted_apoz_df.iloc[0:n_channels_delete, :]

    # Create the Surgeon and add a 'delete_channels' job for each layer
    # whose channels are to be deleted.
    surgeon = Surgeon(model, copy=True)
    for name in high_apoz_index.index.unique().values:
        channels = list(pd.Series(high_apoz_index.loc[name, 'index'],
                                  dtype=np.int64).values)
        surgeon.add_job('delete_channels', model.get_layer(name),
                        channels=channels)
    # Delete channels
    return surgeon.operate()
예제 #7
0
 def prune(self, x, y, keep_ratio):
     saliencies = self._get_saliencies([x, y])
     filter_masks, filter_saliencies = self._produce_filter_pruning_mask(
         saliencies, keep_ratio)
     surgeon = Surgeon(self.model, copy=True)
     for filter_mask, saliency, weight in zip(filter_masks,
                                              filter_saliencies,
                                              self.weights_of_interest):
         layer_name = self.weight_to_layer[weight.name]
         layer = self.model.get_layer(name=layer_name)
         drop_indices = np.squeeze(np.argwhere(filter_mask))
         if drop_indices.size == filter_mask.size:
             best_filter = saliency.argmax()
             drop_indices = np.delete(drop_indices, best_filter)
         if drop_indices.shape:
             surgeon.add_job("delete_channels",
                             layer,
                             channels=drop_indices)
     return surgeon.operate()
예제 #8
0
def test_delete_channels_downstream_sharing():
    # Create all model layers
    input_1 = Input(shape=(5, ))
    dense_1 = Dense(4, name='dense_1')
    dense_2 = Dense(4, name='dense_2')
    dense_3 = Dense(3, name='dense_3')
    # Create the base model
    x = dense_1(input_1)
    y = dense_2(input_1)
    output_1 = dense_3(x)
    output_2 = dense_3(y)
    model_1 = utils.clean_copy(Model(input_1, [output_1, output_2]))
    # Delete channels from dense_1 and dense_2
    surgeon = Surgeon(model_1)
    surgeon.add_job('delete_channels',
                    model_1.get_layer(dense_1.name),
                    channels=[0])
    surgeon.add_job('delete_channels',
                    model_1.get_layer(dense_2.name),
                    channels=[1])
    model_2 = surgeon.operate()
    # Create the expected model
    # input_1 = Input(shape=(5,))
    dense_1_exp = Dense(3, name='dense_1')
    dense_2_exp = Dense(3, name='dense_2')
    dense_3_exp = Dense(3, name='dense_3')
    # Create the base model
    x = dense_1_exp(input_1)
    y = dense_2_exp(input_1)
    output_1 = dense_3_exp(x)
    output_2 = dense_3_exp(y)
    model_2_exp = utils.clean_copy(Model(input_1, [output_1, output_2]))

    config_1 = model_2.get_config()
    config_2 = model_2_exp.get_config()
    config_2['name'] = config_1['name']  # make the config names identical
    assert config_1 == config_2