단어를 시퀀스로 처리하기 : 시퀀스 모델 방식
import os, pathlib, shutil, random
from tensorflow import keras
batch_size = 32
base_dir = pathlib.Path("aclImdb")
val_dir = base_dir / "val"
train_dir = base_dir / "train"
for category in ("neg", "pos"):
os.makedirs(val_dir / category)
files = os.listdir(train_dir / category)
random.Random(1337).shuffle(files)
num_val_samples = int(0.2 * len(files))
val_files = files[-num_val_samples:]
for fname in val_files:
shutil.move(train_dir / category / fname,
val_dir / category / fname)
train_ds = keras.utils.text_dataset_from_directory(
"aclImdb/train", batch_size=batch_size
)
val_ds = keras.utils.text_dataset_from_directory(
"aclImdb/val", batch_size=batch_size
)
test_ds = keras.utils.text_dataset_from_directory(
"aclImdb/test", batch_size=batch_size
)
text_only_train_ds = train_ds.map(lambda x, y: x)
from tensorflow.keras import layers
max_length = 600
max_tokens = 20000
text_vectorization = layers.TextVectorization(
max_tokens=max_tokens,
output_mode="int",
output_sequence_length=max_length,
)
text_vectorization.adapt(text_only_train_ds)
int_train_ds = train_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
int_val_ds = val_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
int_test_ds = test_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
< TextVectorization 레이어 생성 >
text_vectorization = layers.TextVectorization(
max_tokens=max_tokens,
output_mode="int",
output_sequence_length=max_length,
)
text_vectorization.adapt(text_only_train_ds)
int_train_ds = train_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
int_val_ds = val_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
int_test_ds = test_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
int_train_ds = train_ds.map(
lambda x, y: (text_vectorization(x), y),
num_parallel_calls=4)
원- 핫 인코딩된 벡터 시퀀스로 시퀀스 모델 만들기
inputs = keras.Input(shape=(None,), dtype="int64")
-> 입력의 형태는 (None,)으로 지정되어 있으며, None은 가변 길이 시퀀스를 나타냅니다. dtype은 입력의 데이터 타입을 int64로 설정합니다.
embedded = tf.one_hot(inputs, depth=max_tokens)
-> tf.one_hot 함수를 사용하여 입력 데이터를 원-핫 인코딩으로 변환합니다.
-> 원 핫 인코딩된 텐서로 변환
x = layers.Bidirectional(layers.LSTM(32))(embedded)
-> layers.Bidirectional을 사용하여 양방향 LSTM 레이어를 생성
-> 양방향 LSTM은 입력 시퀀스를 양쪽 방향으로 처리하는 LSTM 레이어로, 문맥을 더 잘 이해할 수 있는 장점
model = keras.models.load_model("one_hot_bidir_lstm.keras")
단어 임베딩 이해하기
임베딩 층으로 단어 임베딩 학습하기
embedding_layer = layers.Embedding(input_dim=max_tokens, output_dim=256)
layers.Embedding을 사용하여 임베딩 레이어를 생성
input_dim 매개변수는 입력 차원의 크기를 나타냅니다. 여기서는 max_tokens으로 설정되어 있으며, 이는 토큰의 총 개수를 나타냅니다.
output_dim 매개변수는 출력 차원의 크기를 나타냅니다. 여기서는 256으로 설정되어 있으며, 임베딩된 벡터의 차원 수를 의미
-> 위의 코드를 사용하면 입력된 텍스트 데이터를 임베딩된 벡터로 변환하는 임베딩 레이어를 생성
-> 모델의 첫 번째 레이어로 사용될 수 있으며, 텍스트 데이터의 의미와 특성을 효과적으로 캡처하여 모델의 성능을 향상
임베딩 층을 사용한 모델
embedded = tf.one_hot(inputs, depth=max_tokens)
embedded = layers.Embedding(input_dim=max_tokens, output_dim=256)(inputs)
callbacks
callbacks = [
keras.callbacks.ModelCheckpoint("embeddings_bidir_lstm.keras",
save_best_only=True)
]
keras.callbacks.ModelCheckpoint :모델을 훈련하는 동안 가장 성능이 좋은 모델을 저장하는 콜백
save_best_only=True : ModelCheckpoint 콜백이 최상의 성능을 가진 모델 가중치만 저장하도록 지정
패딩과 마스킹 이해하기
embedded = layers.Embedding(
input_dim=max_tokens, output_dim=256, mask_zero=True)(inputs)
사전 훈련된 단어 임베딩 사용하기
- GloVe 단어 임베딩 파일 파싱하기
import numpy as np
path_to_glove_file = "glove.6B.100d.txt"
embeddings_index = {}
with open(path_to_glove_file) as f:
for line in f:
word, coefs = line.split(maxsplit=1)
coefs = np.fromstring(coefs, "f", sep=" ")
embeddings_index[word] = coefs
embeddings_index는 단어와 해당 단어의 임베딩 벡터를 저장하기 위한 딕셔너리
open(path_to_glove_file)를 사용하여 GloVe 임베딩 파일을 엽니다.
for line in f:를 사용하여 파일의 각 줄을 반복
line.split(maxsplit=1)은 줄을 단어와 임베딩 벡터로 분할합니다. maxsplit=1은 한 번만 분할하도록 지정합니다. 첫 번째 요소는 단어이고, 두 번째 요소는 임베딩 벡터
np.fromstring(coefs, "f", sep=" ")는 임베딩 벡터를 부동소수점 배열로 변환합니다. coefs는 문자열로된 임베딩 벡터이고, "f"는 데이터 유형을 의미합니다. sep=" "는 공백을 구분자로 사용하여 각 요소를 분할
embeddings_index[word] = coefs는 단어를 키로, 임베딩 벡터를 값으로 하는 embeddings_index 딕셔너리에 저장
- GloVe 단어 임베딩 행렬 준비하기
embedding_dim = 100
vocabulary = text_vectorization.get_vocabulary()
word_index = dict(zip(vocabulary, range(len(vocabulary))))
embedding_matrix = np.zeros((max_tokens, embedding_dim))
for word, i in word_index.items():
if i < max_tokens:
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
embedding_matrix[i] = embedding_vector
vocabulary는 text_vectorization 객체의 get_vocabulary() 메서드를 사용하여 텍스트 데이터의 어휘를 가져옵니다
word_index는 어휘의 각 단어를 인덱스에 매핑하는 딕셔너리입니다. zip(vocabulary, range(len(vocabulary)))를 사용하여 단어와 해당 인덱스를 연결합니다.
embedding_matrix는 모든 토큰에 대한 임베딩 벡터를 저장하기 위한 영행렬입니다
embedding_vector = embeddings_index.get(word)를 사용하여 embeddings_index 딕셔너리에서 해당 단어의 임베딩 벡터를 가져옵니다.
if embedding_vector is not None:를 사용하여 임베딩 벡터가 존재하는지 확인합니다.
embedding_matrix[i] = embedding_vector를 사용하여 embedding_matrix의 i번째 행에 임베딩 벡터를 할당
-> 위의 코드를 사용하면 사전 훈련된 임베딩 벡터를 기반으로 단어 임베딩 행렬을 생성할 수 있습니다.
-> 이를 통해 모델의 임베딩 레이어에 초기 가중치로 사용하거나, 텍스트 데이터의 단어를 임베딩 벡터로 매핑하는 데 사용
embedding_layer = layers.Embedding(
max_tokens,
embedding_dim,
embeddings_initializer=keras.initializers.Constant(embedding_matrix),
trainable=False, #trainable - > 가중치가 학습과정에서 업데이트 되지 않습니다.
mask_zero=True,
)