์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- ๋ถํ ์ ๋ณต
- lazy propagation
- ๋ฐฑํธ๋ํน
- ํฌ๋ฃจ์ค์นผ
- ํ๊ณ ๋ก
- tensorflow
- ์๋ฐ์คํฌ๋ฆฝํธ
- ๊ฐ๋์ ๋ง๋ก
- DP
- ์ฐ์ ์์ ํ
- ๊ฐ๋์_๋ง๋ก
- object detection
- NEXT
- ํ๋ก์ด๋ ์์ฌ
- back propagation
- pytorch
- ์ด๋ถ ํ์
- dfs
- ๋ค์ต์คํธ๋ผ
- ๋ฏธ๋๋_ํ์ฌ์_๊ณผ๊ฑฐ๋ก
- c++
- dropout
- ๋๋น ์ฐ์ ํ์
- ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ
- 2023
- ์กฐํฉ๋ก
- ์๊ณ ๋ฆฌ์ฆ
- Overfitting
- ๋ฌธ์์ด
- BFS
- Today
- Total
Doby's Lab
nn.Parameter(), ์ด๊ฑธ ์จ์ผ ํ๋ ์ด์ ๊ฐ ๋ญ๊น? (tensor์ ๋ช ๋ฐฑํ๊ฒ ๋ค๋ฅธ ์ ) ๋ณธ๋ฌธ
nn.Parameter(), ์ด๊ฑธ ์จ์ผ ํ๋ ์ด์ ๊ฐ ๋ญ๊น? (tensor์ ๋ช ๋ฐฑํ๊ฒ ๋ค๋ฅธ ์ )
๋๋น(Doby) 2024. 4. 29. 00:28๐ค Problem
๋ฌธ๋ ์์ ์ ViT๋ฅผ ๊ตฌํํด ๋์ ์ฝ๋๋ฅผ ๋ณด๋ค๊ฐ ๊ทธ๋ฐ ์๊ฐ์ ํ์ต๋๋ค. '๋ด๊ฐ ์ ๊ธฐ์ nn.Parameter()
๋ฅผ ์ ์ผ๋๋ผ?' ์ง๊ธ ์๊ฐํด ๋ณด๋ฉด, ๊ทธ๋ฅ tensor
๋ฅผ ์จ๋ ๋๊ฐ์ ์ฝ๋์ผ ํ
๋ฐ ๋ง์
๋๋ค.
์ด๋ ๋น์์ Attention์ ๊ตฌํํ๋ฉด์ Query, Key, Value๋ฅผ ๋ง๋ค์ด๋ด๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก Weight Matrix๊ฐ ํ์ํ์๊ณ , ์ฌ๋ฌ ์คํ ์์ค๋ฅผ ์ฐธ๊ณ ํ๋ฉด์ ๊ตฌํํ๋ค๊ฐ ๋ฌด์ฌํ๊ฒ ์ผ์๋ ๊ธฐ์ต์ด ๋ฉ๋๋ค.
class ScaledDotProductAttention(nn.Module):
def __init__(self, embedding_length, qkv_vec_length):
'''
embedding_length : embedding ํ๋์ ๊ธธ์ด -> W_(qkv)์ row ๊ฐ์ด ๋๋ค.
qkv_vec_length : W_(qkv) ํ๋ ฌ์ col ๊ฐ
'''
super().__init__()
# Query Matrix (Weight)
self.W_q = nn.Parameter(torch.randn(embedding_length, qkv_vec_length, requires_grad=True))
# Key Matrix (Weight)
self.W_k = nn.Parameter(torch.randn(embedding_length, qkv_vec_length, requires_grad=True))
# Value Matrix (Weight)
self.W_v = nn.Parameter(torch.randn(embedding_length, qkv_vec_length, requires_grad=True))
self.softmax = nn.Softmax(dim=-1)
๋ญ ์ด์จ๋ ์ด๋ฒ ํฌ์คํ
์์ ์๊ณ ์ถ์ ๋ฌธ์ , ํด๊ฒฐํ๊ณ ์ถ์ ๋ฌธ์ ๋ 'nn.Parameter()
๋ฅผ ์ ์จ์ผ ํ๋๊ฐ?'๊ฐ ์ง๋ฌธ์ด์ ๋ฌธ์ ์
๋๋ค.
๐ค Documentation
์ด๋ฐ ๊ฑด ์๋ง ๊ณต์ ๋ฌธ์์ ๋น ๋ฅด๊ฒ ๋ต์ ํ์ธํ ์ ์์ ๊ฑฐ๋ผ ํ๋จํด์ Documentation์ ํ์ธํด ๋ดค์ต๋๋ค.
https://pytorch.org/docs/stable/generated/torch.nn.parameter.Parameter.html
์ป์ ์ ์๋ ์ ๋ณด๋ ํฌ๊ฒ 2๊ฐ์ง์์ต๋๋ค.
(1) model.parameters()
or model.named_parameters()
๋ฅผ ํตํด ํด๋น ๋ชจ๋์ ํ๋ผ๋ฏธํฐ๋ผ๋ ๊ฒ์ ๋ํ๋ผ ์ ์๋ค.
(2) requires_grad = True
์ธ ๊ฒฝ์ฐ, torch.no_grad()
์ด๋๋ผ๋ ์ํฅ์ ๋ฐ์ง ์๊ณ , ๊ณ์ gradient ๊ฐ์ ๊ณ์ฐํ๋ค.
์ฌ์ค 2๋ฒ์ ์์ ํด๋น ํฌ์คํ
๊ณผ ๊ด๋ จ ์๋ ๊ฑฐ ๊ฐ์ผ๋ ์ ์ธ๋ฅผ ํ๊ณ , 1๋ฒ์ ๋ด์ผ ํ๋๋ฐ ์ด์ ๋ํด์๋ ์ฒ์์ ์ด๋ ๊ฒ ํด์ํ์ต๋๋ค. ์ ๊ฐ์ ๊ฒฝ์ฐ์๋ model.parameters()
, ํน์ model.named_parameters()
๋ฅผ ๋ชจ๋ธ ํ๋ฆฌ์ง์ด๋ ๋ชจ๋ธ์ ๊ตฌ์ฑ์์๋ฅผ ํ์ธํ๋ ค๊ณ ํ ๋, ๋ง์ด ์ฌ์ฉํด ์์ต๋๋ค.
๊ทธ๋์ torchsummary
๋ print(model)
์ ๋ํด์ ์ฐจ์ด์ ์ด ์๋ ๊ฑด๊ฐ?๋ฅผ ์๊ฐํด์ ๊ฐ๋จํ ์ฝ๋๋ฅผ ์์
ํด์ ๋๋ ค๋ดค์ต๋๋ค. ์๋์ ๋ชจ๋ธ์ ๋ง๋ค์ด์ฃผ๊ณ , 3๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋ชจ๋ธ์ ๊ตฌ์ฑ ์์์ ๋ํด์ ์ถ๋ ฅํด ๋ณธ ๊ฒฐ๊ณผ, ์ฐจ์ด์ ์ ์์์ต๋๋ค.
class Model(nn.Module):
def __init__(self):
super().__init__()
self.param1 = nn.Parameter(
torch.tensor([1, 2, 3], dtype=torch.float32))
self.param2 = torch.tensor([4, 5, 6], dtype=torch.float32)
self.li = nn.Linear(3, 1)
def forward(self, x):
x = x * self.param1
x = x * self.param2
x = self.li(x)
return x
1๋ฒ์งธ ๋ฐฉ๋ฒ: model.named_parameters()
for name, param in model.named_parameters():
print(name, param)
# OUTPUT
param1 Parameter containing:
tensor([1., 2., 3.], requires_grad=True)
li.weight Parameter containing:
tensor([[-0.2087, 0.4349, 0.3196]], requires_grad=True)
li.bias Parameter containing:
tensor([-0.5716], requires_grad=True)
2๋ฒ์งธ ๋ฐฉ๋ฒ: summary(model, (BATCH_SIZE, 3))
BATCH_SIZE = 16
summary(model, (BATCH_SIZE, 3))
# OUTPUT
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Linear-1 [-1, 16, 1] 4
================================================================
Total params: 4
Trainable params: 4
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
----------------------------------------------------------------
3๋ฒ์งธ ๋ฐฉ๋ฒ: print(model)
print(model)
# OUTPUT
Model(
(li): Linear(in_features=3, out_features=1, bias=True)
)
์ฐจ์ด์ ์ 1๋ฒ์งธ ๋ฐฉ๋ฒ์์๋ง nn.Parameter()
์ ๋ํด์ ์ถ๋ ฅ์ ํ๋ค๋ ๊ฒ์
๋๋ค. 2, 3๋ฒ์งธ ๋ฐฉ๋ฒ์ด ์ถ๋ ฅ์ ์ ํ๋ค๋ ๊ฒ ์กฐ๊ธ ์์ํ๊ธด ํ์ต๋๋ค. 1, 2, 3๋ฒ ๋ฐฉ๋ฒ ๋ชจ๋ tensor
๋ก ์ ์ธ๋ ๋ชจ๋ธ์ ํ๋ผ๋ฏธํฐ์ ๋ํด์๋ ์ถ๋ ฅํ์ง ์์์ต๋๋ค.
๋ฌผ๋ก , 2, 3๋ฒ์งธ ๋ฐฉ๋ฒ์ ํตํด ์ถ๋ ฅํ๊ธฐ ์ํด์๋ nn.Parameter()
์์ฒด๋ฅผ ํ๋์ Layer์ฒ๋ผ ์ทจ๊ธํ์ฌ ๊ณ์ธต์ ์ธ ๊ตฌ์กฐ๋ก ์ถ๋ ฅํด์ผ ํฉ๋๋ค. ๋ฐ๋ฉด, ํด๋น ํ๋ผ๋ฏธํฐ์ ๋ํด์ ์ด๋ ํ ์ฐ์ฐ์ด ์ด๋ฃจ์ด์ง์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์ด์ฐ ๋ณด๋ฉด ๋น์ฐํ ๊ฒฐ๊ณผ์ธ ๊ฑฐ ๊ฐ์ ๋ณด์ด๊ธฐ๋ ํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ, ๊ณ ์ ์ด๋ฐ ์ฐจ์ด์ ์ ์ฃผ์๊ณ nn.Parameter()
๋ฅผ ๋ง๋ค์์๊น๋ฅผ ์๊ฐํด ๋ณด๋ฉด ์ด ์ฐจ์ด์ ์ ํฌ๊ฒ ์ค๋๋ ฅ์ด ์์์ต๋๋ค. ๋ฌด์ธ๊ฐ ๋ ํต์ฌ์ ์ธ ์ด์ ๊ฐ ์์ ๊ฑฐ๋ผ ํ๋จํ์ต๋๋ค.
๐ Solution: optimizer
๊ทธ์ ๋ํ ๋ต์ Stackoverflow์์ ์ฐพ์ ์ ์์์ต๋๋ค.
https://stackoverflow.com/questions/51373919/the-purpose-of-introducing-nn-parameter-in-pytorch
์ฌ๊ธฐ์ ๋ต์ ์์๋์ ๋๋ ์ ๋ง ๊ฐ๊น์ด ๊ณณ์ ๊ทธ ๋ต์ด ์์๊ณ , '์ ์ด๊ฑด ๋๋ฌด ๋ฉ์ฒญํ๋ค'๋ผ๋ ์๊ฐ์ด ๋ค ์ ๋์์ต๋๋ค.
nn.Parameter()
๋ฅผ ์ฐ๋ฉด, model.parameters()
, model.named_parameters()
์์ ๋ํ๋๋ค๋ผ๋ ๊ฒ์ ์์์๋ ์ฌ๋ฌ ๋ฒ ์๊ธฐํ์ต๋๋ค. ํ์ง๋ง, ์ด ์ฉ๋๋ฅผ ์์์๋ ๋จ์ํ ๋ชจ๋ธ์ ๊ตฌ์ฑ ์์ ์ถ๋ ฅ์ ์ํด์๋ผ๊ณ ํ๋จํ์๊ณ ์.
ํ์ง๋ง, ์ฐ๋ฆฌ๊ฐ ๋ชจ๋ธ์ ํ์ต์ํฌ ๋๋ ์ด๋ป๊ฒ ํ์ต์ ์ํต๋๊น?
์ตํฐ๋ง์ด์ ๋ฅผ ์ ์ธํด์ ํด๋น ์ตํฐ๋ง์ด์ ์๊ฒ ๋ชจ๋ธ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋๊ฒจ์ฃผ์ง ์์๋์?
๋ค! ๋ง์ต๋๋ค. ๊ทธ๋ ์ฐ๋ฆฌ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ๋๊ฒจ์ค ๋ ์ด๋ฐ ์ฝ๋๋ฅผ ์ผ์ต๋๋ค.
optimizer = optim.SGD(model.parameters(), lr=0.001)
model.parameters()
๋ฅผ ์ตํฐ๋ง์ด์ ์ ๋๊ฒจ์ ์ตํฐ๋ง์ด์ ์๊ฒ ํ์ต์ ์์ผ์ผ ํ๋ ๋ชจ๋ธ์ ํ๋ผ๋ฏธํฐ๊ฐ ๋ฌด์์ธ์ง ์๋ ค์ฃผ๊ณ ์์๋ค๋ ๊ฒ์
๋๋ค.
์, ๊ทธ๋ฌ๋ฉด tensor
๋ก ๋ชจ๋ธ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ตฌ์ฑํ๋ ๊ฒ์ ์๋์ ์ ํฉํ์ง ์๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค. ํด๋น tensor๋ ํ์ต์ ๋ชป ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
์ฆ, ์ฝ๋๋ก ํํ๋๋ ์ฌ์ํ ์ฐจ์ด์ ์ด ์๋๋ผ, ์น๋ช ์ ์ธ ์ฐจ์ด์ ์ด ์์๋ค๋ ๊ฑฐ์์!
์ด๊ฒ ์ฌ์ค์ธ์ง ํ์ธํด ๋ณด๊ธฐ ์ํด์ ์๋์ ๊ฐ์ ํ๋ จ์ ์ํค๋ ํจ์๋ฅผ ๋ง๋ค์ด์ ์คํํด ๋ณด์์ต๋๋ค.
def train():
model = Model()
optimizer = optim.SGD(model.parameters(), lr=0.001)
loss_fn = nn.MSELoss()
input_data = torch.tensor([1, 2, 3], dtype=torch.float32)
output_data = model(input_data)
target_data = torch.tensor([1], dtype=torch.float32)
loss = loss_fn(output_data, target_data)
_ANNOTATION_MARK = 10
print('#' * _ANNOTATION_MARK +
'[Before Back Propagation]' + '#' * _ANNOTATION_MARK)
print('param1: ', model.param1.data)
print('param2: ', model.param2.data)
print('li: ', model.li.weight.data)
# Back Propagation
optimizer.zero_grad()
loss.backward()
optimizer.step()
print('#' * _ANNOTATION_MARK +
'[Before Back Propagation]' + '#' * _ANNOTATION_MARK)
print('param1: ', model.param1.data)
print('param2: ', model.param2.data)
print('li: ', model.li.weight.data)
์ด์ ๋ํ ์คํ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ์ต๋๋ค.
##########[Before Back Propagation]##########
param1: tensor([1., 2., 3.])
param2: tensor([4., 5., 6.])
li: tensor([[-0.3608, -0.2601, -0.4624]])
##########[Before Back Propagation]##########
param1: tensor([0.9055, 1.8296, 2.4548])
param2: tensor([4., 5., 6.])
li: tensor([[-0.0987, 1.0501, 3.0752]])
nn.Parameter()
๋ฅผ ํตํด์ ์ ์ธ๋ param1
์ ํ์ต์ ์ํํ์ฌ ๊ฐ์ด ๋ณ๊ฒฝ ๋์์ง๋ง, tensor
๋ก ์ ์ธ๋ param2
๋ ํ์ต์ ํ์ง ๋ชปํด์ ๊ฐ์ด ๊ทธ๋๋ก์ธ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
โ Result
์ด์ ๋ ๋ค์ ์ง๋ฌธ์ ๋๋ต์ ํ ์ ์์ต๋๋ค. 'nn.Parameter()
์ tensor
๊ฐ ๋ฌด์จ ์ฐจ์ด๊ฐ ์๊ธธ๋ nn.Parameter()
๋ฅผ ์ฐ๋๊ฐ?'๋ผ๋ ์ง๋ฌธ์ ๋ํด์ 'nn.Parameter()
๋ก ํ๋ผ๋ฏธํฐ๋ฅผ ๋ชจ๋ธ(๋ชจ๋) ๋ด์ ์ ์ธ์ ํด์ผ ์ตํฐ๋ง์ด์ ์ model.parameters()
๋ฅผ ํตํด ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ์ ํด๋น ํ๋ผ๋ฏธํฐ๋ฅผ ํ์ต์ํฌ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.'๋ผ๊ณ ๋ตํ ์ ์์ต๋๋ค.
๋๋ฌด ๊ธด ๊ฑฐ ๊ฐ์ผ๋ ์กฐ๊ธ ๋ ์์ฝ์ ํ๋ฉด, 'tensor
๊ฐ ์๋ nn.Parameter()
๋ก ์ ์ธ์ ํด์ผ ์ตํฐ๋ง์ด์ ๋ฅผ ํตํด ํ์ต์ ํ ์ ์๋ค.'๋ก ์์ฝํ ์ ์์ ๊ฑฐ ๊ฐ์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด, torch.tensor()
๋ ์์ ํ๋ค๊ณ ๋ณผ ์ ์์๊น์? ์๋์ ์ผ๋ก ํ์ต์ ์ํค์ง ์๋ ํ๋ผ๋ฏธํฐ๊ฐ ์์ต๋๋ค๋ง, ๋ง๋ฅ torch.tensor()
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ ํฉํ์ง ์์ต๋๋ค.
์ด์ ๋ํด ์์๋ณด๊ธฐ ์ํด ๋ค์ ๊ธ, "self.register_buffer(), ํ์ตํ์ง ์์ ํ๋ผ๋ฏธํฐ๋ผ๋ฉด? (tensor์ ๋ช ๋ฐฑํ๊ฒ ๋ค๋ฅธ ์ 2)์ ์๊ฐํฉ๋๋ค.
๐ Reference
https://stackoverflow.com/questions/51373919/the-purpose-of-introducing-nn-parameter-in-pytorch