Deeplearning - chap 11-2

심준보·2023년 6월 17일
0
post-thumbnail

단어를 시퀀스로 처리하기 : 시퀀스 모델 방식

  • 데이터 준비
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)
  • max_length는 텍스트 시퀀스의 최대 길이를 나타내며, max_tokens는 고려할 최대 토큰 개수를 나타냅니다

< TextVectorization 레이어 생성 >

text_vectorization = layers.TextVectorization(
    max_tokens=max_tokens,
    output_mode="int",
    output_sequence_length=max_length,
)
  • 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)
  • text_vectorization.adapt(text_only_train_ds)
    : 비교할 수 있는 대상을 만들어 놓는 개념 - adapt 사용으로 인해
int_train_ds = train_ds.map(
    lambda x, y: (text_vectorization(x), y),
    num_parallel_calls=4)
  • 위에 만들어놓은 text_vectorization에 비교를 하는 것이다. 이것이 있는지 없는지

원- 핫 인코딩된 벡터 시퀀스로 시퀀스 모델 만들기

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 레이어로, 문맥을 더 잘 이해할 수 있는 장점

  • layers.LSTM(32): 32개의 유닛을 가진 LSTM 레이어를 생성
model = keras.models.load_model("one_hot_bidir_lstm.keras")

단어 임베딩 이해하기

임베딩 층으로 단어 임베딩 학습하기

  • Embedding 층 만들기
embedding_layer = layers.Embedding(input_dim=max_tokens, output_dim=256)
  • layers.Embedding을 사용하여 임베딩 레이어를 생성

  • input_dim 매개변수는 입력 차원의 크기를 나타냅니다. 여기서는 max_tokens으로 설정되어 있으며, 이는 토큰의 총 개수를 나타냅니다.

  • output_dim 매개변수는 출력 차원의 크기를 나타냅니다. 여기서는 256으로 설정되어 있으며, 임베딩된 벡터의 차원 수를 의미

-> 위의 코드를 사용하면 입력된 텍스트 데이터를 임베딩된 벡터로 변환하는 임베딩 레이어를 생성
-> 모델의 첫 번째 레이어로 사용될 수 있으며, 텍스트 데이터의 의미와 특성을 효과적으로 캡처하여 모델의 성능을 향상

임베딩 층을 사용한 모델

  1. 사용자 생성
embedded = tf.one_hot(inputs, depth=max_tokens)
  1. 함수 사용
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 콜백이 최상의 성능을 가진 모델 가중치만 저장하도록 지정

패딩과 마스킹 이해하기

  • 마스킹을 활성화환 Embedding 층 사용하기
embedded = layers.Embedding(
    input_dim=max_tokens, output_dim=256, mask_zero=True)(inputs)
  • mask_zero=True
    -> Embedding 레이어에 패딩 토큰을 사용할 때 해당 토큰을 마스킹할지 여부를 결정
    -> 패딩 토큰은 시퀀스의 길이를 맞추기 위해 추가되는 토큰
    -> mask_zero=True로 설정하면, 입력 시퀀스의 패딩 토큰은 0으로 마스킹되어 모델이 무시하도록 만듭니다.

사전 훈련된 단어 임베딩 사용하기

  • 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,
)
  • max_tokens은 임베딩 레이어의 입력 차원을 나타냅니다. 이 값은 토큰의 총 개수
  • embedding_dim은 임베딩 레이어의 출력 차원을 나타냅니다. 이 값은 임베딩된 벡터의 차원 수를 의미
  • embeddings_initializer은 임베딩 행렬의 초기 가중치를 설정하는 방법을 지정합니다. keras.initializers.Constant(embedding_matrix)를 사용하여 사전에 생성한 embedding_matrix를 사용합니다
  • trainable=False는 임베딩 레이어의 가중치를 동결하여 훈련 중에 업데이트되지 않도록 설정합니다
  • mask_zero=True는 입력 시퀀스의 패딩 토큰을 마스킹하여 모델이 무시하도록 만듭니다.
    -> 시퀀스의 길이만큼 모자를떄 0으로 padding 해주는 것
profile
밑거름이라고생각합니다

0개의 댓글

Powered by GraphCDN, the GraphQL CDN