torchdiffeq icon indicating copy to clipboard operation
torchdiffeq copied to clipboard

What is the ordering of dimensions of data that odeint() expects?

Open raabuchanan opened this issue 4 years ago • 2 comments

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!

raabuchanan avatar Sep 15 '21 09:09 raabuchanan

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].

rtqichen avatar Sep 17 '21 15:09 rtqichen

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.

raabuchanan avatar Sep 20 '21 15:09 raabuchanan