-
TensorFlow 기초 39 - LSTM을 이용한 텍스트 생성, 문맥을 반영하여 다음 단어를 예측하기TensorFlow 2022. 12. 14. 11:35
# RNN을 이용한 텍스트 생성 # 문맥을 반영하여 다음 단어를 예측하기 import numpy as np from keras.models import Sequential from keras.layers import Embedding, Flatten, Dense, LSTM from keras.preprocessing.text import Tokenizer from keras.utils import pad_sequences, to_categorical from anaconda_project.internal.conda_api import result """ text = ''' 경마장에 있는 말이 뛰고 있다 그의 말이 법이다 가는 말이 고와야 오는 말이 곱다''' """ text = '''수도권 개별 단지들의 전세가격 하락세가 두드러지게 나타나고 있다 경기 파주 힐스테이트 운정은 지난 10월 16층이 2억8000만원에 전세 거래됐다 2020년 같은 달 같은 층수는 3억1500만원에 거래됐다 인천 미추홀구 인천SK스카이뷰 역시 지난달 12층이 3억원에 거래되면서 2년 전 가격보다 5500만원 내렸으며, 부개주공3단지는 2년 전보다 4500만원 내린 1억8000만원에 거래됐다''' tok = Tokenizer() tok.fit_on_texts([text]) # fit_on_texts의 값으로는 무조건 list type으로 주어야 된다. 단어와 인덱싱을 출력 print(tok.word_index) encoded = tok.texts_to_sequences([text]) # 단어를 정수로 메트릭스화 해서 출력 print(encoded) # [[2, 3, 1, 4, 5, 6, 1, 7, 8, 1, 9, 10, 1, 11]] vocab_size = len(tok.word_index) + 1 # Embedding(가능한 토큰 수) print(vocab_size) # 훈련 데이터 만들기 sequences = list() for line in text.split('\n'): # 문장 토큰화 enco = tok.texts_to_sequences([line])[0] # print(enco) # 바로 다음 단어를 label로 사용하기 위해 리스트에 벡터 기억 for i in range(1, len(enco)): sequ = enco[:i + 1] # print(sequ) sequences.append(sequ) print(sequences) # [[2, 3], [2, 3, 1], [2, 3, 1, 4], [2, 3, 1, 4, 5], [6, 1], ... print('학습 참여 샘플 수 :', len(sequences)) # 11 print(max(len(i) for i in sequences)) # 6 # 가장 긴 벡터의 길이를 기준으로 각 벡터의 크기를 통일 max_len = max(len(i) for i in sequences) psequences = pad_sequences(sequences, maxlen=max_len, padding='pre') # pre는 왼쪽을 0 으로 채운다. 'post'는 오른쪽을 0으로 채운다. print(psequences) # 각 벡터의 마지막 요소(단어)를 label로 사용 x = psequences[:, :-1] # feature, 마지막 숫자(단어) 이외의 것이 feature가 된다. y = psequences[:, -1] # label, 마지막 숫자(단어)가 label이 된다. print(x[:2]) print(y) # [ 3 1 4 5 1 7 1 9 10 1 11] # 모델의 최종분류 활성화 함수를 softmax로 사용하므로 y를 원핫 처리 y = to_categorical(y, num_classes=vocab_size) print(y[:2]) # [ 3 1 4 5 1 7 1 9 10 1 11] # model model = Sequential() model.add(Embedding(vocab_size, 32, input_length=max_len - 1)) model.add(LSTM(32, activation='tanh')) model.add(Flatten()) model.add(Dense(32, activation='relu')) model.add(Dense(32, activation='relu')) model.add(Dense(vocab_size, activation='softmax')) print(model.summary()) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(x, y, epochs=200, verbose=0) print('model evaluate :', model.evaluate(x, y)) # 문자열 생성 함수 def seq_gen_text_func(model, t, current_word, n): init_word = current_word # 처음 들어온 단어도 마지막 함께 출력할 계획 sentence = '' for _ in range(n): encoded = t.texts_to_sequences([current_word])[0] encoded = pad_sequences([encoded], maxlen=max_len - 1, padding='pre') result = np.argmax(model.predict(encoded, verbose=0), axis = -1) # 예측 단어 찾기 for word, index in t.word_index.items(): # print(word, ' :', index) if index == result: # 예측한 단어, 그리고 인덱스와 동일한 단어가 있다면 해당 단어는 예측단어 이므로 break break current_word = current_word + ' ' + word sentence = sentence + ' ' + word sentence = init_word + sentence return sentence ''' print(seq_gen_text_func(model, tok, '경마장', 1)) print(seq_gen_text_func(model, tok, '그의', 2)) print(seq_gen_text_func(model, tok, '가는', 3)) print(seq_gen_text_func(model, tok, '가는', 4)) print(seq_gen_text_func(model, tok, '경마장에', 4)) ''' print(seq_gen_text_func(model, tok, '수도권', 4)) print(seq_gen_text_func(model, tok, '인천', 4)) <console> {'거래됐다': 1, '같은': 2, '2년': 3, '수도권': 4, '개별': 5, '단지들의': 6, '전세가격': 7, '하락세가': 8, '두드러지게': 9, '나타나고': 10, '있다': 11, '경기': 12, '파주': 13, '힐스테이트': 14, '운정은': 15, '지난': 16, '10월': 17, '16층이': 18, '2억8000만원에': 19, '전세': 20, '2020년': 21, '달': 22, '층수는': 23, '3억1500만원에': 24, '인천': 25, '미추홀구': 26, '인천sk스카이뷰': 27, '역시': 28, '지난달': 29, '12층이': 30, '3억원에': 31, '거래되면서': 32, '전': 33, '가격보다': 34, '5500만원': 35, '내렸으며': 36, '부개주공3단지는': 37, '전보다': 38, '4500만원': 39, '내린': 40, '1억8000만원에': 41} [[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 21, 2, 22, 2, 23, 24, 1, 25, 26, 27, 28, 29, 30, 31, 32, 3, 33, 34, 35, 36, 37, 3, 38, 39, 40, 41, 1]] 42 [[4, 5], [4, 5, 6], [4, 5, 6, 7], [4, 5, 6, 7, 8], [4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9, 10], [4, 5, 6, 7, 8, 9, 10, 11], [12, 13], [12, 13, 14], [12, 13, 14, 15], [12, 13, 14, 15, 16], [12, 13, 14, 15, 16, 17], [12, 13, 14, 15, 16, 17, 18], [12, 13, 14, 15, 16, 17, 18, 19], [12, 13, 14, 15, 16, 17, 18, 19, 20], [12, 13, 14, 15, 16, 17, 18, 19, 20, 1], [21, 2], [21, 2, 22], [21, 2, 22, 2], [21, 2, 22, 2, 23], [21, 2, 22, 2, 23, 24], [21, 2, 22, 2, 23, 24, 1], [25, 26], [25, 26, 27], [25, 26, 27, 28], [25, 26, 27, 28, 29], [25, 26, 27, 28, 29, 30], [25, 26, 27, 28, 29, 30, 31], [25, 26, 27, 28, 29, 30, 31, 32], [25, 26, 27, 28, 29, 30, 31, 32, 3], [25, 26, 27, 28, 29, 30, 31, 32, 3, 33], [25, 26, 27, 28, 29, 30, 31, 32, 3, 33, 34], [25, 26, 27, 28, 29, 30, 31, 32, 3, 33, 34, 35], [25, 26, 27, 28, 29, 30, 31, 32, 3, 33, 34, 35, 36], [37, 3], [37, 3, 38], [37, 3, 38, 39], [37, 3, 38, 39, 40], [37, 3, 38, 39, 40, 41], [37, 3, 38, 39, 40, 41, 1]] 학습 참여 샘플 수 : 40 13 [[ 0 0 0 0 0 0 0 0 0 0 0 4 5] [ 0 0 0 0 0 0 0 0 0 0 4 5 6] [ 0 0 0 0 0 0 0 0 0 4 5 6 7] [ 0 0 0 0 0 0 0 0 4 5 6 7 8] [ 0 0 0 0 0 0 0 4 5 6 7 8 9] [ 0 0 0 0 0 0 4 5 6 7 8 9 10] [ 0 0 0 0 0 4 5 6 7 8 9 10 11] [ 0 0 0 0 0 0 0 0 0 0 0 12 13] [ 0 0 0 0 0 0 0 0 0 0 12 13 14] [ 0 0 0 0 0 0 0 0 0 12 13 14 15] [ 0 0 0 0 0 0 0 0 12 13 14 15 16] [ 0 0 0 0 0 0 0 12 13 14 15 16 17] [ 0 0 0 0 0 0 12 13 14 15 16 17 18] [ 0 0 0 0 0 12 13 14 15 16 17 18 19] [ 0 0 0 0 12 13 14 15 16 17 18 19 20] [ 0 0 0 12 13 14 15 16 17 18 19 20 1] [ 0 0 0 0 0 0 0 0 0 0 0 21 2] [ 0 0 0 0 0 0 0 0 0 0 21 2 22] [ 0 0 0 0 0 0 0 0 0 21 2 22 2] [ 0 0 0 0 0 0 0 0 21 2 22 2 23] [ 0 0 0 0 0 0 0 21 2 22 2 23 24] [ 0 0 0 0 0 0 21 2 22 2 23 24 1] [ 0 0 0 0 0 0 0 0 0 0 0 25 26] [ 0 0 0 0 0 0 0 0 0 0 25 26 27] [ 0 0 0 0 0 0 0 0 0 25 26 27 28] [ 0 0 0 0 0 0 0 0 25 26 27 28 29] [ 0 0 0 0 0 0 0 25 26 27 28 29 30] [ 0 0 0 0 0 0 25 26 27 28 29 30 31] [ 0 0 0 0 0 25 26 27 28 29 30 31 32] [ 0 0 0 0 25 26 27 28 29 30 31 32 3] [ 0 0 0 25 26 27 28 29 30 31 32 3 33] [ 0 0 25 26 27 28 29 30 31 32 3 33 34] [ 0 25 26 27 28 29 30 31 32 3 33 34 35] [25 26 27 28 29 30 31 32 3 33 34 35 36] [ 0 0 0 0 0 0 0 0 0 0 0 37 3] [ 0 0 0 0 0 0 0 0 0 0 37 3 38] [ 0 0 0 0 0 0 0 0 0 37 3 38 39] [ 0 0 0 0 0 0 0 0 37 3 38 39 40] [ 0 0 0 0 0 0 0 37 3 38 39 40 41] [ 0 0 0 0 0 0 37 3 38 39 40 41 1]] [[0 0 0 0 0 0 0 0 0 0 0 4] [0 0 0 0 0 0 0 0 0 0 4 5]] [ 5 6 7 8 9 10 11 13 14 15 16 17 18 19 20 1 2 22 2 23 24 1 26 27 28 29 30 31 32 3 33 34 35 36 3 38 39 40 41 1] [[0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] [0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]] 2022-12-14 11:38:38.601465: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX AVX2 To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding (Embedding) (None, 12, 32) 1344 lstm (LSTM) (None, 32) 8320 flatten (Flatten) (None, 32) 0 dense (Dense) (None, 32) 1056 dense_1 (Dense) (None, 32) 1056 dense_2 (Dense) (None, 42) 1386 ================================================================= Total params: 13,162 Trainable params: 13,162 Non-trainable params: 0 _________________________________________________________________ None 1/2 [==============>...............] - ETA: 0s - loss: 0.3459 - accuracy: 0.9688 2/2 [==============================] - 0s 3ms/step - loss: 0.3261 - accuracy: 0.9750 model evaluate : [0.326116144657135, 0.9750000238418579] 수도권 개별 단지들의 전세가격 하락세가 인천 미추홀구 인천sk스카이뷰 역시 지난달
token을 생성하고 나서 fit_on_texts의 값으로는 무조건 list type으로 주어야 된다. 단어와 인덱싱을 출력
texts_to_sequences() 단어를 정수로 메트릭스화 해서 출력한다.
단어를 정수로 바꿔주었기 때문에 predict(x) x에 들어가는 값도 정수로 바꿔서 넣어주어야 된다.
그리고 예측 후 다시 단어로 바꿔준다.
학습 내용에 따라 그것이 적용되므로 text 안의 내용만 바꿔주면 된다.
'TensorFlow' 카테고리의 다른 글
TensorFlow 기초 40 - 자소 단위로 분리한 후 텍스트 생성 모델 (0) 2022.12.16 뉴욕타임즈 뉴스 기사 중 헤드라인을 읽어 텍스트 생성 연습(LSTM) (0) 2022.12.14 TensorFlow 기초 38 - 문자열(corpus - 자연어 데이터 집합) 토큰화 + LSTM으로 감성 분류 (0) 2022.12.13 TensorFlow 기초 37 - RNN(Recurrent Neural Network) (0) 2022.12.13 TensorFlow 기초 36 - 네이버 영화 리뷰 데이터로 word2vec 객체 생성 후 특정 단에 대한 유사도 확인 (0) 2022.12.13