일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- SQL예제
- pandas
- python
- 알고리즘기초
- 해석
- pythone
- 선형회기모델
- Deep Learning
- HeidiSQL
- 예측
- 파이썬
- 머신러닝
- sklearn
- 딥러닝
- Database
- 크롤링(crawling)
- 데이터전처리
- 시각화
- keras
- 데이터 분석
- 훈련
- 데이터 가공
- python기초
- 정확도
- MariaDB
- 데이터 수집
- 회귀모델
- tensorflow
- 데이터
- 데이터베이스
- Today
- Total
코딩헤딩
Deep learning[딥러닝] RNN 응용 규칙기반 챗봇 본문
* 라이브러리 정의
import tensorflow as tf
### 단어사전 만들기
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
* 규칙기반 데이터 정의하기(질문/답변)
questions = [
"전기요금 어때?",
"안녕하세요",
"너 이름이 뭐니?",
.
.
.
answers = [
"전기요금이 계속 인상되고 있어요!",
"안녕하세요! 반가워요^^",
"제 이름은 챗봇이에요.",
.
.
.
len(questions), len(answers)
결과 : (49, 49)
* 단어사전 만들기
tokenizer = Tokenizer()
tokenizer
결과 : <keras_preprocessing.text.Tokenizer at 0x1d3fe1bab20>
- 텍스트 데이터를 토큰(단어)화 하여 단어 사전을 구축하기
* 질문과 답변을 하나의 데이터로 합쳐서 전체 텍스트 데이터로 사용
- 이를 기반으로 토큰나이저가 단어 사전을 구축하게 됨
- 각 단어들은 순차적인 인덱스 번호를 부여받게 됨
- 토큰나이저가 인식하는 문장 내에서 단어의 의미 : 띄어쓰기가 없는 연결되어 있으면 하나의 단어로 인지
* 문장 내에서 순차적 인덱스 부여하기
tokenizer.fit_on_texts(questions + answers)
- fit_in_texts(텍스트 문장) : 문장 내에서 단어들을 추출하여 순차적 인덱스 부여하기
* 단어별 부여된 인덱스 확인하기
print("단어 개수 : ", len(tokenizer.word_index))
tokenizer.word_index
결과 :
단어 개수 : 74
{'가장': 1,
'좋아하는': 2,
'무엇인가요': 3,
'음식은': 4,
.
.
.
* 신경망에서 사용할 단어의 크기 설정 : 하나 더 크게 설정
voca_size = len(tokenizer.word_index) + 1
voca_size
결과 : 75
* texts_to_sequences(문장) : 질문에 대한 텍스트 문장을 단어사전의 인덱스 번호로 변환하기
questions_sequences = tokenizer.texts_to_sequences(questions)
print(len(questions_sequences))
questions_sequences
결과 :
49
[[57, 15],
[21],
[58, 59, 60],
[61, 62],
.
.
.
* 질문 데이터 단어의 기이 통일시키기(정규화)
question_padded = pad_sequences(questions_sequences,padding="post")
print(len(questions_sequences))
question_padded
결과 :
array([[57, 15, 0, 0, 0, 0],
[21, 0, 0, 0, 0, 0],
[58, 59, 60, 0, 0, 0],
.
.
.
- 잘라낼 max길이 기준 : 문장들 중 최대 max단어길이 기준으로
(maxien를 넣지 않으면, 문장들의 길이가 가장 긴 것 기준으로 한다. / 디폴트로, 알아서 가장 긴 개수를 찾아낸다.)
- 채우기는 뒤쪽
* 답변에 대한 데이터로 각 단어사전의 인덱스 번호로 변환하기
answerss_sequences = tokenizer.texts_to_sequences(answers)
print(len(answerss_sequences))
answerss_sequences
결과 :
49
[[64, 65, 66, 13],
[21, 67],
[68, 69, 70],
.
.
.
* 답변 데이터에 대한 길이 통일시키기
answers_padded = pad_sequences(answerss_sequences,padding="post")
print(len(answers_padded))
len(answers_padded[1])
결과 :
49
7
* 모델 생성
model = tf.keras.Sequential()
model
결과 : <keras.engine.sequential.Sequential at 0x1d3fe1ba220>
* 계층 추가하기
- 단어 임베딩(입력계층으로 사용) : 출력 64
- simple RNN 사용 : 출력 138, 활성화 함수 relu
model.add(tf.keras.layers.Embedding(voca_size, 64, input_length=question_padded.shape[1]))
model.add(tf.keras.layers.SimpleRNN(128, activation="relu"))
### 입력을 복제하는 전처리 계층 : 텍스트에 대한 Enoder와 Decoder를 담당함
model.add(tf.keras.layers.RepeatVector(answers_padded.shape[1]))
model.add(tf.keras.layers.SimpleRNN(128, activation="relu", return_sequences=True))
model.add(tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(voca_size, activation="softmax")))
각 타임별로 동일한 가중치를 적용하도록 처리하며,
- 전체 시퀀스들의 이전/다음 인덱스 처리 값을 가지고 있다고 보면 됨
- 예측에 주로 사용되는 계층
- 최종 출력 계층을 감싸고 있음
model.summary()
* 모델 설정하기
model.compile(optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
* 모델 훈련하기
model.fit(question_padded, answers_padded, epochs=100, batch_size=64, verbose=1)
결과 ;
Epoch 1/100
1/1 [==============================] - 1s 1s/step - loss: 4.3152 - accuracy: 0.0058
Epoch 2/100
1/1 [==============================] - 0s 9ms/step - loss: 4.2899 - accuracy: 0.0087
Epoch 3/100
1/1 [==============================] - 0s 10ms/step - loss: 4.2638 - accuracy: 0.3936
.
.
.
"""질문 / 답변 테스트"""
user_input = "너 이름이 뭐니?"
"""새로운 질문 텍스트를 단어사전의 인덱스 번호로 변환하기"""
input_seq = tokenizer.texts_to_sequences([user_input])
input_seq
"""단어의 길이을 훈련에서 사용한 길이로 통일 시키기(정규화)"""
padded_seq = pad_sequences(input_seq, padding="post",
maxlen=question_padded.shape[1])
padded_seq
"""예측하기 : 새로운 질문에 대한 답변 추룰하기"""
pred = model.predict(padded_seq)
len(pred[0][0])
"""답변으로 가장 확률이 높은 값 추출하기"""
pred_index = tf.argmax(pred, axis=-1).numpy()[0]
print(len(pred_index), pred_index)
"""
시퀀스에 해당하는 텍스트 추출하기
- 인덱스에 해당하는 실제 텍스트 추출하기
"""
response = tokenizer.sequences_to_texts([pred_index])[0]
response
결과:
7 [68 69 70 0 0 0 0]
'제 이름은 챗봇이에요'
model, tokenizer
결과 :
(<keras.engine.sequential.Sequential at 0x1d3fe1ba220>,
<keras_preprocessing.text.Tokenizer at 0x1d3fe1bab20>)
* 답변 함수 만들기
def get_Generate_Response(model, tokenizer, user_input):
"""새로운 질문 텍스트를 단어사전의 인덱스 번호로 변환하기"""
input_seq = tokenizer.texts_to_sequences([user_input])
input_seq
"""단어의 길이을 훈련에서 사용한 길이로 통일 시키기(정규화)"""
padded_seq = pad_sequences(input_seq, padding="post",
maxlen=question_padded.shape[1])
padded_seq
"""예측하기 : 새로운 질문에 대한 답변 추룰하기"""
pred = model.predict(padded_seq)
len(pred[0][0])
"""답변으로 가장 확률이 높은 값 추출하기"""
pred_index = tf.argmax(pred, axis=-1).numpy()[0]
# print(len(pred_index), pred_index)
"""
시퀀스에 해당하는 텍스트 추출하기
- 인덱스에 해당하는 실제 텍스트 추출하기
"""
response = tokenizer.sequences_to_texts([pred_index])[0]
return response
* 질문받고 응답하기 : 무한 반복
while True:
"""새로운 입력 받기"""
user_input = input("질문입력 : ")
"""반복을 종료시키기"""
if user_input == "종료":
print("채팅을 종료 합니다-----------------")
break
"""함수를 호출하여 질문에 대한 답변 받아오기"""
response = get_Generate_Response(model, tokenizer, user_input)
"""답변 출력하기"""
print("챗봇 : ", response)
'머신러닝 | 딥러닝' 카테고리의 다른 글
Deep learning[딥러닝] YOLO 객체탐지 네트워크 기초 (0) | 2024.01.10 |
---|---|
Deep learning[딥러닝] 합성곱신경망(CNN; Convolutional Neural Network) (0) | 2024.01.09 |
Deep learning[딥러닝] LSTM GRU (0) | 2024.01.08 |
Deep learning[딥러닝] 심플순환신경망(simple RNN) (1) | 2024.01.08 |
Deep learning[딥러닝] 퍼셉트론(Perceptron) (0) | 2024.01.06 |