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 }
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)
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)
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)
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)