Skip to content

Commit 1a36334

Browse files
committed
Initial commit of our automated illusion generator package. Much to be done.
1 parent 51e0fd0 commit 1a36334

File tree

6 files changed

+172
-0
lines changed

6 files changed

+172
-0
lines changed

autogen/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Automated generation of novel illusions
2+
3+
This package leverages a new theory of visual illusions to generate new illusions of new types.
4+
5+
In human vision, there is a robust connection between perceptial bias (i.e. an illusion) and discrimination errors (i.e. uncertainty).
6+
(see [this paper](https://www.sas.upenn.edu/~astocker/lab/publications-files/journals/PNAS2017/Wei_Stocker2017.pdf)or
7+
[this paper too](https://www.sas.upenn.edu/~astocker/lab/publications-files/journals/NN2015/Wei_Stocker2015b.pdf)).
8+
9+
10+
Since pretrained deep neural networks show similar uncertainty about the world (in a Fisher information sense),
11+
we can use them as proxies for human uncertainty. This allows us to find new illusions in an automated fashion.
12+
13+
14+
#### Algorithm
15+
To create an image with an illusory percept for thing x (e.g. curvature of some line, lightness, etc.)
16+
17+
1) Define a parameterized image generator G with x as a smoothly-varying input parameter.
18+
2) For any generated image, estimate to Fisher of a pretrained DNN w/r/t x
19+
3) Sample from the density of G parameters that yield images for which the Fisher for x changes quickly, using deep density techniques (e.g. GANs)
20+
21+
22+
#### Organization
23+
24+
In `image_generators.py`, we define our image generators. Each subclass of `BaseImageGenerator` has methods to generate
25+
an image deterministically and smoothly from "context" inputs and a 1D "theta" input.
26+
27+
In `fisher_estimation.py`, we define scripts that calculates the Fisher information of a pretrained deep neural network
28+
layer as a function of "theta", given some "context".
29+
30+
In `density_estimation.py`, we define scripts that can sample from the density of "context" variables to find values
31+
where the Fisher information w/r/t theta has a large value.
32+
33+
34+

autogen/density_estimation.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import torch
2+
3+
""" These scripts aim to find values of 'context' that have highly sloped Fisher
4+
information in pretrained network representations.
5+
6+
There are a few possibilities. All of them would benefit from speed, and smoothness of the map from context to Fisher.
7+
In order of complexity:
8+
9+
1. Optimization
10+
----------------
11+
For low-dimensional contexts, we could use an out-of-the-box, general purpose optimizer, e.g. in scipy. This approach
12+
is more promising when the context is not expected to have image-like structure (see 'Deep Image Prior').
13+
14+
Initially, we'll simply optimize a neural network to transform random noise into the context parameters, with the loss
15+
being the squared slope of the Fisher at that value of context.
16+
If degenerate modes are found, we might have to impose an entropy constraint on the output.
17+
18+
2. Sampling
19+
-----------
20+
Using the derivative of the Fisher as the likelihood, or energy, we can also apply MCMC sampling methods. This is
21+
probably more likely to work in higher-dimensional situations.
22+
23+
If this shows slow convergence, we can attempt new MCMC methods that additionally incorporate a model that selects
24+
which things are sampled. (e.g. https://papers.nips.cc/paper/7099-a-nice-mc-adversarial-training-for-mcmc.pdf)
25+
26+
"""

autogen/fisher_estimation.py

Whitespace-only changes.

autogen/image_generators.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import numpy as np
2+
import torch
3+
4+
class BaseDifferentiableImageGenerator(object):
5+
6+
"""Base class for all image generators that are written in pytorch and differentiable into theta.
7+
All classes should output an image of ImageNet dimensions (224x224).
8+
"""
9+
10+
def __init__(self):
11+
12+
pass
13+
14+
def generate_image(self, theta, context):
15+
"""To be redefined in any subclass.
16+
17+
Deterministically generates an image as a function of theta and context.
18+
19+
Context and theta should both smoothly relate to the image. Small changes in
20+
theta and changes in context should cause small changes in the output image.
21+
For two values of theta but the same context, the two output images should be
22+
the same in all manners except for theta.
23+
24+
Methods need to be written in pytorch, such that they take a Variable and produce an
25+
image that is differentiable with respect to theta
26+
27+
"""
28+
raise NotImplementedError()
29+
30+
31+
class BaseNonDifferentiableImageGenerator(object):
32+
"""Base class for all image generators that aren't differentiable.
33+
34+
All classes should output an image of ImageNet dimensions (224x224).
35+
36+
When possible, all methods should still use torch methods and not numpy or scipy methods, for speed."""
37+
38+
def __init__(self):
39+
pass
40+
41+
def generate_image(self, theta, context):
42+
"""To be redefined in any subclass.
43+
44+
Deterministically generates an image as a function of theta and context.
45+
46+
Context and theta should both smoothly relate to the image. Small changes in
47+
theta and changes in context should cause small changes in the output image.
48+
For two values of theta but the same context, the two output images should be
49+
the same in all manners except for theta.
50+
51+
"""
52+
raise NotImplementedError()
53+
54+
class OneCurvedLineGenerator(BaseDifferentiableImageGenerator):
55+
"""This is designed to create illusions like the Herring illusion.
56+
"""
57+
58+
def __init__(self, n_lines = 5):
59+
super(OneCurvedLineGenerator, self).__init__()
60+
self.n_lines = n_lines
61+
62+
63+
def generate_image(self, theta, context):
64+
"""
65+
Theta is the curvature of the central horizontal line.
66+
Context are parameters that describe the overlaid lines.
67+
e.g. a list of midpoints and orientations, for a total of n_lines x 3 parameters. """
68+
69+
raise NotImplementedError()
70+
71+
72+
73+
class CentralPixelGenerator(BaseDifferentiableImageGenerator):
74+
"""This is designed to generate images with a central block of pixels whose lightness is an illusions.
75+
"""
76+
77+
def __init__(self, n_pixels_blocks_per_side = 5):
78+
"""
79+
80+
81+
:param n_pixels_blocks_per_side: an odd integer
82+
"""
83+
super(CentralPixelGenerator, self).__init__()
84+
assert n_pixels_blocks_per_side % 2 == 1, "n_pixels_blocks_per_side must be odd"
85+
86+
self.n_pixels_blocks_per_side = n_pixels_blocks_per_side
87+
88+
89+
def generate_image(self, theta, context):
90+
"""
91+
:param theta: the lightness of the central pixel block.
92+
:param context: the lightness of the surrounding pixels.
93+
:return: A 224x224x3 image
94+
"""
95+
assert len(context) == self.n_pixels_blocks_per_side**2-1
96+
97+
raise NotImplementedError()

autogen/main.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import argparse
2+
3+
"""Runs it all"""
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import numpy as np
2+
3+
4+
"""Unit tests for any image generator.
5+
6+
Includes:
7+
- tests of differentiability w/r/t theta
8+
- output sizes
9+
10+
11+
12+
"""

0 commit comments

Comments
 (0)