Licensed under the Apache License, Version 2.0 (the "License");


In [0]:
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

Feature Visualization with Alpha Transparency

This notebook uses Lucid to produce feature visualizations that use alpha transparency to reduce visual noise, like the ones found in The Building Blocks of Interpretability.

This notebook doesn't introduce the abstractions behind lucid; you may wish to also read the .

Note: The easiest way to use this tutorial is as a colab notebook, which allows you to dive in with no setup. We recommend you enable a free GPU by going:

Runtime   →   Change runtime type   →   Hardware Accelerator: GPU

Install, Import, Load Model


In [0]:
# Install Lucid
!pip install --quiet lucid==0.1.0
#tensorflow_version only works on colab
%tensorflow_version 1.x

# Import libraries
import numpy as np
import tensorflow as tf
assert tf.__version__.startswith('1')

import lucid.modelzoo.vision_models as models
import lucid.optvis.objectives as objectives
import lucid.optvis.param as param
import lucid.optvis.render as render
import lucid.optvis.transform as transform
from lucid.misc.io import show, load
from lucid.misc.io.reading import read

In [0]:
# Import the InceptionV1 (GoogLeNet) model from the Lucid modelzoo
model = models.InceptionV1()
model.load_graphdef()

Setup


In [0]:
def global_step():
  return tf.cast(tf.train.get_or_create_global_step(), tf.float32)

@objectives.wrap_objective
def penalize_alpha():
  def inner(T):
    return tf.reduce_mean(T('input')[..., 3:4])
  return inner

@objectives.wrap_objective
def decay(n_steps):
  def inner(T):
    return 1 - (global_step() / n_steps)
  return inner

@objectives.wrap_objective
def only_after(n_steps):
  def inner(T):
    return tf.cond(global_step() < n_steps, lambda: 0.0, lambda: 1.0)
  return inner

In [0]:
def alpha_feature_vis(neurons, layer='mixed4d', size=50, margin=30, k=0.7, 
                      verbose=True, n_steps=1000):
  n_batch = len(neurons)
  size += 2*margin

  obj = 0.5 * sum([
      objectives.neuron(layer + '_pre_relu', neurons[i], batch=i) +
      objectives.channel(layer, neurons[i], batch=i)
      for i in range(n_batch)
  ]) + sum([
      -1 * decay(n_steps*1.5) * objectives.blur_input_each_step(),
      -1 * decay(n_steps) * objectives.blur_alpha_each_step(),
      -20000 * only_after(150) * decay(n_steps*1.5) * penalize_alpha()
  ])

  param_f = lambda: param.image(size, fft=True, decorrelate=True, batch=n_batch, alpha=True)

  transforms = [
      transform.collapse_alpha_random(),
      transform.pad(4, mode='constant', constant_value=1),
      transform.jitter(4),
      transform.jitter(4),
      transform.jitter(8),
      transform.jitter(8),
      transform.jitter(8),
      transform.random_scale([0.995**n for n in range(-5,80)] + [0.998**n for n in 2*range(20,40)]),
      transform.random_rotate(range(-20, 20)+range(-10,10)+range(-5,5)+5*[0])
  ]

  img_steps = render.render_vis(model, obj, param_f, transforms=transforms, 
                                thresholds=(n_steps//4, n_steps//2, n_steps),
                                verbose=verbose)
  
  imgs = img_steps[-1]  # remove thresholds
  img = np.hstack(imgs) # remove batch
  img_rgb = img[:,:,:3]
  img_a = img[:,:,3:]
  
  img = img_rgb*((1-k)+k*img_a) + k*(1-img_a)
  show(img)
  return img

Run


In [58]:
# Dog and cat neurons
_ = alpha_feature_vis([426, 436, 43, 477, 383, 493, 517, 221])


250 4662.5034
500 8784.786
1000 10115.771

In [59]:
# Vase, flower, and lemon neurons
_ = alpha_feature_vis([469, 234, 25, 185])


250 -705.2256
500 -273.17407
1000 3345.7937

In [60]:
# Bow tie, lapel, and sunglasses neurons
_ = alpha_feature_vis([490, 519, 458, 442])


250 -3307.185
500 -862.573
1000 1498.919