Discussion:
[theano-users] Re: Backprop in time error for learning of physics simulation
Juan Camilo Gamboa Higuera
2017-08-02 13:25:19 UTC
Permalink
Hi,

In your call to theano scan you are passing a compiled theano function.
What you really want is a python function that constructs the inner graph
for the scan operator. I.e. you would do something like this:

def forward_pass_step(x, ffn):
x_next = lasagne.layers.get_output(ffn, x)

x0 = theano.tensor.matrix('x0')

X, updates = theano.scan(forward_pass_step,
outputs_info=[x0],
n_steps=5)

lastCost = cost(X[-1])

f = theano.function([x0], X, updates=updates)


In this case, calling f(some_input) will do a forward pass through your
network five times, each time feeding the output of the previous step as
the input for the next step. Taking the gradient of lastCost, via
theano.grad, will perform backpropagation through time.

-- Juan Camilo
Hello everyone,
I am trying to implement the multi-frame loss in this paper (equation (4)
https://arxiv.org/pdf/1607.03597.pdf
I am using a custom convolutional layer that operates on meshes and needs
a sparse matrix per training sample.
Basically, in order to learn a physics simulation, I want to calculate
the velocity loss for a single frame n and then step in the future 5 times,
get that future loss and accumulate its partial derivatives to the gradient
of the single frame.
The stepping in the future is the problematic part. I am trying with a
scan at each loop to pass as input the result of the previous iteration (a
vector with 3 channels X,Y,Z) and a sparse matrix.
*NotImplementedError: Theano has no sparse vectorUse X[a:b, c:d], X[a:b,
c:c+1] or X[a:b] instead.*
So essentially I don't know how to create a scan loop in which at each
iteration inp.input_var (network input) is updated with the output of the
network at the previous step. It seems in fact that inp.input_var can be
passed only from a theano.function ??
1- is this the correct way to do backpropagation through time ? (I want
the loss to be a composition of losses like in RNNs, but from the future)
my doubt is especially how I have to use inp.input_var
2- should I use deterministic = true when I do the prediction in the
future ?
Any suggestions would be greatly appreciated !
Please ask me anything that is not clear.
import numpy as np
import theano
import theano.tensor as T
import theano.sparse as Tsp
import lasagne as L
import lasagne.layers as LL
import lasagne.objectives as LO
import re
# Built a deep network with custom convolutional layers for meshes
icnn = inp
# Geodesic convolutional layer
icnn = (utils_lasagne.GCNNLayer([icnn, patch_op], 32, nrings=5, nrays=
16))
icnn = (utils_lasagne.GCNNLayer([icnn, patch_op], 64, nrings=5, nrays=
16))
icnn = (utils_lasagne.GCNNLayer([icnn, patch_op], 128, nrings=5, nrays
=16))
ffn = utils_lasagne.GCNNLayer([icnn, patch_op], 3, nrings=5, nrays=16
, nonlinearity=None)
return ffn
inp = LL.InputLayer(shape=(None, 3 ))
# patches (disks)
patch_op = LL.InputLayer(input_var=Tsp.csc_fmatrix('patch_op'), shape=(
None, None))
ffn = get_model(inp, patch_op)
# ground truth velocities
truth = T.matrix('Truth')
disk1 = Tsp.csc_fmatrix('disk1')
disk2 = Tsp.csc_fmatrix('disk2')
disk3 = Tsp.csc_fmatrix('disk3')
disk4 = Tsp.csc_fmatrix('disk4')
disk5 = Tsp.csc_fmatrix('disk5')
targetFutureVelocitiesTruth = T.matrix('targetFutureVelocitiesTruth')
learn_rate = T.scalar('learning_rate')
output = LL.get_output(ffn)
pred = LL.get_output(ffn, deterministic=True)
# Skip Connection
inputVelocities = inp.input_var[:,:3] # slice x y z excluding the
constraint last dimension of zeros and ones
output += inputVelocities
targetVelocities = truth[:,3:6]
velCost = squared_error(output, targetVelocities)
regL2 = L.regularization.regularize_network_params(ffn, L.regularization.
l2)
# the cost of a single frame
cost = lambda_vel*velCost + l2_weight*regL2
# one step of the network
step = theano.function([patch_op.input_var, inp.input_var],
[output],
on_unused_input='warn'
)
# lists of sparse matrices
disks = [disk1,disk2,disk3,disk4,disk5]
# step 5 frames in the future
futurePredictions, _ = theano.scan(step,
outputs_info = inp.input_var,
sequences = disks,
n_steps = 5 )
# future velocity
lastFuturePrediction = futurePredictions[-1]
# error in the future
futureCost = squared_error(lastFuturePrediction,
targetFutureVelocitiesTruth)
# get network parameters
params = LL.get_all_params(ffn, trainable=True)
# accumulate partial derivatives from this frame and from future frame
grads = T.grad(cost, params)
gradsFuture = T.grad(futureCost, params)
grads = grads + gradsFuture
updates = L.updates.adam(grads, params, learning_rate=learn_rate)
funcs = dict()
funcs['train'] = theano.function([inp.input_var, patch_op.input_var, truth
, learn_rate,
targetFutureVelocitiesTruth, disk1, disk2,
disk3, disk4, disk5 ],
[cost],
updates=updates,
on_unused_input='warn')
# now just call the train function with a velocity field, disks, truth etc
to have the global loss in one go
Thank you very much for your help
Fab
--
---
You received this message because you are subscribed to the Google Groups "theano-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to theano-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...