๋ฐ์ํ
โ ๏ธ ๋ณธ ๋ด์ฉ์ PyTorch Korea์ ๊ณต์ ๋ฌธ์์ ๊ธฐ๋ฐํ์ฌ ๊ณต๋ถํ ๋ด์ฉ์ ์ ์๊ฒ์ด๋ ์ํด๋ฐ๋๋๋ค!
Neural Network Model (์ ๊ฒฝ๋ง ๋ชจ๋ธ) ๊ตฌ์ฑํ๊ธฐ
- ์ ๊ฒฝ๋ง์ ๋ฐ์ดํฐ์ ๋ํ ์ฐ์ฐ์ ์ํํ๋ ๊ณ์ธต(layer)/๋ชจ๋(module)๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
- torch.nn ๋ค์์คํ์ด์ค๋ ์ ๊ฒฝ๋ง์ ๊ตฌ์ฑํ๋๋ฐ ํ์ํ ๋ชจ๋ ๊ตฌ์ฑ ์์๋ฅผ ์ ๊ณตํฉ๋๋ค. PyTorch์ ๋ชจ๋ ๋ชจ๋์ nn.Module ์ ํ์ ํด๋์ค(subclass) ์ ๋๋ค.
- torch.nn ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
- nn.Module ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
- ๋ํ ์ ๊ฒฝ๋ง์ ๋ค๋ฅธ ๋ชจ๋(๊ณ์ธต, layer)๋ก ๊ตฌ์ฑ๋ ๋ชจ๋์ ๋๋ค.
- ์ด๋ฌํ ์ค์ฒฉ๋ ๊ตฌ์กฐ๋ ๋ณต์กํ ์ํคํ ์ฒ๋ฅผ ์ฝ๊ฒ ๊ตฌ์ถํ๊ณ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ํ๋ฒ ์ด๋ฒ์๋ COCO Dataset์ผ๋ก ํ๋ฒ ๊ตฌ์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
ํ์ต์ ์ํ ์ฅ์น ์ค์
- ๊ฐ๋ฅํ ๊ฒฝ์ฐ GPU ๋๋ MPS์ ๊ฐ์ ํ๋์จ์ด ๊ฐ์๊ธฐ์์ ๋ชจ๋ธ์ ํ์ตํ๋ ค๊ณ ํฉ๋๋ค.
- torch.cuda ๋๋ torch.backends.mps๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ์ง ํ์ธํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด CPU๋ฅผ ๊ณ์ ์ฌ์ฉํฉ๋๋ค.
- torch.cuda ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
- torch.backends.mps ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
import torch
device = (
"cuda" if torch.cuda.is_available() else
"mps" if torch.backends.mps.is_available() else
"cpu"
)
print(f"Using {device} device")
Using cpu device
- COCO ๋ฐ์ดํฐ์ ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ pycocotools๊ฐ ํ์ํฉ๋๋ค.
pip install pycocotools
- ๋ํ ๋ฐ์ดํฐ์ ์ ๋ค์ด๋ก๋ ํด์ผํฉ๋๋ค. ์๋์ ์ฝ๋๋ก ๋ค์ด๋ก๋ ๋ฐ ์์ถ์ ํด์ ํํ, ๋ฐ์ดํฐ ๋ก๋๋ฅผ ํด๋ณด๊ฒ ์ต๋๋ค.
import os
# ๋๋ ํ ๋ฆฌ ์์ฑ
os.makedirs('data/coco/images', exist_ok=True)
os.makedirs('data/coco/annotations', exist_ok=True)
# COCO ๋ฐ์ดํฐ์
๋ค์ด๋ก๋
!wget http://images.cocodataset.org/zips/train2017.zip -P data/coco/images/
!wget http://images.cocodataset.org/zips/val2017.zip -P data/coco/images/
!wget http://images.cocodataset.org/annotations/annotations_trainval2017.zip -P data/coco/annotations/
# ๋ค์ด๋ก๋๋ ํ์ผ ๋ชฉ๋ก ํ์ธ
!ls data/coco/images/
!ls data/coco/annotations/
# ์ด๋ฏธ์ง ์์ถ ํด์
!unzip data/coco/images/train2017.zip -d data/coco/images/
!unzip data/coco/images/val2017.zip -d data/coco/images/
# ์ฃผ์ ํ์ผ ์์ถ ํด์
!unzip data/coco/annotations/annotations_trainval2017.zip -d data/coco/annotations/
# ์์ถ ํด์ ๋ ํ์ผ ๋ชฉ๋ก ํ์ธ
!ls data/coco/images/train2017 | head -n 5 # train2017 ๋๋ ํ ๋ฆฌ์ ํ์ผ ๋ชฉ๋ก ํ์ธ (์ฒ์ 5๊ฐ ํ์ผ๋ง)
!ls data/coco/annotations/ | head -n 5 # annotations ๋๋ ํ ๋ฆฌ์ ํ์ผ ๋ชฉ๋ก ํ์ธ (์ฒ์ 5๊ฐ ํ์ผ๋ง)
- ๋ฐ์ดํฐ๊ฐ ๋ค์ด๋ก๋๊ฐ ์๋ฃ๋๋ฉด, ๋ฐ์ดํฐ ๋ณํ ๋ถ๋ถ์ ์ ์ํํ, ๊ฒฝ๋ก์ ์ฃผ์ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์ค์ ํ ํ, ๋ฐ์ดํฐ๋ฅผ Load ํด๋ณด๊ฒ ์ต๋๋ค.
from torchvision import datasets, transforms
# ๋ฐ์ดํฐ ๋ณํ ์ ์
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
- Dataset ๋ถ๋ฌ์ค๊ธฐ
# COCO ๋ฐ์ดํฐ์
๊ฒฝ๋ก์ ์ฃผ์ ํ์ผ ๊ฒฝ๋ก ์ค์
train_data_path = '/content/data/coco/images/train2017'
train_ann_file = '/content/data/coco/annotations/annotations/instances_train2017.json'
val_data_path = '/content/data/coco/images/val2017'
val_ann_file = '/content/data/coco/annotations/annotations/instances_val2017.json'
# COCO ํ์ต ๋ฐ์ดํฐ์
๋ถ๋ฌ์ค๊ธฐ
coco_train = datasets.CocoDetection(root=train_data_path, annFile=train_ann_file, transform=transform)
# COCO ๊ฒ์ฆ ๋ฐ์ดํฐ์
๋ถ๋ฌ์ค๊ธฐ
coco_val = datasets.CocoDetection(root=val_data_path, annFile=val_ann_file, transform=transform)
loading annotations into memory...
Done (t=21.98s)
creating index...
index created!
loading annotations into memory...
Done (t=1.12s)
creating index...
index created!
- DataLoader ์์ฑ & Image, Annotation ์๊ฐํ
import matplotlib.pyplot as plt
# ์ปค์คํ
collate_fn ์ ์
def collate_fn(batch):
return tuple(zip(*batch))
# DataLoader ์์ฑ
train_loader = DataLoader(coco_train, batch_size=2, shuffle=True, num_workers=2, collate_fn=collate_fn)
val_loader = DataLoader(coco_val, batch_size=2, shuffle=False, num_workers=2, collate_fn=collate_fn)
# DataLoader์์ ์ฒซ ๋ฒ์งธ ๋ฐฐ์น ๊ฐ์ ธ์ค๊ธฐ
images, targets = next(iter(train_loader))
# ๋ฐฐ์น ํฌ๊ธฐ ์ถ๋ ฅ
print(f"Batch size: {len(images)}")
# ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ์ด๋
ธํ
์ด์
์ ๊ฐ์ ธ์์ ์๊ฐํ
image = images[0]
annotations = targets[0]
# ์ด๋ฏธ์ง ์๊ฐํ
image = image.permute(1, 2, 0) / 2 + 0.5 # ์ ๊ทํ ํด์ ๋ฐ (C, H, W) -> (H, W, C) ๋ณ๊ฒฝ
plt.imshow(image.numpy())
plt.axis("off")
# ์ด๋
ธํ
์ด์
์ถ๋ ฅ
print("Annotations:", annotations)
# ์ด๋
ธํ
์ด์
์๊ฐํ
for annotation in annotations:
bbox = annotation['bbox']
x, y, width, height = bbox
rect = plt.Rectangle((x, y), width, height, fill=False, color='red')
plt.gca().add_patch(rect)
plt.show()
Batch size: 2
Annotations: [{'segmentation': [[133.48, 183.91, 164.13, 188.85, 200.72, 222.47, 229.39, 232.36, 259.06, 187.87, 244.22, 179.96, 263.01, 161.17, 293.66, 162.16, 282.79, 117.66, 286.74, 104.81, 335.19, 86.02, 366.83, 111.73, 355.96, 155.24, 375.73, 176.99, 380.67, 327.28, 411.33, 434.07, 362.88, 435.06, 357.93, 414.29, 300.58, 401.44, 276.85, 433.08, 248.18, 433.08, 279.82, 356.94, 289.71, 270.92, 273.89, 213.57, 237.3, 265.98, 197.75, 260.04, 130.52, 206.65]], 'area': 38538.08794999999, 'iscrowd': 0, 'image_id': 257219, 'bbox': [130.52, 86.02, 280.81, 349.04], 'category_id': 1, 'id': 520718}, {'segmentation': [[136.45, 185.89, 128.54, 142.38, 119.64, 121.62, 109.75, 89.98, 110.74, 57.35, 113.71, 27.69, 116.67, 11.87, 128.54, 15.82, 137.44, 26.7, 137.44, 56.36, 138.43, 89.98, 141.39, 140.4, 149.3, 186.88], [141.39, 194.79, 151.28, 195.78, 158.2, 212.58, 143.37, 215.55, 147.33, 201.71, 142.38, 197.75]], 'area': 3782.494, 'iscrowd': 0, 'image_id': 257219, 'bbox': [109.75, 11.87, 48.45, 203.68], 'category_id': 43, 'id': 659445}]
์ ๊ฒฝ๋ง ํด๋์ค ์ ์ํ๊ธฐ
- ์ ๊ฒฝ๋ง ๋ชจ๋ธ์ nn.Module ์ ํ์ํด๋์ค๋ก ์ ์ํ๊ณ , __init__ ์์ ์ ๊ฒฝ๋ง ๊ณ์ธต๋ค์ ์ด๊ธฐํํฉ๋๋ค.
- nn.Module ์ ์์๋ฐ์ ๋ชจ๋ ํด๋์ค๋ forward ๋ฉ์๋์ ์ ๋ ฅ ๋ฐ์ดํฐ์ ๋ํ ์ฐ์ฐ๋ค์ ๊ตฌํํฉ๋๋ค.
# ์ ๊ฒฝ๋ง ํด๋์ค ์ ์
class NeuralNetwork(nn.Module):
def __init__(self):
super(NeuralNetwork, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
self.fc1 = nn.Linear(64 * 8 * 8, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 64 * 8 * 8)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
- NeuralNetwork ์ ์ธ์คํด์ค(instance)๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ device ๋ก ์ด๋ํ ๋ค, ๊ตฌ์กฐ(structure)๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
model = NeuralNetwork().to(device)
print(model)
NeuralNetwork(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(fc1): Linear(in_features=4096, out_features=128, bias=True)
(fc2): Linear(in_features=128, out_features=10, bias=True)
)
- ๋ชจ๋ธ์ ์ฌ์ฉํ๊ธฐ ์ํด ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํฉ๋๋ค.
- ์ด๋ ์ผ๋ถ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ฐ์ฐ๋ค๊ณผ ํจ๊ป ๋ชจ๋ธ์ forward ๋ฅผ ์คํํฉ๋๋ค. model.forward() ๋ฅผ ์ง์ ํธ์ถํ์ง ๋ง์ธ์!
- ๋ชจ๋ธ์ ์ ๋ ฅ์ ์ ๋ฌํ์ฌ ํธ์ถํ๋ฉด 2์ฐจ์ ํ ์๋ฅผ ๋ฐํํฉ๋๋ค.
- 2์ฐจ์ ํ ์์ dim=0์ ๊ฐ ๋ถ๋ฅ(class)์ ๋ํ ์์(raw) ์์ธก๊ฐ 10๊ฐ๊ฐ, dim=1์๋ ๊ฐ ์ถ๋ ฅ์ ๊ฐ๋ณ ๊ฐ๋ค์ด ํด๋นํฉ๋๋ค.
- ์์ ์์ธก๊ฐ์ nn.Softmax ๋ชจ๋์ ์ธ์คํด์ค์ ํต๊ณผ์์ผ ์์ธก ํ๋ฅ ์ ์ป์ต๋๋ค.
import torch.nn as nn
import torch.nn.functional as F
# ํ
์คํธ์ฉ ๋๋ค ๋ฐ์ดํฐ ์์ฑ (3์ฑ๋, 32x32 ํฌ๊ธฐ)
X = torch.rand(1, 3, 32, 32, device=device)
# ๋ชจ๋ธ์ ์
๋ ฅ ์ ๋ฌํ์ฌ ์์ ์์ธก๊ฐ(logits) ์ป๊ธฐ
logits = model(X)
# ์์ ์์ธก๊ฐ์ Softmax ํจ์์ ํต๊ณผ์์ผ ์์ธก ํ๋ฅ ์ ๊ณ์ฐ
pred_probab = nn.Softmax(dim=1)(logits)
# ๊ฐ์ฅ ๋์ ํ๋ฅ ์ ๊ฐ์ง ํด๋์ค๋ฅผ ์์ธก
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")
Predicted class: tensor([5])
- ์์ ์ฝ๋์์ ์ฐ๋ฆฌ๊ฐ ์ ์ ์๋๊ฑด, logits์ ์ฐจ์์ด [batch_size, num_classes]์์ ํ์ธํ ์ ์์ต๋๋ค.
- ์ฌ๊ธฐ์ batch_size๋ 1์ด๊ณ , num_classes๋ 10์ ๋๋ค. ๋ฐ๋ผ์ nn.Softmax(dim=1)์ ์ฌ์ฉํ์ฌ ๊ฐ ํด๋์ค์ ๋ํ ์์ธก ํ๋ฅ ์ ๊ณ์ฐํ๊ณ , argmax(1)์ ์ฌ์ฉํ์ฌ ๊ฐ์ฅ ๋์ ํ๋ฅ ์ ๊ฐ์ง ํด๋์ค๋ฅผ ์์ธกํฉ๋๋ค.
๋ชจ๋ธ ๊ณ์ธต(Layer)
- COCO Dataset์ผ๋ก ๊ตฌ์ฑํ ๋ชจ๋ธ์ ๊ณ์ธต๋ค์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
- ์ด๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด, 32x32 ํฌ๊ธฐ์ ์ด๋ฏธ์ง 3๊ฐ๋ก ๊ตฌ์ฑ๋ 3๊ฐ์ ๋ฏธ๋๋ฐฐ์น๋ฅผ ๊ฐ์ ธ์, ์ ๊ฒฝ๋ง์ ํต๊ณผํ ๋ ์ด๋ค ์ผ์ด ๋ฐ์ํ๋์ง ์์๋ณด๊ฒ ์ต๋๋ค.
input_image = torch.rand(3, 3, 32, 32).to(device) # ์์ ์ด๋ฏธ์ง (batch_size=3, ์ฑ๋=3, ๋์ด=32, ๋๋น=32)
print(f"Input image size: {input_image.size()}")
Input image size: torch.Size([3, 3, 32, 32])
nn.Flatten
- nn.Flatten ๊ณ์ธต์ ์ด๊ธฐํํ์ฌ ๊ฐ 32x32์ 3๊ฐ 2D ์ด๋ฏธ์ง๋ฅผ 1024 ํฝ์ ๊ฐ์ ๊ฐ๋ ์ฐ์๋ ๋ฐฐ์ด๋ก ๋ณํํฉ๋๋ค.
- (dim=0์ ๋ฏธ๋๋ฐฐ์น ์ฐจ์์ ์ ์ง๋ฉ๋๋ค.)
flatten = nn.Flatten()
flat_image = flatten(input_image)
print(flat_image.size())
torch.Size([3, 3072])
- ์๋๋ Flatten ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
nn.Linear
- Linear(์ ํ)์ ์ ์ฅ๋ ๊ฐ์ค์น(weight)์ ํธํฅ(bias)์ ์ฌ์ฉํ์ฌ ์ ๋ ฅ์ ์ ํ ๋ณํ(linear transformation)์ ์ ์ฉํ๋ ๋ชจ๋์ ๋๋ค.
layer1 = nn.Linear(in_features=3*32*32, out_features=20)
hidden1 = layer1(flat_image)
print(hidden1.size())
torch.Size([3, 20])
- ์๋๋ Linear ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
nn.ReLU
- ๋น์ ํ ํ์ฑํ(activation)๋ ๋ชจ๋ธ์ ์ ๋ ฅ๊ณผ ์ถ๋ ฅ ์ฌ์ด์ ๋ณต์กํ ๊ด๊ณ(mapping)๋ฅผ ๋ง๋ญ๋๋ค.
- ๋น์ ํ ํ์ฑํ๋ ์ ํ ๋ณํ ํ์ ์ ์ฉ๋์ด ๋น์ ํ์ฑ(nonlinearity) ์ ๋์ ํ๊ณ , ์ ๊ฒฝ๋ง์ด ๋ค์ํ ํ์์ ํ์ตํ ์ ์๋๋ก ๋์ต๋๋ค.
- ์ด ๋ชจ๋ธ์์๋ nn.ReLU ๋ฅผ ์ ํ ๊ณ์ธต๋ค ์ฌ์ด์ ์ฌ์ฉํ์ง๋ง, ๋ชจ๋ธ์ ๋ง๋ค ๋๋ ๋น์ ํ์ฑ์ ๊ฐ์ง ๋ค๋ฅธ ํ์ฑํ๋ฅผ ๋์ ํ ์๋ ์์ต๋๋ค.
print(f"Before ReLU: {hidden1}\n\n")
hidden1 = nn.ReLU()(hidden1)
print(f"After ReLU: {hidden1}")
Before ReLU: tensor([[ 0.0573, -0.4209, 0.1609, 0.0883, -0.2229, -0.2041, 0.4565, -0.5007,
0.4450, 0.1568, 0.5146, -0.0457, 0.2785, 0.1053, 0.2393, 0.0431,
-0.2777, 0.4349, 0.5298, 0.2587],
[ 0.2132, -0.5740, 0.4295, -0.0561, -0.2113, 0.1131, 0.2910, -0.1083,
0.8356, 0.1414, 0.6412, 0.0399, -0.1169, 0.2886, -0.1195, -0.1499,
-0.2063, 0.1675, 0.5169, 0.1049],
[-0.0463, -0.5933, 0.3965, -0.0786, 0.2606, -0.0190, 0.0483, -0.1813,
0.1006, 0.1953, 0.5511, -0.0894, 0.0535, 0.0100, -0.1465, 0.3288,
-0.6016, 0.4170, 0.4967, -0.0904]], grad_fn=<AddmmBackward0>)
After ReLU: tensor([[0.0573, 0.0000, 0.1609, 0.0883, 0.0000, 0.0000, 0.4565, 0.0000, 0.4450,
0.1568, 0.5146, 0.0000, 0.2785, 0.1053, 0.2393, 0.0431, 0.0000, 0.4349,
0.5298, 0.2587],
[0.2132, 0.0000, 0.4295, 0.0000, 0.0000, 0.1131, 0.2910, 0.0000, 0.8356,
0.1414, 0.6412, 0.0399, 0.0000, 0.2886, 0.0000, 0.0000, 0.0000, 0.1675,
0.5169, 0.1049],
[0.0000, 0.0000, 0.3965, 0.0000, 0.2606, 0.0000, 0.0483, 0.0000, 0.1006,
0.1953, 0.5511, 0.0000, 0.0535, 0.0100, 0.0000, 0.3288, 0.0000, 0.4170,
0.4967, 0.0000]], grad_fn=<ReluBackward0>)
- ์๋๋ ReLU ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
nn.Sequential
- nn.Sequential์ ์์๋ฅผ ๊ฐ๋ ๋ชจ๋์ ์ปจํ ์ด๋์ ๋๋ค. ๋ฐ์ดํฐ๋ ์ ์๋ ๊ฒ๊ณผ ๊ฐ์ ์์๋ก ๋ชจ๋ ๋ชจ๋๋ค์ ํตํด ์ ๋ฌ๋ฉ๋๋ค.
- ์์ฐจ ์ปจํ ์ด๋(sequential container)๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ seq_modules์ ๊ฐ์ ์ ๊ฒฝ๋ง์ ๋น ๋ฅด๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
seq_modules = nn.Sequential(
flatten,
layer1,
nn.ReLU(),
nn.Linear(20, 10)
)
input_image = torch.rand(3,3,32,32)
logits = seq_modules(input_image)
- ์๋๋ Sequential ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
nn.Softmax
- ์ ๊ฒฝ๋ง์ ๋ง์ง๋ง ์ ํ ๊ณ์ธต์ nn.Softmax ๋ชจ๋์ ์ ๋ฌ๋ ([-\infty, \infty] ๋ฒ์์ ์์ ๊ฐ(raw value)์ธ) logits๋ฅผ ๋ฐํํฉ๋๋ค.
- logits๋ ๋ชจ๋ธ์ ๊ฐ ๋ถ๋ฅ(class)์ ๋ํ ์์ธก ํ๋ฅ ์ ๋ํ๋ด๋๋ก [0, 1] ๋ฒ์๋ก ๋น๋กํ์ฌ ์กฐ์ (scale)๋ฉ๋๋ค.
- dim ๋งค๊ฐ๋ณ์๋ ๊ฐ์ ํฉ์ด 1์ด ๋๋ ์ฐจ์์ ๋ํ๋ ๋๋ค.
softmax = nn.Softmax(dim=1)
pred_probab = softmax(logits)
- ์๋๋ Softmax ๊ด๋ จ ๊ณต์๋ฌธ์ ์ ๋๋ค.
Model Parameter (๋ชจ๋ธ ๋งค๊ฐ๋ณ์)
- ์ ๊ฒฝ๋ง ๋ด๋ถ์ ๋ง์ ๊ณ์ธต๋ค์ ๋งค๊ฐ๋ณ์ํ๋์ด ์์ต๋๋ค. ์ฆ, ํ์ต ์ค์ ์ต์ ํ๋๋ ๊ฐ์ค์น์ ํธํฅ๊ณผ ์ฐ๊ด์ง์ด์ง๋๋ค.
- nn.Module์ ์์ํ๋ฉด ๋ชจ๋ธ ๊ฐ์ฒด ๋ด๋ถ์ ๋ชจ๋ ํ๋๊ฐ ์๋์ผ๋ก ์ถ์ ๋๋ฉฐ, ๋ชจ๋ธ์ parameters() ๋ฐ named_parameters() ๋ฉ์๋๋ก ๋ชจ๋ ๋งค๊ฐ๋ณ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
print(f"Model structure: {model}\n\n")
for name, param in model.named_parameters():
print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")
Model structure: NeuralNetwork(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(fc1): Linear(in_features=4096, out_features=128, bias=True)
(fc2): Linear(in_features=128, out_features=10, bias=True)
)
Layer: conv1.weight | Size: torch.Size([32, 3, 3, 3]) | Values : tensor([[[[ 0.1862, 0.0348, -0.0016],
[ 0.1516, 0.0909, 0.1756],
[ 0.0587, 0.0633, -0.1128]],
[[-0.0136, -0.1710, -0.0311],
[ 0.0688, 0.1021, -0.1459],
[ 0.0731, -0.0228, 0.1869]],
[[-0.0159, -0.1800, 0.0410],
[ 0.0596, -0.1067, 0.1680],
[ 0.0100, 0.0703, 0.1224]]],
[[[ 0.1516, -0.0855, 0.1784],
[-0.0829, 0.1167, 0.0004],
[ 0.1342, -0.1512, 0.1785]],
[[ 0.1377, 0.0012, 0.1171],
[-0.0868, 0.1479, -0.0939],
[ 0.1452, -0.0420, 0.0158]],
[[ 0.1411, 0.1788, -0.1186],
[-0.0699, -0.0885, -0.1091],
[-0.1139, -0.1580, -0.0119]]]], grad_fn=<SliceBackward0>)
Layer: conv1.bias | Size: torch.Size([32]) | Values : tensor([0.0369, 0.0015], grad_fn=<SliceBackward0>)
Layer: conv2.weight | Size: torch.Size([64, 32, 3, 3]) | Values : tensor([[[[ 0.0261, -0.0033, 0.0156],
[-0.0116, -0.0022, -0.0400],
[ 0.0550, -0.0473, -0.0462]],
[[-0.0382, 0.0463, 0.0364],
[-0.0196, -0.0553, 0.0280],
[ 0.0524, -0.0005, 0.0318]],
[[-0.0081, -0.0541, 0.0227],
[-0.0107, -0.0046, -0.0394],
[ 0.0346, -0.0484, 0.0203]],
[[ 0.0248, 0.0074, -0.0435],
[ 0.0494, -0.0539, -0.0313],
[-0.0139, 0.0093, 0.0336]],
[[ 0.0106, 0.0555, -0.0151],
[-0.0106, 0.0161, -0.0478],
[-0.0356, 0.0211, -0.0143]],
[[ 0.0135, -0.0491, 0.0255],
[-0.0516, -0.0486, -0.0282],
[-0.0481, -0.0337, -0.0122]],
[[-0.0450, 0.0032, -0.0472],
[ 0.0033, 0.0053, -0.0034],
[ 0.0570, -0.0098, 0.0086]],
[[ 0.0385, -0.0578, -0.0576],
[-0.0207, 0.0442, 0.0084],
[-0.0220, -0.0454, -0.0353]],
[[-0.0533, -0.0340, 0.0005],
[ 0.0214, 0.0571, 0.0404],
[ 0.0541, -0.0429, 0.0041]],
[[-0.0509, 0.0586, 0.0317],
[-0.0149, 0.0130, 0.0563],
[-0.0043, -0.0228, -0.0563]],
[[ 0.0543, -0.0420, -0.0074],
[-0.0381, 0.0271, 0.0301],
[ 0.0370, 0.0410, -0.0316]],
[[ 0.0021, 0.0214, 0.0581],
[-0.0217, 0.0067, -0.0300],
[-0.0211, 0.0366, -0.0019]],
[[-0.0322, 0.0204, -0.0094],
[-0.0565, 0.0257, -0.0122],
[-0.0130, -0.0266, 0.0578]],
[[ 0.0239, -0.0355, -0.0376],
[-0.0540, -0.0484, 0.0044],
[ 0.0365, 0.0062, 0.0125]],
[[-0.0328, -0.0446, -0.0387],
[-0.0175, 0.0550, -0.0388],
[-0.0031, -0.0325, 0.0301]],
[[-0.0568, 0.0489, 0.0270],
[ 0.0042, -0.0009, -0.0015],
[ 0.0099, -0.0251, -0.0406]],
[[ 0.0460, -0.0018, -0.0092],
[-0.0310, -0.0528, -0.0348],
[ 0.0435, 0.0479, -0.0393]],
[[ 0.0181, -0.0132, 0.0326],
[-0.0507, -0.0439, 0.0052],
[-0.0025, 0.0068, 0.0248]],
[[-0.0230, -0.0340, -0.0012],
[ 0.0510, 0.0510, 0.0431],
[ 0.0512, -0.0428, -0.0508]],
[[ 0.0119, -0.0538, 0.0500],
[-0.0086, 0.0308, 0.0172],
[ 0.0502, -0.0181, 0.0502]],
[[ 0.0187, -0.0369, 0.0261],
[-0.0415, 0.0309, -0.0035],
[ 0.0058, 0.0536, -0.0583]],
[[-0.0217, -0.0399, 0.0368],
[ 0.0092, -0.0585, -0.0009],
[-0.0216, 0.0067, -0.0349]],
[[-0.0355, 0.0068, 0.0549],
[ 0.0041, 0.0237, 0.0102],
[-0.0146, -0.0274, 0.0007]],
[[ 0.0155, 0.0301, -0.0056],
[ 0.0213, 0.0533, -0.0066],
[ 0.0281, -0.0354, 0.0441]],
[[ 0.0214, -0.0189, 0.0268],
[-0.0203, 0.0103, -0.0122],
[-0.0404, -0.0540, -0.0231]],
[[ 0.0250, -0.0109, -0.0444],
[-0.0113, 0.0586, -0.0411],
[ 0.0061, -0.0321, 0.0382]],
[[-0.0398, 0.0332, -0.0158],
[ 0.0252, 0.0501, 0.0411],
[-0.0523, -0.0247, -0.0231]],
[[ 0.0333, -0.0042, 0.0410],
[ 0.0511, -0.0215, -0.0217],
[ 0.0438, -0.0457, 0.0523]],
[[ 0.0555, -0.0308, -0.0160],
[ 0.0074, -0.0546, 0.0205],
[-0.0022, 0.0011, 0.0252]],
[[-0.0271, -0.0518, 0.0335],
[-0.0443, -0.0261, 0.0511],
[ 0.0046, 0.0201, 0.0094]],
[[-0.0394, 0.0041, -0.0435],
[-0.0553, 0.0472, 0.0565],
[-0.0239, -0.0169, -0.0285]],
[[-0.0039, -0.0521, 0.0482],
[-0.0156, 0.0064, 0.0396],
[-0.0213, 0.0476, -0.0256]]],
[[[-0.0046, 0.0145, -0.0351],
[ 0.0564, -0.0398, 0.0059],
[ 0.0561, -0.0317, 0.0107]],
[[ 0.0096, 0.0249, 0.0532],
[-0.0453, 0.0322, 0.0254],
[-0.0229, 0.0005, -0.0043]],
[[ 0.0281, -0.0389, 0.0429],
[-0.0140, -0.0191, -0.0558],
[-0.0169, -0.0095, 0.0411]],
[[-0.0243, -0.0522, -0.0273],
[-0.0224, 0.0407, -0.0153],
[ 0.0296, 0.0472, 0.0269]],
[[-0.0263, -0.0583, 0.0072],
[-0.0126, 0.0386, 0.0588],
[ 0.0572, 0.0260, 0.0397]],
[[ 0.0055, -0.0057, 0.0373],
[ 0.0238, 0.0137, -0.0032],
[-0.0514, 0.0505, 0.0456]],
[[-0.0052, 0.0263, -0.0408],
[-0.0184, 0.0117, 0.0134],
[ 0.0475, 0.0481, -0.0333]],
[[ 0.0055, -0.0045, 0.0471],
[-0.0450, 0.0412, -0.0281],
[ 0.0115, -0.0316, -0.0519]],
[[ 0.0589, -0.0305, -0.0120],
[ 0.0583, 0.0129, -0.0020],
[-0.0315, 0.0077, -0.0470]],
[[ 0.0085, 0.0025, 0.0049],
[-0.0427, 0.0585, -0.0448],
[ 0.0425, -0.0255, 0.0457]],
[[-0.0528, -0.0304, 0.0579],
[ 0.0587, 0.0509, -0.0329],
[-0.0472, 0.0526, -0.0013]],
[[ 0.0328, 0.0343, 0.0536],
[ 0.0441, -0.0492, -0.0204],
[-0.0176, -0.0359, -0.0517]],
[[ 0.0475, 0.0533, -0.0492],
[ 0.0375, 0.0327, 0.0192],
[ 0.0313, 0.0143, -0.0359]],
[[-0.0457, 0.0343, -0.0035],
[ 0.0054, 0.0266, -0.0178],
[ 0.0465, -0.0529, 0.0227]],
[[ 0.0222, 0.0580, 0.0492],
[-0.0518, -0.0102, 0.0129],
[ 0.0024, -0.0120, -0.0244]],
[[ 0.0328, 0.0052, -0.0091],
[ 0.0147, -0.0322, 0.0079],
[ 0.0581, 0.0536, 0.0395]],
[[ 0.0571, 0.0274, -0.0572],
[-0.0291, -0.0071, 0.0309],
[-0.0275, -0.0344, -0.0133]],
[[ 0.0083, -0.0212, -0.0163],
[ 0.0016, 0.0081, -0.0539],
[ 0.0514, 0.0232, -0.0131]],
[[-0.0459, 0.0439, -0.0050],
[ 0.0580, -0.0120, 0.0053],
[-0.0080, -0.0338, -0.0377]],
[[-0.0240, -0.0519, 0.0208],
[ 0.0300, 0.0120, -0.0509],
[ 0.0177, -0.0357, 0.0280]],
[[ 0.0411, 0.0466, 0.0216],
[-0.0384, -0.0498, -0.0453],
[ 0.0241, -0.0505, 0.0160]],
[[ 0.0215, -0.0070, -0.0181],
[-0.0092, 0.0424, 0.0435],
[ 0.0562, 0.0579, 0.0340]],
[[ 0.0467, -0.0024, 0.0314],
[-0.0296, 0.0027, -0.0065],
[ 0.0082, 0.0352, -0.0466]],
[[ 0.0436, 0.0248, 0.0524],
[-0.0072, 0.0512, 0.0185],
[-0.0121, -0.0014, 0.0202]],
[[-0.0540, -0.0575, 0.0341],
[-0.0342, 0.0018, -0.0057],
[ 0.0339, 0.0207, -0.0463]],
[[ 0.0514, 0.0430, 0.0307],
[ 0.0415, -0.0236, -0.0101],
[-0.0385, 0.0199, -0.0051]],
[[-0.0059, 0.0523, -0.0029],
[-0.0448, 0.0465, 0.0226],
[ 0.0475, -0.0575, 0.0475]],
[[-0.0255, 0.0292, 0.0408],
[-0.0033, -0.0244, 0.0022],
[ 0.0374, 0.0469, -0.0379]],
[[-0.0435, 0.0137, 0.0501],
[ 0.0573, -0.0491, -0.0328],
[ 0.0438, -0.0108, 0.0485]],
[[-0.0228, 0.0402, 0.0572],
[ 0.0113, 0.0134, 0.0338],
[-0.0061, -0.0067, 0.0375]],
[[-0.0228, -0.0290, -0.0110],
[-0.0108, 0.0270, -0.0585],
[ 0.0146, -0.0237, 0.0506]],
[[ 0.0435, -0.0279, 0.0165],
[ 0.0082, -0.0263, 0.0276],
[-0.0117, -0.0587, -0.0093]]]], grad_fn=<SliceBackward0>)
Layer: conv2.bias | Size: torch.Size([64]) | Values : tensor([0.0459, 0.0281], grad_fn=<SliceBackward0>)
Layer: fc1.weight | Size: torch.Size([128, 4096]) | Values : tensor([[ 0.0027, 0.0142, 0.0116, ..., -0.0154, -0.0137, 0.0089],
[-0.0085, 0.0151, -0.0105, ..., 0.0156, 0.0036, -0.0009]],
grad_fn=<SliceBackward0>)
Layer: fc1.bias | Size: torch.Size([128]) | Values : tensor([ 0.0078, -0.0027], grad_fn=<SliceBackward0>)
Layer: fc2.weight | Size: torch.Size([10, 128]) | Values : tensor([[-0.0851, 0.0683, 0.0769, -0.0242, -0.0485, -0.0455, 0.0060, -0.0253,
-0.0572, -0.0365, 0.0849, 0.0399, 0.0157, 0.0204, 0.0319, -0.0372,
-0.0494, 0.0634, 0.0423, -0.0338, 0.0369, 0.0409, 0.0178, 0.0684,
0.0281, 0.0873, 0.0663, -0.0873, 0.0347, 0.0824, -0.0862, 0.0227,
0.0617, -0.0119, 0.0280, -0.0161, -0.0133, 0.0130, 0.0692, 0.0263,
0.0263, -0.0480, 0.0850, -0.0179, -0.0554, 0.0884, -0.0409, 0.0543,
-0.0825, -0.0377, -0.0680, -0.0828, 0.0304, 0.0386, -0.0743, -0.0141,
-0.0210, 0.0412, -0.0695, -0.0612, 0.0089, 0.0348, -0.0394, -0.0589,
-0.0567, 0.0732, -0.0868, 0.0110, -0.0298, 0.0296, -0.0836, -0.0622,
0.0703, -0.0871, 0.0445, -0.0328, 0.0007, -0.0167, -0.0450, 0.0015,
0.0158, -0.0162, 0.0810, -0.0437, -0.0159, -0.0166, -0.0782, -0.0789,
0.0116, 0.0774, 0.0143, 0.0677, 0.0234, 0.0194, 0.0540, -0.0581,
-0.0653, -0.0875, -0.0568, 0.0002, -0.0132, 0.0447, 0.0854, 0.0395,
0.0877, 0.0092, 0.0413, 0.0386, -0.0218, 0.0191, 0.0814, 0.0778,
0.0066, -0.0696, -0.0212, -0.0205, -0.0504, 0.0609, -0.0035, 0.0474,
-0.0036, -0.0858, 0.0570, 0.0103, 0.0613, -0.0809, -0.0502, 0.0717],
[-0.0091, -0.0816, 0.0686, 0.0110, -0.0248, 0.0754, -0.0131, 0.0510,
0.0722, 0.0730, -0.0234, -0.0703, 0.0167, -0.0108, -0.0445, -0.0461,
-0.0363, -0.0355, -0.0004, 0.0655, -0.0189, 0.0531, 0.0087, 0.0299,
0.0200, 0.0815, -0.0547, 0.0513, -0.0094, -0.0386, 0.0424, 0.0031,
-0.0328, -0.0378, -0.0621, 0.0712, 0.0810, -0.0394, -0.0790, 0.0012,
0.0828, 0.0331, 0.0110, -0.0693, 0.0290, -0.0009, 0.0421, 0.0749,
0.0463, -0.0605, -0.0233, -0.0585, 0.0719, 0.0710, -0.0057, -0.0842,
-0.0150, -0.0310, -0.0813, 0.0693, -0.0095, -0.0017, -0.0735, -0.0168,
-0.0459, -0.0039, 0.0684, 0.0805, -0.0185, -0.0492, 0.0621, -0.0356,
-0.0129, 0.0469, 0.0093, -0.0339, -0.0582, 0.0289, 0.0318, -0.0200,
0.0064, -0.0593, 0.0564, -0.0241, -0.0087, -0.0299, -0.0273, -0.0353,
0.0287, -0.0618, 0.0057, -0.0189, -0.0270, 0.0270, -0.0456, 0.0602,
-0.0198, 0.0471, -0.0039, 0.0838, -0.0289, -0.0536, -0.0015, -0.0819,
0.0193, 0.0430, 0.0797, 0.0279, 0.0719, 0.0276, -0.0168, 0.0597,
-0.0049, -0.0140, -0.0434, 0.0210, -0.0388, -0.0803, -0.0560, -0.0640,
-0.0567, -0.0504, -0.0409, -0.0306, 0.0519, 0.0862, -0.0011, 0.0158]],
grad_fn=<SliceBackward0>)
Layer: fc2.bias | Size: torch.Size([10]) | Values : tensor([-0.0226, 0.0007], grad_fn=<SliceBackward0>)
๋ ์์ธํ ๋ด์ฉ์ ๋ณด๊ณ ์ถ์ผ์๋ฉด ์๋ ๋งํฌ์ ๋ค์ด๊ฐ์ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์!
- torch.nn API ๊ด๋ จ ๊ณต์๋ฌธ์
๋ฐ์ํ
'๐ฅ PyTorch' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[PyTorch] ๋ชจ๋ธ ๋งค๊ฐ๋ณ์ ์ต์ ํ(Optimization) ํ๊ธฐ (0) | 2024.07.30 |
---|---|
[PyTorch] Torch.Autograd๋ฅผ ์ด์ฉํ ์๋ ๋ฏธ๋ถ (0) | 2024.07.30 |
[PyTorch] Transform (๋ณํ) (0) | 2024.07.26 |
[PyTorch] Dataset & DataLoader with CIFAR-10 (0) | 2024.07.26 |
[PyTorch] PyTorch Intro & Tensor (ํ ์) (0) | 2024.07.26 |