I am trying to implement a neural net in PyTorch but it doesn’t seem to work. The problem seems to be in the training loop. I’ve spend several hours into this but can’t get it right. Please help, thanks.
I haven’t added the data preprocessing parts.
JavaScript
x
9
1
# importing libraries
2
import pandas as pd
3
import numpy as np
4
import torch
5
import torch.nn as nn
6
from torch.utils.data import Dataset
7
from torch.utils.data import DataLoader
8
import torch.nn.functional as F
9
JavaScript
1
15
15
1
# get x function (dataset related stuff)
2
def Getx(idx):
3
sample = samples[idx]
4
vector = Calculating_bottom(sample)
5
vector = torch.as_tensor(vector, dtype = torch.float64)
6
7
return vector
8
9
# get y function (dataset related stuff)
10
def Gety(idx):
11
y = np.array(train.iloc[idx, 4], dtype = np.float64)
12
y = torch.as_tensor(y, dtype = torch.float64)
13
14
return y
15
JavaScript
1
17
17
1
# dataset
2
class mydataset(Dataset):
3
4
def __init__(self):
5
super().__init__()
6
7
def __getitem__(self, index):
8
x = Getx(index)
9
y = Gety(index)
10
11
return x, y
12
13
def __len__(self):
14
return len(train)
15
16
dataset = mydataset()
17
JavaScript
1
3
1
# sample dataset value
2
print(dataset.__getitem__(0))
3
(tensor([ 5., 5., 8., 14.], dtype=torch.float64), tensor(-0.3403, dtype=torch.float64))
JavaScript
1
3
1
# data-loader
2
dataloader = DataLoader(dataset, batch_size = 1, shuffle = True)
3
JavaScript
1
17
17
1
# nn architecture
2
class Net(nn.Module):
3
def __init__(self):
4
super().__init__()
5
self.fc1 = nn.Linear(4, 4)
6
self.fc2 = nn.Linear(4, 2)
7
self.fc3 = nn.Linear(2, 1)
8
9
def forward(self, x):
10
x = x.float()
11
x = F.relu(self.fc1(x))
12
x = F.relu(self.fc2(x))
13
x = self.fc3(x)
14
return x
15
16
model = Net()
17
JavaScript
1
4
1
# device
2
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
3
model.to(device)
4
JavaScript
1
4
1
# hyper-parameters
2
criterion = nn.MSELoss()
3
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
4
JavaScript
1
26
26
1
# training loop
2
3
for epoch in range(5):
4
5
for batch in dataloader:
6
7
# unpacking
8
x, y = batch
9
x.to(device)
10
y.to(device)
11
12
# reset gradients
13
optimizer.zero_grad()
14
15
# forward propagation through the network
16
out = model(x)
17
18
# calculate the loss
19
loss = criterion(out, y)
20
21
# backpropagation
22
loss.backward()
23
24
# update the parameters
25
optimizer.step()
26
Error:
JavaScript
1
27
27
1
/opt/conda/lib/python3.7/site-packages/torch/nn/modules/loss.py:446: UserWarning: Using a target size (torch.Size([1])) that is different to the input size (torch.Size([1, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
2
return F.mse_loss(input, target, reduction=self.reduction)
3
---------------------------------------------------------------------------
4
RuntimeError Traceback (most recent call last)
5
<ipython-input-18-3f68fcee9ff3> in <module>
6
20
7
21 # backpropagation
8
---> 22 loss.backward()
9
23
10
24 # update the parameters
11
12
/opt/conda/lib/python3.7/site-packages/torch/tensor.py in backward(self, gradient, retain_graph, create_graph)
13
219 retain_graph=retain_graph,
14
220 create_graph=create_graph)
15
--> 221 torch.autograd.backward(self, gradient, retain_graph, create_graph)
16
222
17
223 def register_hook(self, hook):
18
19
/opt/conda/lib/python3.7/site-packages/torch/autograd/__init__.py in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables)
20
130 Variable._execution_engine.run_backward(
21
131 tensors, grad_tensors_, retain_graph, create_graph,
22
--> 132 allow_unreachable=True) # allow_unreachable flag
23
133
24
134
25
26
RuntimeError: Found dtype Double but expected Float
27
Advertisement
Answer
You need the data type of the data to match the data type of the model.
Either convert the model to double (recommended for simple nets with no serious performance problems such as yours)
JavaScript
1
9
1
# nn architecture
2
class Net(nn.Module):
3
def __init__(self):
4
super().__init__()
5
self.fc1 = nn.Linear(4, 4)
6
self.fc2 = nn.Linear(4, 2)
7
self.fc3 = nn.Linear(2, 1)
8
self.double()
9
or convert the data to float.
JavaScript
1
11
11
1
class mydataset(Dataset):
2
3
def __init__(self):
4
super().__init__()
5
6
def __getitem__(self, index):
7
x = Getx(index)
8
y = Gety(index)
9
10
return x.float(), y.float()
11