Hướng dẫn dùng nn module python

Tôi sẽ chia nhỏ nó cho bạn. Tensors, như bạn có thể biết, là ma trận nhiều chiều. Tham số, ở dạng thô của nó, là một tensor tức là một ma trận nhiều chiều. Nó phân lớp lớp Variable.

Sự khác biệt giữa Biến và Tham số xuất hiện khi được liên kết với một mô-đun. Khi một Tham số được liên kết với một mô-đun dưới dạng thuộc tính mô hình, nó sẽ tự động được thêm vào danh sách tham số và có thể được truy cập bằng cách sử dụng trình lặp 'tham số'.

Ban đầu trong Torch, một Biến (ví dụ có thể là trạng thái trung gian) cũng sẽ được thêm vào như một tham số của mô hình khi gán. Sau đó, có những trường hợp sử dụng được xác định trong đó cần phải lưu trữ các biến thay vì thêm chúng vào danh sách tham số đã được xác định.

Một trong những trường hợp như vậy, như đã đề cập trong tài liệu là RNN, nơi bạn cần lưu trạng thái ẩn cuối cùng để không phải vượt qua nó nhiều lần. Sự cần thiết phải lưu vào bộ nhớ cache của một Biến thay vì để nó tự động đăng ký như một tham số cho mô hình là lý do tại sao chúng ta có một cách rõ ràng để đăng ký các tham số cho mô hình của chúng ta, tức là lớp nn.Parameter.

Ví dụ: chạy đoạn mã sau:

import torch
import torch.nn as nn
from torch.optim import Adam

class NN_Network(nn.Module):
    def __init__(self,in_dim,hid,out_dim):
        super(NN_Network, self).__init__()
        self.linear1 = nn.Linear(in_dim,hid)
        self.linear2 = nn.Linear(hid,out_dim)
        self.linear1.weight = torch.nn.Parameter(torch.zeros(in_dim,hid))
        self.linear1.bias = torch.nn.Parameter(torch.ones(hid))
        self.linear2.weight = torch.nn.Parameter(torch.zeros(in_dim,hid))
        self.linear2.bias = torch.nn.Parameter(torch.ones(hid))

    def forward(self, input_array):
        h = self.linear1(input_array)
        y_pred = self.linear2(h)
        return y_pred

in_d = 5
hidn = 2
out_d = 3
net = NN_Network(in_d, hidn, out_d)

Bây giờ, hãy kiểm tra danh sách tham số được liên kết với mô hình này -

for param in net.parameters():
    print(type(param.data), param.size())

""" Output
 torch.Size([5, 2])
 torch.Size([2])
 torch.Size([5, 2])
 torch.Size([2])
"""

Hay là thử,

list(net.parameters())

Điều này có thể dễ dàng được cung cấp cho trình tối ưu hóa của bạn -

opt = Adam(net.parameters(), learning_rate=0.001)

Ngoài ra, hãy lưu ý rằng các Tham số được đặt theo mặc định là request_grad.

115 hữu ích 4 bình luận chia sẻ

I will break it down for you. Tensors, as you might know, are multi dimensional matrices. Parameter, in its raw form, is a tensor i.e. a multi dimensional matrix. It sub-classes the Variable class.

The difference between a Variable and a Parameter comes in when associated with a module. When a Parameter is associated with a module as a model attribute, it gets added to the parameter list automatically and can be accessed using the 'parameters' iterator.

Initially in Torch, a Variable (which could for example be an intermediate state) would also get added as a parameter of the model upon assignment. Later on there were use cases identified where a need to cache the variables instead of having them added to the parameter list was identified.

One such case, as mentioned in the documentation is that of RNN, where in you need to save the last hidden state so you don't have to pass it again and again. The need to cache a Variable instead of having it automatically register as a parameter to the model is why we have an explicit way of registering parameters to our model i.e. nn.Parameter class.

For instance, run the following code -

import torch
import torch.nn as nn
from torch.optim import Adam

class NN_Network(nn.Module):
    def __init__(self,in_dim,hid,out_dim):
        super(NN_Network, self).__init__()
        self.linear1 = nn.Linear(in_dim,hid)
        self.linear2 = nn.Linear(hid,out_dim)
        self.linear1.weight = torch.nn.Parameter(torch.zeros(in_dim,hid))
        self.linear1.bias = torch.nn.Parameter(torch.ones(hid))
        self.linear2.weight = torch.nn.Parameter(torch.zeros(in_dim,hid))
        self.linear2.bias = torch.nn.Parameter(torch.ones(hid))

    def forward(self, input_array):
        h = self.linear1(input_array)
        y_pred = self.linear2(h)
        return y_pred

in_d = 5
hidn = 2
out_d = 3
net = NN_Network(in_d, hidn, out_d)

Now, check the parameter list associated with this model -

for param in net.parameters():
    print(type(param.data), param.size())

""" Output
 torch.Size([5, 2])
 torch.Size([2])
 torch.Size([5, 2])
 torch.Size([2])
"""

Or try,

list(net.parameters())

This can easily be fed to your optimizer -

opt = Adam(net.parameters(), learning_rate=0.001)

Also, note that Parameters have require_grad set by default.