import torch
import torchvision
import matplotlib.pyplot as plt08wk-1: (합성곱신경망) – MNIST, CIFAR10, XAI란?
1. 강의영상
2. Imports
plt.rcParams['figure.figsize'] = (4.5, 3.0)# CNN
# net = 2d --> 1d
# 1d: (linr -> relu)
# 2d: (conv -> relu -> mp) 3. MNIST
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, download=True,transform=torchvision.transforms.ToTensor())
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, download=True,transform=torchvision.transforms.ToTensor())
X,y = next(iter(torch.utils.data.DataLoader(train_dataset,batch_size=6000,shuffle=True)))
XX,yy = next(iter(torch.utils.data.DataLoader(train_dataset,batch_size=1000,shuffle=True)))100.0%
100.0%
100.0%
100.0%
net = torch.nn.Sequential(
torch.nn.Conv2d(1,32,kernel_size=5),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Conv2d(32,32,kernel_size=3),
torch.nn.ReLU(),
torch.nn.Flatten(),
#---#
torch.nn.Linear(3200,10)
)
loss_fn = torch.nn.CrossEntropyLoss()
optimizr = torch.optim.Adam(net.parameters())
#---#
net.to("cuda:0")
X = X.to("cuda:0")
y = y.to("cuda:0")
XX = XX.to("cuda:0")
yy = yy.to("cuda:0")
#---#
for epoc in range(100):
#1
netout = net(X)
#2
loss = loss_fn(netout,y)
#3
loss.backward()
#4
optimizr.step()
optimizr.zero_grad()(net(X).argmax(axis=1) == y).float().mean()tensor(0.9733, device='cuda:0')
(net(XX).argmax(axis=1) == yy).float().mean()tensor(0.9540, device='cuda:0')
torch.cuda.empty_cache()4. CIFAR10
train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True,transform=torchvision.transforms.ToTensor())
test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True,transform=torchvision.transforms.ToTensor())
X,y = next(iter(torch.utils.data.DataLoader(train_dataset,batch_size=10000,shuffle=True)))
XX,yy = next(iter(torch.utils.data.DataLoader(train_dataset,batch_size=2000,shuffle=True)))100.0%
A. 직접설계
net = torch.nn.Sequential(
torch.nn.Conv2d(3,32,kernel_size=5),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2),
torch.nn.Conv2d(32,32,kernel_size=3),
torch.nn.ReLU(),
torch.nn.Flatten(),
#---#
torch.nn.Linear(4608,10)
)
loss_fn = torch.nn.CrossEntropyLoss()
optimizr = torch.optim.Adam(net.parameters())
#---#
net.to("cuda:0")
X = X.to("cuda:0")
y = y.to("cuda:0")
XX = XX.to("cuda:0")
yy = yy.to("cuda:0")
#---#
for epoc in range(500):
#1
netout = net(X)
#2
loss = loss_fn(netout,y)
#3
loss.backward()
#4
optimizr.step()
optimizr.zero_grad()(net(X).argmax(axis=1) == y).float().mean()tensor(0.7344, device='cuda:0')
(net(XX).argmax(axis=1) == yy).float().mean()tensor(0.6080, device='cuda:0')
- 표현력자체에 문제가 있어보임
torch.cuda.empty_cache()B. 알렉스넷?
![]()
img = torch.zeros(1,3*224*224).reshape(1,3,224,224)
img.shapetorch.Size([1, 3, 224, 224])
net = torch.nn.Sequential(
torch.nn.Conv2d(3,96,kernel_size=(11,11),stride=4),
torch.nn.ReLU(),
torch.nn.MaxPool2d((3,3),stride=2), # default stride는 3
torch.nn.Conv2d(96,256,kernel_size=(5,5),padding=2),
torch.nn.ReLU(),
torch.nn.MaxPool2d((3,3),stride=2), # default stride는 3
torch.nn.Conv2d(256,384,kernel_size=(3,3),padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(384,384,kernel_size=(3,3),padding=1),
torch.nn.ReLU(),
torch.nn.Conv2d(384,256,kernel_size=(3,3),padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d((3,3),stride=2),
torch.nn.Flatten(),
torch.nn.Linear(6400,4096),
torch.nn.ReLU(),
torch.nn.Dropout(0.5),
torch.nn.Linear(4096,4096),
torch.nn.ReLU(),
torch.nn.Dropout(0.5),
torch.nn.Linear(4096,1000),
)C. 알렉스넷으로 ImageNet 적합
net[-1] = torch.nn.Linear(4096,10)img = torch.randn(1,3,32,32)net(img)--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) Cell In[18], line 1 ----> 1 net(img) File ~/anaconda3/envs/dl2025/lib/python3.9/site-packages/torch/nn/modules/module.py:1739, in Module._wrapped_call_impl(self, *args, **kwargs) 1737 return self._compiled_call_impl(*args, **kwargs) # type: ignore[misc] 1738 else: -> 1739 return self._call_impl(*args, **kwargs) File ~/anaconda3/envs/dl2025/lib/python3.9/site-packages/torch/nn/modules/module.py:1750, in Module._call_impl(self, *args, **kwargs) 1745 # If we don't have any hooks, we want to skip the rest of the logic in 1746 # this function, and just call forward. 1747 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks 1748 or _global_backward_pre_hooks or _global_backward_hooks 1749 or _global_forward_hooks or _global_forward_pre_hooks): -> 1750 return forward_call(*args, **kwargs) 1752 result = None 1753 called_always_called_hooks = set() File ~/anaconda3/envs/dl2025/lib/python3.9/site-packages/torch/nn/modules/container.py:250, in Sequential.forward(self, input) 248 def forward(self, input): 249 for module in self: --> 250 input = module(input) 251 return input File ~/anaconda3/envs/dl2025/lib/python3.9/site-packages/torch/nn/modules/module.py:1739, in Module._wrapped_call_impl(self, *args, **kwargs) 1737 return self._compiled_call_impl(*args, **kwargs) # type: ignore[misc] 1738 else: -> 1739 return self._call_impl(*args, **kwargs) File ~/anaconda3/envs/dl2025/lib/python3.9/site-packages/torch/nn/modules/module.py:1750, in Module._call_impl(self, *args, **kwargs) 1745 # If we don't have any hooks, we want to skip the rest of the logic in 1746 # this function, and just call forward. 1747 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks 1748 or _global_backward_pre_hooks or _global_backward_hooks 1749 or _global_forward_hooks or _global_forward_pre_hooks): -> 1750 return forward_call(*args, **kwargs) 1752 result = None 1753 called_always_called_hooks = set() File ~/anaconda3/envs/dl2025/lib/python3.9/site-packages/torch/nn/modules/pooling.py:213, in MaxPool2d.forward(self, input) 212 def forward(self, input: Tensor): --> 213 return F.max_pool2d( 214 input, 215 self.kernel_size, 216 self.stride, 217 self.padding, 218 self.dilation, 219 ceil_mode=self.ceil_mode, 220 return_indices=self.return_indices, 221 ) File ~/anaconda3/envs/dl2025/lib/python3.9/site-packages/torch/_jit_internal.py:624, in boolean_dispatch.<locals>.fn(*args, **kwargs) 622 return if_true(*args, **kwargs) 623 else: --> 624 return if_false(*args, **kwargs) File ~/anaconda3/envs/dl2025/lib/python3.9/site-packages/torch/nn/functional.py:830, in _max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode, return_indices) 828 if stride is None: 829 stride = torch.jit.annotate(List[int], []) --> 830 return torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode) RuntimeError: Given input size: (256x2x2). Calculated output size: (256x0x0). Output size is too small
net[:5](img).shapetorch.Size([1, 256, 2, 2])
net[5]MaxPool2d(kernel_size=(3, 3), stride=2, padding=0, dilation=1, ceil_mode=False)
실패 ㅠㅠ
D. renset18
- res: https://arxiv.org/pdf/1512.03385
net = torchvision.models.resnet18()
# net net.fc = torch.nn.Linear(512,10)loss_fn = torch.nn.CrossEntropyLoss()
optimizr = torch.optim.Adam(net.parameters())
#---#
net.to("cuda:0")
X = X.to("cuda:0")
y = y.to("cuda:0")
XX = XX.to("cuda:0")
yy = yy.to("cuda:0")
#---#
for epoc in range(500):
#1
netout = net(X)
#2
loss = loss_fn(netout,y)
#3
loss.backward()
#4
optimizr.step()
optimizr.zero_grad()net.eval()
print((net(X).argmax(axis=1) == y).float().mean())
print((net(XX).argmax(axis=1) == yy).float().mean())tensor(1., device='cuda:0')
tensor(0.5930, device='cuda:0')
- 오버피팅이 있어보긴하지만 표현력자체는 올라감
torch.cuda.empty_cache()E. resnet18, pretrained=True
- 아이디어: 하나를 잘하는 모델은 다른것도 잘하지 않을까? <– transfer learning
net = torchvision.models.resnet18(pretrained=True) # 아키텍처 + 학습된 가중치까지
net.fc = torch.nn.Linear(512,10)/home/cgb3/anaconda3/envs/dl2025/lib/python3.9/site-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.
warnings.warn(
/home/cgb3/anaconda3/envs/dl2025/lib/python3.9/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet18_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet18_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
loss_fn = torch.nn.CrossEntropyLoss()
optimizr = torch.optim.Adam(net.parameters())
#---#
net.to("cuda:0")
X = X.to("cuda:0")
y = y.to("cuda:0")
XX = XX.to("cuda:0")
yy = yy.to("cuda:0")
#---#
for epoc in range(500):
#1
netout = net(X)
#2
loss = loss_fn(netout,y)
#3
loss.backward()
#4
optimizr.step()
optimizr.zero_grad()net.eval()
print((net(X).argmax(axis=1) == y).float().mean())
print((net(XX).argmax(axis=1) == yy).float().mean())tensor(1., device='cuda:0')
tensor(0.8050, device='cuda:0')
- 잘함 (오버피팅은 여전히 있음)
torch.cuda.empty_cache()