def check_metadata(component_type_string,
                   target_class=None,
                   layer_name=None,
                   ideal_activation=None,
                   neuron_indices=None,
                   channel_index=None):
    """Error-checks metadata for saliency calculations.

    :param component_type_string: Component type (must be accepted by
        `model_interpretation.check_component_type`).
    :param target_class: See doc for `get_saliency_maps_for_class_activation`.
    :param layer_name: See doc for `get_saliency_maps_for_neuron_activation` or
        `get_saliency_maps_for_channel_activation`.
    :param ideal_activation: Same.
    :param neuron_indices: See doc for
        `get_saliency_maps_for_neuron_activation`.
    :param channel_index: See doc for `get_saliency_maps_for_class_activation`.

    :return: metadata_dict: Dictionary with the following keys.
    metadata_dict['component_type_string']: See input doc.
    metadata_dict['target_class']: Same.
    metadata_dict['layer_name']: Same.
    metadata_dict['ideal_activation']: Same.
    metadata_dict['neuron_indices']: Same.
    metadata_dict['channel_index']: Same.
    """

    model_interpretation.check_component_type(component_type_string)
    if (component_type_string ==
            model_interpretation.CLASS_COMPONENT_TYPE_STRING):
        error_checking.assert_is_integer(target_class)
        error_checking.assert_is_geq(target_class, 0)

    if component_type_string in [
            model_interpretation.NEURON_COMPONENT_TYPE_STRING,
            model_interpretation.CHANNEL_COMPONENT_TYPE_STRING
    ]:
        error_checking.assert_is_string(layer_name)
        if ideal_activation is not None:
            error_checking.assert_is_greater(ideal_activation, 0.)

    if (component_type_string ==
            model_interpretation.NEURON_COMPONENT_TYPE_STRING):
        error_checking.assert_is_integer_numpy_array(neuron_indices)
        error_checking.assert_is_geq_numpy_array(neuron_indices, 0)
        error_checking.assert_is_numpy_array(neuron_indices, num_dimensions=1)

    if (component_type_string ==
            model_interpretation.CHANNEL_COMPONENT_TYPE_STRING):
        error_checking.assert_is_integer(channel_index)
        error_checking.assert_is_geq(channel_index, 0)

    return {
        COMPONENT_TYPE_KEY: component_type_string,
        TARGET_CLASS_KEY: target_class,
        LAYER_NAME_KEY: layer_name,
        IDEAL_ACTIVATION_KEY: ideal_activation,
        NEURON_INDICES_KEY: neuron_indices,
        CHANNEL_INDEX_KEY: channel_index
    }
Exemple #2
0
def check_metadata(component_type_string,
                   target_class=None,
                   layer_name=None,
                   neuron_index_matrix=None,
                   channel_indices=None):
    """Error-checks metadata for activation calculations.

    C = number of model components (classes, neurons, or channels) for which
        activations were computed

    :param component_type_string: Component type (must be accepted by
        `model_interpretation.check_component_type`).
    :param target_class: See doc for `get_class_activation_for_examples`.
    :param layer_name: See doc for `get_neuron_activation_for_examples` or
        `get_channel_activation_for_examples`.
    :param neuron_index_matrix: [used only if component_type_string = "neuron"]
        C-by-? numpy array, where neuron_index_matrix[j, :] contains array
        indices of the [j]th neuron whose activation was computed.
    :param channel_indices: [used only if component_type_string = "channel"]
        length-C numpy array, where channel_indices[j] is the index of the
        [j]th channel whose activation was computed.
    :return: num_components: Number of model components (classes, neurons, or
        channels) whose activation was computed.
    """

    model_interpretation.check_component_type(component_type_string)

    if (component_type_string ==
            model_interpretation.CLASS_COMPONENT_TYPE_STRING):
        error_checking.assert_is_integer(target_class)
        error_checking.assert_is_geq(target_class, 0)
        num_components = 1

    if component_type_string in [
            model_interpretation.NEURON_COMPONENT_TYPE_STRING,
            model_interpretation.CHANNEL_COMPONENT_TYPE_STRING
    ]:
        error_checking.assert_is_string(layer_name)

    if (component_type_string ==
            model_interpretation.NEURON_COMPONENT_TYPE_STRING):
        error_checking.assert_is_integer_numpy_array(neuron_index_matrix)
        error_checking.assert_is_geq_numpy_array(neuron_index_matrix, 0)
        error_checking.assert_is_numpy_array(neuron_index_matrix,
                                             num_dimensions=2)
        num_components = neuron_index_matrix.shape[0]

    if (component_type_string ==
            model_interpretation.CHANNEL_COMPONENT_TYPE_STRING):
        error_checking.assert_is_integer_numpy_array(channel_indices)
        error_checking.assert_is_geq_numpy_array(channel_indices, 0)
        num_components = len(channel_indices)

    return num_components
def _run(model_file_name, init_function_name, component_type_string,
         target_class, layer_name, neuron_indices, channel_index,
         ideal_activation, num_iterations, learning_rate, output_file_name):
    """Runs backwards optimization on a trained CNN.

    This is effectively the main method.

    :param model_file_name: See documentation at top of file.
    :param init_function_name: Same.
    :param component_type_string: Same.
    :param target_class: Same.
    :param layer_name: Same.
    :param neuron_indices: Same.
    :param channel_index: Same.
    :param ideal_activation: Same.
    :param num_iterations: Same.
    :param learning_rate: Same.
    :param output_file_name: Same.
    """

    model_interpretation.check_component_type(component_type_string)
    if ideal_activation <= 0:
        ideal_activation = None

    print('Reading model from: "{0:s}"...'.format(model_file_name))
    model_object = load_keras_model(
        model_file_name,
        custom_objects={'brier_skill_score_keras': _brier_skill_score_keras})

    init_function = _create_initializer(init_function_name)
    print(SEPARATOR_STRING)

    if component_type_string == CLASS_COMPONENT_TYPE_STRING:
        print(
            'Optimizing image for target class {0:d}...'.format(target_class))

        result_dict = backwards_opt.optimize_input_for_class(
            model_object=model_object,
            target_class=target_class,
            init_function_or_matrices=init_function,
            num_iterations=num_iterations,
            learning_rate=learning_rate)

    elif component_type_string == NEURON_COMPONENT_TYPE_STRING:
        print('Optimizing image for neuron {0:s} in layer "{1:s}"...'.format(
            str(neuron_indices), layer_name))

        result_dict = backwards_opt.optimize_input_for_neuron(
            model_object=model_object,
            layer_name=layer_name,
            neuron_indices=neuron_indices,
            init_function_or_matrices=init_function,
            num_iterations=num_iterations,
            learning_rate=learning_rate,
            ideal_activation=ideal_activation)

    else:
        print('Optimizing image for channel {0:d} in layer "{1:s}"...'.format(
            channel_index, layer_name))

        result_dict = backwards_opt.optimize_input_for_channel(
            model_object=model_object,
            layer_name=layer_name,
            channel_index=channel_index,
            init_function_or_matrices=init_function,
            stat_function_for_neuron_activations=K.max,
            num_iterations=num_iterations,
            learning_rate=learning_rate,
            ideal_activation=ideal_activation)

    print(SEPARATOR_STRING)

    initial_activations = numpy.array(
        [result_dict[backwards_opt.INITIAL_ACTIVATION_KEY]])
    final_activations = numpy.array(
        [result_dict[backwards_opt.FINAL_ACTIVATION_KEY]])

    print('Denormalizing input and output (optimized) example...')
    denorm_input_matrix = _denormalize_data(
        result_dict[backwards_opt.NORM_INPUT_MATRICES_KEY])
    denorm_output_matrix = _denormalize_data(
        result_dict[backwards_opt.NORM_OUTPUT_MATRICES_KEY])

    print('Writing results to: "{0:s}"...'.format(output_file_name))
    bwo_metadata_dict = backwards_opt.check_metadata(
        component_type_string=component_type_string,
        num_iterations=num_iterations,
        learning_rate=learning_rate,
        target_class=target_class,
        layer_name=layer_name,
        ideal_activation=ideal_activation,
        neuron_indices=neuron_indices,
        channel_index=channel_index,
        l2_weight=None,
        radar_constraint_weight=None,
        minmax_constraint_weight=None)

    backwards_opt.write_standard_file(
        pickle_file_name=output_file_name,
        denorm_input_matrices=[denorm_input_matrix],
        denorm_output_matrices=[denorm_output_matrix],
        initial_activations=initial_activations,
        final_activations=final_activations,
        model_file_name=model_file_name,
        metadata_dict=bwo_metadata_dict,
        full_storm_id_strings=None,
        storm_times_unix_sec=None,
        sounding_pressure_matrix_pa=None)
def _run(model_file_name, component_type_string, target_class, layer_name,
         neuron_indices_flattened, channel_indices, top_example_dir_name,
         first_spc_date_string, last_spc_date_string, output_file_name):
    """Creates activation maps for one class, neuron, or channel of a CNN.

    This is effectively the main method.

    :param model_file_name: See documentation at top of file.
    :param component_type_string: Same.
    :param target_class: Same.
    :param layer_name: Same.
    :param neuron_indices_flattened: Same.
    :param channel_indices: Same.
    :param top_example_dir_name: Same.
    :param first_spc_date_string: Same.
    :param last_spc_date_string: Same.
    :param output_file_name: Same.
    """

    # Check input args.
    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)
    model_interpretation.check_component_type(component_type_string)

    if component_type_string == CHANNEL_COMPONENT_TYPE_STRING:
        error_checking.assert_is_geq_numpy_array(channel_indices, 0)
    if component_type_string == NEURON_COMPONENT_TYPE_STRING:
        neuron_indices_flattened = neuron_indices_flattened.astype(float)
        neuron_indices_flattened[neuron_indices_flattened < 0] = numpy.nan

        neuron_indices_2d_list = general_utils.split_array_by_nan(
            neuron_indices_flattened)
        neuron_index_matrix = numpy.array(neuron_indices_2d_list, dtype=int)
    else:
        neuron_index_matrix = None

    # Read model and metadata.
    print('Reading model from: "{0:s}"...'.format(model_file_name))
    model_object = cnn.read_model(model_file_name)

    metadata_file_name = '{0:s}/model_metadata.p'.format(
        os.path.split(model_file_name)[0])

    print('Reading metadata from: "{0:s}"...'.format(metadata_file_name))
    model_metadata_dict = cnn.read_model_metadata(metadata_file_name)
    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]

    # Create generator.
    example_file_names = input_examples.find_many_example_files(
        top_directory_name=top_example_dir_name,
        shuffled=False,
        first_spc_date_string=first_spc_date_string,
        last_spc_date_string=last_spc_date_string,
        raise_error_if_any_missing=False)

    training_option_dict[trainval_io.SAMPLING_FRACTIONS_KEY] = None
    training_option_dict[trainval_io.EXAMPLE_FILES_KEY] = example_file_names
    training_option_dict[trainval_io.FIRST_STORM_TIME_KEY] = (
        time_conversion.get_start_of_spc_date(first_spc_date_string))
    training_option_dict[trainval_io.LAST_STORM_TIME_KEY] = (
        time_conversion.get_end_of_spc_date(last_spc_date_string))

    if model_metadata_dict[cnn.LAYER_OPERATIONS_KEY] is not None:
        generator_object = testing_io.gridrad_generator_2d_reduced(
            option_dict=training_option_dict,
            list_of_operation_dicts=model_metadata_dict[
                cnn.LAYER_OPERATIONS_KEY],
            num_examples_total=LARGE_INTEGER)

    elif model_metadata_dict[cnn.CONV_2D3D_KEY]:
        generator_object = testing_io.myrorss_generator_2d3d(
            option_dict=training_option_dict, num_examples_total=LARGE_INTEGER)
    else:
        generator_object = testing_io.generator_2d_or_3d(
            option_dict=training_option_dict, num_examples_total=LARGE_INTEGER)

    # Compute activation for each example (storm object) and model component.
    full_id_strings = []
    storm_times_unix_sec = numpy.array([], dtype=int)
    activation_matrix = None

    print(SEPARATOR_STRING)

    for _ in range(len(example_file_names)):
        try:
            this_storm_object_dict = next(generator_object)
        except StopIteration:
            break

        this_list_of_input_matrices = this_storm_object_dict[
            testing_io.INPUT_MATRICES_KEY]
        these_id_strings = this_storm_object_dict[testing_io.FULL_IDS_KEY]
        these_times_unix_sec = this_storm_object_dict[
            testing_io.STORM_TIMES_KEY]

        full_id_strings += these_id_strings
        storm_times_unix_sec = numpy.concatenate(
            (storm_times_unix_sec, these_times_unix_sec))

        if component_type_string == CLASS_COMPONENT_TYPE_STRING:
            print('Computing activations for target class {0:d}...'.format(
                target_class))

            this_activation_matrix = (
                model_activation.get_class_activation_for_examples(
                    model_object=model_object,
                    target_class=target_class,
                    list_of_input_matrices=this_list_of_input_matrices))

            this_activation_matrix = numpy.reshape(
                this_activation_matrix, (len(this_activation_matrix), 1))

        elif component_type_string == NEURON_COMPONENT_TYPE_STRING:
            this_activation_matrix = None

            for j in range(neuron_index_matrix.shape[0]):
                print((
                    'Computing activations for neuron {0:s} in layer "{1:s}"...'
                ).format(str(neuron_index_matrix[j, :]), layer_name))

                these_activations = (
                    model_activation.get_neuron_activation_for_examples(
                        model_object=model_object,
                        layer_name=layer_name,
                        neuron_indices=neuron_index_matrix[j, :],
                        list_of_input_matrices=this_list_of_input_matrices))

                these_activations = numpy.reshape(these_activations,
                                                  (len(these_activations), 1))

                if this_activation_matrix is None:
                    this_activation_matrix = these_activations + 0.
                else:
                    this_activation_matrix = numpy.concatenate(
                        (this_activation_matrix, these_activations), axis=1)
        else:
            this_activation_matrix = None

            for this_channel_index in channel_indices:
                print(('Computing activations for channel {0:d} in layer '
                       '"{1:s}"...').format(this_channel_index, layer_name))

                these_activations = (
                    model_activation.get_channel_activation_for_examples(
                        model_object=model_object,
                        layer_name=layer_name,
                        channel_index=this_channel_index,
                        list_of_input_matrices=this_list_of_input_matrices,
                        stat_function_for_neuron_activations=K.max))

                these_activations = numpy.reshape(these_activations,
                                                  (len(these_activations), 1))

                if this_activation_matrix is None:
                    this_activation_matrix = these_activations + 0.
                else:
                    this_activation_matrix = numpy.concatenate(
                        (this_activation_matrix, these_activations), axis=1)

        if activation_matrix is None:
            activation_matrix = this_activation_matrix + 0.
        else:
            activation_matrix = numpy.concatenate(
                (activation_matrix, this_activation_matrix), axis=0)

        print(SEPARATOR_STRING)

    print('Writing activations to file: "{0:s}"...'.format(output_file_name))
    model_activation.write_file(pickle_file_name=output_file_name,
                                activation_matrix=activation_matrix,
                                full_id_strings=full_id_strings,
                                storm_times_unix_sec=storm_times_unix_sec,
                                model_file_name=model_file_name,
                                component_type_string=component_type_string,
                                target_class=target_class,
                                layer_name=layer_name,
                                neuron_index_matrix=neuron_index_matrix,
                                channel_indices=channel_indices)
Exemple #5
0
def _run(model_file_name, component_type_string, target_class, layer_name,
         ideal_activation, neuron_indices, channel_index, top_example_dir_name,
         storm_metafile_name, num_examples, randomize_weights,
         cascading_random, output_file_name):
    """Computes saliency map for each storm object and each model component.

    This is effectively the main method.

    :param model_file_name: See documentation at top of file.
    :param component_type_string: Same.
    :param target_class: Same.
    :param layer_name: Same.
    :param ideal_activation: Same.
    :param neuron_indices: Same.
    :param channel_index: Same.
    :param top_example_dir_name: Same.
    :param storm_metafile_name: Same.
    :param num_examples: Same.
    :param randomize_weights: Same.
    :param cascading_random: Same.
    :param output_file_name: Same.
    """

    # Check input args.
    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)
    model_interpretation.check_component_type(component_type_string)

    # Read model and metadata.
    print('Reading model from: "{0:s}"...'.format(model_file_name))
    model_object = cnn.read_model(model_file_name)

    model_metafile_name = '{0:s}/model_metadata.p'.format(
        os.path.split(model_file_name)[0])

    print(
        'Reading model metadata from: "{0:s}"...'.format(model_metafile_name))
    model_metadata_dict = cnn.read_model_metadata(model_metafile_name)
    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]
    training_option_dict[trainval_io.REFLECTIVITY_MASK_KEY] = None

    output_dir_name, pathless_output_file_name = os.path.split(
        output_file_name)
    extensionless_output_file_name, output_file_extension = os.path.splitext(
        pathless_output_file_name)

    if randomize_weights:
        conv_dense_layer_names = _find_conv_and_dense_layers(model_object)
        conv_dense_layer_names.reverse()
        num_sets = len(conv_dense_layer_names)
    else:
        conv_dense_layer_names = []
        num_sets = 1

    print(
        'Reading storm metadata from: "{0:s}"...'.format(storm_metafile_name))
    full_storm_id_strings, storm_times_unix_sec = (
        tracking_io.read_ids_and_times(storm_metafile_name))

    print(SEPARATOR_STRING)

    if 0 < num_examples < len(full_storm_id_strings):
        full_storm_id_strings = full_storm_id_strings[:num_examples]
        storm_times_unix_sec = storm_times_unix_sec[:num_examples]

    example_dict = testing_io.read_predictors_specific_examples(
        top_example_dir_name=top_example_dir_name,
        desired_full_id_strings=full_storm_id_strings,
        desired_times_unix_sec=storm_times_unix_sec,
        option_dict=training_option_dict,
        layer_operation_dicts=model_metadata_dict[cnn.LAYER_OPERATIONS_KEY])
    print(SEPARATOR_STRING)

    predictor_matrices = example_dict[testing_io.INPUT_MATRICES_KEY]
    sounding_pressure_matrix_pa = example_dict[
        testing_io.SOUNDING_PRESSURES_KEY]

    denorm_predictor_matrices = trainval_io.separate_shear_and_reflectivity(
        list_of_input_matrices=copy.deepcopy(predictor_matrices),
        training_option_dict=training_option_dict)

    print('Denormalizing model inputs...')
    denorm_predictor_matrices = model_interpretation.denormalize_data(
        list_of_input_matrices=denorm_predictor_matrices,
        model_metadata_dict=model_metadata_dict)
    print(SEPARATOR_STRING)

    for k in range(num_sets):
        if randomize_weights:
            if cascading_random:
                _reset_weights_in_layer(model_object=model_object,
                                        layer_name=conv_dense_layer_names[k])

                this_model_object = model_object

                this_output_file_name = (
                    '{0:s}/{1:s}_cascading-random_{2:s}{3:s}').format(
                        output_dir_name, extensionless_output_file_name,
                        conv_dense_layer_names[k].replace('_', '-'),
                        output_file_extension)
            else:
                this_model_object = keras.models.Model.from_config(
                    model_object.get_config())
                this_model_object.set_weights(model_object.get_weights())

                _reset_weights_in_layer(model_object=this_model_object,
                                        layer_name=conv_dense_layer_names[k])

                this_output_file_name = '{0:s}/{1:s}_random_{2:s}{3:s}'.format(
                    output_dir_name, extensionless_output_file_name,
                    conv_dense_layer_names[k].replace('_', '-'),
                    output_file_extension)
        else:
            this_model_object = model_object
            this_output_file_name = output_file_name

        # print(K.eval(this_model_object.get_layer(name='dense_3').weights[0]))

        if component_type_string == CLASS_COMPONENT_TYPE_STRING:
            print('Computing saliency maps for target class {0:d}...'.format(
                target_class))

            saliency_matrices = (
                saliency_maps.get_saliency_maps_for_class_activation(
                    model_object=this_model_object,
                    target_class=target_class,
                    list_of_input_matrices=predictor_matrices))

        elif component_type_string == NEURON_COMPONENT_TYPE_STRING:
            print(
                ('Computing saliency maps for neuron {0:s} in layer "{1:s}"...'
                 ).format(str(neuron_indices), layer_name))

            saliency_matrices = (
                saliency_maps.get_saliency_maps_for_neuron_activation(
                    model_object=this_model_object,
                    layer_name=layer_name,
                    neuron_indices=neuron_indices,
                    list_of_input_matrices=predictor_matrices,
                    ideal_activation=ideal_activation))

        else:
            print((
                'Computing saliency maps for channel {0:d} in layer "{1:s}"...'
            ).format(channel_index, layer_name))

            saliency_matrices = (
                saliency_maps.get_saliency_maps_for_channel_activation(
                    model_object=this_model_object,
                    layer_name=layer_name,
                    channel_index=channel_index,
                    list_of_input_matrices=predictor_matrices,
                    stat_function_for_neuron_activations=K.max,
                    ideal_activation=ideal_activation))

        saliency_matrices = trainval_io.separate_shear_and_reflectivity(
            list_of_input_matrices=saliency_matrices,
            training_option_dict=training_option_dict)

        print('Writing saliency maps to file: "{0:s}"...'.format(
            this_output_file_name))

        saliency_metadata_dict = saliency_maps.check_metadata(
            component_type_string=component_type_string,
            target_class=target_class,
            layer_name=layer_name,
            ideal_activation=ideal_activation,
            neuron_indices=neuron_indices,
            channel_index=channel_index)

        saliency_maps.write_standard_file(
            pickle_file_name=this_output_file_name,
            denorm_predictor_matrices=denorm_predictor_matrices,
            saliency_matrices=saliency_matrices,
            full_storm_id_strings=full_storm_id_strings,
            storm_times_unix_sec=storm_times_unix_sec,
            model_file_name=model_file_name,
            metadata_dict=saliency_metadata_dict,
            sounding_pressure_matrix_pa=sounding_pressure_matrix_pa)
Exemple #6
0
def _run(model_file_name, init_function_name, component_type_string,
         target_class, layer_name, neuron_indices, channel_index,
         ideal_activation, num_iterations, learning_rate, output_file_name):
    """Runs backwards optimization on a trained CNN.

    This is effectively the main method.

    :param model_file_name: See documentation at top of file.
    :param init_function_name: Same.
    :param component_type_string: Same.
    :param target_class: Same.
    :param layer_name: Same.
    :param neuron_indices: Same.
    :param channel_index: Same.
    :param ideal_activation: Same.
    :param num_iterations: Same.
    :param learning_rate: Same.
    :param output_file_name: Same.
    """

    model_interpretation.check_component_type(component_type_string)
    if ideal_activation <= 0:
        ideal_activation = None

    print('Reading model from: "{0:s}"...'.format(model_file_name))
    custom_dict = {'brier_skill_score_keras': _brier_skill_score_keras}
    model_object = load_keras_model(model_file_name, custom_objects=custom_dict)

    init_function = _create_initializer(init_function_name)
    print(SEPARATOR_STRING)

    if component_type_string == CLASS_COMPONENT_TYPE_STRING:
        print('Optimizing image for target class {0:d}...'.format(target_class))

        list_of_optimized_matrices, initial_activation, final_activation = (
            backwards_opt.optimize_input_for_class(
                model_object=model_object, target_class=target_class,
                init_function_or_matrices=init_function,
                num_iterations=num_iterations, learning_rate=learning_rate)
        )

    elif component_type_string == NEURON_COMPONENT_TYPE_STRING:
        print('Optimizing image for neuron {0:s} in layer "{1:s}"...'.format(
            str(neuron_indices), layer_name
        ))

        list_of_optimized_matrices, initial_activation, final_activation = (
            backwards_opt.optimize_input_for_neuron(
                model_object=model_object, layer_name=layer_name,
                neuron_indices=neuron_indices,
                init_function_or_matrices=init_function,
                num_iterations=num_iterations, learning_rate=learning_rate,
                ideal_activation=ideal_activation)
        )

    else:
        print('Optimizing image for channel {0:d} in layer "{1:s}"...'.format(
            channel_index, layer_name))

        list_of_optimized_matrices, initial_activation, final_activation = (
            backwards_opt.optimize_input_for_channel(
                model_object=model_object, layer_name=layer_name,
                channel_index=channel_index,
                init_function_or_matrices=init_function,
                stat_function_for_neuron_activations=K.max,
                num_iterations=num_iterations, learning_rate=learning_rate,
                ideal_activation=ideal_activation)
        )

    print(SEPARATOR_STRING)

    print('Denormalizing optimized examples...')
    list_of_optimized_matrices[0] = _denormalize_data(
        list_of_optimized_matrices[0]
    )

    print('Writing results to: "{0:s}"...'.format(output_file_name))
    backwards_opt.write_standard_file(
        pickle_file_name=output_file_name,
        list_of_optimized_matrices=list_of_optimized_matrices,
        initial_activations=numpy.array([initial_activation]),
        final_activations=numpy.array([final_activation]),
        model_file_name=model_file_name,
        init_function_name_or_matrices=init_function_name,
        num_iterations=num_iterations, learning_rate=learning_rate,
        component_type_string=component_type_string, target_class=target_class,
        layer_name=layer_name, neuron_indices=neuron_indices,
        channel_index=channel_index, ideal_activation=ideal_activation)
Exemple #7
0
def _run(model_file_name, init_function_name, storm_metafile_name,
         num_examples, top_example_dir_name, component_type_string,
         target_class, layer_name, neuron_indices, channel_index,
         num_iterations, ideal_activation, learning_rate, output_file_name):
    """Runs backwards optimization on a trained CNN.

    This is effectively the main method.

    :param model_file_name: See documentation at top of file.
    :param init_function_name: Same.
    :param storm_metafile_name: Same.
    :param num_examples: Same.
    :param top_example_dir_name: Same.
    :param component_type_string: Same.
    :param target_class: Same.
    :param layer_name: Same.
    :param neuron_indices: Same.
    :param channel_index: Same.
    :param num_iterations: Same.
    :param ideal_activation: Same.
    :param learning_rate: Same.
    :param output_file_name: Same.
    """

    model_interpretation.check_component_type(component_type_string)

    if ideal_activation <= 0:
        ideal_activation = None
    if init_function_name in ['', 'None']:
        init_function_name = None

    model_metafile_name = '{0:s}/model_metadata.p'.format(
        os.path.split(model_file_name)[0])

    print 'Reading model metadata from: "{0:s}"...'.format(model_metafile_name)
    model_metadata_dict = cnn.read_model_metadata(model_metafile_name)

    if init_function_name is None:
        print 'Reading storm metadata from: "{0:s}"...'.format(
            storm_metafile_name)

        storm_ids, storm_times_unix_sec = tracking_io.read_ids_and_times(
            storm_metafile_name)

        if 0 < num_examples < len(storm_ids):
            storm_ids = storm_ids[:num_examples]
            storm_times_unix_sec = storm_times_unix_sec[:num_examples]

        list_of_init_matrices = testing_io.read_specific_examples(
            desired_storm_ids=storm_ids,
            desired_times_unix_sec=storm_times_unix_sec,
            option_dict=model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY],
            top_example_dir_name=top_example_dir_name,
            list_of_layer_operation_dicts=model_metadata_dict[
                cnn.LAYER_OPERATIONS_KEY])[0]

        num_examples = list_of_init_matrices[0].shape[0]
        print SEPARATOR_STRING

    else:
        storm_ids = None
        storm_times_unix_sec = None
        num_examples = 1

        init_function = _create_initializer(
            init_function_name=init_function_name,
            model_metadata_dict=model_metadata_dict)

    print 'Reading model from: "{0:s}"...'.format(model_file_name)
    model_object = cnn.read_model(model_file_name)

    list_of_optimized_matrices = None

    for i in range(num_examples):
        if init_function_name is None:
            this_init_arg = [a[[i], ...] for a in list_of_init_matrices]
        else:
            this_init_arg = init_function

        if component_type_string == CLASS_COMPONENT_TYPE_STRING:
            print(
                '\nOptimizing {0:d}th of {1:d} images for target class {2:d}...'
            ).format(i + 1, num_examples, target_class)

            these_optimized_matrices = backwards_opt.optimize_input_for_class(
                model_object=model_object,
                target_class=target_class,
                init_function_or_matrices=this_init_arg,
                num_iterations=num_iterations,
                learning_rate=learning_rate)

        elif component_type_string == NEURON_COMPONENT_TYPE_STRING:
            print(
                '\nOptimizing {0:d}th of {1:d} images for neuron {2:s} in layer'
                ' "{3:s}"...').format(i + 1, num_examples, str(neuron_indices),
                                      layer_name)

            these_optimized_matrices = backwards_opt.optimize_input_for_neuron(
                model_object=model_object,
                layer_name=layer_name,
                neuron_indices=neuron_indices,
                init_function_or_matrices=this_init_arg,
                num_iterations=num_iterations,
                learning_rate=learning_rate,
                ideal_activation=ideal_activation)

        else:
            print(
                '\nOptimizing {0:d}th of {1:d} images for channel {2:d} in '
                'layer "{3:s}"...').format(i + 1, num_examples, channel_index,
                                           layer_name)

            these_optimized_matrices = backwards_opt.optimize_input_for_channel(
                model_object=model_object,
                layer_name=layer_name,
                channel_index=channel_index,
                init_function_or_matrices=this_init_arg,
                stat_function_for_neuron_activations=K.max,
                num_iterations=num_iterations,
                learning_rate=learning_rate,
                ideal_activation=ideal_activation)

        if list_of_optimized_matrices is None:
            num_matrices = len(these_optimized_matrices)
            list_of_optimized_matrices = [None] * num_matrices

        for k in range(len(list_of_optimized_matrices)):
            if list_of_optimized_matrices[k] is None:
                list_of_optimized_matrices[
                    k] = these_optimized_matrices[k] + 0.
            else:
                list_of_optimized_matrices[k] = numpy.concatenate(
                    (list_of_optimized_matrices[k],
                     these_optimized_matrices[k]),
                    axis=0)

    print SEPARATOR_STRING

    print 'Denormalizing optimized examples...'
    list_of_optimized_matrices = model_interpretation.denormalize_data(
        list_of_input_matrices=list_of_optimized_matrices,
        model_metadata_dict=model_metadata_dict)

    if init_function_name is None:
        print 'Denormalizing input examples...'
        list_of_init_matrices = model_interpretation.denormalize_data(
            list_of_input_matrices=list_of_init_matrices,
            model_metadata_dict=model_metadata_dict)

        this_init_arg = list_of_init_matrices
    else:
        this_init_arg = init_function_name + ''

    print 'Writing results to: "{0:s}"...'.format(output_file_name)
    backwards_opt.write_standard_file(
        pickle_file_name=output_file_name,
        list_of_optimized_matrices=list_of_optimized_matrices,
        model_file_name=model_file_name,
        init_function_name_or_matrices=this_init_arg,
        num_iterations=num_iterations,
        learning_rate=learning_rate,
        component_type_string=component_type_string,
        target_class=target_class,
        layer_name=layer_name,
        neuron_indices=neuron_indices,
        channel_index=channel_index,
        ideal_activation=ideal_activation,
        storm_ids=storm_ids,
        storm_times_unix_sec=storm_times_unix_sec)
def _run(model_file_name, init_function_name, storm_metafile_name,
         num_examples, top_example_dir_name, component_type_string,
         target_class, layer_name, neuron_indices, channel_index,
         num_iterations, ideal_activation, learning_rate, l2_weight,
         radar_constraint_weight, minmax_constraint_weight, output_file_name):
    """Runs backwards optimization on a trained CNN.

    This is effectively the main method.

    :param model_file_name: See documentation at top of file.
    :param init_function_name: Same.
    :param storm_metafile_name: Same.
    :param num_examples: Same.
    :param top_example_dir_name: Same.
    :param component_type_string: Same.
    :param target_class: Same.
    :param layer_name: Same.
    :param neuron_indices: Same.
    :param channel_index: Same.
    :param num_iterations: Same.
    :param ideal_activation: Same.
    :param learning_rate: Same.
    :param l2_weight: Same.
    :param radar_constraint_weight: Same.
    :param minmax_constraint_weight: Same.
    :param output_file_name: Same.
    """

    if l2_weight <= 0:
        l2_weight = None
    if radar_constraint_weight <= 0:
        radar_constraint_weight = None
    if minmax_constraint_weight <= 0:
        minmax_constraint_weight = None
    if ideal_activation <= 0:
        ideal_activation = None
    if init_function_name in ['', 'None']:
        init_function_name = None

    model_interpretation.check_component_type(component_type_string)

    model_metafile_name = '{0:s}/model_metadata.p'.format(
        os.path.split(model_file_name)[0])

    print(
        'Reading model metadata from: "{0:s}"...'.format(model_metafile_name))
    model_metadata_dict = cnn.read_model_metadata(model_metafile_name)

    input_matrices = None
    init_function = None
    full_storm_id_strings = None
    storm_times_unix_sec = None
    sounding_pressure_matrix_pa = None

    if init_function_name is None:
        print('Reading storm metadata from: "{0:s}"...'.format(
            storm_metafile_name))

        full_storm_id_strings, storm_times_unix_sec = (
            tracking_io.read_ids_and_times(storm_metafile_name))

        if 0 < num_examples < len(full_storm_id_strings):
            full_storm_id_strings = full_storm_id_strings[:num_examples]
            storm_times_unix_sec = storm_times_unix_sec[:num_examples]

        example_dict = testing_io.read_predictors_specific_examples(
            top_example_dir_name=top_example_dir_name,
            desired_full_id_strings=full_storm_id_strings,
            desired_times_unix_sec=storm_times_unix_sec,
            option_dict=model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY],
            layer_operation_dicts=model_metadata_dict[
                cnn.LAYER_OPERATIONS_KEY])
        print(SEPARATOR_STRING)

        input_matrices = example_dict[testing_io.INPUT_MATRICES_KEY]
        sounding_pressure_matrix_pa = example_dict[
            testing_io.SOUNDING_PRESSURES_KEY]
        num_examples = input_matrices[0].shape[0]
    else:
        num_examples = 1
        init_function = _create_initializer(
            init_function_name=init_function_name,
            model_metadata_dict=model_metadata_dict)

    print('Reading model from: "{0:s}"...'.format(model_file_name))
    model_object = cnn.read_model(model_file_name)

    output_matrices = None
    initial_activations = numpy.full(num_examples, numpy.nan)
    final_activations = numpy.full(num_examples, numpy.nan)

    for i in range(num_examples):
        if init_function_name is None:
            this_init_arg = [a[[i], ...] for a in input_matrices]
        else:
            this_init_arg = init_function

        if component_type_string == CLASS_COMPONENT_TYPE_STRING:
            print((
                '\nOptimizing {0:d}th of {1:d} images for target class {2:d}...'
            ).format(i + 1, num_examples, target_class))

            this_result_dict = backwards_opt.optimize_input_for_class(
                model_object=model_object,
                target_class=target_class,
                init_function_or_matrices=this_init_arg,
                num_iterations=num_iterations,
                learning_rate=learning_rate,
                l2_weight=l2_weight,
                radar_constraint_weight=radar_constraint_weight,
                minmax_constraint_weight=minmax_constraint_weight,
                model_metadata_dict=model_metadata_dict)

        elif component_type_string == NEURON_COMPONENT_TYPE_STRING:
            print((
                '\nOptimizing {0:d}th of {1:d} images for neuron {2:s} in layer'
                ' "{3:s}"...').format(i + 1, num_examples, str(neuron_indices),
                                      layer_name))

            this_result_dict = backwards_opt.optimize_input_for_neuron(
                model_object=model_object,
                layer_name=layer_name,
                neuron_indices=neuron_indices,
                init_function_or_matrices=this_init_arg,
                num_iterations=num_iterations,
                learning_rate=learning_rate,
                l2_weight=l2_weight,
                ideal_activation=ideal_activation,
                radar_constraint_weight=radar_constraint_weight,
                minmax_constraint_weight=minmax_constraint_weight,
                model_metadata_dict=model_metadata_dict)

        else:
            print(('\nOptimizing {0:d}th of {1:d} images for channel {2:d} in '
                   'layer "{3:s}"...').format(i + 1, num_examples,
                                              channel_index, layer_name))

            this_result_dict = backwards_opt.optimize_input_for_channel(
                model_object=model_object,
                layer_name=layer_name,
                channel_index=channel_index,
                init_function_or_matrices=this_init_arg,
                stat_function_for_neuron_activations=K.max,
                num_iterations=num_iterations,
                learning_rate=learning_rate,
                l2_weight=l2_weight,
                ideal_activation=ideal_activation,
                radar_constraint_weight=radar_constraint_weight,
                minmax_constraint_weight=minmax_constraint_weight,
                model_metadata_dict=model_metadata_dict)

        initial_activations[i] = this_result_dict[
            backwards_opt.INITIAL_ACTIVATION_KEY]
        final_activations[i] = this_result_dict[
            backwards_opt.FINAL_ACTIVATION_KEY]
        these_output_matrices = this_result_dict[
            backwards_opt.NORM_OUTPUT_MATRICES_KEY]

        if output_matrices is None:
            output_matrices = [None] * len(these_output_matrices)

        for k in range(len(output_matrices)):
            if output_matrices[k] is None:
                output_matrices[k] = these_output_matrices[k] + 0.
            else:
                output_matrices[k] = numpy.concatenate(
                    (output_matrices[k], these_output_matrices[k]), axis=0)

        if init_function_name is None:
            continue

        these_input_matrices = this_result_dict[
            backwards_opt.NORM_INPUT_MATRICES_KEY]

        if input_matrices is None:
            input_matrices = [None] * len(these_input_matrices)

        for k in range(len(input_matrices)):
            if input_matrices[k] is None:
                input_matrices[k] = these_input_matrices[k] + 0.
            else:
                input_matrices[k] = numpy.concatenate(
                    (input_matrices[k], these_input_matrices[k]), axis=0)

    print(SEPARATOR_STRING)
    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]

    print('Denormalizing input examples...')
    input_matrices = trainval_io.separate_shear_and_reflectivity(
        list_of_input_matrices=input_matrices,
        training_option_dict=training_option_dict)

    input_matrices = model_interpretation.denormalize_data(
        list_of_input_matrices=input_matrices,
        model_metadata_dict=model_metadata_dict)

    print('Denormalizing optimized examples...')
    output_matrices = trainval_io.separate_shear_and_reflectivity(
        list_of_input_matrices=output_matrices,
        training_option_dict=training_option_dict)

    output_matrices = model_interpretation.denormalize_data(
        list_of_input_matrices=output_matrices,
        model_metadata_dict=model_metadata_dict)

    print('Writing results to: "{0:s}"...'.format(output_file_name))
    bwo_metadata_dict = backwards_opt.check_metadata(
        component_type_string=component_type_string,
        num_iterations=num_iterations,
        learning_rate=learning_rate,
        target_class=target_class,
        layer_name=layer_name,
        ideal_activation=ideal_activation,
        neuron_indices=neuron_indices,
        channel_index=channel_index,
        l2_weight=l2_weight,
        radar_constraint_weight=radar_constraint_weight,
        minmax_constraint_weight=minmax_constraint_weight)

    backwards_opt.write_standard_file(
        pickle_file_name=output_file_name,
        denorm_input_matrices=input_matrices,
        denorm_output_matrices=output_matrices,
        initial_activations=initial_activations,
        final_activations=final_activations,
        model_file_name=model_file_name,
        metadata_dict=bwo_metadata_dict,
        full_storm_id_strings=full_storm_id_strings,
        storm_times_unix_sec=storm_times_unix_sec,
        sounding_pressure_matrix_pa=sounding_pressure_matrix_pa)
def _run(model_file_name, component_type_string, target_class, layer_name,
         ideal_activation, neuron_indices, channel_index, top_example_dir_name,
         storm_metafile_name, num_examples, output_file_name):
    """Computes saliency map for each storm object and each model component.

    This is effectively the main method.

    :param model_file_name: See documentation at top of file.
    :param component_type_string: Same.
    :param target_class: Same.
    :param layer_name: Same.
    :param ideal_activation: Same.
    :param neuron_indices: Same.
    :param channel_index: Same.
    :param top_example_dir_name: Same.
    :param storm_metafile_name: Same.
    :param num_examples: Same.
    :param output_file_name: Same.
    """

    # Check input args.
    file_system_utils.mkdir_recursive_if_necessary(file_name=output_file_name)
    model_interpretation.check_component_type(component_type_string)

    # Read model and metadata.
    print 'Reading model from: "{0:s}"...'.format(model_file_name)
    model_object = cnn.read_model(model_file_name)
    model_metafile_name = '{0:s}/model_metadata.p'.format(
        os.path.split(model_file_name)[0])

    print 'Reading model metadata from: "{0:s}"...'.format(model_metafile_name)
    model_metadata_dict = cnn.read_model_metadata(model_metafile_name)
    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]
    training_option_dict[trainval_io.REFLECTIVITY_MASK_KEY] = None

    print 'Reading storm metadata from: "{0:s}"...'.format(storm_metafile_name)
    storm_ids, storm_times_unix_sec = tracking_io.read_ids_and_times(
        storm_metafile_name)
    print SEPARATOR_STRING

    if 0 < num_examples < len(storm_ids):
        storm_ids = storm_ids[:num_examples]
        storm_times_unix_sec = storm_times_unix_sec[:num_examples]

    list_of_input_matrices, sounding_pressure_matrix_pascals = (
        testing_io.read_specific_examples(
            top_example_dir_name=top_example_dir_name,
            desired_storm_ids=storm_ids,
            desired_times_unix_sec=storm_times_unix_sec,
            option_dict=training_option_dict,
            list_of_layer_operation_dicts=model_metadata_dict[
                cnn.LAYER_OPERATIONS_KEY]))
    print SEPARATOR_STRING

    if component_type_string == CLASS_COMPONENT_TYPE_STRING:
        print 'Computing saliency maps for target class {0:d}...'.format(
            target_class)

        list_of_saliency_matrices = (
            saliency_maps.get_saliency_maps_for_class_activation(
                model_object=model_object,
                target_class=target_class,
                list_of_input_matrices=list_of_input_matrices))

    elif component_type_string == NEURON_COMPONENT_TYPE_STRING:
        print('Computing saliency maps for neuron {0:s} in layer "{1:s}"...'
              ).format(str(neuron_indices), layer_name)

        list_of_saliency_matrices = (
            saliency_maps.get_saliency_maps_for_neuron_activation(
                model_object=model_object,
                layer_name=layer_name,
                neuron_indices=neuron_indices,
                list_of_input_matrices=list_of_input_matrices,
                ideal_activation=ideal_activation))

    else:
        print('Computing saliency maps for channel {0:d} in layer "{1:s}"...'
              ).format(channel_index, layer_name)

        list_of_saliency_matrices = (
            saliency_maps.get_saliency_maps_for_channel_activation(
                model_object=model_object,
                layer_name=layer_name,
                channel_index=channel_index,
                list_of_input_matrices=list_of_input_matrices,
                stat_function_for_neuron_activations=K.max,
                ideal_activation=ideal_activation))

    print 'Denormalizing model inputs...'
    list_of_input_matrices = model_interpretation.denormalize_data(
        list_of_input_matrices=list_of_input_matrices,
        model_metadata_dict=model_metadata_dict)

    print 'Writing saliency maps to file: "{0:s}"...'.format(output_file_name)

    saliency_metadata_dict = saliency_maps.check_metadata(
        component_type_string=component_type_string,
        target_class=target_class,
        layer_name=layer_name,
        ideal_activation=ideal_activation,
        neuron_indices=neuron_indices,
        channel_index=channel_index)

    saliency_maps.write_standard_file(
        pickle_file_name=output_file_name,
        list_of_input_matrices=list_of_input_matrices,
        list_of_saliency_matrices=list_of_saliency_matrices,
        storm_ids=storm_ids,
        storm_times_unix_sec=storm_times_unix_sec,
        model_file_name=model_file_name,
        saliency_metadata_dict=saliency_metadata_dict,
        sounding_pressure_matrix_pascals=sounding_pressure_matrix_pascals)