Hello,
My code is very simple, but the Dataset is a little bit problematic, because it has a variable size.
I have a custom dataset with the following structure: Notes x N_bins x Temp_values
Notes is 2904
N_bins is ALWAYS 252
Temp_values varies depending on the note.
I prepare my own dataset and I make the transforms manually.
class MusicDataSet(Dataset):
def __init__(self, transform=None):
self.ms, self.target, self.tam = sd.loadData()
def __len__(self):
return self.tam
def __getitem__(self, idx):
inp = torch.from_numpy(self.ms[idx]).float()
#Transpose
inp = inp.t()
#to cuda
inp = inp.to('cuda')
target = self.target[idx]
target= torch.from_numpy(self.target[idx])
target = target.long()
target = target.t()
return inp, target
I have created my own collate_fn to be able to split the dataset into small batches but the problem is that I can’t return the batches as a tensor, just as a list.
def music_collate_fn(batch):
data = [item[0] for item in batch]
target = [item[1] for item in batch]
return torch.tensor(data), torch.tensor(target)
train_loader = torch.utils.data.DataLoader(musicSet, batch_size=10, shuffle=False, collate_fn=music_collate_fn)
class MLP(nn.Module):
def __init__(self):
super(MLP, self).__init__()
self.dense1 = nn.Linear(252, 512)
self.dense2 = nn.Linear(512, 88)
def forward(self, x):
x = self.dense1(x)
x = self.relu(x)
x = self.dense2(x)
return x
The train is very simple:
mlp = MLP(input_dim, hidden_dim, output_dim).to(device)
optimizer = torch.optim.RMSprop(mlp.parameters(), lr = learning_rate)
mlp.train()
for batch_idx, (x,y) in enumerate(train_loader):
outputs = mlp(x.to(device))
loss = criterion(outputs, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
Fail:
File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 704, in runfile
execfile(filename, namespace)
File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/Antonio López León/Documents/Universidad/TFG/PROYECTO/BBDD/audioCQT/ProcesamientoNN.py", line 102, in <module>
for batch_idx, (x,y) in enumerate(train_loader):
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\utils\data\dataloader.py", line 615, in __next__
batch = self.collate_fn([self.dataset[i] for i in indices])
File "C:/Users/Antonio López León/Documents/Universidad/TFG/PROYECTO/BBDD/audioCQT/ProcesamientoNN.py", line 65, in music_collate_fn
return torch.tensor(data), torch.tensor(target)
ValueError: only one element tensors can be converted to Python scalars
I tried to make a pad_sequence over the data in the music_collate_fn and it works at the moment of fed the network, but the target give me problems when I calculate the loss so I can’t use the padding with the target.
I need some ideas to make it possible. Thank so much!