Dealing with weights matrices and gradients can be tricky and sometimes not trivial. Theano is a great framework for handling vectors, matrices and high dimensional tensor algebra. Most of this tutorial will refer to Theano however TensorFlow is another great framework capable of providing an incredible abstraction for complex algebra. More on TensorFlow in the next chapters.
In [1]:
import theano
import theano.tensor as T
Theano has it's own variables and functions, defined the following
In [2]:
x = T.scalar()
In [3]:
x
Out[3]:
Variables can be used in expressions
In [4]:
y = 3*(x**2) + 1
y is an expression now
Result is symbolic as well
In [5]:
type(y)
y.shape
Out[5]:
As we are about to see, normal printing isn't the best when it comes to theano
In [6]:
print(y)
In [7]:
theano.pprint(y)
Out[7]:
In [8]:
theano.printing.debugprint(y)
In [9]:
y.eval({x: 2})
Out[9]:
Or compile a function
In [10]:
f = theano.function([x], y)
In [11]:
f(2)
Out[11]:
In [12]:
X = T.vector()
X = T.matrix()
X = T.tensor3()
X = T.tensor4()
In [13]:
x = T.scalar()
y = T.log(x)
In [14]:
gradient = T.grad(y, x)
print(gradient)
print(gradient.eval({x: 2}))
print((2 * gradient))
In [15]:
import numpy as np
x = theano.shared(np.zeros((2, 3), dtype=theano.config.floatX))
In [16]:
x
Out[16]:
We can get and set the variable's value
In [17]:
values = x.get_value()
print(values.shape)
print(values)
In [18]:
x.set_value(values)
Shared variables can be used in expressions as well
In [19]:
(x + 2) ** 2
Out[19]:
Their value is used as input when evaluating
In [20]:
((x + 2) ** 2).eval()
Out[20]:
In [21]:
theano.function([], (x + 2) ** 2)()
Out[21]:
In [22]:
count = theano.shared(0)
new_count = count + 1
updates = {count: new_count}
f = theano.function([], count, updates=updates)
In [23]:
f()
Out[23]:
In [24]:
f()
Out[24]:
In [25]:
f()
Out[25]: