① 복잡한 데이터 처리 한계: 초기 신경망은 입력 데이터가 고정된 크기와 구조를 가져야만 했음
ㄴ> 이미지, 텍스트, 시계열 데이터와 같은 복잡한 데이터에 대한 처리 능력 부족
② 비선형 패턴 학습의 부족: 단순한 모델에서는 비선형 관계나 복잡한 패턴을 학습하기 어려움
ㄴ> 은닉층이 부족하거나 활성화 함수가 비효율적이면 모델의 표현력 제한
③ 과적합: 복잡한 문제를 해결하기 위해 뉴런 수를 늘리면 -> 훈련 데이터에 지나치게 적합하여 일반화 성능 감소
④ 기울기 소멸: 역전파 알고리즘에서 기울기가 작어져, 초깊은 신경망의 가중치 업데이트가 어려움
⑤ 연산량 문제: 계산량과 메모리 사용량이 매우 큼 -> 학습 속도 감소, 모델 학습 어려움
=> 이를 위해 등장한 것이 CNN, RNN, DNN
이미지 데이터의 공간적 패턴을 효율적으로 처리하기 위해 설계
순서와 시간 의존성이 중요한 데이터를 처리하기 위해 설계
기존 신경망의 표현력 부족 문제를 해결하기 위해 여러 은닉층을 쌓은 심층 구조 등장
① 작은 크기의 필터(3x3, 5x5 등)가 이미지 위를 한 칸씩 이동
② 각 필터는 이미지의 특정 패턴(ex. 수직선, 수평선)을 탐지
③ 결과로 생성된 값들이 새로운 행렬(특징 맵)을 생성
① 풀링 필터(2x2, 3x3 등)가 이미지 위를 이동하며 각 영역의 값을 축소
② 데이터 크기를 줄여 계산 효율성을 높이고 과적합을 방지
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
# 1. 데이터 전처리
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 데이터 정규화 및 차원 변경, 인코딩
x_train = x_train / 255.0
x_test = x_test / 255.0
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
# 2. 모델 정의 및 레이어 추가
# CNN 모델 정의
model = Sequential()
# 첫 번째 합성곱 레이어와 활성화 함수
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
# 최대 풀링 레이어
model.add(MaxPooling2D(pool_size=(2, 2)))
# 두 번째 합성곱 레이어와 최대 풀링 레이어
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# 평탄화 레이어 (Fully Connected 레이어에 입력하기 위해 1차원으로 변환)
model.add(Flatten())
# 완전 연결층과 출력층
model.add(Dense(128, activation='relu')) # 은닉층
model.add(Dense(10, activation='softmax')) # 출력층 (10개 클래스)
# 모델 요약
model.summary()
# 3. 모델 컴파일
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 모델 학습
history = model.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.2)
# 4. 데이터 시각화
plt.figure(figsize=(12, 4))
# 정확도 그래프
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
# 손실 그래프
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
# 5. 모델 평가
# 테스트 데이터로 성능 평가
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f'테스트 손실: {test_loss}')
print(f'테스트 정확도: {test_accuracy}')
기존 CNN을 확장한 형태, 모델의 깊이가 더 깊어진 합성곱 신경망
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.applications import VGG16, ResNet50
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
# 1. 데이터셋 준비
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# 데이터 정규화 및 레이블 인코딩
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
y_train = to_categorical(y_train, num_classes=10)
y_test = to_categorical(y_test, num_classes=10)
# 2. 사전 학습된 VGG16 모델 로드
vgg16_base = VGG16(weights='imagenet',
include_top=False,
input_shape=(32, 32, 3))
# 모델의 가중치 고정
vgg16_base.trainable = False
# 3. 새로운 모델 정의
model = models.Sequential([
vgg16_base, # 사전 학습된 VGG16 모델
layers.Flatten(), # 평탄화: 다차원 데이터를 1차원으로 변환
layers.Dense(256, activation='relu'), # Fully Connected Layer 추가, 256개의 뉴런 사용
layers.Dropout(0.5),
layers.Dense(10, activation='softmax') # CIFAR-10 클래스에 맞는 출력, 10개의 뉴런과 softmax 활성화 함수
])
# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 4. 모델 학습
history = model.fit(x_train,
y_train,
validation_data=(x_test, y_test),
epochs=5,
batch_size=32)
# 5. Fine-Tuning (세부 조정)
for layer in vgg16_base.layers[-4:]:
layer.trainable = True
# 모델 재컴파일
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5), loss='categorical_crossentropy', metrics=['accuracy'])
# Fine-Tuning 학습 진행
fine_tune_history = model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=5, batch_size=64)
# 6. 모델 평가
loss, accuracy = model.evaluate(x_test, y_test)
print(f'테스트 손실: {loss}')
print(f'테스트 정확도: {accuracy}')
# 7. 모델 시각화
plt.plot(history.history['accuracy'], label='Initial Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Initial Validation Accuracy')
plt.plot(fine_tune_history.history['accuracy'], label='Fine-Tuning Training Accuracy')
plt.plot(fine_tune_history.history['val_accuracy'], label='Fine-Tuning Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
순환 신경망, 시퀀스 데이터를 처리하고 학습하기 위해 설계된 딥러닝 모델
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import SimpleRNN, LSTM, GRU, Dense, Embedding
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 1. 샘플 텍스트 데이터
data = """나는 오늘 기분이 좋아.
나는 내일도 기분이 좋을거야.
기분이 좋은 날엔 춤을 추고 싶어."""
# 2. 토근화 및 시퀀스 변환
tokenizer = Tokenizer()
tokenizer.fit_on_texts(data.split('\n'))
sequences = tokenizer.texts_to_sequences(data.split('\n'))
# 3. 단어 인덱스 확인
word_index = tokenizer.word_index
print('단어 인덱스: ', word_index)
# 4. 시퀀스를 학습 데이터로 변환
input_sequences = []
for sequence in sequences:
for i in range(1, len(sequence)):
input_sequences.append(sequence[:i+1])
# 5. 패딩 처리
max_len = max(len(x) for x in input_sequences)
input_sequences = pad_sequences(input_sequences,
maxlen=max_len,
padding='pre')
# 6. 입력(x)과 출력(y) 분리
x = input_sequences[:, :-1]
y = input_sequences[:, -1]
# 7. 출력(y)을 원-핫 인코딩
y = to_categorical(y, num_classes=len(word_index) + 1)
# 8. RNN 모델 정의
rnn_model = Sequential([
Embedding(input_dim=len(word_index) + 1,
output_dim=10,
input_length=max_len - 1), # 임베딩 층
SimpleRNN(64, return_sequences=False), # RNN 층
Dense(len(word_index) + 1,
activation='softmax') # 출력 층
])
# 모델 컴파일 및 학습
rnn_model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
rnn_model.fit(x, y, epochs=20, verbose=1)
# 9. LSTM 모델 정의
lstm_model = Sequential([
Embedding(input_dim=len(word_index) + 1,
output_dim=10,
input_length=max_len - 1), # 임베딩 층
LSTM(64, return_sequences=False), # LSTM 층
Dense(len(word_index) + 1,
activation='softmax') # 출력 층
])
lstm_model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
lstm_model.fit(x, y, epochs=20, verbose=1)
# 10. GRU 모델 정의
gru_model = Sequential([
Embedding(input_dim=len(word_index) + 1,
output_dim=10,
input_length=max_len - 1), # 임베딩 층
GRU(64, return_sequences=False), # GRU 층
Dense(len(word_index) + 1,
activation='softmax') # 출력 층
])
gru_model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
gru_model.fit(x, y, epochs=20, verbose=1)
# 11. 텍스트 데이터 예제
def generate_text(model, tokenizer, seed_text, next_words, max_len):
for _ in range(next_words):
token_list = tokenizer.texts_to_sequences([seed_text])[0]
token_list = pad_sequences([token_list], maxlen=max_len - 1, padding='pre')
predicted = np.argmax(model.predict(token_list, verbose=0), axis=-1)
for word, index in tokenizer.word_index.items():
if index == predicted:
seed_text += " " + word
break
return seed_text
# 12. 텍스트 생성 예제
seed_text = "나는 오늘"
print("RNN 생성 결과:", generate_text(rnn_model, tokenizer, seed_text, next_words=5, max_len=max_len))
print("LSTM 생성 결과:", generate_text(lstm_model, tokenizer, seed_text, next_words=5, max_len=max_len))
print("GRU 생성 결과:", generate_text(gru_model, tokenizer, seed_text, next_words=5, max_len=max_len))