Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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