Seeking advice on building a model to analyse input vectors

christophertaylor: <p>Hi everyone,<br>
I am new to all of this and have been using PyTorch for a couple weeks, and I have been set a task as a part of a project. This task is to create a deep learning model, or series of models, which when given a 3 x n input vector, can produce a output vector of 9 numbers which pertain to the initial input. For example, the first number of the output vector is the number of rows of the input vector, and the second number is the highest number in the input vector. From my research, I have struggled to find any problems similar to this and as a result I am not sure what to do. My approach thus far has been to create 9 models, each trained to output 1 of the 9 numbers. I have attempted this with simple fully-connected neural networks, however the models are performing very badly. If anybody could give me any advice as to how to classify and approach this problem or tell me what I am doing wrong it would be a massive help. I have attached code aimed at outputting the max number in the input vector. Thanks <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<blockquote>
<p>import torch<br>
import torch.nn as nn<br>
import torch.optim as optim<br>
from torch.utils.data import DataLoader, Dataset<br>
import numpy as np<br>
import pandas as pd<br>
import glob<br>
from sklearn.model_selection import train_test_split<br>
import os</p>
<p>print(torch.cuda.is_available())<br>
print(torch.cuda.get_device_name(0))</p>
<p>class VectorDataset(Dataset):<br>
def <strong>init</strong>(self, file_pairs, max_len=500):<br>
self.file_pairs = file_pairs<br>
self.max_len = max_len</p>
<pre><code>def __len__(self):
    return len(self.file_pairs)

def __getitem__(self, idx):
    input_file, output_file = self.file_pairs[idx]
    
    input_vector = pd.read_csv(input_file, header=None, skiprows=1).values
    output_vector = pd.read_csv(output_file, header=None, skiprows=1).values
    
    label = float(output_vector[0, 1])
    
    input_vector = input_vector[:self.max_len, :]
    padding_rows = self.max_len - input_vector.shape[0]
    padded_vector = np.pad(input_vector, ((0, padding_rows), (0, 0)), 'constant')
    
    return torch.tensor(padded_vector, dtype=torch.float32), torch.tensor(label, dtype=torch.float32)
</code></pre>
<p>directory_path = “c:/Project/data_short”</p>
<p>input_file_paths = glob.glob(directory_path + ‘/*data.csv’)  # Assuming input files have ‘data’ in their names<br>
output_file_paths = [f.replace(‘data.csv’, ‘output.csv’) for f in input_file_paths]</p>
<p>file_pairs = [(input, output) for input, output in zip(input_file_paths, output_file_paths) if os.path.exists(output)]</p>
<p>def accuracy_fn(y_true, y_pred):<br>
correct = torch.eq(y_true, y_pred.round()).sum().item()<br>
acc = (correct / len(y_pred)) * 100<br>
return acc</p>
<p>train_file_pairs, test_file_pairs = train_test_split(file_pairs, test_size=0.3, random_state=42)<br>
max_len = 500<br>
train_dataset = VectorDataset(train_file_pairs, max_len)<br>
test_dataset = VectorDataset(test_file_pairs, max_len)</p>
<p>train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)<br>
test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)</p>
<p>input_size = max_len * 3</p>
<p>class SimpleNN(nn.Module):<br>
def <strong>init</strong>(self, input_size):<br>
super(SimpleNN, self).<strong>init</strong>()<br>
self.fc1 = nn.Linear(input_size, 128)<br>
self.fc2 = nn.Linear(128, 256)<br>
self.fc3 = nn.Linear(256, 1)</p>
<pre><code>def forward(self, x):
    x = x.view(x.size(0), -1) 
    x = torch.relu(self.fc1(x))
    x = self.fc2(x)
    x = self.fc3(x)
    return x
</code></pre>
<p>device = torch.device(“cuda” if torch.cuda.is_available() else “cpu”)<br>
model = SimpleNN(input_size).to(device)</p>
<p>criterion = nn.MSELoss()<br>
optimizer = optim.Adam(model.parameters(), lr=0.001)</p>
<p>num_epochs = 20</p>
<p>for epoch in range(num_epochs):<br>
model.train()<br>
running_loss = 0.0</p>
<pre><code>for batch, (vectors, labels) in enumerate(train_dataloader):
    vectors, labels = vectors.to(device), labels.to(device)
    
    outputs = model(vectors)
    loss = criterion(outputs.squeeze(), labels)
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    running_loss += loss.item()
    
    
    if (batch + 1) % 100 == 0:  
        print(f'Epoch [{epoch+1}/{num_epochs}], Batch [{batch+1}/{len(train_dataloader)}], Loss: {loss.item():.4f}')

train_loss = running_loss / len(train_dataloader)
print(f'Epoch [{epoch+1}/{num_epochs}], Average Loss: {train_loss}')

test_loss, test_acc = 0,0
model.eval()
test_labels_list = []
predictions_list = []
with torch.no_grad():
    for vectors, labels in test_dataloader:
        
        vectors, labels = vectors.to(device), labels.to(device)
        predictions = model(vectors).squeeze()
        test_loss += criterion(predictions.squeeze(), labels)
        test_acc += accuracy_fn(y_true=labels.view(-1), y_pred= predictions.view(-1))
    
    test_loss /= len(test_dataloader)
    test_acc /= len(test_dataloader)
    
print(f"Train loss: {train_loss}, Test loss: {test_loss}, Test acc: {test_acc}")
</code></pre>
</blockquote>