I'm building a neural network and I don't know how to access the model weights for each layer.
I've tried
model.input_size.weight
Code:
input_size = 784
hidden_sizes = [128, 64]
output_size = 10
# Build a feed-forward network
model = nn.Sequential(nn.Linear(input_size, hidden_sizes[0]),
nn.ReLU(),
nn.Linear(hidden_sizes[0], hidden_sizes[1]),
nn.ReLU(),
nn.Linear(hidden_sizes[1], output_size),
nn.Softmax(dim=1))
I expected to get the weights but I got
'Sequential' object has no attribute 'input_size'
So nn. Sequential is a construction which is used when you want to run certain layers sequentially. It makes the forward to be readable and compact.
PyTorch has inbuilt weight initialization which works quite well so you wouldn't have to worry about it but. You can check the default initialization of the Conv layer and Linear layer.
The objective of nn. Sequential is to quickly implement sequential modules such that you are not required to write the forward definition, it being implicitly known because the layers are sequentially called on the outputs. In a more complicated module though, you might need to use multiple sequential submodules.
nn. Sequential is faster than not using it.
If you print out the model usingprint(model)
, you would get
Sequential(
(0): Linear(in_features=784, out_features=128, bias=True)
(1): ReLU()
(2): Linear(in_features=128, out_features=64, bias=True)
(3): ReLU()
(4): Linear(in_features=64, out_features=10, bias=True)
(5): Softmax(dim=1) )
Now you have access to all indices of layers so you can get the weights of (let's say) second linear layer by model[4].weight
.
As per the official pytorch discussion forum here, you can access weights of a specific module in nn.Sequential()
using
model.layer[0].weight # for accessing weights of first layer wrapped in nn.Sequential()
I've tried many ways, and it seems that the only way is by naming each layer by passing OrderedDict
from collections import OrderedDict
model = nn.Sequential(OrderedDict([
('fc1', nn.Linear(input_size, hidden_sizes[0])),
('relu1', nn.ReLU()),
('fc2', nn.Linear(hidden_sizes[0], hidden_sizes[1])),
('relu2', nn.ReLU()),
('output', nn.Linear(hidden_sizes[1], output_size)),
('softmax', nn.Softmax(dim=1))]))
So to access the weights of each layer, we need to call it by its own unique layer name.
For example to access weights of layer 1 model.fc1.weight
Parameter containing:
tensor([[-7.3584e-03, -2.3753e-02, -2.2565e-02, ..., 2.1965e-02,
1.0699e-02, -2.8968e-02],
[ 2.2930e-02, -2.4317e-02, 2.9939e-02, ..., 1.1536e-02,
1.9830e-02, -1.4294e-02],
[ 3.0891e-02, 2.5781e-02, -2.5248e-02, ..., -1.5813e-02,
6.1708e-03, -1.8673e-02],
...,
[-1.2596e-03, -1.2320e-05, 1.9106e-02, ..., 2.1987e-02,
-3.3817e-02, -9.4880e-03],
[ 1.4234e-02, 2.1246e-02, -1.0369e-02, ..., -1.2366e-02,
-4.7024e-04, -2.5259e-02],
[ 7.5356e-03, 3.4400e-02, -1.0673e-02, ..., 2.8880e-02,
-1.0365e-02, -1.2916e-02]], requires_grad=True)
Let's say you define the model as a class. Then you can call model.parameters().
`# Build a feed-forward network
class FFN(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Linear(input_size, hidden_sizes[0])
self.layer2 = nn.Linear(hidden_sizes[0], hidden_sizes[1])
self.layer3 = nn.Linear(hidden_sizes[1], output_size)
self.relu = nn.ReLU()
self.softmax = nn.Softmax(dim=1)
def forward(self, x):
x = self.relu(self.layer1(x))
x = self.relu(self.layer2(x))
x = self.softmax(self.layer3(x))
return x
model = FFN()
print(model.parameters())`
Which will print <generator object Module.parameters at 0x7f99886d0d58>
, so you can pass that to an optimizer right away!
But, if you want to access particular weights or look at them manually, you can just convert to a list: print(list(model.parameters()))
. Which will spit out a giant list of weights.
But, let's say you only want the last layer, then you can do: print(list(model.parameters())[-1])
, which will print: tensor([-0.0347, -0.0289, -0.0652, -0.1233, 0.1093, 0.1187, -0.0407, 0.0885, -0.0045, -0.1238], requires_grad=True)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With