Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 제로베이스 데이터사이언스
- 파이썬
- 제어문
- 속성
- 딥러닝
- 파이썬코딩도장
- Set
- 후기
- 데이터사이언티스트
- 자연어처리
- TensorFlow
- 딕셔너리
- NLP
- 클래스
- 추천시스템
- 코딩도장
- 카카오
- 머신러닝
- 데이터사이언스 스쿨
- AIFFEL
- 사이킷런
- 재귀함수
- AI
- numpy
- 스크랩
- 기사
- 데이터분석
- Python
- 아이펠
- 함수
Archives
- Today
- Total
뮤트 개발일지
AIFFEL 아이펠 13일차 본문
시퀀스 데이터: 나열된 데이터, 각 요소들이 동일한 속성을 띌 필요가 없으며 어떤 기준에 따라 정렬되어 있지 않아도 된다.
https://kukuta.tistory.com/310
순환신경망 RNN
<start> 토큰으로 시작하여 생성된 단어를 다시 input하는 방식, <end>로 끝난다.
tk.keras.preprocessing.test.Tokenizer: 텐서플로우가 제공하는 모듈(패키지), 정제된 데이터를 토큰화하고, 단어 사전을 만들어주며, 데이터를 숫자로 변환해준다.
벡터화vectorize: 데이터를 숫자로 변환해주는 과정
텐서tensor: 숫자로 변환된 데이터
https://rekt77.tistory.com/102
인공지능 작사가 만들기
import glob
import os, re
import tensorflow as tf
from sklearn.model_selection import train_test_split
txt_file_path = os.getenv('HOME')+'/aiffel/lyricist/data/lyrics/*'
txt_list = glob.glob(txt_file_path)
raw_corpus = []
# 여러개의 txt 파일을 모두 읽어서 raw_corpus 에 담습니다.
for txt_file in txt_list:
with open(txt_file, "r") as f:
raw = f.read().splitlines()
raw_corpus.extend(raw)
def preprocess_sentence(sentence):
sentence = sentence.lower().strip() # 1
sentence = re.sub(r"([?.!,¿])", r" \1 ", sentence) # 2
sentence = re.sub(r'[" "]+', " ", sentence) # 3
sentence = re.sub(r"[^a-zA-Z?.!,¿]+", " ", sentence) # 4
sentence = sentence.strip() # 5
sentence = '<start> ' + sentence + ' <end>' # 6
return sentence
# 정제된 문장 모으기
corpus = []
for sentence in raw_corpus:
if len(sentence) == 0: continue
if len(sentence) >= 15: continue
preprocessed_sentence = preprocess_sentence(sentence)
corpus.append(preprocessed_sentence)
def tokenize(corpus):
# 12000단어를 기억할 수 있는 tokenizer를 만들기
# 12000단어에 포함되지 못한 단어는 '<unk>'로 바꾸기
tokenizer = tf.keras.preprocessing.text.Tokenizer(
num_words=12000,
filters=' ',
oov_token="<unk>"
)
# corpus를 이용해 tokenizer 내부의 단어장을 완성하기
tokenizer.fit_on_texts(corpus)
# 준비한 tokenizer를 이용해 corpus를 Tensor로 변환
tensor = tokenizer.texts_to_sequences(corpus)
# 입력 데이터의 시퀀스 길이를 일정하게 맞춰준다
# 만약 시퀀스가 짧다면 문장 뒤에 패딩을 붙여 길이를 맞춰준다
# (문장 앞에 패딩을 붙이고 싶다면, padding='pre'를 사용)
tensor = tf.keras.preprocessing.sequence.pad_sequences(tensor, padding='post')
print(tensor,tokenizer)
return tensor, tokenizer
tensor, tokenizer = tokenize(corpus)
# tensor에서 마지막 토큰(<pad>일 확률이 높음)을 잘라내서 소스 문장을 생성
src_input = tensor[:, :-1]
# tensor에서 <start>를 잘라내서 타겟 문장을 생성
tgt_input = tensor[:, 1:]
enc_train, enc_val, dec_train, dec_val = train_test_split(src_input,
tgt_input,
test_size=0.2,
random_state=7)
BUFFER_SIZE = len(enc_train)
BATCH_SIZE = 256
steps_per_epoch = len(enc_train) // BATCH_SIZE
# tokenizer가 구축한 단어사전 내 12000개와, 여기 포함되지 않은 0:<pad>를 포함하여 12001개
VOCAB_SIZE = tokenizer.num_words + 1
dataset = tf.data.Dataset.from_tensor_slices((enc_train, dec_train))
dataset = dataset.shuffle(BUFFER_SIZE)
dataset = dataset.batch(BATCH_SIZE, drop_remainder=True)
class TextGenerator(tf.keras.Model):
def __init__(self, vocab_size, embedding_size, hidden_size):
super().__init__()
self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_size)
self.rnn_1 = tf.keras.layers.LSTM(hidden_size, return_sequences=True)
self.rnn_2 = tf.keras.layers.LSTM(hidden_size, return_sequences=True)
self.linear = tf.keras.layers.Dense(vocab_size)
def call(self, x):
out = self.embedding(x)
out = self.rnn_1(out)
out = self.rnn_2(out)
out = self.linear(out)
return out
embedding_size = 3072
hidden_size = 1024
model = TextGenerator(tokenizer.num_words + 1, embedding_size , hidden_size)
optimizer = tf.keras.optimizers.Adam()
loss = tf.keras.losses.SparseCategoricalCrossentropy(
from_logits=True, reduction='none')
model.compile(loss=loss, optimizer=optimizer)
model.fit(enc_train, dec_train, epochs=5, validation_data=(enc_val, dec_val))
BUFFER_SIZE = len(enc_val)
BATCH_SIZE = 256
steps_per_epoch = len(enc_val) // BATCH_SIZE
# tokenizer가 구축한 단어사전 내 12000개와, 여기 포함되지 않은 0:<pad>를 포함하여 12001개
VOCAB_SIZE = tokenizer.num_words + 1
test_dataset = tf.data.Dataset.from_tensor_slices((enc_val, dec_val))
test_dataset = test_dataset.shuffle(BUFFER_SIZE)
test_dataset = test_dataset.batch(BATCH_SIZE, drop_remainder=True)
results = model.evaluate(test_dataset)
def generate_text(model, tokenizer, init_sentence="<start>", max_len=20):
test_input = tokenizer.texts_to_sequences([init_sentence])
test_tensor = tf.convert_to_tensor(test_input, dtype=tf.int64)
end_token = tokenizer.word_index["<end>"]
# 단어 하나씩 예측해 문장을 만든다
# 1. 입력받은 문장의 텐서를 입력
# 2. 예측된 값 중 가장 높은 확률인 word index를 뽑는다
# 3. 2에서 예측된 word index를 문장 뒤에 붙인다
# 4. 모델이 <end>를 예측했거나, max_len에 도달했다면 문장 생성을 마친다
while True:
# 1
predict = model(test_tensor)
# 2
predict_word = tf.argmax(tf.nn.softmax(predict, axis=-1), axis=-1)[:, -1]
# 3
test_tensor = tf.concat([test_tensor, tf.expand_dims(predict_word, axis=0)], axis=-1)
# 4
if predict_word.numpy()[0] == end_token: break
if test_tensor.shape[1] >= max_len: break
generated = ""
# tokenizer를 이용해 word index를 단어로 하나씩 변환
for word_index in test_tensor[0].numpy():
generated += tokenizer.index_word[word_index] + " "
return generated
generate_text(model, tokenizer, init_sentence="<start> i love ", max_len=20)
'AIFFEL' 카테고리의 다른 글
AIFFEL 아이펠 15일차 (0) | 2022.01.24 |
---|---|
AIFFEL 아이펠 14일차 (0) | 2022.01.17 |
AIFFEL 아이펠 12일차 (0) | 2022.01.12 |
AIFFEL 아이펠 11일차 (0) | 2022.01.11 |
AIFFEL 아이펠 10일차 (0) | 2022.01.11 |