이번 주는 딥러닝 모델들에 대한 이해를 높이기 위해 CNN, RNN, LSTM 모델을 각각 분류 문제와 회귀 문제에 적용하는 예제를 실습했다.
CNN 모델은 이미지 분류에 매우 효과적이다. Conv2D 레이어를 통해 이미지에서 중요한 특징을 추출하고, MaxPooling2D 레이어를 사용하여 특징 맵의 크기를 축소한 뒤, Dense 레이어로 분류를 진행한다. 이를 통해 MNIST 데이터셋의 이미지 분류 문제를 해결하는 예제이다.
import tensorflow as tf
from tensorflow.keras import layers, models
# Conv2D 레이어 클래스 정의
class Conv2DLayer(layers.Layer):
def __init__(self, filters, kernel_size, activation='relu'):
super(Conv2DLayer, self).__init__()
self.conv = layers.Conv2D(filters, kernel_size, activation=activation)
self.pool = layers.MaxPooling2D((2, 2))
def call(self, inputs):
x = self.conv(inputs)
return self.pool(x)
# Fully Connected 레이어 클래스 정의
class FullyConnectedLayer(layers.Layer):
def __init__(self, units, activation='relu'):
super(FullyConnectedLayer, self).__init__()
self.dense = layers.Dense(units, activation=activation)
def call(self, inputs):
return self.dense(inputs)
# CNN 모델 클래스 정의
class CNNModel(models.Model):
def __init__(self):
super(CNNModel, self).__init__()
self.conv1 = Conv2DLayer(32, (3, 3))
self.conv2 = Conv2DLayer(64, (3, 3))
self.flatten = layers.Flatten()
self.fc1 = FullyConnectedLayer(64)
self.fc2 = FullyConnectedLayer(10, activation='softmax') # 10개의 클래스 분류
def call(self, inputs):
x = self.conv1(inputs)
x = self.conv2(x)
x = self.flatten(x)
x = self.fc1(x)
return self.fc2(x)
# 모델 생성
model = CNNModel()
model.build((None, 28, 28, 1)) # MNIST 이미지 크기
# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
회귀 문제에서는 출력층에서 선형 활성화 함수를 사용하여 연속적인 값을 예측하도록 설정했다. CNN 모델을 회귀 문제에 맞게 조정하여 Boston Housing 데이터셋에서 주택 가격 예측 문제를 해결하는 예제이다.
class CNNRegressor(models.Model):
def __init__(self):
super(CNNRegressor, self).__init__()
self.conv1 = Conv2DLayer(32, (3, 3))
self.conv2 = Conv2DLayer(64, (3, 3))
self.flatten = layers.Flatten()
self.fc1 = FullyConnectedLayer(64)
self.fc2 = FullyConnectedLayer(1) # 회귀 문제: 선형 활성화 함수
def call(self, inputs):
x = self.conv1(inputs)
x = self.conv2(x)
x = self.flatten(x)
x = self.fc1(x)
return self.fc2(x)
# 모델 생성
model = CNNRegressor()
model.build((None, 28, 28, 1))
# 모델 컴파일
model.compile(optimizer='adam', loss='mean_squared_error')
RNN 모델은 시퀀스 데이터에서 시간적인 의존성을 학습하는 데 강점이 있다. SimpleRNN 레이어를 사용하여 텍스트 데이터를 시퀀스별로 처리하고, Dense 레이어를 사용하여 이진 분류 문제를 해결하는 예제이다.
class RNNLayer(layers.Layer):
def __init__(self, units, activation='relu'):
super(RNNLayer, self).__init__()
self.rnn = layers.SimpleRNN(units, activation=activation)
def call(self, inputs):
return self.rnn(inputs)
class FullyConnectedLayer(layers.Layer):
def __init__(self, units, activation='relu'):
super(FullyConnectedLayer, self).__init__()
self.dense = layers.Dense(units, activation=activation)
def call(self, inputs):
return self.dense(inputs)
class RNNModel(models.Model):
def __init__(self):
super(RNNModel, self).__init__()
self.embedding = layers.Embedding(10000, 128, input_length=500)
self.rnn1 = RNNLayer(128)
self.fc1 = FullyConnectedLayer(64)
self.fc2 = FullyConnectedLayer(1, activation='sigmoid') # 이진 분류
def call(self, inputs):
x = self.embedding(inputs)
x = self.rnn1(x)
x = self.fc1(x)
return self.fc2(x)
# 모델 생성
model = RNNModel()
# 모델 컴파일
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
회귀 문제에서는 RNN을 시계열 데이터에 적용하여 연속적인 값을 예측하는 모델을 구현하는 예제이다. 출력층에서 선형 활성화 함수를 사용하여 시계열 예측 문제를 해결한다.
class RNNRegressor(models.Model):
def __init__(self):
super(RNNRegressor, self).__init__()
self.embedding = layers.Embedding(10000, 128, input_length=500)
self.rnn1 = RNNLayer(128)
self.fc1 = FullyConnectedLayer(64)
self.fc2 = FullyConnectedLayer(1) # 회귀 문제: 선형 활성화 함수
def call(self, inputs):
x = self.embedding(inputs)
x = self.rnn1(x)
x = self.fc1(x)
return self.fc2(x)
# 모델 생성
model = RNNRegressor()
# 모델 컴파일
model.compile(optimizer='adam', loss='mean_squared_error')
LSTM은 RNN의 개선된 버전으로, 장기 의존성 문제를 해결할 수 있는 모델이다. LSTM 레이어를 사용하여 텍스트 데이터의 시퀀스를 처리하고, Dense 레이어를 통해 이진 분류 문제를 해결하는 예제이다.
class LSTMLayer(layers.Layer):
def __init__(self, units, activation='relu'):
super(LSTMLayer, self).__init__()
self.lstm = layers.LSTM(units, activation=activation)
def call(self, inputs):
return self.lstm(inputs)
class FullyConnectedLayer(layers.Layer):
def __init__(self, units, activation='relu'):
super(FullyConnectedLayer, self).__init__()
self.dense = layers.Dense(units, activation=activation)
def call(self, inputs):
return self.dense(inputs)
class LSTMModel(models.Model):
def __init__(self):
super(LSTMModel, self).__init__()
self.embedding = layers.Embedding(10000, 128, input_length=500)
self.lstm1 = LSTMLayer(128)
self.fc1 = FullyConnectedLayer(64)
self.fc2 = FullyConnectedLayer(1, activation='sigmoid') # 이진 분류
def call(self, inputs):
x = self.embedding(inputs)
x = self.lstm1(x)
x = self.fc1(x)
return self.fc2(x)
# 모델 생성
model = LSTMModel()
# 모델 컴파일
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
LSTM을 사용하여 시계열 데이터를 처리하고, Dense 레이어에서 선형 활성화 함수를 사용하여 연속적인 값을 예측하는 모델을 구현하는 예제이다.
class LSTMRegressor(models.Model):
def __init__(self):
super(LSTMRegressor, self).__init__()
self.embedding = layers.Embedding(10000, 128, input_length=500)
self.lstm1 = LSTMLayer(128)
self.fc1 = FullyConnectedLayer(64)
self.fc2 = FullyConnectedLayer(1) # 회귀 문제: 선형 활성화 함수
def call(self, inputs):
x = self.embedding(inputs)
x = self.lstm1(x)
x = self.fc1(x)
return self.fc2(x)
# 모델 생성
model = LSTMRegressor()
# 모델 컴파일
model.compile(optimizer='adam', loss='mean_squared_error')
자연어 처리(NLP)에서 어휘집(Vocabulary)이란 **텍스트 데이터를 토큰화한
후, 등장한 단어(또는 서브워드, 문자 등)에 대해 인덱스를 부여한 목록을 의미한다. 이 어휘집을 생성할 때 Train Dataset을 기반으로 하는 것이 중요한 이유**는 다음과 같다.
<unk>
(unknown token)으로 처리한다.➡ 따라서, NLP 프로젝트에서 어휘집을 만들 때는 반드시 Train Dataset을 기준으로 생성해야 하며, Test Dataset을 포함해서는 안 된다.
CNN 1D(1차원 합성곱 신경망)는 자연어 처리(NLP)에서 문장을 벡터로 변환하고, 의미 있는 특징을 추출하여 분류하는 데 사용되는 모델이다. 이 모델의 주요 구조는 3가지 주요 레이어로 구성된다.
📖 역할
🛠 작동 방식
n
차원의 벡터로 변환 (예: 128차원)📖 역할
📖 역할
기능 | apply() | map() |
---|---|---|
DataFrame 전체 적용 | ✅ 가능 | ❌ 불가능 (Series만 가능) |
여러 열(column) 활용 가능 | ✅ 가능 | ❌ 불가능 |
행(row) 단위 연산 (axis=1 ) | ✅ 가능 | ❌ 불가능 |
단일 열 변환 | 가능 | 가능 |
👉 결론: reviewTitle
과 reviewDescription
을 합치는 작업은 여러 열을 활용하므로 apply()
를 사용해야 한다.