In [1]:
# derivative easy example
import theano 
import theano.tensor as T
from theano import pp
x = T.dscalar('x')
y = x ** 2
gy = T.grad(y, x)
f = theano.function([x], gy)

In [3]:
f(8)
f(16)


Out[3]:
array(32.0)

In [4]:
# derivative logistic function
x = T.dmatrix('x')
s = T.sum(1 / (1 + T.exp(-x)))
gs = T.grad(s, x)
dlogistic = theano.function([x], gs)

In [5]:
dlogistic([[0,1], [12, 7]])


Out[5]:
array([[  2.50000000e-01,   1.96611933e-01],
       [  6.14413685e-06,   9.10221180e-04]])

In [6]:
# scan function
# easy example

import theano
import theano.tensor as T

k = T.iscalar("k")
A = T.vector("A")

# Symbolic description of the result
result, updates = theano.scan(fn=lambda prior_result, A: prior_result * A,
                              outputs_info=T.ones_like(A),
                              non_sequences=A,
                              n_steps=k)

# We only care about A**k, but scan has provided us with A**1 through A**k.
# Discard the values that we don't care about. Scan is smart enough to
# notice this and not waste memory saving them.
final_result = result[-1]

# compiled function that returns A**k
power = theano.function(inputs=[A,k], outputs=final_result, updates=updates)

print power(range(10),2)


[  0.   1.   4.   9.  16.  25.  36.  49.  64.  81.]
/Users/susu/anaconda/lib/python2.7/site-packages/theano/gof/cmodule.py:293: RuntimeWarning: numpy.ndarray size changed, may indicate binary incompatibility
  rval = __import__(module_name, {}, {}, [module_name])

In [21]:
# computing jacobian
# manually do it as follows
import theano 
import theano.tensor as T

x = T.dvector('x')
y = x ** 2
J, updates = theano.scan(lambda i, y, x : T.grad(y[i], x), sequences = T.arange(y.shape[0]), non_sequences = [y, x])
f = theano.function([x], J, updates = updates)
f([4,4])


Out[21]:
array([[ 8.,  0.],
       [ 0.,  8.]])

In [20]:
# computing hessian
# manually do it as follows

y = x ** 2
cost = y.sum()
gy = T.grad(cost, x)
H, updates = theano.scan(lambda i, gy,x : T.grad(gy[i], x), sequences=T.arange(gy.shape[0]), non_sequences=[gy, x])
f = theano.function([x], H, updates = updates)
f([4,4])


Out[20]:
array([[ 2.,  0.],
       [ 0.,  2.]])

In [22]:
# jacobian times vector -> R-operator
# vector times jacobian -> L-operator
# both of these can be used to Hessian 

W = T.dmatrix('W')
V = T.dmatrix('V')
x = T.dvector('x')
y = T.dot(x, W)
JV = T.Rop(y, W, V) # R-operator
f = theano.function([W, V, x], JV)
f([[1, 1], [1, 1]], [[2, 2], [2, 2]], [0,1])


Out[22]:
array([ 2.,  2.])

In [ ]: