딥러닝 파이토치 강좌, 횟수 예측 기반 임베딩

이 글에서는 딥러닝의 한 분야인 임베딩(Embedding)에 관하여 알아보고, 특히 횟수 기반과 예측 기반 임베딩 기법에 대해 자세히 설명합니다. 또한, 파이토치(PyTorch) 라이브러리를 활용하여 이를 구현하는 예제 코드를 제공하겠습니다.

1. 임베딩이란?

임베딩은 고차원 데이터를 저차원으로 변환하여 의미를 보존하는 방법을 의미합니다. 특히 자연어 처리(NLP)와 추천 시스템에서 많이 사용됩니다. 예를 들어, 단어를 벡터로 표현하여 단어 간의 의미 유사성을 계산할 때 임베딩 기법을 사용합니다. 임베딩은 다양한 형태로 존재할 수 있으며, 여기에서는 두 가지 주요 방식인 횟수 기반 임베딩과 예측 기반 임베딩에 대해 설명합니다.

2. 횟수 기반 임베딩

횟수 기반 임베딩은 특정 데이터의 발생 빈도 수를 기반으로 임베딩을 수행하는 방식입니다. 가장 대표적인 예로는 TF-IDF(vectorization), Bag of Words(BOW) 등이 있습니다. 이러한 방법들은 단어의 출현 빈도를 기반으로 하여 문서의 특징을 파악합니다.

2.1. TF-IDF 설명

TF-IDF(Term Frequency-Inverse Document Frequency)는 단어의 중요성을 평가하기 위한 통계적 수치입니다. TF는 특정 단어가 문서 내에서 얼마나 자주 나타나는지를 나타내며, IDF는 대량의 문서 내에서 특정 단어가 얼마나 드물게 나타나는지를 나타냅니다.

2.2. 파이토치로 TF-IDF 구현하기

아래는 파이토치를 사용하여 간단한 TF-IDF 계산 예제입니다.


import torch
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np

# 샘플 텍스트 데이터
documents = [
    "이것은 첫 번째 문서입니다.",
    "이 문서는 두 번째 문서입니다.",
    "그리고 이 문서는 세 번째 문서입니다.",
    "문서는 여기서 끝납니다."
]

# TF-IDF 벡터화
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(documents)
tfidf_array = tfidf_matrix.toarray()

# 결과 출력
print("단어 목록:", vectorizer.get_feature_names_out())
print("TF-IDF 행렬:\n", tfidf_array)
        

위 코드는 TF-IDF 벡터화를 통해 각 문서에서의 단어 출현 빈도를 계산합니다. 결과적으로 단어 목록과 각 문서에 대한 TF-IDF 행렬을 출력합니다.

3. 예측 기반 임베딩

예측 기반 임베딩은 딥러닝 모델을 통해 단어 또는 아이템의 임베딩을 학습하는 방법입니다. Word2Vec, GloVe 등의 기법이 대표적입니다. 이 방법은 주변 단어를 기반으로 특정 단어의 임베딩을 학습하는 방식이며, 이 결과로 얻어진 임베딩은 의미적으로 유사한 단어 간의 거리도 가까워지는 특성을 가집니다.

3.1. Word2Vec 설명

Word2Vec은 단어를 벡터 공간에 매핑하는 대표적인 예측 기반 임베딩 기법으로, Continuous Bag of Words (CBOW)와 Skip-Gram 두 가지 모델을 제공합니다. CBOW 모델은 주어진 단어의 주변 단어들로부터 그 단어를 예측하는 방식을 사용하고, Skip-Gram 모델은 주어진 단어로부터 주변 단어들을 예측하는 방식입니다.

3.2. PyTorch로 Word2Vec 구현하기

아래는 PyTorch를 사용하여 Skip-Gram 모델을 구현하는 예제입니다.


import torch
import torch.nn as nn
import torch.optim as optim
from collections import Counter

# 샘플 데이터를 실행할 함수 정의
def prepare_data(documents):
    words = [word for doc in documents for word in doc.split()]
    word_counts = Counter(words)
    vocabulary_size = len(word_counts)
    word2idx = {words: i for i, words in enumerate(word_counts.keys())}
    idx2word = {i: words for words, i in word2idx.items()}
    return word2idx, idx2word, vocabulary_size

# Skip-Gram 모델 정의
class SkipGramModel(nn.Module):
    def __init__(self, vocab_size, embed_size):
        super(SkipGramModel, self).__init__()
        self.embedding = nn.Embedding(vocab_size, embed_size)

    def forward(self, center_word):
        return self.embedding(center_word)

# 설정 및 데이터 준비
documents = [
    "이것은 첫 번째 문서입니다",
    "이 문서는 두 번째 문서입니다",
    "그리고 이 문서는 세 번째 문서입니다"
]
word2idx, idx2word, vocab_size = prepare_data(documents)

# 모델 설정 및 훈련
embed_size = 10
model = SkipGramModel(vocab_size, embed_size)
loss_function = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 예제 입력
input_word = torch.tensor([word2idx['이것은']])
target_word = torch.tensor([word2idx['첫 번째']])

# 훈련 프로세스 (1 epochs 예시)
for epoch in range(1):
    model.zero_grad()
    # 예측
    predictions = model(input_word)
    # 손실 계산
    loss = loss_function(predictions.view(1, -1), target_word)
    loss.backward()
    optimizer.step()
    
# 결과 출력
print("단어 '이것은'의 임베딩 벡터:\n", model.embedding.weight[word2idx['이것은']].detach().numpy())
        

위 코드는 PyTorch를 사용하여 Skip-Gram 모델을 간단히 구현한 것입니다. 각 단어 엠베딩을 학습하고, 특정 단어의 임베딩 벡터를 출력합니다.

4. 결론

이번 글에서는 임베딩의 개념과 함께 횟수 기반 및 예측 기반 임베딩 기법에 대해 알아보았습니다. TF-IDF와 같은 횟수 기반 방식은 데이터의 발생 빈도를 바탕으로 한 것이고, Word2Vec과 같은 예측 기반 방식은 딥러닝 모델을 통해 단어의 의미를 학습하는 방식입니다. 각 임베딩 기법의 특성을 이해하고, 실제 예제를 통해 이를 적용하는 과정을 배웠습니다.

딥러닝에서는 데이터의 특성을 이해하고 이를 기반으로 한 임베딩 기법의 선택이 매우 중요한데, 이를 통해 모델의 성능을 크게 향상시킬 수 있습니다. 다음 내용에서는 이들 기법을 확장하여 더 복잡한 모델을 구현해 나가는 방법을 다룰 예정이니 많은 관심 부탁드립니다.

이 글을 읽어주셔서 감사합니다!

딥러닝 파이토치 강좌, 합성곱층의 필요성

딥러닝은 머신러닝의 한 분야로, 여러 층의 뉴런을 통해 데이터에서 패턴을 학습합니다. 다양한 딥러닝 모델이 존재하지만, 그 중에서도 합성곱 신경망(Convolutional Neural Networks, CNN)은 주로 이미지 처리에 적합한 아키텍처입니다. 본 강좌에서는 합성곱층의 필요성과 작동 원리를 이해하고, 이를 파이토치(PyTorch)를 사용하여 구현해보겠습니다.

1. 합성곱층의 개념

합성곱층은 이미지의 특징을 추출하기 위해 설계된 층으로, 일반적인 전결합층(Fully Connected Layer)과는 다른 방식으로 작동합니다. 합성곱층은 입력 이미지에 대해 커널(kernel) 또는 필터(filter)라 불리는 매개변수를 사용하여, 이미지의 지역적인 특징을 학습합니다. 이 과정에서는 지역적인 영역을 분석하여 필터와의 합성곱(convolution)을 수행합니다.

1.1. 합성곱 연산

합성곱 연산은 입력 이미지에 대해 커널을 슬라이딩하여 지역적인 피쳐를 추출하는 과정입니다. 구체적으로, 커널이 이미지의 특정 영역에 위치할 때, 해당 영역의 픽셀 값과 커널의 값들을 곱하고, 그 결과를 모두 더하여 새로운 Pixel Value를 생성합니다.

1.2. 풀링 레이어(Pooling Layer)

합성곱 연산 후, 풀링 레이어를 사용하여 차원을 축소하고 계산량을 줄이며, 노이즈에 강한 특징을 유지할 수 있게 됩니다. 일반적으로 최대 풀링(Max Pooling)이나 평균 풀링(Average Pooling)을 사용합니다. 풀링은 이미지의 특정 특징을 강조하고, 위치 불변성을 더욱 강화합니다.

2. 합성곱층의 필요성

2.1. 파라미터 수 감소

전결합층은 모든 입력 노드가 모든 출력 노드와 연결되므로, 매개변수의 수가 급격히 증가합니다. 반면, 합성곱층은 커널의 크기(예: 3×3)만큼의 매개변수만 필요하므로, 전결합층에 비해 훨씬 적은 수의 파라미터로도 효과적으로 특징을 추출할 수 있습니다.

2.2. 지역적인 특징 추출

이미지는 주로 지역적인 정보를 지니고 있습니다. 예를 들어, 이미지의 어떤 국소 영역이 특징 객체를 포함하고 있을 경우, 해당 영역의 특징을 잘 추출하는 것이 중요합니다. 합성곱층은 이러한 지역적인 패턴을 잘 학습하여 정확한 예측을 가능하게 합니다.

2.3. 위치 불변성

합성곱층과 풀링층을 통해 학습된 특징들은 이미지 내에서의 위치에 독립적입니다. 즉, 이미지의 객체가 어디에 위치하더라도 해당 특징을 잘 인식할 수 있게 됩니다. 이는 이미지 분류와 같은 작업에서 큰 장점이 됩니다.

2.4. 다양한 응용 분야

합성곱층은 이미지 분류, 객체 탐지, 이미지 생성, 심지어 자연어 처리와 같은 다양한 분야에 걸쳐 응용될 수 있습니다. 인공지능의 급속한 발전에도 불구하고 CNN의 기본 구조는 여전히 많은 최신 모델의 핵심 요소로 남아있습니다.

3. 파이토치에서의 합성곱층 구현

이제 파이토치를 사용하여 간단한 CNN을 구현해보겠습니다. 다음은 기본적인 합성곱층, 풀링층, 그리고 전결합층을 포함한 CNN 모델의 예입니다.

import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torch.optim as optim

# CNN 모델 정의
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, stride=1, padding=1)  # 합성곱층
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)  # 풀링층
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=1)
        self.fc1 = nn.Linear(64 * 7 * 7, 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 * 7 * 7)  # Flatten
        x = F.relu(self.fc1(x))  # 첫 번째 전결합층
        x = self.fc2(x)  # 출력층
        return x

# 데이터셋 불러오기 및 전처리
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))  # 정규화
])
trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)

# 모델, 손실 함수, 최적화 알고리즘 정의
model = SimpleCNN()
criterion = nn.CrossEntropyLoss()  # 손실 함수
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 최적화 알고리즘

# 훈련 루프
for epoch in range(10):  # 10 epochs
    for inputs, labels in trainloader:
        optimizer.zero_grad()  # Gradient 초기화
        outputs = model(inputs)  # Forward pass
        loss = criterion(outputs, labels)  # 손실 계산
        loss.backward()  # Backward pass
        optimizer.step()  # Weight 업데이트

    print(f'Epoch [{epoch+1}/10], Loss: {loss.item():.4f}')

print('훈련 완료!')

3.1. 코드 설명

위 코드에서는 SimpleCNN 클래스를 정의하고, 두 개의 합성곱층과 두 개의 전결합층으로 구성된 CNN 모델을 설계했습니다. torch.nn.Conv2d를 사용하여 합성곱층을 정의하였고, torch.nn.MaxPool2d를 통해 풀링층을 설정했습니다. 훈련 과정에서는 MNIST 데이터셋을 사용하였고, 10 epoch 동안 모델을 훈련시켰습니다.

4. 결론

합성곱층은 이미지 데이터에서 중요한 특징을 효과적으로 추출하는 데 매우 중요한 역할을 합니다. 기본적인 합성곱 신경망의 구조와 동작 원리를 이해하는 것은 딥러닝 분야에서 중요합니다. 이 글을 통해 합성곱층의 필요성과 그 기능, 그리고 파이토치를 이용한 간단한 구현 예제를 살펴보았습니다. 앞으로 더 복잡한 CNN 아키텍처와 다양한 응용 분야를 탐구해 나가길 바랍니다.

5. 참고 자료

이 강좌에서 참고한 자료는 아래와 같습니다:

딥러닝 파이토치 강좌, 횟수 기반 임베딩

딥러닝 분야에서 임베딩(embedding)은 데이터의 품질을 높이고, 더 나은 학습 결과를 얻기 위해 매우 유용한 기법입니다. 본 강좌에서는 횟수 기반 임베딩에 대해 소개하고, PyTorch를 사용해 이를 어떻게 구현하는지에 대해 살펴보겠습니다.

1. 임베딩이란 무엇인가?

임베딩은 고차원 데이터를 저차원으로 변환하여 의미를 가진 벡터 공간을 만드는 방법입니다. 특히 자연어 처리, 추천 시스템, 이미지 처리 분야에서 널리 사용됩니다. 예를 들어, 단어를 벡터로 표현하면 단어들 간의 의미적 유사성을 계산할 수 있습니다.

2. 횟수 기반 임베딩의 개념

횟수 기반 임베딩은 주어진 데이터의 출현 빈도(count)를 기반으로 단어 또는 객체를 임베딩하는 방법입니다. 이 방법은 주로 문서에서 단어의 출현 빈도를 기반으로 단어 간의 관계를 토대로 임베딩을 생성합니다. 가장 널리 알려진 방법은 TF-IDF(용어 빈도-역 문서 빈도)와 같은 접근 방식입니다.

2.1. TF-IDF의 기본 개념

TF-IDF는 문서 내의 특정 단어의 중요도를 평가하는 방법으로, 단순히 단어의 빈도(frequency)를 비교하는 것보다 더 유용한 정보를 제공합니다. TF는 ‘용어 빈도(Term Frequency)’를 의미하고, IDF는 ‘역 문서 빈도(Inverse Document Frequency)’를 의미합니다.

2.2. TF-IDF 계산

TF-IDF는 다음과 같이 계산됩니다:


TF = (해당 단어의 문서 내 출현 횟수) / (문서 내 전체 단어 수)
IDF = log(총 문서 수 / (해당 단어가 출현한 문서 수 + 1))
TF-IDF = TF * IDF

3. PyTorch로 횟수 기반 임베딩 구현하기

이제 PyTorch를 사용하여 횟수 기반 임베딩을 구현하는 방법을 살펴보겠습니다. 예제로는 간단한 텍스트 데이터셋을 사용하여 TF-IDF 임베딩을 계산해 보겠습니다.

3.1. 필요한 라이브러리 설치


pip install torch scikit-learn numpy pandas

3.2. 데이터 준비

우선 사용할 간단한 예제 데이터를 생성하겠습니다.


import pandas as pd

# 예제 데이터 생성
data = {
    'text': [
        '사과는 맛있다',
        '바나나는 노란색이다',
        '사과와 바나나는 과일이다',
        '사과는 비타민이 많다',
        '바나나 과일은 에너지원이다'
    ]
}

df = pd.DataFrame(data)
print(df)

3.3. TF-IDF 벡터화

이제 텍스트 데이터를 TF-IDF 벡터로 변환합니다. 이를 위해 sklearnTfidfVectorizer를 사용할 것입니다.


from sklearn.feature_extraction.text import TfidfVectorizer

# TF-IDF 벡터 생성
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(df['text'])

# 결과 출력
tfidf_df = pd.DataFrame(tfidf_matrix.toarray(), columns=vectorizer.get_feature_names_out())
print(tfidf_df)

3.4. PyTorch 데이터셋 및 DataLoader 준비

PyTorch에서 데이터를 처리할 수 있도록 DatasetDataLoader를 정의하겠습니다.


import torch
from torch.utils.data import Dataset, DataLoader

class TFIDFDataset(Dataset):
    def __init__(self, tfidf_matrix):
        self.tfidf_matrix = tfidf_matrix

    def __len__(self):
        return self.tfidf_matrix.shape[0]

    def __getitem__(self, idx):
        return torch.tensor(self.tfidf_matrix[idx], dtype=torch.float32)

# 데이터셋 생성
tfidf_dataset = TFIDFDataset(tfidf_df.values)
data_loader = DataLoader(tfidf_dataset, batch_size=2, shuffle=True)

3.5. 모델 정의

이제 간단한 신경망 모델을 정의하여 횟수 기반 임베딩을 학습해 보겠습니다.


import torch.nn as nn

class SimpleNN(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 모델 초기화
input_dim = tfidf_df.shape[1]
hidden_dim = 4
output_dim = 2  # 예를 들어, 두 개의 클래스로 분류
model = SimpleNN(input_dim, hidden_dim, output_dim)

3.6. 학습 과정 설정

모델을 학습하기 위해 손실 함수와 최적화 알고리즘을 정의합니다.


criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 학습 과정
num_epochs = 100
for epoch in range(num_epochs):
    for batch in data_loader:
        optimizer.zero_grad()
        outputs = model(batch)
        labels = torch.tensor([0, 1])  # 더미 레이블
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
    
    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

4. 결론

본 강좌에서는 횟수 기반 임베딩의 개념과 이를 PyTorch로 구현하는 방법에 대해 살펴보았습니다. TF-IDF를 사용하여 단순한 텍스트 데이터셋의 임베딩을 생성하고, 간단한 신경망 모델을 정의하여 학습하는 과정을 보여드렸습니다. 이러한 임베딩 기법은 자연어 처리 및 데이터 분석에서 매우 유용하게 사용될 수 있습니다.

참고 문헌

  • V. D. P. P. M. (2023). “Deep Learning: A Comprehensive Guide”. Cambridge Press.
  • Goodfellow, I., Bengio, Y., & Courville, A. (2016). “Deep Learning”. MIT Press.

딥러닝 파이토치 강좌, 합성곱 신경망 구조

1. 서론

딥러닝은 기계학습의 한 분야로, 인공지능 연구의 주요한 영역 중 하나입니다. 그 중에서도 합성곱 신경망(Convolutional Neural Networks, CNN)은 주로 이미지 인식 및 처리에 매우 효과적인 구조입니다. 본 강좌에서는 파이토치(PyTorch)를 사용하여 CNN의 기본 구조와 동작 원리에 대해 알아보겠습니다.

2. 합성곱 신경망의 기본 개념

합성곱 신경망은 다음과 같은 주요 구성 요소로 이루어져 있습니다:

  • 합성곱 층(Convolutional Layer): 이미지와 같은 고차원 데이터를 처리하기 위한 층입니다.
  • 풀링 층(Pooling Layer): 특징 맵의 차원을 축소하여 계산량을 줄이고 불변성을 부여합니다.
  • 완전 연결 층(Fully Connected Layer): 네트워크의 마지막 단계에서 클래스를 분류하기 위한 층입니다.

3. 합성곱 신경망 구조

합성곱 신경망의 기본 구조는 다음과 같이 정리할 수 있습니다:

  1. 입력층: 원본 이미지가 입력됩니다.
  2. 합성곱층: 입력 이미지에 필터를 적용하여 특징 맵을 생성합니다.
  3. 활성화층(ReLU): 비선형성을 추가하기 위해 ReLU 활성화 함수를 사용합니다.
  4. 풀링층: 특징 맵의 크기를 줄여 계산량을 감소시킵니다.
  5. 완전 연결층: 다양한 클래스에 대한 예측을 수행합니다.

4. 파이토치로 CNN 구현하기

이제 파이토치를 사용하여 간단한 CNN을 구현해 보겠습니다. 우리는 Fashion MNIST 데이터셋을 사용하여 의류 이미지를 분류할 것입니다.

4.1. 환경 설정

필요한 라이브러리를 설치하고 가져옵니다. 아래 명령어를 사용하여 파이토치를 설치합니다:

pip install torch torchvision

4.2. 데이터셋 로딩

Fashion MNIST 데이터셋을 로드하고 전처리합니다. 다음 코드로 데이터를 다운로드하고 로드할 수 있습니다.


import torch
import torchvision.transforms as transforms
import torchvision.datasets as datasets
from torch.utils.data import DataLoader

# 데이터 전처리
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

# 트레이닝 및 테스트 데이터셋 로드
train_dataset = datasets.FashionMNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.FashionMNIST(root='./data', train=False, transform=transform)

# 데이터로더 설정
train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)
    

4.3. CNN 모델 정의

CNN 모델을 정의해 보겠습니다. 다음 코드는 합성곱층, 활성화층, 풀링층, 완전 연결층으로 구성된 간단한 CNN을 구현합니다.


import torch.nn as nn

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 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)  # 최대 풀링층
        self.fc1 = nn.Linear(64 * 7 * 7, 128)  # 첫 번째 완전 연결층
        self.fc2 = nn.Linear(128, 10)  # 두 번째 완전 연결층

    def forward(self, x):
        x = self.pool(torch.relu(self.conv1(x)))  # 첫 번째 합성곱과 풀링
        x = self.pool(torch.relu(self.conv2(x)))  # 두 번째 합성곱과 풀링
        x = x.view(-1, 64 * 7 * 7)  # 텐서를 평탄화
        x = torch.relu(self.fc1(x))  # 첫 번째 완전 연결층
        x = self.fc2(x)  # 두 번째 완전 연결층
        return x
    

4.4. 모델 훈련하기

모델을 훈련시키기 위해 손실 함수와 최적화 알고리즘을 설정합니다. 다음 코드를 사용하여 훈련을 위한 설정을 할 수 있습니다.


import torch.optim as optim

# 모델, 손실함수 및 최적화기 정의
model = CNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 모델 훈련
num_epochs = 5
for epoch in range(num_epochs):
    model.train()
    running_loss = 0.0
    for images, labels in train_loader:
        optimizer.zero_grad()  # 기울기 초기화
        outputs = model(images)  # 모델에 대한 예측
        loss = criterion(outputs, labels)  # 손실 계산
        loss.backward()  # 역전파
        optimizer.step()  # 가중치 갱신
        running_loss += loss.item()

    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}')
    

4.5. 모델 평가하기

훈련된 모델을 평가하여 테스트 데이터셋에서의 정확도를 확인합니다. 아래 코드를 사용하여 평가를 수행할 수 있습니다.


model.eval()
correct = 0
total = 0
with torch.no_grad():
    for images, labels in test_loader:
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy of the model on the test images: {100 * correct / total:.2f}%')
    

5. 결론

본 강좌에서는 딥러닝의 핵심 구성 요소인 합성곱 신경망(CNN)의 기본 구조와 파이토치를 활용한 실전 구현 방법에 대해 알아보았습니다. CNN을 통해 이미지 데이터의 특징을 효율적으로 구별하고 분류하는 방법을 이해하셨기를 바랍니다. 딥러닝의 세계는 무궁무진하며, 앞으로 많은 응용 분야에서 활용되고 있습니다. 지속적인 학습과 실습을 통해 실력 향상에 힘쓰시길 바랍니다.

6. 참고 문헌

– Ian Goodfellow, Yoshua Bengio, Aaron Courville, Deep Learning, MIT Press, 2016
– PyTorch Documentation: https://pytorch.org/docs/stable/index.html

딥러닝 파이토치 강좌, 합성곱 신경망 맛보기

딥러닝은 최근 몇 년 동안 인공지능 및 머신러닝 분야에서 우세한 방법론으로 자리 잡았습니다. 오늘은 그 중에서도 합성곱 신경망(Convolutional Neural Network, CNN)에 대해 살펴보겠습니다. CNN은 이미지 인식 및 처리에 특히 효과적이며, 여러 산업에서 광범위하게 사용됩니다.

합성곱 신경망이란?

합성곱 신경망은 바로 사진이나 비디오 같은 주어진 데이터의 시각적 패턴을 인식하는 데 특화된 신경망의 일종입니다. CNN은 기본적으로 합성곱 층, 풀링 층, 완전 연결 층으로 구성됩니다.

합성곱 층(Convolutional Layer)

합성곱 층은 입력 데이터에서 특징을 추출하는 역할을 합니다. 이 층은 작은 필터(커널)를 사용하여 입력 이미지의 특정 부분과 연산을 수행하여 출력을 생성합니다. 이렇게 생성된 특성 맵(feature map)은 입력 데이터의 유용한 정보만을 담고 있습니다.

풀링 층(Pooling Layer)

풀링 층은 특성 맵의 크기를 줄이는 데 사용됩니다. 이는 모델의 복잡성을 줄이고 연산량을 감소시켜 과적합을 방지하는 데 도움을 줍니다. 가장 일반적인 방법은 최대 풀링(max pooling)으로, 이 방법은 주어진 영역에서 가장 큰 값을 선택하여 특성 맵의 크기를 줄입니다.

완전 연결 층(Fully Connected Layer)

신경망의 마지막 부분에서는 완전 연결 층이 존재합니다. 이 층은 이전 층에서 얻은 정보들을 바탕으로 최종 예측을 하게 됩니다. 모든 뉴런이 이전 층과 연결되어 있는 구조이므로, 입력 데이터에 대한 복잡한 결정을 내릴 수 있습니다.

파이토치(PyTorch)로 CNN 구현하기

이제 파이토치를 사용하여 간단한 CNN 모델을 구현해보겠습니다. MNIST 데이터셋을 사용하여 손글씨 숫자를 분류하는 모델을 만들어 보겠습니다.

사전 준비

먼저 필요한 라이브러리를 설치하고 데이터셋을 다운로드하겠습니다. 다음은 필요한 라이브러리입니다:

pip install torch torchvision

데이터셋 준비

MNIST 데이터셋을 다운로드하고 불러옵니다. 아래 코드를 사용하여 학습 및 테스트 데이터셋을 준비할 수 있습니다.


import torch
import torchvision
import torchvision.transforms as transforms

# 데이터 변환 정의
transform = transforms.Compose(
    [transforms.ToTensor(), 
     transforms.Normalize((0.5,), (0.5,))])  # 평균과 표준편차를 사용한 정규화

# 학습 데이터셋
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)

# 테스트 데이터셋
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)

모델 정의

이제 합성곱 신경망 모델을 정의해 봅시다. CNN 모델은 일반적으로 합성곱 층과 풀링 층을 조합한 구조로 설계됩니다.


import torch.nn as nn
import torch.nn.functional as F

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3)  # 입력 채널 1, 출력 채널 32
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  # 최대 풀링
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3)  # 입력 채널 32, 출력 채널 64
        self.fc1 = nn.Linear(64 * 6 * 6, 128)  # 완전 연결 층, 64x6x6은 출력 크기
        self.fc2 = nn.Linear(128, 10)  # 최종 출력 10개(0~9)

    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 * 6 * 6)  # 텐서 형태 변경
        x = F.relu(self.fc1(x))  # 첫 번째 완전 연결 층
        x = self.fc2(x)  # 두 번째 완전 연결 층
        return x

모델 학습

모델을 학습시키기 위해서는 손실 함수와 옵티마이저를 정의하고 데이터에 대해 반복적으로 학습을 진행해야 합니다.


# 모델 초기화
cnn = CNN()
criterion = nn.CrossEntropyLoss()  # 손실 함수
optimizer = torch.optim.SGD(cnn.parameters(), lr=0.01)  # 확률적 경사 하강법

# 모델 학습
for epoch in range(5):  # 에폭 수
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        optimizer.zero_grad()  # 기울기 초기화
        outputs = cnn(inputs)  # 예측
        loss = criterion(outputs, labels)  # 손실 계산
        loss.backward()  # 기울기 계산
        optimizer.step()  # 파라미터 업데이트
        running_loss += loss.item()
    print(f'Epoch {epoch + 1}, Loss: {running_loss / len(trainloader)}')

모델 평가

학습이 완료된 후, 테스트 데이터셋을 통해 모델의 성능을 평가합니다.


correct = 0
total = 0

with torch.no_grad():  # 기울기 계산 비활성화
    for data in testloader:
        images, labels = data
        outputs = cnn(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy on the test set: {100 * correct / total} %')

결론

이제 우리는 간단한 합성곱 신경망을 파이토치를 사용하여 구성하고, 실제 데이터셋을 통해 학습시키고 평가하는 과정을 경험했습니다. 이 강좌를 통해 딥러닝의 기본적인 구조와 파이썬을 활용한 실습을 이해하는 데 도움이 되셨기를 바랍니다. 앞으로 더 복잡한 모델과 다양한 데이터셋을 다루는 데에도 도전해보십시오!

참고자료