debconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76, <> line 4.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin:
Processing triggers for fontconfig (2.12.6-0ubuntu2) ...
/usr/share/fonts: caching, new cache contents: 0 fonts, 1 dirs
/usr/share/fonts/truetype: caching, new cache contents: 0 fonts, 3 dirs
/usr/share/fonts/truetype/humor-sans: caching, new cache contents: 1 fonts, 0 dirs
/usr/share/fonts/truetype/liberation: caching, new cache contents: 16 fonts, 0 dirs
/usr/share/fonts/truetype/nanum: caching, new cache contents: 31 fonts, 0 dirs
/usr/local/share/fonts: caching, new cache contents: 0 fonts, 0 dirs
/root/.local/share/fonts: skipping, no such directory
/root/.fonts: skipping, no such directory
/var/cache/fontconfig: cleaning cache directory
/root/.cache/fontconfig: not cleaning non-existent cache directory
/root/.fontconfig: not cleaning non-existent cache directory
fc-cache: succeeded
# warning 표시 끄기import warningswarnings.simplefilter('ignore')# 기본 폰트 설정plt.rcParams['font.family'] = font_name# 기본 폰트 사이즈 변경plt.rcParams['font.size'] = 14# 기본 그래프 사이즈 변경plt.rcParams['figure.figsize'] = (6,6)# 기본 그리드 표시# 필요에 따라 설정할 때는, plt.grid()plt.rcParams['axes.grid'] = Trueplt.rcParams["grid.linestyle"] = ":"# 마이너스 기호 정상 출력plt.rcParams['axes.unicode_minus'] = False# 넘파이 부동소수점 자릿수 표시np.set_printoptions(suppress=True, precision=4)
# GPU 디바이스 할당device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")print(device)
cuda:0
공통 함수 불러오기
# 공통 함수 다운로드!git clone https://github.com/wikibook/pythonlibs.git# # 공통 함수 불러오기from pythonlibs.torch_lib1 import *# # 공통 함수 확인print(README)
Common Library for PyTorch
Author: M. Akaishi
데이터 준비
# 분류 클래스명 정의classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')# 분류 클래스 수는 10n_output = len(classes)
import torch.nn as nnfrom typing import Optionalclass BasicBlock(nn.Module): expansion = 1 # Output channels are the same as input channels def __init__(self, inplanes: int, planes: int, stride: int = 1, downsample: Optional[nn.Module] = None, groups: int = 1, dilation: int = 1, norm_layer: Optional[nn.Module] = None): super().__init__() # Normalization layer (default to BatchNorm2d if not specified) if norm_layer is None: norm_layer = nn.BatchNorm2d # First convolutional layer (3x3 conv, stride is applied) self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3, stride=stride, padding=dilation, groups=groups, bias=False, dilation=dilation) self.bn1 = norm_layer(planes) # BatchNorm2d after the first convolution self.relu = nn.ReLU(inplace=True) # ReLU activation function # Second convolutional layer (3x3 conv, no stride) self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=dilation, groups=groups, bias=False, dilation=dilation) self.bn2 = norm_layer(planes) # BatchNorm2d after the second convolution # Optional downsample layer (to adjust dimensions of input and output if necessary) self.downsample = downsample self.stride = stride def forward(self, x): identity = x # Store the input for the residual connection # Apply the first convolutional layer followed by BatchNorm and ReLU out = self.conv1(x) out = self.bn1(out) out = self.relu(out) # Apply the second convolutional layer followed by BatchNorm out = self.conv2(out) out = self.bn2(out) # If downsampling is needed (i.e., the dimensions don't match), apply the downsample layer if self.downsample is not None: identity = self.downsample(x) # Add the residual (skip connection) out += identity out = self.relu(out) # Apply ReLU activation after adding the residual return out
Bottleneck
import torch.nn as nnfrom typing import Optionalclass Bottleneck(nn.Module): expansion = 4 # Output channel expansion factor def __init__(self, inplanes: int, planes: int, stride: int = 1, downsample: Optional[nn.Module] = None, groups: int = 1, base_width: int = 64, dilation: int = 1, norm_layer: Optional[nn.Module] = None): super().__init__() if norm_layer is None: norm_layer = nn.BatchNorm2d # Width for the 1x1 and 3x3 convolutions width = int(planes * (base_width / 64.)) * groups # 1x1 Convolution (Reduce dimensions) self.conv1 = nn.Conv2d(inplanes, width, kernel_size=1, stride=1, bias=False) self.bn1 = norm_layer(width) # 3x3 Convolution (Main computation) self.conv2 = nn.Conv2d(width, width, kernel_size=3, stride=stride, padding=dilation, groups=groups, dilation=dilation, bias=False) self.bn2 = norm_layer(width) # 1x1 Convolution (Expand dimensions) self.conv3 = nn.Conv2d(width, planes * self.expansion, kernel_size=1, stride=1, bias=False) self.bn3 = norm_layer(planes * self.expansion) # Downsample layer for residual connection self.downsample = downsample self.stride = stride self.relu = nn.ReLU(inplace=True) def forward(self, x): identity = x # First layer: 1x1 Convolution out = self.conv1(x) out = self.bn1(out) out = self.relu(out) # Second layer: 3x3 Convolution out = self.conv2(out) out = self.bn2(out) out = self.relu(out) # Third layer: 1x1 Convolution out = self.conv3(out) out = self.bn3(out) # Residual connection if self.downsample is not None: identity = self.downsample(x) out += identity out = self.relu(out) return out
ResNet18 from scratch
import torchimport torch.nn as nnfrom typing import Type, List, Optional# Type[nn.Module] = BasicBlock (nn.Module을 상속한 클래스)# Optional[nn.Module] = nn.Linear(...) 또는 None (nn.Module 인스턴스 또는 None)# BasicBlock for ResNet18class BasicBlock(nn.Module): expansion = 1 # Number of output channels will be same as input channels def __init__(self, inplanes: int, planes: int, stride: int = 1, downsample: Optional[nn.Module] = None, groups: int = 1, dilation: int = 1, norm_layer: Optional[nn.Module] = None): super().__init__() # Default normalization layer is BatchNorm2d if norm_layer is None: norm_layer = nn.BatchNorm2d # First Convolution Layer self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3, stride=stride, padding=dilation, groups=groups, bias=False, dilation=dilation) self.bn1 = norm_layer(planes) self.relu = nn.ReLU(inplace=True) # Second Convolution Layer self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=dilation, groups=groups, bias=False, dilation=dilation) self.bn2 = norm_layer(planes) # Downsample layer for matching dimensions self.downsample = downsample self.stride = stride def forward(self, x): identity = x # Store the input for the skip connection # Apply first convolution and batch normalization out = self.conv1(x) out = self.bn1(out) out = self.relu(out) # Apply second convolution and batch normalization out = self.conv2(out) out = self.bn2(out) # If downsampling is required, apply it to the identity if self.downsample is not None: identity = self.downsample(x) # Add the residual (skip connection) out += identity out = self.relu(out) # Final ReLU activation return out# ResNet18 Modelclass ResNet18(nn.Module): def __init__(self, block: Type[nn.Module], layers: List[int], num_classes: int = 1000, groups: int = 1, width_per_group: int = 64, norm_layer: Optional[nn.Module] = None): super().__init__() # Default normalization layer is BatchNorm2d if norm_layer is None: norm_layer = nn.BatchNorm2d self._norm_layer = norm_layer # Initialize parameters self.inplanes = 64 self.dilation = 1 self.groups = groups self.base_width = width_per_group # Initial Convolution Layer (7x7 Conv) self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3, bias=False) self.bn1 = norm_layer(self.inplanes) self.relu = nn.ReLU(inplace=True) self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) # ResNet layers (consists of blocks of BasicBlock) self.layer1 = self._make_layer(block, 64, layers[0]) self.layer2 = self._make_layer(block, 128, layers[1], stride=2) self.layer3 = self._make_layer(block, 256, layers[2], stride=2) self.layer4 = self._make_layer(block, 512, layers[3], stride=2) # Fully connected layer self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) self.fc = nn.Linear(512 * block.expansion, num_classes) # Initialize parameters for m in self.modules(): if isinstance(m, nn.Conv2d): nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)): nn.init.constant_(m.weight, 1) nn.init.constant_(m.bias, 0) def _make_layer(self, block: Type[nn.Module], planes: int, blocks: int, stride: int = 1) -> nn.Sequential: downsample = None if stride != 1 or self.inplanes != planes * block.expansion: downsample = nn.Sequential( nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, bias=False), self._norm_layer(planes * block.expansion), ) layers = [block(self.inplanes, planes, stride, downsample, groups=self.groups, dilation=self.dilation, norm_layer=self._norm_layer)] self.inplanes = planes * block.expansion for _ in range(1, blocks): layers.append(block(self.inplanes, planes, stride=1, downsample=None, groups=self.groups, dilation=self.dilation, norm_layer=self._norm_layer)) return nn.Sequential(*layers) def forward(self, x: torch.Tensor) -> torch.Tensor: # Initial layers x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.maxpool(x) # Apply ResNet layers (BasicBlock residual layers) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) # Pooling and fully connected layer x = self.avgpool(x) x = torch.flatten(x, 1) x = self.fc(x) return x# Function to instantiate the ResNet18 modeldef resnet18(num_classes: int = 1000, norm_layer: Optional[nn.Module] = None) -> ResNet18: """Constructs a ResNet-18 model.""" return ResNet18( block=BasicBlock, # Use the BasicBlock for ResNet-18 layers=[2, 2, 2, 2], # ResNet-18 has 2 blocks per stage num_classes=num_classes, norm_layer=norm_layer )# Example usagenet = resnet18(num_classes=10) # Example for 10 classes (e.g., CIFAR-10)