What is the ordering of dimensions of data that odeint() expects?
I'm trying to train the network learn a 6 dimensional time series trajectory. Normally I organize this as:
[batch_size, channels, length]
Where channels = 6 and length is the time series length. However in the spiral example I see the input initial value is organized as:
[batch_size, 1, channels] where channels = 2 and the output is
[length, batch_size, 1, channels] where length = 10
I find this a really confusing way to organize things, maybe I'm misunderstanding something? What is the ordering of dimensions of data that odeint() expects? What does that extra dimension of 1 represent?
Thanks!
Hmm, odeint always adds a first dimension that corresponds to time. Other than that, you're free to use any ordering you want. The ordering is mostly imposed by how the ODE function is implemented. Also, remember you can always permute the ordering before and after operations.
I'm not quite familiar with the latent_ode example, but where do you see the output having an extra dimension? From the use of permute in this line (https://github.com/rtqichen/torchdiffeq/blob/master/examples/latent_ode.py#L262) it looks to me there are 3 dimensions. My guess is the output of odeint here is [length, batch, dim] and gets permuted into [batch, length, dim].
Hi @rtqichen
When I use this ordering for input:
batch_y0: [batch, channels, length] ([64, 6, 1])
batch_t: [length] ([60])
I get the following error:
Traceback (most recent call last):
File "main_net.py", line 71, in <module>
network.train.net_train(args)
File "/home/russell/git/imu_noise_learning/src/network/train.py", line 420, in net_train
attr_dict = get_inference(network, train_loader, device)
File "/home/russell/git/imu_noise_learning/src/network/train.py", line 151, in get_inference
pred_y = odeint(network, batch_y0, batch_t[1], method='rk4', options=options).to(device) # forward pass
File "/home/russell/.cache/pypoetry/virtualenvs/imu-noise-learning-YZtiLgq0-py3.8/lib/python3.8/site-packages/torchdiffeq/_impl/adjoint.py", line 198, in odeint_adjoint
ans = OdeintAdjointMethod.apply(shapes, func, y0, t, rtol, atol, method, options, event_fn, adjoint_rtol, adjoint_atol,
File "/home/russell/.cache/pypoetry/virtualenvs/imu-noise-learning-YZtiLgq0-py3.8/lib/python3.8/site-packages/torchdiffeq/_impl/adjoint.py", line 25, in forward
ans = odeint(func, y0, t, rtol=rtol, atol=atol, method=method, options=options, event_fn=event_fn)
File "/home/russell/.cache/pypoetry/virtualenvs/imu-noise-learning-YZtiLgq0-py3.8/lib/python3.8/site-packages/torchdiffeq/_impl/odeint.py", line 77, in odeint
solution = solver.integrate(t)
File "/home/russell/.cache/pypoetry/virtualenvs/imu-noise-learning-YZtiLgq0-py3.8/lib/python3.8/site-packages/torchdiffeq/_impl/solvers.py", line 110, in integrate
solution[j] = self._linear_interp(t0, t1, y0, y1, t[j])
RuntimeError: The expanded size of the tensor (1) must match the existing size (6) at non-singleton dimension 2. Target sizes: [64, 6, 1]. Tensor sizes: [64, 6, 6]
But if I swap channels and length in batch_y0 then it works.