Multi Hot Vector network ( let me know if this the wrong topic)

gunsmoke1416: <p>Im attempting to make a self driving car the input is a list of values from game. the out put is a list of<br>
“wasd” being pressed or not eg.[0,1,0,1] i think the correct thing for me to do would be a Multi hot vector (gas and turn at the same time) but how do I get out put from this? Right now im using ive manually tried various sample data but output doesnt change and is a digit. Since I have 4 output nodes would that mean i just convert to binary eg 3 would be [0,0,1,1]and then that would be my controls?</p>
<pre><code class="lang-auto">import torch
import torchvision
from torchvision import transforms,datasets
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import TensorDataset, DataLoader



np_load_old = np.load
np.load = lambda *a, **k: np_load_old(*a, allow_pickle=True, **k)
train_data = np.load('training_datav2.npy')

np.load = np_load_old

training_inputs= []
training_outputs= []

for row in train_data:
    training_inputs.append(row[0])
    training_outputs.append(row[1])

trainX= training_inputs[:len(training_inputs)//2]
testX= training_inputs[len(training_inputs)//2:]
trainY= training_outputs[:len(training_outputs)//2]
testY= training_outputs[len(training_outputs)//2:]


my_x = np.array(trainX) # a list of numpy arrays
my_y = np.array(trainY) # another list of numpy arrays (targets)

tensor_x = torch.Tensor(my_x) # transform to torch tensor
tensor_y = torch.Tensor(my_y)

trainDataset = TensorDataset(tensor_x,tensor_y)

my_testx = np.array(testX) # a list of numpy arrays
my_testy = np.array(testY) # another list of numpy arrays (targets)

tensor_testx = torch.Tensor(my_testx) # transform to torch tensor
tensor_testy = torch.Tensor(my_testy)

testDataset = TensorDataset(tensor_testx,tensor_testy)

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1=nn.Linear(5,10)
        self.fc2=nn.Linear(10,10)
        self.fc3=nn.Linear(10,5)
        self.fc4=nn.Linear(5,4)

    def forward(self,x):
        x=F.relu(self.fc1(x))
        x=F.relu(self.fc2(x))
        x=F.relu(self.fc3(x))
        x=(self.fc4(x))


        return x
net = Net()
print(net)

optimizer= optim.Adam(net.parameters(),lr=0.001)
criterion = torch.nn.MSELoss()
EPOCHS = 1

for epoch in range(EPOCHS):
    count=0
    for data in trainDataset:
        x,y=data

        net.zero_grad()
        out=net(x)


        loss= criterion(out,y)
        loss.backward()
        optimizer.step()

        count+=1
    print(loss)
correct =0
total=0
with torch.no_grad():
    for data in testDataset:
        x, y = data
        out = net(x)
        for idx, i in enumerate(out):
            if torch.argmax(i)==y[idx]:
                correct+=1
            total+=1
guess=torch.argmax(net(torch.Tensor([11, 0, 1, 0, -0.18750000000000006])))
print(guess)

print("Accuraccy:",round(correct/total,3))
</code></pre>
<p>Accuracy is on 65% at the moment with about 6700 samples i would like more but i feel like this should be good enough to make sure its working any advice is appreciated.</p>

ptrblck: <p>Based on the description it seems you are working on a multi-label classification, where zero, one, or multiple classes can be active for each sample.<br>
In that case, you could use <code>nn.BCEWithLogitsLoss</code> as the criterion and get the predictions using a threshold either on the logits or probabilities:</p>
<pre><code class="lang-python">output = model(x)
preds = output &gt; 0.0
# or
preds = torch.sigmoid(output) &gt; 0.5
</code></pre>
<p>where the threshold can be defined as you wish.</p>

gunsmoke1416: <p>Thank you in the time since ive been working with BCEWithLogitsLoss and also have discovered the applying sigmoid to the output idea. my only concern is the raw numbers I’m outputting are as follow:</p>
<pre><code class="lang-auto">guessright = net(torch.tensor([6, 0, 1, 0, 0.3971354166666663]))
guessleft = net(torch.tensor([6, 0, 1, 0, -0.3971354166666663]))

print("right", (guessright &gt; 0.5).float())
print("left", (guessleft &gt; 0.5).float())
print("right Sigmoid",  torch.round(torch.sigmoid(guessright)))
print("left Sigmoid", torch.round(torch.sigmoid(guessright)))
print("right", (guessright))
print("left", (guessleft))
</code></pre>
<pre><code class="lang-auto">right tensor([0., 1., 0., 0.])
left tensor([0., 1., 0., 0.])
right Sigmoid tensor([0., 1., 0., 0.], grad_fn=&lt;RoundBackward&gt;)
left Sigmoid tensor([0., 1., 0., 0.], grad_fn=&lt;RoundBackward&gt;)
right tensor([-4.9131,  1.6094, -4.4618, -1.3654], grad_fn=&lt;AddBackward0&gt;)
left tensor([-4.4941,  1.5184, -5.1282, -1.4909], grad_fn=&lt;AddBackward0&gt;)
</code></pre>
<p>The idea is i have 2 examples to test but the raw data coming out i was in my head expecting to be between 0-1 but the raw numbers are any number is this normal behavior?</p>
<p>I’m just trying to understand if the out put that is given is actually what its meant to be or if my conversions are flawed</p>

ptrblck: <aside class="quote no-group" data-username="gunsmoke1416" data-post="3" data-topic="125737">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/gunsmoke1416/48/39924_2.png" class="avatar"> gunsmoke1416:</div>
<blockquote>
<p>The idea is i have 2 examples to test but the raw data coming out i was in my head expecting to be between 0-1 but the raw numbers are any number is this normal behavior?</p>
</blockquote>
</aside>
<p>Logits can take any arbitrary value in <code>[-Inf, +Inf]</code>, while applying a <code>sigmoid</code> on them would give you probabilities in <code>[0, 1]</code>. Thus, if you want to apply a probability threshold, apply the <code>sigmoid</code> on the output first.<br>
The posted numbers look reasonable.</p>