# StopIteration Exception and tensors don't have gradients !?

I’m implemnting a model that requires custom dataset. Using torchdyn as dependency.
Dataset

``````class LotkaVolterraDataset(torch.utils.data.Dataset):

def __init__(self, X):
self.t, X = X

self.x, self.y = np.array([]), np.array([])

for val in X:

self.x = np.append(self.x, val[0])
self.y = np.append(self.y, val[1])

def __len__(self):
return len(self.t)

def __getitem__(self, idx):

return self.t[idx], self.x[idx], self.y[idx]

res = odeint(derivative, X0, t_span, solver='tsit5')
``````

where `derivative` is a function :

``````class LotkaVolterraDataset(torch.utils.data.Dataset):

def __init__(self, X):
self.t, X = X

self.x, self.y = np.array([]), np.array([])

for val in X:

self.x = np.append(self.x, val[0])
self.y = np.append(self.y, val[1])

def __len__(self):
return len(self.t)

def __getitem__(self, idx):

return self.t[idx], self.x[idx], self.y[idx]

res = odeint(derivative, X0, t_span, solver='tsit5')
``````

My model looks like this :

``````class f(nn.Module):
def __init__(self, dim):
super(f, self).__init__()
self.model = nn.Sequential(
nn.Linear(dim,124),
nn.ReLU(),
nn.Linear(124,124),
nn.ReLU(),
nn.Linear(124,dim),
nn.Tanh()
)

def forward(self, t, x):
x = x.float()
return self.model(x)

from torchdyn.core import NeuralODE

class DifferentialEquation(nn.Module):

def __init__(self,
network:nn.Module = f(dim=1000),
t_span=torch.Tensor([0., 1.]),
solver='tsit5',
order=1,
atol=0.001,
rtol=0.001,
interpolator = None,
integral_loss=None,
seminorm=False,
return_t_eval=True,
optimizable_params={}) -> None:

super(DifferentialEquation, self).__init__()

#self.input_layer = nn.Linear(1000,124)
self.model = NeuralODE(vector_field=network,
solver=solver,
order=order,
atol=atol,
rtol=rtol,
sensitivity=sensitivity,
interpolator=interpolator,
integral_loss=integral_loss,
seminorm=seminorm,
return_t_eval=return_t_eval,
optimizable_params=optimizable_params)
#self.output_layer = nn.Linear(124,1000)

self.t_span = t_span

def forward(self, t):
z = self.model(t, self.t_span)
#print(z.shape)
return z
``````

and finally the training code:

``````N_EPOCH = 5

lossFn = nn.L1Loss()

running_loss = 0.0

for epoch in tqdm.tqdm(range(N_EPOCH)):

x_train, y_train, t_train = data_iter.next()
print(type(x_train), type(y_train), type(t_train))

x_out, _ = predator(t_train)
y_out, _ = prey(t_train)
print(x_train.shape, x_out.shape)
loss_predator = lossFn(x_out, x_train)

print(y_train.shape, y_out.shape)
loss_prey = lossFn(y_out, y_train)

loss_predator.backward()
loss_prey.backward()

optimizer.step()

running_loss += loss_predator
running_loss += loss_prey

``````

** Output **

``````  0%|          | 0/5 [00:00<?, ?it/s]<class 'torch.Tensor'> <class 'torch.Tensor'> <class 'torch.Tensor'>
20%|██        | 1/5 [00:07<00:30,  7.51s/it]torch.Size([1000]) torch.Size([1000])
torch.Size([1000]) torch.Size([1000])
**StopIteration** Traceback (most recent call last) **c:\Users\shiva\Desktop\deepchem\Demonstrating_neuralode_api.ipynb Cell 20** in <cell line: 13>**()** [12](vscode-notebook-cell:/c%3A/Users/shiva/Desktop/deepchem/Demonstrating_neuralode_api.ipynb#X25sZmlsZQ%3D%3D?line=11) predator.train() [13](vscode-notebook-cell:/c%3A/Users/shiva/Desktop/deepchem/Demonstrating_neuralode_api.ipynb#X25sZmlsZQ%3D%3D?line=12) for epoch in tqdm.tqdm(range(N_EPOCH)): [14](vscode-notebook-cell:/c%3A/Users/shiva/Desktop/deepchem/Demonstrating_neuralode_api.ipynb#X25sZmlsZQ%3D%3D?line=13) #try: **---> [15](vscode-notebook-cell:/c%3A/Users/shiva/Desktop/deepchem/Demonstrating_neuralode_api.ipynb#X25sZmlsZQ%3D%3D?line=14)** x_train, y_train, t_train = data_iter.next() [16](vscode-notebook-cell:/c%3A/Users/shiva/Desktop/deepchem/Demonstrating_neuralode_api.ipynb#X25sZmlsZQ%3D%3D?line=15) print(type(x_train), type(y_train), type(t_train)) [18](vscode-notebook-cell:/c%3A/Users/shiva/Desktop/deepchem/Demonstrating_neuralode_api.ipynb#X25sZmlsZQ%3D%3D?line=17) x_train.requires_grad = True File **c:\Users\shiva\.conda\envs\pytorch\lib\site-packages\torch\utils\data\dataloader.py:681**, in _BaseDataLoaderIter.__next__**(self)** 678 if self._sampler_iter is None: 679 # TODO(https://github.com/pytorch/pytorch/issues/76750) 680 self._reset() # type: ignore[call-arg] **--> 681** data = self._next_data() 682 self._num_yielded += 1 683 if self._dataset_kind == _DatasetKind.Iterable and \ 684 self._IterableDataset_len_called is not None and \ 685 self._num_yielded > self._IterableDataset_len_called: File **c:\Users\shiva\.conda\envs\pytorch\lib\site-packages\torch\utils\data\dataloader.py:720**, in _SingleProcessDataLoaderIter._next_data**(self)** 719 def _next_data(self): **--> 720** index = self._next_index() # may raise StopIteration 721 data = self._dataset_fetcher.fetch(index) # may raise StopIteration 722 if self._pin_memory:

...

File **c:\Users\shiva\.conda\envs\pytorch\lib\site-packages\torch\utils\data\dataloader.py:671**, in _BaseDataLoaderIter._next_index**(self)** 670 def _next_index(self): **--> 671** return next(self._sampler_iter) **StopIteration**:
``````

My question :

1. Why does not tensors in dataset have gradients, even though I’m explicitly setting it to true.
2. How to eliminate the `StopIteration` exception, and why am I getting it in first place?
1. It seems you are setting the `.requires_grad` attribute to `True` on `val[0]` and `val[1]` (I don’t know what kind of object these variables are) but are then appending them to a numpy array.
Assuming `val` was indeed a numpy array, your custom attribute will not have any effect on PyTorch or `Autograd`.

2. This is expected and is how `iterator`s work on Python if you call `.next()` explicitly. If you don’t want to deal with the `StopIteration` use a for loop instead.