Skip to content

Commit 0f3741d

Browse files
committed
Move the exercies from the basic tutorial to a ipython notebook.
1 parent b22999e commit 0f3741d

10 files changed

+972
-0
lines changed

ipnb/01_scalar_soln.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import numpy as np
2+
from theano import function
3+
import theano.tensor as T
4+
5+
6+
def make_scalar():
7+
"""
8+
Returns a new Theano scalar.
9+
"""
10+
11+
return T.scalar()
12+
13+
14+
def log(x):
15+
"""
16+
Returns the logarithm of a Theano scalar x.
17+
"""
18+
19+
return T.log(x)
20+
21+
22+
def add(x, y):
23+
"""
24+
Adds two theano scalars together and returns the result.
25+
"""
26+
27+
return x + y
28+
29+
a = make_scalar()
30+
b = make_scalar()
31+
c = log(b)
32+
d = add(a, c)
33+
f = function([a, b], d)
34+
a = np.cast[a.dtype](1.)
35+
b = np.cast[b.dtype](2.)
36+
actual = f(a, b)
37+
expected = 1. + np.log(2.)
38+
assert np.allclose(actual, expected)
39+
print "SUCCESS!"

ipnb/02_vector_mat_soln.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import numpy as np
2+
from theano import function
3+
import theano.tensor as T
4+
5+
6+
def make_vector():
7+
"""
8+
Returns a new Theano vector.
9+
"""
10+
11+
return T.vector()
12+
13+
14+
def make_matrix():
15+
"""
16+
Returns a new Theano matrix.
17+
"""
18+
19+
return T.matrix()
20+
21+
22+
def elemwise_mul(a, b):
23+
"""
24+
a: A theano matrix
25+
b: A theano matrix
26+
Returns the elementwise product of a and b
27+
"""
28+
29+
return a * b
30+
31+
32+
def matrix_vector_mul(a, b):
33+
"""
34+
a: A theano matrix
35+
b: A theano vector
36+
Returns the matrix-vector product of a and b
37+
"""
38+
39+
return T.dot(a, b)
40+
41+
a = make_vector()
42+
b = make_vector()
43+
c = elemwise_mul(a, b)
44+
d = make_matrix()
45+
e = matrix_vector_mul(d, c)
46+
47+
f = function([a, b, d], e)
48+
49+
rng = np.random.RandomState([1, 2, 3])
50+
a_value = rng.randn(5).astype(a.dtype)
51+
b_value = rng.rand(5).astype(b.dtype)
52+
c_value = a_value * b_value
53+
d_value = rng.randn(5, 5).astype(d.dtype)
54+
expected = np.dot(d_value, c_value)
55+
56+
actual = f(a_value, b_value, d_value)
57+
58+
assert np.allclose(actual, expected)
59+
print "SUCCESS!"

ipnb/03_tensor_soln.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import numpy as np
2+
from theano import function
3+
import theano.tensor as T
4+
5+
6+
def make_tensor(dim):
7+
"""
8+
Returns a new Theano tensor with no broadcastable dimensions.
9+
dim: the total number of dimensions of the tensor.
10+
"""
11+
12+
return T.TensorType(broadcastable=tuple([False] * dim), dtype='float32')()
13+
14+
15+
def broadcasted_add(a, b):
16+
"""
17+
a: a 3D theano tensor
18+
b: a 4D theano tensor
19+
Returns c, a 4D theano tensor, where
20+
21+
c[i, j, k, l] = a[l, k, i] + b[i, j, k, l]
22+
23+
for all i, j, k, l
24+
"""
25+
26+
return a.dimshuffle(2, 'x', 1, 0) + b
27+
28+
29+
def partial_max(a):
30+
"""
31+
a: a 4D theano tensor
32+
33+
Returns b, a theano matrix, where
34+
35+
b[i, j] = max_{k,l} a[i, k, l, j]
36+
37+
for all i, j
38+
"""
39+
40+
return a.max(axis=(1, 2))
41+
42+
a = make_tensor(3)
43+
b = make_tensor(4)
44+
c = broadcasted_add(a, b)
45+
d = partial_max(c)
46+
47+
f = function([a, b], d)
48+
49+
rng = np.random.RandomState([1, 2, 3])
50+
a_value = rng.randn(2, 2, 2).astype(a.dtype)
51+
b_value = rng.rand(2, 2, 2, 2).astype(b.dtype)
52+
c_value = np.transpose(a_value, (2, 1, 0))[:, None, :, :] + b_value
53+
expected = c_value.max(axis=1).max(axis=1)
54+
55+
actual = f(a_value, b_value)
56+
57+
assert np.allclose(actual, expected), (actual, expected)
58+
print "SUCCESS!"

ipnb/11_function_soln.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from theano import tensor as T
2+
from theano import function
3+
4+
5+
def evaluate(x, y, expr, x_value, y_value):
6+
"""
7+
x: A theano variable
8+
y: A theano variable
9+
expr: A theano expression involving x and y
10+
x_value: A numpy value
11+
y_value: A numpy value
12+
13+
Returns the value of expr when x_value is substituted for x
14+
and y_value is substituted for y
15+
"""
16+
17+
return function([x, y], expr)(x_value, y_value)
18+
19+
20+
x = T.iscalar()
21+
y = T.iscalar()
22+
z = x + y
23+
assert evaluate(x, y, z, 1, 2) == 3
24+
print "SUCCESS!"

ipnb/12_shared_soln.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import numpy as np
2+
from theano.compat.python2x import OrderedDict
3+
from theano import function
4+
from theano import shared
5+
6+
7+
def make_shared(shape):
8+
"""
9+
Returns a theano shared variable containing a tensor of the specified
10+
shape.
11+
You can use any value you want.
12+
"""
13+
return shared(np.zeros(shape))
14+
15+
16+
def exchange_shared(a, b):
17+
"""
18+
a: a theano shared variable
19+
b: a theano shared variable
20+
Uses get_value and set_value to swap the values stored in a and b
21+
"""
22+
temp = a.get_value()
23+
a.set_value(b.get_value())
24+
b.set_value(temp)
25+
26+
27+
def make_exchange_func(a, b):
28+
"""
29+
a: a theano shared variable
30+
b: a theano shared variable
31+
Returns f
32+
where f is a theano function, that, when called, swaps the
33+
values in a and b
34+
f should not return anything
35+
"""
36+
37+
updates = OrderedDict()
38+
updates[a] = b
39+
updates[b] = a
40+
f = function([], updates=updates)
41+
return f
42+
43+
44+
a = make_shared((5, 4, 3))
45+
assert a.get_value().shape == (5, 4, 3)
46+
b = make_shared((5, 4, 3))
47+
assert a.get_value().shape == (5, 4, 3)
48+
a.set_value(np.zeros((5, 4, 3), dtype=a.dtype))
49+
b.set_value(np.ones((5, 4, 3), dtype=b.dtype))
50+
exchange_shared(a, b)
51+
assert np.all(a.get_value() == 1.)
52+
assert np.all(b.get_value() == 0.)
53+
f = make_exchange_func(a, b)
54+
rval = f()
55+
assert isinstance(rval, list)
56+
assert len(rval) == 0
57+
assert np.all(a.get_value() == 0.)
58+
assert np.all(b.get_value() == 1.)
59+
60+
print "SUCCESS!"

ipnb/13_bug_soln.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# The weird thing is that the function succeeds.
2+
#
3+
# This is weird because the two values passed in for x and y do not
4+
# have the same shape, yet x is added with something that has the same
5+
# shape as y (z).
6+
#
7+
# This happens because optimizations realize that z is always zero and
8+
# therefore remove the addition, which removes the error.
9+
#
10+
# The problem is more evident if FAST_COMPILE or DEBUG_MODE is used.

ipnb/21_grad_soln.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Fill in the TODOs in this exercise, then run
2+
# python 01_grad.py to see if your solution works!
3+
#
4+
from theano import tensor as T
5+
6+
7+
def grad_sum(x, y, z):
8+
"""
9+
x: A theano variable
10+
y: A theano variable
11+
z: A theano expression involving x and y
12+
13+
Returns dz / dx + dz / dy
14+
"""
15+
16+
return sum(T.grad(z, [x, y]))
17+
18+
x = T.scalar()
19+
y = T.scalar()
20+
z = x + y
21+
s = grad_sum(x, y, z)
22+
assert s.eval({x: 0, y: 0}) == 2
23+
print "SUCCESS!"

ipnb/22_traverse_soln.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import numpy as np
2+
from theano.gof import Variable
3+
from theano import tensor as T
4+
5+
6+
def arg_to_softmax(prob):
7+
"""
8+
Oh no! Someone has passed you the probability output,
9+
"prob", of a softmax function, and you want the unnormalized
10+
log probability--the argument to the softmax.
11+
12+
Verify that prob really is the output of a softmax. Raise a
13+
TypeError if it is not.
14+
15+
If it is, return the argument to the softmax.
16+
"""
17+
18+
if not isinstance(prob, Variable):
19+
raise TypeError()
20+
21+
if prob.owner is None:
22+
raise TypeError()
23+
24+
owner = prob.owner
25+
26+
if not isinstance(owner.op, T.nnet.Softmax):
27+
raise TypeError()
28+
29+
rval, = owner.inputs
30+
31+
return rval
32+
33+
if __name__ == "__main__":
34+
x = np.ones((5, 4))
35+
try:
36+
arg_to_softmax(x)
37+
raise Exception("You should have raised an error.")
38+
except TypeError:
39+
pass
40+
41+
x = T.matrix()
42+
try:
43+
arg_to_softmax(x)
44+
raise Exception("You should have raised an error.")
45+
except TypeError:
46+
pass
47+
48+
y = T.nnet.sigmoid(x)
49+
try:
50+
arg_to_softmax(y)
51+
raise Exception("You should have raised an error.")
52+
except TypeError:
53+
pass
54+
55+
y = T.nnet.softmax(x)
56+
rval = arg_to_softmax(y)
57+
assert rval is x
58+
59+
print "SUCCESS!"

ipnb/31_debug_soln.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import numpy as np
2+
from theano import function
3+
from theano import tensor as T
4+
from theano import config
5+
config.compute_test_value = 'raise'
6+
a = T.vector()
7+
a.tag.test_value = np.ones((3,)).astype(a.dtype)
8+
b = T.log(a)
9+
c = T.nnet.sigmoid(b)
10+
d = T.sqrt(c)
11+
e = T.concatenate((d, c), axis=0)
12+
f = b * c * d
13+
# This is the first bad line
14+
g = e + f
15+
h = g / c
16+
fn = function([a], h)
17+
fn(np.ones((3,)).astype(a.dtype))

0 commit comments

Comments
 (0)