Weights not updating and all parameters set to none with pytorch neural network

username: infernal_zhull
cooked: <pre><code class="lang-auto">from tkinter import Variable
import pandas as pd
from tqdm import tqdm
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import torch.optim as optim
import matplotlib.pyplot as plt
import time
import sys
import os


os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

#Load Training.csv
trainingData = pd.read_csv('training.csv')


#The training data labels the data as either s or b for signal or background
#we use this mappings lambda to make s be 1 and b be 0 
mappings = {
    's': 1, 
    'b': 0
}
trainingData['Label'] = trainingData['Label'].apply(lambda x: mappings[x])

trainingData = trainingData.where(trainingData &gt; -998.0, 0)

sig = nn.Sigmoid()


model = nn.Sequential(  nn.Linear(31, 60), 
                        nn.ReLU(), 
                        nn.Linear(60, 60),
                        nn.Linear(60, 60),
                        nn.Linear(60, 60),
                        nn.ReLU(),
                        nn.Linear(60, 60),
                        nn.Linear(60, 60), 
                        nn.ReLU(),
                        nn.Linear(60, 1))



criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)


#initializing some variables for plotting loss over epoch
yList = []
xList = []
yListlater = []
xListlater = []
laterInt = 1


inputData = torch.tensor(trainingData.drop(['Weight', 'Label'], axis=1).values, dtype=float)
outputData = torch.tensor(trainingData['Label'].values, dtype=float).reshape(250000, 1)
listIn = torch.chunk(inputData, 25000, dim=0)
listOut = torch.chunk(outputData, 25000, dim=0)

epochs = 100

for name, param in model.named_parameters():
        print(name, param.grad)

print(model)

print(model[0].weight)

for i in tqdm(range(epochs)):
    x = listIn[i]
    y = listOut[i]

    outData = model(x.float())
    
    optimizer.zero_grad()

    loss = criterion(outData, target=y)

    loss.backward()

    optimizer.step()

    if (i % 1 == 0):
        yList.append(loss.item())
        xList.append(i)

print(model[0].weight)

plt.plot(xList, yList)
plt.xlabel('epoch')
plt.ylabel('running_loss')
plt.title('loss vs epoch')
plt.show()
</code></pre>
<p>Here is the code, I have been trying to figure out why nothing is changing for a couple days now and no luck.<br>
Here is the output as well.</p>
<p>0.weight None<br>
0.bias None<br>
2.weight None<br>
2.bias None<br>
3.weight None<br>
3.bias None<br>
4.weight None<br>
4.bias None<br>
6.weight None<br>
6.bias None<br>
7.weight None<br>
7.bias None<br>
9.weight None<br>
9.bias None<br>
Sequential(<br>
(0): Linear(in_features=31, out_features=60, bias=True)<br>
(1): ReLU()<br>
(2): Linear(in_features=60, out_features=60, bias=True)<br>
(3): Linear(in_features=60, out_features=60, bias=True)<br>
(4): Linear(in_features=60, out_features=60, bias=True)<br>
(5): ReLU()<br>
(6): Linear(in_features=60, out_features=60, bias=True)<br>
(7): Linear(in_features=60, out_features=60, bias=True)<br>
(8): ReLU()<br>
(9): Linear(in_features=60, out_features=1, bias=True)<br>
)<br>
Parameter containing:<br>
tensor([[ 0.1255, -0.0629, -0.0803,  …,  0.0183, -0.1115,  0.0929],<br>
[ 0.0016, -0.1008,  0.1053,  …,  0.1485, -0.0020, -0.0183],<br>
[ 0.0559, -0.0457,  0.0267,  …,  0.0708,  0.0448, -0.0680],<br>
…,<br>
[ 0.0056,  0.1003,  0.0257,  …, -0.1627,  0.0517, -0.0623],<br>
[-0.0674,  0.1298, -0.0035,  …,  0.1628, -0.0131, -0.1417],<br>
[-0.0073,  0.1473, -0.0778,  …,  0.1646,  0.0768,  0.1202]],<br>
requires_grad=True)<br>
<strong>[In here is the training loop]</strong><br>
Parameter containing:<br>
tensor([[ 0.1255, -0.0629, -0.0803,  …,  0.0183, -0.1115,  0.0929],<br>
[ 0.0016, -0.1008,  0.1053,  …,  0.1485, -0.0020, -0.0183],<br>
[ 0.0559, -0.0457,  0.0267,  …,  0.0708,  0.0448, -0.0680],<br>
…,<br>
[ 0.0056,  0.1003,  0.0257,  …, -0.1627,  0.0517, -0.0623],<br>
[-0.0674,  0.1298, -0.0035,  …,  0.1628, -0.0131, -0.1417],<br>
[-0.0073,  0.1473, -0.0778,  …,  0.1646,  0.0768,  0.1202]],</p>

username: ptrblck
cooked: <p>There are a few issues in your script:</p>
<ul>
<li>“all parameters set to None” is not the case, as you are printing the <code>.grad</code> attributes before the first backward pass and thus it’s expected to see <code>None</code> gradients</li>
<li>the last linear layer outputs a single logit, which doesn’t make sense in combination with <code>nn.CrossEntropyLoss</code> as the loss function is used for a multi-class classification. Since your current model only outputs logits for a single class, it has to be correct since only a single target class is valid</li>
</ul>
<p>If I fix this issue and use e.g. 2 classes, you can see that the model parameters change:</p>
<pre><code class="lang-python">model = nn.Sequential(  nn.Linear(31, 60), 
                        nn.ReLU(), 
                        nn.Linear(60, 60),
                        nn.Linear(60, 60),
                        nn.Linear(60, 60),
                        nn.ReLU(),
                        nn.Linear(60, 60),
                        nn.Linear(60, 60), 
                        nn.ReLU(),
                        nn.Linear(60, 2))

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

print(model[0].weight)

epochs = 1000
for i in range(epochs):
    x = torch.randn(1, 31)
    y = torch.randint(0, 2, (1,))
    output = model(x)
    optimizer.zero_grad()
    loss = criterion(output, y)
    loss.backward()
    optimizer.step()

print(model[0].weight)
</code></pre>

username: infernal_zhull
cooked: <p>So if i wanted my target to be just a single number between 0 and 1, CrossEntropyLoss would be the wrong criterion? Which would be a better one? Or should I just have the last layer of nn.Linear be (60, 2) and have the two outputs, could I then make those two outputs be like the confidence in the input leading to a background event (0) or a signal event (1)? At least that was my vision just train a neural network to give me either a 0 or 1, also sorry I don’t really know whats possible with neural networks I am very new to this.</p>

username: ptrblck
cooked: <p>It depends what your actual use case is. If you are working on a binary classification you could use a single output and use <code>nn.BCEWithLogitsLoss</code> instead as the loss function.<br>
Also, note that multiple stacked linear layers can be replaced with a single one if no activation function is used, so you might also want to adapt the model architecture.</p>

username: infernal_zhull
cooked: <p>Okay I will look into that new loss function, but after making the changes you mentioned to the code, at least from what I see all the weight and bias tensors are at zero and nan now. I may have also just changed it wrong but here are the sections of the code that I changed:</p>
<pre><code class="lang-auto">model = nn.Sequential(  nn.Linear(31, 60), 
                        nn.ReLU(), 
                        nn.Linear(60, 60),
                        nn.Linear(60, 60),
                        nn.Linear(60, 60),
                        nn.ReLU(),
                        nn.Linear(60, 60),
                        nn.Linear(60, 60), 
                        nn.ReLU(),
                        nn.Linear(60, 2))
</code></pre>
<p>Also changed the outputData to dtype=torch.long to fix an issue. Then also got rid of the reshape function on the outputData to make it a 0D tensor. Also thank you so much for the help its greatly appreciated!</p>
<pre><code class="lang-auto">Parameter containing:
tensor([[ 0.0539,  0.0271,  0.0439,  ...,  0.1696, -0.0786, -0.1070],
        [-0.0865,  0.0066, -0.1254,  ..., -0.1123, -0.0493, -0.0810],
        [ 0.0880, -0.0347,  0.1111,  ..., -0.1072,  0.1138, -0.1486],
        ...,
        [ 0.0956,  0.1438,  0.1690,  ..., -0.0213, -0.1159,  0.0290],
        [-0.0837,  0.0139, -0.0046,  ..., -0.1025,  0.0138, -0.0071],
        [ 0.1230, -0.0192,  0.0522,  ..., -0.1669, -0.1791,  0.0807]],
       requires_grad=True)

Parameter containing:
tensor([[-5.9281e+06, -3.3843e+03, -3.5574e+03,  ..., -1.2967e+01,
          1.5325e+01, -2.1859e+03],
        [-8.6483e-02,  6.5728e-03, -1.2543e-01,  ..., -1.1226e-01,
         -4.9323e-02, -8.1002e-02],
        [-1.0422e+07, -5.9497e+03, -6.2538e+03,  ..., -2.3201e+01,
          2.7193e+01, -3.8428e+03],
        ...,
        [-1.5777e+01,  1.2120e-01,  1.6190e-01,  ..., -2.1391e-02,
         -1.1571e-01,  9.5351e-03],
        [-8.3709e-02,  1.3877e-02, -4.5941e-03,  ..., -1.0254e-01,
          1.3761e-02, -7.1247e-03],
        [-1.8538e+07, -1.0584e+04, -1.1125e+04,  ..., -4.1247e+01,
          4.7990e+01, -6.8354e+03]], requires_grad=True)
0.weight tensor([[0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        ...,
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.],
        [0., 0., 0.,  ..., 0., 0., 0.]])
0.bias tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
2.weight tensor([[nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        ...,
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan]])
2.bias tensor([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan])
3.weight tensor([[nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        ...,
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan]])
3.bias tensor([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan])
4.weight tensor([[nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        ...,
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan]])
4.bias tensor([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan])
6.weight tensor([[nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        ...,
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan]])
6.bias tensor([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan])
7.weight tensor([[nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        ...,
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan],
        [nan, nan, nan,  ..., nan, nan, nan]])
7.bias tensor([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
        nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan])
9.weight tensor([[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
         nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
         nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan],
        [nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
         nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,
         nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]])
9.bias tensor([nan, nan])
</code></pre>

username: ptrblck
cooked: <p>If your parameters are invalid after a few iterations, your loss (and thus the gradients) might blow up which would overflow the parameters.<br>
You could add the new loss function to my code snippet and experiment with it.<br>
If you initialize the random data once using my code you will be able to overfit the dataset properly.</p>

username: infernal_zhull
cooked: <p>So I am not sure how to make it so the loss doesn’t blow up as you say? Something I have seen in some of the neural network examples I have seen online is a nn.logsoftmax is this related to what you are suggesting I do? Also I have implemented the new loss function but not sure if I am using it correctly.</p>
<pre><code class="lang-auto">pos_weight = torch.ones([1])

criterionBCE = nn.BCEWithLogitsLoss(pos_weight=pos_weight)

inputData = torch.tensor(trainingData.drop(['Weight', 'Label'], axis=1).values, dtype=float)
outputData = torch.tensor(trainingData['Label'].values, dtype=torch.long)
listIn = torch.chunk(inputData, 25000, dim=0)
listOut = torch.chunk(outputData, 25000, dim=0)

epochs = 1000

print(model[0].weight)

for i in tqdm(range(epochs)):
    x = listIn[i]
    y = listOut[i].reshape([10, 1])

    outData = model(x.float())
    
    optimizer.zero_grad()

    loss = criterionBCE(outData, y.float())

    loss.backward()

    optimizer.step()

    if (i % 1 == 0):
        yList.append(loss.item())
        xList.append(i)

print(model[0].weight)
</code></pre>
<p>The way I made it is just by blindly following guides and seeing what other people do, but I don’t know how it works or if I am even using it the intended way.</p>
<p>Also going back to a previous point with the output layer of the model, should I keep the output layer to be nn.Linear(60, 2) or make it (60, 1). And followup question if I am to keep it (60, 2) should I make my true value reflect that? A thought I had since I want the nn to identify if the event is a signal or background make the true data have two columns one for if its a signal event and one for if its a column event and set the corresponding column value to 1 and the other 0?</p>
<p>Another question for how I am splitting up the training data, should I be feeding it to the model in these “batches” of 10? Is this normal or is there some better way I should be doing this.</p>