示例#1
0
def test_find_activation_layer():
    conv1_filters = 1
    conv2_filters = 1
    dense_units = 1
    model = Sequential()
    model.add(
        Conv2D(conv1_filters, [3, 3],
               input_shape=(28, 28, 1),
               data_format="channels_last",
               name='conv_1'))
    model.add(Activation('relu', name='act_1'))
    model.add(MaxPool2D((2, 2), name='pool_1'))
    model.add(
        Conv2D(conv2_filters, [3, 3],
               data_format="channels_last",
               name='conv_2'))
    model.add(Activation('relu', name='act_2'))
    model.add(MaxPool2D((2, 2), name='pool_2'))
    model.add(Flatten(name='flat_1'))
    model.add(Dense(dense_units, name='dense_1'))
    model.add(Activation('relu', name='act_3'))
    model.add(Dense(10, name='dense_2'))
    model.add(Activation('softmax', name='act_4'))
    assert find_activation_layer(model.get_layer('conv_1'),
                                 0) == (model.get_layer('act_1'), 0)
    assert find_activation_layer(model.get_layer('conv_2'),
                                 0) == (model.get_layer('act_2'), 0)
    assert find_activation_layer(model.get_layer('dense_1'),
                                 0) == (model.get_layer('act_3'), 0)
    assert find_activation_layer(model.get_layer('dense_2'),
                                 0) == (model.get_layer('act_4'), 0)
示例#2
0
def test_find_activation_layer():
    conv1_filters = 1
    conv2_filters = 1
    dense_units = 1
    model = Sequential()
    model.add(
        Conv2D(
            conv1_filters,
            [3, 3],
            input_shape=(28, 28, 1),
            data_format="channels_last",
            name="conv_1",
        ))
    model.add(Activation("relu", name="act_1"))
    model.add(MaxPool2D((2, 2), name="pool_1"))
    model.add(
        Conv2D(conv2_filters, [3, 3],
               data_format="channels_last",
               name="conv_2"))
    model.add(Activation("relu", name="act_2"))
    model.add(MaxPool2D((2, 2), name="pool_2"))
    model.add(Flatten(name="flat_1"))
    model.add(Dense(dense_units, name="dense_1"))
    model.add(Activation("relu", name="act_3"))
    model.add(Dense(10, name="dense_2"))
    model.add(Activation("softmax", name="act_4"))
    assert find_activation_layer(model.get_layer("conv_1"), 0) == (
        model.get_layer("act_1"),
        0,
    )
    assert find_activation_layer(model.get_layer("conv_2"), 0) == (
        model.get_layer("act_2"),
        0,
    )
    assert find_activation_layer(model.get_layer("dense_1"), 0) == (
        model.get_layer("act_3"),
        0,
    )
    assert find_activation_layer(model.get_layer("dense_2"), 0) == (
        model.get_layer("act_4"),
        0,
    )
示例#3
0
def get_channels_apoz_importance(model, layer, x_val, node_indices=None):
    if isinstance(layer, str):
        layer = model.get_layer(name=layer)

    # Check that layer is in the model
    if layer not in model.layers:
        raise ValueError('layer is not a valid Layer in model.')

    layer_node_indices = utils.find_nodes_in_model(model, layer)
    # If no nodes are specified, all of the layer's inbound nodes which are
    # in model are selected.
    if not node_indices:
        node_indices = layer_node_indices
    # Check for duplicate node indices
    elif len(node_indices) != len(set(node_indices)):
        raise ValueError('`node_indices` contains duplicate values.')
    # Check that all of the selected nodes are in the layer
    elif not set(node_indices).issubset(layer_node_indices):
        raise ValueError('One or more nodes specified by `layer` and '
                         '`node_indices` are not in `model`.')

    data_format = getattr(layer, 'data_format', 'channels_last')
    # Perform the forward pass and get the activations of the layer.
    mean_calculator = utils.MeanCalculator(sum_axis=0)
    print('layer:', layer, layer_node_indices, node_indices)

    for node_index in node_indices:
        act_layer, act_index = utils.find_activation_layer(layer, node_index)
        print('act layer', act_layer, act_index)
        # Get activations
        if hasattr(x_val, "__iter__"):
            temp_model = Model(model.inputs,
                               act_layer.get_output_at(act_index))
            print('before: act output', act_layer.get_output_at(act_index))
            a = temp_model.predict(x_val)
            #a=temp_model.predict_generator(x_val, x_val.n // x_val.batch_size)
            print('after:', layer, a.shape)
        else:
            get_activations = K.function(
                [single_element(model.inputs),
                 K.learning_phase()], [act_layer.get_output_at(act_index)])
            a = get_activations([x_val, 0])[0]
            # Ensure that the channels axis is last
        if data_format == 'channels_first':
            a = np.swapaxes(a, 1, -1)
        # Flatten all except channels axis
        activations = np.reshape(a, [-1, a.shape[-1]])
        zeros = (activations == 0).astype(int)
        mean_calculator.add(zeros)

    return mean_calculator.calculate()
示例#4
0
def get_apoz(model, layer, x_val, node_indices=None, batch_size=1):
    """Identify neurons with high Average Percentage of Zeros (APoZ).

    The APoZ a.k.a. (A)verage (P)ercentage (o)f activations equal to (Z)ero,
    is a metric for the usefulness of a channel defined in this paper:
    "Network Trimming: A Data-Driven Neuron Pruning Approach towards Efficient
    Deep Architectures" - [Hu et al. (2016)][]
    `high_apoz()` enables the pruning methodology described in this paper to be
    replicated.

    If node_indices are not specified and the layer is shared within the model
    the APoZ will be calculated over all instances of the shared layer.

    Args:
        model: A Keras model.
        layer: The layer whose channels will be evaluated for pruning.
        x_val: The input of the validation set. This will be used to calculate
            the activations of the layer of interest.
        node_indices(list[int]): (optional) A list of node indices.

    Returns:
        List of the APoZ values for each channel in the layer.
    """

    if isinstance(layer, str):
        layer = model.get_layer(name=layer)

    # Check that layer is in the model
    if layer not in model.layers:
        raise ValueError('layer is not a valid Layer in model.')

    layer_node_indices = utils.find_nodes_in_model(model, layer)
    # If no nodes are specified, all of the layer's inbound nodes which are
    # in model are selected.
    if not node_indices:
        node_indices = layer_node_indices
    # Check for duplicate node indices
    elif len(node_indices) != len(set(node_indices)):
        raise ValueError('`node_indices` contains duplicate values.')
    # Check that all of the selected nodes are in the layer
    elif not set(node_indices).issubset(layer_node_indices):
        raise ValueError('One or more nodes specified by `layer` and '
                         '`node_indices` are not in `model`.')

    data_format = getattr(layer, 'data_format', 'channels_last')
    # Perform the forward pass and get the activations of the layer.
    mean_calculator = utils.MeanCalculator(sum_axis=0)
    for node_index in node_indices:
        act_layer, act_index = utils.find_activation_layer(layer, node_index)
        # Get activations
        if isinstance(x_val, np.ndarray):
            temp_model = Model(model.inputs,
                               act_layer.get_output_at(act_index))
            a = temp_model.predict_generator(
                x_val, x_val.shape[0] // batch_size)
        elif hasattr(x_val, "__iter__"):
            temp_model = Model(model.inputs,
                               act_layer.get_output_at(act_index))
            a = temp_model.predict_generator(
                x_val, x_val.n // batch_size)
        else:
            get_activations = k.function(
                [utils.single_element(model.inputs), k.learning_phase()],
                [act_layer.get_output_at(act_index)])
            a = get_activations([x_val, 0])[0]
            # Ensure that the channels axis is last
        if data_format == 'channels_first':
            a = np.swapaxes(a, 1, -1)
        # Flatten all except channels axis
        activations = np.reshape(a, [-1, a.shape[-1]])
        zeros = (activations == 0).astype(int)
        mean_calculator.add(zeros)

    return mean_calculator.calculate()
示例#5
0
def get_activations(model, layer, x_val):
    act_layer, act_index = utils.find_activation_layer(layer, 0)

    temp_model = Model(inputs=model.inputs,
                       outputs=act_layer.get_output_at(act_index))
    return temp_model.predict(x_val)
示例#6
0
def get_output_sum(model, layer, x_val, node_indices=None, steps=None):
    """
    Args:
        model: A Keras model.
        layer: The layer whose channels will be evaluated for pruning.
        x_val: The input of the validation set. This will be used to calculate
            the activations of the layer of interest.
        node_indices(list[int]): (optional) A list of node indices.
        steps: number of steps for a generator 

    Returns:
        total: total output given a dataset from each kernel

    """

    if isinstance(layer, str):
        layer = model.get_layer(name=layer)

    # Check that layer is in the model
    if layer not in model.layers:
        raise ValueError('layer is not a valid Layer in model.')

    layer_node_indices = utils.find_nodes_in_model(model, layer)
    # If no nodes are specified, all of the layer's inbound nodes which are
    # in model are selected.
    if not node_indices:
        node_indices = layer_node_indices
    # Check for duplicate node indices
    elif len(node_indices) != len(set(node_indices)):
        raise ValueError('`node_indices` contains duplicate values.')
    # Check that all of the selected nodes are in the layer
    elif not set(node_indices).issubset(layer_node_indices):
        raise ValueError('One or more nodes specified by `layer` and '
                         '`node_indices` are not in `model`.')

    data_format = getattr(layer, 'data_format', 'channels_last')
    # Perform the forward pass and get the activations of the layer.
    total_sum = None
    for node_index in node_indices:
        act_layer, act_index = utils.find_activation_layer(layer, node_index)
        # Get activations
        if isinstance(x_val, types.GeneratorType):

            # temp_model = Model(model.inputs, act_layer.get_output_at(act_index))
            temp_model = Model(model.inputs, layer.get_output_at(node_index))
            a = temp_model.predict_generator_intermediate(x_val, steps=steps)

        else:
            get_activations = k.function(
                [utils.single_element(model.inputs),
                 k.learning_phase()], [act_layer.get_output_at(act_index)])
            a = get_activations([x_val, 0])[0]

        # Ensure that the channels axis is last
        if data_format == 'channels_first':
            a = np.swapaxes(a, 1, -1)

        numAxes = len(a.shape) - 1
        total = np.sum(a, axis=numAxes)
        for n in range(numAxes - 1, -1, -1):
            total = np.sum(total, axis=n)

        # previous - for time distributed convolution
        # a = np.abs(a)
        # total = np.sum(a, axis=2)
        # total = np.sum(total, axis=1)
        # total = np.sum(total, axis=0)

        if total_sum is None:
            total_sum = total
        else:
            total_sum += total

    return total_sum