forked from nouiz/ccw_tutorial_theano
-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move the exercies from the basic tutorial to a ipython notebook.
- Loading branch information
Showing
10 changed files
with
972 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import numpy as np | ||
from theano import function | ||
import theano.tensor as T | ||
|
||
|
||
def make_scalar(): | ||
""" | ||
Returns a new Theano scalar. | ||
""" | ||
|
||
return T.scalar() | ||
|
||
|
||
def log(x): | ||
""" | ||
Returns the logarithm of a Theano scalar x. | ||
""" | ||
|
||
return T.log(x) | ||
|
||
|
||
def add(x, y): | ||
""" | ||
Adds two theano scalars together and returns the result. | ||
""" | ||
|
||
return x + y | ||
|
||
a = make_scalar() | ||
b = make_scalar() | ||
c = log(b) | ||
d = add(a, c) | ||
f = function([a, b], d) | ||
a = np.cast[a.dtype](1.) | ||
b = np.cast[b.dtype](2.) | ||
actual = f(a, b) | ||
expected = 1. + np.log(2.) | ||
assert np.allclose(actual, expected) | ||
print "SUCCESS!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import numpy as np | ||
from theano import function | ||
import theano.tensor as T | ||
|
||
|
||
def make_vector(): | ||
""" | ||
Returns a new Theano vector. | ||
""" | ||
|
||
return T.vector() | ||
|
||
|
||
def make_matrix(): | ||
""" | ||
Returns a new Theano matrix. | ||
""" | ||
|
||
return T.matrix() | ||
|
||
|
||
def elemwise_mul(a, b): | ||
""" | ||
a: A theano matrix | ||
b: A theano matrix | ||
Returns the elementwise product of a and b | ||
""" | ||
|
||
return a * b | ||
|
||
|
||
def matrix_vector_mul(a, b): | ||
""" | ||
a: A theano matrix | ||
b: A theano vector | ||
Returns the matrix-vector product of a and b | ||
""" | ||
|
||
return T.dot(a, b) | ||
|
||
a = make_vector() | ||
b = make_vector() | ||
c = elemwise_mul(a, b) | ||
d = make_matrix() | ||
e = matrix_vector_mul(d, c) | ||
|
||
f = function([a, b, d], e) | ||
|
||
rng = np.random.RandomState([1, 2, 3]) | ||
a_value = rng.randn(5).astype(a.dtype) | ||
b_value = rng.rand(5).astype(b.dtype) | ||
c_value = a_value * b_value | ||
d_value = rng.randn(5, 5).astype(d.dtype) | ||
expected = np.dot(d_value, c_value) | ||
|
||
actual = f(a_value, b_value, d_value) | ||
|
||
assert np.allclose(actual, expected) | ||
print "SUCCESS!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import numpy as np | ||
from theano import function | ||
import theano.tensor as T | ||
|
||
|
||
def make_tensor(dim): | ||
""" | ||
Returns a new Theano tensor with no broadcastable dimensions. | ||
dim: the total number of dimensions of the tensor. | ||
""" | ||
|
||
return T.TensorType(broadcastable=tuple([False] * dim), dtype='float32')() | ||
|
||
|
||
def broadcasted_add(a, b): | ||
""" | ||
a: a 3D theano tensor | ||
b: a 4D theano tensor | ||
Returns c, a 4D theano tensor, where | ||
c[i, j, k, l] = a[l, k, i] + b[i, j, k, l] | ||
for all i, j, k, l | ||
""" | ||
|
||
return a.dimshuffle(2, 'x', 1, 0) + b | ||
|
||
|
||
def partial_max(a): | ||
""" | ||
a: a 4D theano tensor | ||
Returns b, a theano matrix, where | ||
b[i, j] = max_{k,l} a[i, k, l, j] | ||
for all i, j | ||
""" | ||
|
||
return a.max(axis=(1, 2)) | ||
|
||
a = make_tensor(3) | ||
b = make_tensor(4) | ||
c = broadcasted_add(a, b) | ||
d = partial_max(c) | ||
|
||
f = function([a, b], d) | ||
|
||
rng = np.random.RandomState([1, 2, 3]) | ||
a_value = rng.randn(2, 2, 2).astype(a.dtype) | ||
b_value = rng.rand(2, 2, 2, 2).astype(b.dtype) | ||
c_value = np.transpose(a_value, (2, 1, 0))[:, None, :, :] + b_value | ||
expected = c_value.max(axis=1).max(axis=1) | ||
|
||
actual = f(a_value, b_value) | ||
|
||
assert np.allclose(actual, expected), (actual, expected) | ||
print "SUCCESS!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from theano import tensor as T | ||
from theano import function | ||
|
||
|
||
def evaluate(x, y, expr, x_value, y_value): | ||
""" | ||
x: A theano variable | ||
y: A theano variable | ||
expr: A theano expression involving x and y | ||
x_value: A numpy value | ||
y_value: A numpy value | ||
Returns the value of expr when x_value is substituted for x | ||
and y_value is substituted for y | ||
""" | ||
|
||
return function([x, y], expr)(x_value, y_value) | ||
|
||
|
||
x = T.iscalar() | ||
y = T.iscalar() | ||
z = x + y | ||
assert evaluate(x, y, z, 1, 2) == 3 | ||
print "SUCCESS!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import numpy as np | ||
from theano.compat.python2x import OrderedDict | ||
from theano import function | ||
from theano import shared | ||
|
||
|
||
def make_shared(shape): | ||
""" | ||
Returns a theano shared variable containing a tensor of the specified | ||
shape. | ||
You can use any value you want. | ||
""" | ||
return shared(np.zeros(shape)) | ||
|
||
|
||
def exchange_shared(a, b): | ||
""" | ||
a: a theano shared variable | ||
b: a theano shared variable | ||
Uses get_value and set_value to swap the values stored in a and b | ||
""" | ||
temp = a.get_value() | ||
a.set_value(b.get_value()) | ||
b.set_value(temp) | ||
|
||
|
||
def make_exchange_func(a, b): | ||
""" | ||
a: a theano shared variable | ||
b: a theano shared variable | ||
Returns f | ||
where f is a theano function, that, when called, swaps the | ||
values in a and b | ||
f should not return anything | ||
""" | ||
|
||
updates = OrderedDict() | ||
updates[a] = b | ||
updates[b] = a | ||
f = function([], updates=updates) | ||
return f | ||
|
||
|
||
a = make_shared((5, 4, 3)) | ||
assert a.get_value().shape == (5, 4, 3) | ||
b = make_shared((5, 4, 3)) | ||
assert a.get_value().shape == (5, 4, 3) | ||
a.set_value(np.zeros((5, 4, 3), dtype=a.dtype)) | ||
b.set_value(np.ones((5, 4, 3), dtype=b.dtype)) | ||
exchange_shared(a, b) | ||
assert np.all(a.get_value() == 1.) | ||
assert np.all(b.get_value() == 0.) | ||
f = make_exchange_func(a, b) | ||
rval = f() | ||
assert isinstance(rval, list) | ||
assert len(rval) == 0 | ||
assert np.all(a.get_value() == 0.) | ||
assert np.all(b.get_value() == 1.) | ||
|
||
print "SUCCESS!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# The weird thing is that the function succeeds. | ||
# | ||
# This is weird because the two values passed in for x and y do not | ||
# have the same shape, yet x is added with something that has the same | ||
# shape as y (z). | ||
# | ||
# This happens because optimizations realize that z is always zero and | ||
# therefore remove the addition, which removes the error. | ||
# | ||
# The problem is more evident if FAST_COMPILE or DEBUG_MODE is used. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Fill in the TODOs in this exercise, then run | ||
# python 01_grad.py to see if your solution works! | ||
# | ||
from theano import tensor as T | ||
|
||
|
||
def grad_sum(x, y, z): | ||
""" | ||
x: A theano variable | ||
y: A theano variable | ||
z: A theano expression involving x and y | ||
Returns dz / dx + dz / dy | ||
""" | ||
|
||
return sum(T.grad(z, [x, y])) | ||
|
||
x = T.scalar() | ||
y = T.scalar() | ||
z = x + y | ||
s = grad_sum(x, y, z) | ||
assert s.eval({x: 0, y: 0}) == 2 | ||
print "SUCCESS!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import numpy as np | ||
from theano.gof import Variable | ||
from theano import tensor as T | ||
|
||
|
||
def arg_to_softmax(prob): | ||
""" | ||
Oh no! Someone has passed you the probability output, | ||
"prob", of a softmax function, and you want the unnormalized | ||
log probability--the argument to the softmax. | ||
Verify that prob really is the output of a softmax. Raise a | ||
TypeError if it is not. | ||
If it is, return the argument to the softmax. | ||
""" | ||
|
||
if not isinstance(prob, Variable): | ||
raise TypeError() | ||
|
||
if prob.owner is None: | ||
raise TypeError() | ||
|
||
owner = prob.owner | ||
|
||
if not isinstance(owner.op, T.nnet.Softmax): | ||
raise TypeError() | ||
|
||
rval, = owner.inputs | ||
|
||
return rval | ||
|
||
if __name__ == "__main__": | ||
x = np.ones((5, 4)) | ||
try: | ||
arg_to_softmax(x) | ||
raise Exception("You should have raised an error.") | ||
except TypeError: | ||
pass | ||
|
||
x = T.matrix() | ||
try: | ||
arg_to_softmax(x) | ||
raise Exception("You should have raised an error.") | ||
except TypeError: | ||
pass | ||
|
||
y = T.nnet.sigmoid(x) | ||
try: | ||
arg_to_softmax(y) | ||
raise Exception("You should have raised an error.") | ||
except TypeError: | ||
pass | ||
|
||
y = T.nnet.softmax(x) | ||
rval = arg_to_softmax(y) | ||
assert rval is x | ||
|
||
print "SUCCESS!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import numpy as np | ||
from theano import function | ||
from theano import tensor as T | ||
from theano import config | ||
config.compute_test_value = 'raise' | ||
a = T.vector() | ||
a.tag.test_value = np.ones((3,)).astype(a.dtype) | ||
b = T.log(a) | ||
c = T.nnet.sigmoid(b) | ||
d = T.sqrt(c) | ||
e = T.concatenate((d, c), axis=0) | ||
f = b * c * d | ||
# This is the first bad line | ||
g = e + f | ||
h = g / c | ||
fn = function([a], h) | ||
fn(np.ones((3,)).astype(a.dtype)) |
Oops, something went wrong.