Hi there,
I am new to python and pytorch and stuck with my “little” project. I would like to train a model to predict a single value if it is provided a record of 30 values. I have a tensor of features and targets (provided below) for training purposes and a similar set for validation.
While writing this I stumbled upon the feature structure and I guess the feature tensor isnt correct. It should be a list of 8760 *3 records but it is a list of 3 containing a list of 8760 values. Is there an easy way to fix this (I ll have a look at the flatten function)?
It should select a batch of 10 records out of 8760*3 records for each training iteration.
I would like to get feedback on my code, the model a hint regarding the error and if the goal could be achieved with my model.
import torch
from torch import nn
from torch.utils.data import random_split, DataLoader, TensorDataset
import numpy as np
import ann_model as annM
import feature_selections as fs


# Get cpu or gpu device for ann_training.
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))

dataset_filename = 'file.npy'
dataset_filename = 'file2.npy' # sample input

print("Loading dataset: started")
print(dataset_filename, " will be loaded")
rawDataSet = np.load(dataset_filename, allow_pickle=True)
print("Loading dataset: finished")

# normierung aller Daten ?

print("Specify columns used for the moddeling dataset")
featureSelections = fs.feature_selection()
# https://stackoverflow.com/questions/44429199/how-to-load-a-list-of-numpy-arrays-to-pytorch-dataset-loader
featureData = torch.tensor(np.array(rawDataSet[:][featureSelections.s02()["names"]].tolist()))
targetsData = torch.tensor(np.array(rawDataSet[:]["trafo_q"].tolist()))

print("build pytorch dataset")
dataset = TensorDataset(featureData, targetsData)

print("split dataset into train and test")
train_size = int(0.8 * len(dataset))
test_size = len(dataset) - train_size
train, test = random_split(dataset, [train_size, test_size])

print("Create train- and testsets with dataloader and batchsze = 10")
batch_size = 10
trainset = DataLoader(train, batch_size=batch_size, shuffle=True)
testset = DataLoader(test, batch_size=batch_size, shuffle=True)

print("Creating NeuralNetwork Model")
numberOfFeatures = len(featureSelections.s02()["names"]) # number of features per record
model = annM.NeuralNetwork(numberOfFeatures) # create Model
model.to(device)

print("Optimizing Parameters")
optimizer = torch.optim.SGD(model.parameters(), lr = 0.9) # lr=1e-3
criterion = nn.BCELoss()

## TRAINING
print("Training NeuralNetwork")
model.train()
epochs = 5000
errors = []
for epoch in range(epochs):
    optimizer.zero_grad() # sets gradients to zero
    for feature, target in trainset:
        # Forward pass
        y_pred = model.forward(feature)
        # Compute Loss
        loss = criterion(y_pred.squeeze(), target)
        errors.append(loss.item())

        print('Epoch {}: train loss: {}'.format(epoch, loss.item()))
        # Backward pass
        loss.backward()
        optimizer.step()

### MODEL
import torch.nn as nn
import torch.nn.functional as F


# Define model
class NeuralNetwork (nn.Module):
    def __init__(self, numberOfFeatures):
        super(NeuralNetwork, self).__init__()
        self.l0 = nn.Linear(numberOfFeatures, 1024)
        self.l1 = nn.Linear(1024, 512)
        self.l2 = nn.Linear(512, 128)
        self.l3 = nn.Linear(numberOfFeatures, 1)

    def forward(self, inputs):
        output = self.l0(inputs)
        output = F.relu(self.l1(output))
        output = F.relu(self.l2(output))
        output = F.relu(self.l3(output))
        return output

    def training(self, trainset, optimizer, criterion):
        # self.model.train() # et mode to train other mode model.eval() called outside of class
        epochs = 5000
        errors = []
        for epoch in range(epochs):
            optimizer.zero_grad() # sets gradients to zero
            for feature, target in trainset:
                # Forward pass
                y_pred = self.forward(feature)
                # Compute Loss
                loss = criterion(y_pred.squeeze(), target)
                errors.append(loss.item())

                print('Epoch {}: train loss: {}'.format(epoch, loss.item()))
                # Backward pass
                loss.backward()
                optimizer.step()

## TRAINING
model.train()
epochs = 5000
errors = []
for epoch in range(epochs):
    optimizer.zero_grad() # sets gradients to zero
    for feature, target in trainset:
        # Forward pass
        y_pred = model.forward(feature)
        # Compute Loss
        loss = criterion(y_pred.squeeze(), target)
        errors.append(loss.item())

        print('Epoch {}: train loss: {}'.format(epoch, loss.item()))
        # Backward pass
        loss.backward()
        optimizer.step()

## FEATURES
>>> feature
tensor([[[ 1.0000e+00, -6.5955e+01,  1.4160e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         [ 2.0000e+00, -6.4064e+01,  1.4160e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         [ 3.0000e+00, -6.1796e+01,  1.6460e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         ...,
         [ 8.7580e+03, -1.0670e+02,  4.3340e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         [ 8.7590e+03, -1.0681e+02,  4.1720e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         [ 8.7600e+03, -1.0487e+02,  4.3040e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00]],

        [[ 1.0000e+00, -7.6689e+01,  1.4160e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         [ 2.0000e+00, -7.4489e+01,  1.4160e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         [ 3.0000e+00, -7.1851e+01,  1.6460e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         ...,
         [ 8.7580e+03, -1.2383e+02,  4.3340e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         [ 8.7590e+03, -1.2397e+02,  4.1720e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00],
         [ 8.7600e+03, -1.2170e+02,  4.3040e+01,  ...,  2.0000e+00,
           0.0000e+00,  2.0000e+00]],

        [[ 1.0000e+00, -3.7761e+01,  4.6055e+03,  ...,  2.7200e+02,
           1.6400e+02,  2.8600e+02],
         [ 2.0000e+00, -5.0640e+01,  4.6055e+03,  ...,  2.7200e+02,
           1.6400e+02,  2.8600e+02],
         [ 3.0000e+00, -4.5840e+01,  4.9473e+03,  ...,  2.7200e+02,
           1.6400e+02,  2.8600e+02],
         ...,
         [ 8.7580e+03,  3.6286e+01,  2.6821e+04,  ...,  2.7200e+02,
           1.6400e+02,  2.8600e+02],
         [ 8.7590e+03,  4.0603e+01,  2.6394e+04,  ...,  2.7200e+02,
           1.6400e+02,  2.8600e+02],
         [ 8.7600e+03,  3.9810e+01,  2.6441e+04,  ...,  2.7200e+02,
           1.6400e+02,  2.8600e+02]]], dtype=torch.float64)
>>> feature.shape
torch.Size([3, 8760, 30])

## TARGETS

>>> target
tensor([[ 31.6668,  33.5949,  35.8350,  ..., -26.1178, -24.8364, -24.1894],
        [ 36.8206,  39.0619,  41.6658,  ..., -30.3122, -28.8252, -28.0726],
        [  3.4025,   6.6635,   3.2758,  ..., -12.6210, -15.8263, -15.4595]],
       dtype=torch.float64)
torch.Size([3, 8760])

## ERROR
>>> y_pred = model.forward(feature)
Traceback (most recent call last):
  File "~Eclipse-2020-09\dropins\PyDev 8.0.1\plugins\org.python.pydev.core_8.0.1.202011071328\pysrc\_pydevd_bundle\pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<console>", line 1, in <module>
  File "~workspace\q_estimation\ann_model.py", line 24, in forward
    output = self.l0(inputs)
  File "~Python\Python38\site-packages\torch\nn\modules\module.py", line 889, in _call_impl
    result = self.forward(*input, **kwargs)
  File "~Python\Python38\site-packages\torch\nn\modules\linear.py", line 94, in forward
    return F.linear(input, self.weight, self.bias)
  File "~\Python\Python38\site-packages\torch\nn\functional.py", line 1753, in linear
    return torch._C._nn.linear(input, weight, bias)
RuntimeError: expected scalar type Double but found Float