Empty state_dict

Hello,

I’m a n00b trying to make a simple neural network for the MNIST dataset. My goal is to make this net have a variable number of layers and activation functions chosen by the user.

I have pytorch 0.4.1 with no cuda on my laptop

So first I set off to define my own module, which had an empty parameter list and I read on stack overflow that I could just overwrite the parameters method by adding all the parameters of each Linear layer to one list. I also made a one-hot encoding function.

import torch

def encoding_function(num_categories):
“”“one hot encoder, given the number of categories returns a one-hot
encoder function the eats tensors of size (N,1) (where N is batch size
and each row corresonds to one numerical value) and spits out a
tensors of size (N,num_categories) where each row corresponds to
the one hot encoding associated to the numerical value”“”

def encoder(vals):
    """vals of size (N,1), each row is a one value in 
    [0,num_categories-1]"""
    batch_size = vals.size(0)
    encoded_vals = torch.zeros((batch_size, num_categories))
    
    for i in range(batch_size):
        val = vals[i].item()
        encoded_vals[i][val] = 1
        
    return encoded_vals
    
return encoder 

class NNet(torch.nn.Module):

def __init__(self, layer_shapes, activation_functions):
    super(NNet, self).__init__()
    assert len(layer_shapes) == len(activation_functions) + 1
    self.layer_shapes = layer_shapes
    self.activation_functions = activation_functions
    
    linear_functions = list()
    for i in range(len(self.layer_shapes)-1):
        linear_functions.append(torch.nn.Linear(
                self.layer_shapes[i], self.layer_shapes[i+1]))
    
    self.linear_functions = linear_functions

def parameters(self):
    parameters = list()
    for function in self.linear_functions:
        parameters = parameters+list(function.parameters())
    
    return parameters 

def forward(self, x):
    y = x
    for i in range(len(self.layer_shapes)-1):
        assert y.shape[1] == self.layer_shapes[i]
        y = self.activation_functions[i](self.linear_functions[i](y))
    return y

data:

import matplotlib.pyplot as plt
import torch
import torchvision
import ai.neural_network as nnet

batch_size = 30
epochs = 500
learning_rate = 0.001

train_set = torchvision.datasets.MNIST(root = ‘/home/carson/Desktop/Archive/Computing/Projects/Python/Data’,
train=True,
transform=torchvision.transforms.ToTensor(),
download=True)
test_set = torchvision.datasets.MNIST(root = ‘/home/carson/Desktop/Archive/Computing/Projects/Python/Data’,
train=False,
transform=torchvision.transforms.ToTensor(),
download=True)

train_loader = torch.utils.data.DataLoader(dataset=train_set, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_set, batch_size=batch_size, shuffle=False)

model = nnet.NNet([784, 16, 10], [torch.nn.Tanh(), torch.nn.Softmax(dim=1)])
loss_function = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

training:

loss_items = list()

for t in range(epochs):
for i, (images, labels) in enumerate(train_loader):

    encoder = nnet.encoding_function(10)
    labels = encoder(labels)
    
    images = images.reshape(-1,28*28)
    outputs = model(images)
    
    
    loss = loss_function(outputs, labels)
    
    if i%1000 == 0:
        loss_items.append(loss.item())
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

plot it:

plt.figure(figsize=(15,5))
plt.plot(loss_items)

test it:

with torch.no_grad():
correct = 0
total = 0

for images, labels in test_loader:
    images = images.reshape(-1, 28*28)
    outputs = model(images)
    _, predicted = torch.max(outputs.data, 1)
    total += labels.size(0)
    correct += (predicted == labels).sum()

print('Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))

results:

So it came up 90% accurate for me which I felt was good enough for this network.
I wanted to save it, but it says

model.state_dict() => OrderedDict()

is empty :frowning:

I haven’t found anything about this yet, so I was sondering if anybody knew off the back how I could fix this. I do have the parameters in a list, so there is that. Not sure if I can manually set those with any fresh network.

Also, I’m new to pytorch, like started two days ago. So if there is any recommendation for doing something in a better way, please let me know

Go through this post:

Thank you so much, this solved my problem!