1. nn.Conv2d()
계산 효율을 위해 다양한 추가 옵션을 사용할 수 있음
2. nn.Pool2d()
이미지에서 대표값을 추출해 출력의 크기를 줄이는 연산으로,
불필요한 정보를 제거하고 계산량을 줄이는데 사용
MaxPooling : nn.MaxPool2d()
AveragePooling : nn.AvgPool2d()
3. CNN 연산 후 size 구하기
Convolution layer 통과 후 FCN을 붙여 최종 출력하는데,
이때 입력의 크기를 알아야 Linear layer를 만들 수 있음



특별한 옵션 없을 시 계산 후 내림 연산으로 출력




실습. Pytorch를 이용하여 강아지, 고양이 이미지 분류
이미지 폴더를 이용하여 데이터셋 불러오기 및 나누기
from torchvision.datasets import ImageFolder
from sklearn.model_selection import train_test_split
dataset = ImageFolder('train_test_set_small')
train_data, test_data = train_test_split(dataset.imgs, test_size=0.2, random_state=42)
2-1) Batch size만큼 RGB 데이터를 출력하는 데이터셋 클래스 만들기
class ImageLoader(Dataset):
def __init__(self, dataset):
self.dataset=dataset
def __len__(self):
return len(self.dataset)
def __getitem__(self, item):
image=cv2.imread(self.dataset[item][0])
image=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image=cv2.resize(image,(28,28))
image=image.reshape(28*28)
label=self.dataset[item][1]
return image, label
train_dataset=ImageLoader(train_data)
test_dataset=ImageLoader(test_data)
2-2) 데이터 불러오기 방식 설정
train_loader=DataLoader(train_dataset, batch_size=16, shuffle=True)
for img, label in train_loader:
break
img.shape
Pytorch에서 nn.Conv2d()/Maxpool2d() 를 사용하여 만들 수 있음
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1=nn.Conv2d(3,4)
self.pool=nn.MaxPool2d(2,2)
def forward(self,x):
x=self.pool(self.relu(self.fc1(x)))
return x

class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
# Fully connected layer
self.fc1 = nn.Linear(64 * 3 * 3, 512)
self.dropout = nn.Dropout(0.5)
self.fc2 = nn.Linear(512, 2)
def forward(self, x):
x = F.relu(self.conv1(x)) # 28x28x3 → 28x28x16
x = self.pool(x) # → 14x14x16
x = F.relu(self.conv2(x)) # → 14x14x32
x = self.pool(x) # → 7x7x32
x = F.relu(self.conv3(x)) # → 7x7x64
x = self.pool(x) # → 3x3x64
x = x.view(-1, 64 * 3 * 3) # Flatten
x = F.relu(self.fc1(x)) # → 512
x = self.dropout(x)
x = self.fc2(x) # → 2
return x
model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
num_epochs = 10
for epoch in range(num_epochs):
model.train()
total_loss = 0
for images, labels in train_loader:
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss:.4f}")