def create_heatmap_fn(all_layers, rules, pool_by_grad, min_in=None, max_in=None, return_all=False, use_output_as_relevance=False, a=None, b=None, biases=False): # only using single trial, so one less dim than input shape if len(get_input_shape(all_layers[-1])) == 2: input_trials = T.fmatrix() elif len(get_input_shape(all_layers[-1])) == 4: input_trials = T.ftensor4() if use_output_as_relevance: out_relevances = lasagne.layers.get_output(all_layers[-1], inputs=input_trials, deterministic=True, input_var=input_trials) else: if len(all_layers[-1].output_shape) == 2: out_relevances = T.fmatrix() elif len(all_layers[-1].output_shape) == 4: out_relevances = T.ftensor4() heatmap = create_heatmap(out_relevances, input_trials, all_layers, rules, pool_by_grad=pool_by_grad, min_in=min_in, max_in=max_in, return_all=return_all, a=a,b=b, biases=biases) if use_output_as_relevance: heatmap_fn = theano.function([input_trials], heatmap) else: heatmap_fn = theano.function([out_relevances, input_trials], heatmap) return heatmap_fn
def create_heatmap_fn( all_layers, rules, pool_by_grad, min_in=None, max_in=None, return_all=False, use_output_as_relevance=False, a=None, b=None, biases=False, ): # only using single trial, so one less dim than input shape if len(get_input_shape(all_layers[-1])) == 2: input_trials = T.fmatrix() elif len(get_input_shape(all_layers[-1])) == 4: input_trials = T.ftensor4() if use_output_as_relevance: out_relevances = lasagne.layers.get_output( all_layers[-1], inputs=input_trials, deterministic=True, input_var=input_trials ) else: if len(all_layers[-1].output_shape) == 2: out_relevances = T.fmatrix() elif len(all_layers[-1].output_shape) == 4: out_relevances = T.ftensor4() heatmap = create_heatmap( out_relevances, input_trials, all_layers, rules, pool_by_grad=pool_by_grad, min_in=min_in, max_in=max_in, return_all=return_all, a=a, b=b, biases=biases, ) if use_output_as_relevance: heatmap_fn = theano.function([input_trials], heatmap) else: heatmap_fn = theano.function([out_relevances, input_trials], heatmap) return heatmap_fn
def compute_patterns_for_layers(needed_layers, input_data): in_layers = [l.input_layer for l in needed_layers] in_and_out = zip(in_layers, needed_layers) in_and_out = np.array(in_and_out).flatten() if len(get_input_shape(needed_layers[0])) == 2: inputs = T.fmatrix() else: inputs = T.ftensor4() output = lasagne.layers.get_output(in_and_out, deterministic=True, inputs=inputs) log.info("Compiling forward pass...") out_fn = theano.function([inputs], output) outs_by_layer = out_fn(input_data) in_outs_by_layer = [ outs_by_layer[2 * i:2 * i + 2] for i in xrange(len(outs_by_layer) / 2) ] patterns_per_layer = [] for i_layer in xrange(len(needed_layers)): layer = needed_layers[i_layer] inputs = in_outs_by_layer[i_layer][0] outputs = in_outs_by_layer[i_layer][1] if hasattr(layer, 'filter_size'): log.info("Transforming to patterns for layer {:d}: {:s}...".format( i_layer, layer.__class__.__name__)) conv_weights = layer.W.get_value() # TODO: take different implementation # if inputs bytes times conv_weights.shape[2:] # are below 2GB... pattern = transform_to_patterns( conv_weights, inputs, outputs, flip_filters=True) # conv weighs were flipped... log.info("Done.") elif isinstance(layer, lasagne.layers.DenseLayer): log.info("Transforming to patterns for layer {:d}: {:s}...".format( i_layer, layer.__class__.__name__)) if inputs.ndim > 2: inputs = inputs.reshape(inputs.shape[0], -1) in_cov = np.cov(inputs.T) pattern = np.dot(in_cov, layer.W.get_value()) log.info("Done.") else: raise ValueError( "Trying to compute patterns for unknown layer " "type {:s}", layer.__class__.__name__) patterns_per_layer.append(pattern) return patterns_per_layer
def compute_patterns_for_layers(needed_layers, input_data): in_layers = [l.input_layer for l in needed_layers] in_and_out = zip(in_layers, needed_layers) in_and_out = np.array(in_and_out).flatten() if len(get_input_shape(needed_layers[0])) == 2: inputs = T.fmatrix() else: inputs = T.ftensor4() output = lasagne.layers.get_output(in_and_out, deterministic=True, inputs=inputs) log.info("Compiling forward pass...") out_fn = theano.function([inputs], output) outs_by_layer = out_fn(input_data) in_outs_by_layer = [outs_by_layer[2*i:2*i + 2] for i in xrange(len(outs_by_layer) /2)] patterns_per_layer = [] for i_layer in xrange(len(needed_layers)): layer = needed_layers[i_layer] inputs = in_outs_by_layer[i_layer][0] outputs = in_outs_by_layer[i_layer][1] if hasattr(layer, 'filter_size'): log.info("Transforming to patterns for layer {:d}: {:s}...".format( i_layer, layer.__class__.__name__)) conv_weights = layer.W.get_value() # TODO: take different implementation # if inputs bytes times conv_weights.shape[2:] # are below 2GB... pattern = transform_to_patterns(conv_weights, inputs, outputs, flip_filters=True) # conv weighs were flipped... log.info("Done.") elif isinstance(layer, lasagne.layers.DenseLayer): log.info("Transforming to patterns for layer {:d}: {:s}...".format( i_layer, layer.__class__.__name__)) if inputs.ndim > 2: inputs = inputs.reshape(inputs.shape[0], -1) in_cov = np.cov(inputs.T) pattern = np.dot(in_cov, layer.W.get_value()) log.info("Done.") else: raise ValueError("Trying to compute patterns for unknown layer " "type {:s}", layer.__class__.__name__) patterns_per_layer.append(pattern) return patterns_per_layer
def optimize_to_move_to_cluster(out_layer, n_cluster_samples, learning_rate=0.1, seed=983748374, input_cost=None, n_trials=1): """Create function to optimize input to be close to cluster. Returns shared random variable which will be optimized and update function. Supply cluster activations to the update function""" rng = RandomState(seed) in_shape = get_input_shape(out_layer) in_shape = [n_trials] + list(in_shape[1:]) rand_input = rng.randn(*in_shape).astype(np.float32) rand_in_var = theano.shared(rand_input) # have to supply input_var extra in case of final reshape layer output = lasagne.layers.get_output(out_layer, deterministic=True, inputs=rand_in_var, input_var=rand_in_var) if output.ndim == 4: cluster_activations_var = T.ftensor4() elif output.ndim == 2: cluster_activations_var = T.fmatrix() # Calculate distances for all given "trials" distance = T.constant(0, dtype=np.float32) for i_trial in xrange(n_trials): distance += mean_min_distance_to_cluster(output[i_trial], cluster_activations_var, n_cluster_samples) distance = distance / n_trials # to get mean..not sure if smart if input_cost is None: cost = distance else: cost = distance + input_cost(rand_in_var) updates = lasagne.updates.adam(cost, [rand_in_var], learning_rate=learning_rate) update_fn = theano.function([cluster_activations_var], cost, updates=updates) return rand_in_var, update_fn
def create_descent_function(layer, wanted_activation, learning_rate=0.1, input_cost=None, n_trials=1, seed=983748374, deterministic=True, loss='sqr', init_factor=0.1): """ Create descent function that updates random variable to match given wanted activation. Parameters ---------- layer : Layer to compute descent from. wanted_activation: list or nd array Activation to move towards. learning_rate : float Learning rate for adam updates input_cost : function or None Optional additional cost on the input. n_trials : int Number of inputs to randomly initialize and optimize. seed : int Random seed to initialize random variable. deterministic : boolean Whether to use deterministic mode when computing activations, i.e. no dropout etc. loss : function or 'sqr' Loss to use between wanted activation and actual activation. init_factor : float Factor for initialization of random variable. Returns ------- rand_in_var: theano shared variable Random input variable to be optimized update_fn: theano compiled function Function to compute updates, returns current cost """ rng = RandomState(seed) wanted_activation = np.array(wanted_activation) in_shape = get_input_shape(layer) in_shape = [n_trials] + list(in_shape[1:]) rand_input = rng.randn(*in_shape).astype(np.float32) * init_factor rand_in_var = theano.shared(rand_input) # have to supply input_var extra in case of final reshape layer output = lasagne.layers.get_output(layer, deterministic=deterministic, inputs=rand_in_var, input_var=rand_in_var) if loss == 'sqr': output_cost = T.sqr(output - wanted_activation[np.newaxis]) else: output_cost = loss(output, wanted_activation[np.newaxis]) output_cost = T.mean(output_cost) if input_cost is None: cost = output_cost else: cost = output_cost + input_cost(rand_in_var) updates = lasagne.updates.adam(cost, [rand_in_var], learning_rate=learning_rate) update_fn = theano.function([], cost, updates=updates) return rand_in_var, update_fn
def create_descent_function(layer, wanted_activation, learning_rate=0.1, input_cost=None, n_trials=1, seed=983748374, deterministic=True, loss='sqr', init_factor=0.1): """ Create descent function that updates random variable to match given wanted activation. Parameters ---------- layer : Layer to compute descent from. wanted_activation: list or nd array Activation to move towards. learning_rate : float Learning rate for adam updates input_cost : function or None Optional additional cost on the input. n_trials : int Number of inputs to randomly initialize and optimize. seed : int Random seed to initialize random variable. deterministic : boolean Whether to use deterministic mode when computing activations, i.e. no dropout etc. loss : function or 'sqr' Loss to use between wanted activation and actual activation. init_factor : float Factor for initialization of random variable. Returns ------- rand_in_var: theano shared variable Random input variable to be optimized update_fn: theano compiled function Function to compute updates, returns current cost """ rng = RandomState(seed) wanted_activation = np.array(wanted_activation) in_shape = get_input_shape(layer) in_shape = [n_trials] + list(in_shape[1:]) rand_input = rng.randn(*in_shape).astype(np.float32) * init_factor rand_in_var = theano.shared(rand_input) # have to supply input_var extra in case of final reshape layer output = lasagne.layers.get_output(layer, deterministic=deterministic, inputs=rand_in_var, input_var=rand_in_var) if loss == 'sqr': output_cost = T.sqr(output - wanted_activation[np.newaxis]) else: output_cost = loss(output, wanted_activation[np.newaxis]) output_cost = T.mean(output_cost) if input_cost is None: cost = output_cost else: cost = output_cost + input_cost(rand_in_var) updates = lasagne.updates.adam(cost, [rand_in_var], learning_rate=learning_rate) update_fn = theano.function([], cost, updates=updates) return rand_in_var, update_fn