Reputation: 1
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
Reputation: 1219
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.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