Žymantas Rastenis
Žymantas Rastenis

Reputation: 1

PyTorch Target torch size doesn't match to the input size

I am trying to train my model on some data and the torch size is not matching. I included everything I tried lower in my post. I tried everything that I knew to try. Please help

This is the error:

Traceback (most recent call last):
  File "C:\Users\zyman\PycharmProjects\Neural_network_trading_bot\main.py", line 150, in <module>
    train(model, dataset, num_generations, num_networks, num_clones, batch_size, num_epochs)
  File "C:\Users\zyman\PycharmProjects\Neural_network_trading_bot\main.py", line 85, in train
    loss = criterion(outputs.view(-1), batch_targets.view(-1))
  File "C:\Users\zyman\AppData\Local\Programs\Python\Python39\lib\site-packages\torch\nn\modules\module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "C:\Users\zyman\AppData\Local\Programs\Python\Python39\lib\site-packages\torch\nn\modules\loss.py", line 720, in forward
    return F.binary_cross_entropy_with_logits(input, target,
  File "C:\Users\zyman\AppData\Local\Programs\Python\Python39\lib\site-packages\torch\nn\functional.py", line 3163, in binary_cross_entropy_with_logits
    raise ValueError("Target size ({}) must be the same as input size ({})".format(target.size(), input.size()))
ValueError: Target size (torch.Size([32])) must be the same as input size (torch.Size([3200]))

This is my code:

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
import numpy as np
import pandas as pd


class Net(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu1 = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, hidden_size)
        self.relu2 = nn.ReLU()
        self.fc3 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu1(x)
        x = self.fc2(x)
        x = self.relu2(x)
        x = self.fc3(x)
        x = torch.sigmoid(x)
        return x


class CustomDataset(Dataset):
    def __init__(self, data_path, sequence_length):
        data = pd.read_csv('c:\\Users\\zyman\\PycharmProjects\\Pulling-Data\\NeuralNetworkTrainingData.csv', delimiter=',')
        normalized_data = (data.iloc[:, :-1] - data.iloc[:, :-1].mean()) / data.iloc[:, :-1].std()

        self.inputs = []
        self.targets = []
        for i in range(len(data) - sequence_length - 1):
            self.inputs.append(normalized_data.iloc[i:i+sequence_length].values)
            close_price = data.iloc[i+sequence_length]['close']
            open_price = data.iloc[i+sequence_length]['open']
            if close_price > open_price:
                self.targets.extend([1] * sequence_length)  # Green candle
            else:
                self.targets.extend([0] * sequence_length)  # Red candle

        self.inputs = np.array(self.inputs)
        self.targets = np.array(self.targets)


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

    def __getitem__(self, index):
        return torch.tensor(self.inputs[index], dtype=torch.float32), torch.tensor(self.targets[index], dtype=torch.float32)



def train(model, dataset, num_generations, num_networks, num_clones, batch_size, num_epochs):
    for generation in range(num_generations):
        print(f"Generation: {generation + 1}")
        print("Training...")

        top_performers = []

        for network_index in range(num_networks):
            print(f"Network: {network_index + 1}")
            model_clone = Net(input_size, hidden_size, output_size)
            model_clone.load_state_dict(model.state_dict())

            dataset_size = len(dataset)
            train_size = int(0.8 * dataset_size)
            train_set, val_set = torch.utils.data.random_split(dataset, [train_size, dataset_size - train_size])

            train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True)
            val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=True)

            criterion = nn.BCEWithLogitsLoss()
            optimizer = optim.Adam(model_clone.parameters(), lr=learning_rate)

            best_val_accuracy = 0.0

            for epoch in range(num_epochs):
                model_clone.train()
                for batch_inputs, batch_targets in train_loader:
                    optimizer.zero_grad()
                    outputs = model_clone(batch_inputs)
                    loss = criterion(outputs.view(-1), batch_targets.view(-1))
                    loss.backward()
                    optimizer.step()

                model_clone.eval()
                correct_predictions = 0
                total_predictions = 0

                with torch.no_grad():
                    for val_inputs, val_targets in val_loader:
                        val_outputs = model_clone(val_inputs)
                        val_predictions = torch.round(torch.sigmoid(val_outputs))
                        correct_predictions += (val_predictions == val_targets).sum().item()
                        total_predictions += val_targets.numel()

                val_accuracy = correct_predictions / total_predictions

                if val_accuracy > best_val_accuracy:
                    best_val_accuracy = val_accuracy
                    model.load_state_dict(model_clone.state_dict())

            top_performers.append(model_clone)

        print("Evaluation...")
        correct_predictions = 0
        total_predictions = 0

        with torch.no_grad():
            for inputs, targets in dataset:
                outputs = model(inputs.unsqueeze(0))
                predictions = torch.round(torch.sigmoid(outputs))
                correct_predictions += (predictions == targets).sum().item()
                total_predictions += targets.numel()

        accuracy = correct_predictions / total_predictions
        print(f"Accuracy: {accuracy * 100:.2f}%")

        if generation < num_generations - 1:
            top_performers = sorted(top_performers, key=lambda m: -best_val_accuracy)[:num_clones]
            model_clones = [Net(input_size, hidden_size, output_size) for _ in range(num_networks)]

            for i, performer in enumerate(top_performers):
                for j in range(num_clones):
                    model_clones[i * num_clones + j].load_state_dict(performer.state_dict())

            model = nn.Sequential(*model_clones)

        print("=" * 50)


input_size = 4
hidden_size = 64
output_size = 10
learning_rate = 0.001
batch_size = 32
num_epochs = 10
sequence_length = 10
num_generations = 100
num_networks = 100
num_clones = 10


model = Net(input_size, hidden_size, output_size)
dataset = CustomDataset('c:\\Users\\zyman\\PycharmProjects\\Pulling-Data\\NeuralNetworkTrainingData.csv', sequence_length)

train(model, dataset, num_generations, num_networks, num_clones, batch_size, num_epochs)

I tried adjusting the batch size, and the target size is two 0 less than the input size. For example: target size 32, input size 3200.

Upvotes: 0

Views: 537

Answers (1)

Valentin Goldit&#233;
Valentin Goldit&#233;

Reputation: 1219

  1. T.view(-1) flatten the tensor T so calling criterion(outputs.view(-1), batch_targets.view(-1)) will flatten your outputs and targets before applying criterion.
  2. Here criterion is BCEWithLogitsLoss doc. It takes the logits as inputs, so the raw outputs of the model (and without sigmoid!) instead of flat vectors.

So remove the sigmoid, remove the view(-1) in the criterion call and finally I guess your targets are sparse values (1, 2, 3, ...) so you should one-hot encode them to make them compatible with logits: batch_targets = torch.nn.functional.one_hot(batch_targets, output_size) in the data processing.

Upvotes: 0

Related Questions