这是我的训练模型,我几乎遵循本教程https://www.youtube.com/watch?v=1lwddP0KUEg,但我必须使用西班牙语版本的节包:
import random
import json
import pickle
import numpy as np
import pandas as pd
import nltk
from nltk.tokenize.toktok import ToktokTokenizer
import stanza
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout
from tensorflow.keras.optimizers import SGD
toktok = ToktokTokenizer()
intents = json.loads(open("intents.json", "rb").read())
words = []
classes = []
documents = []
ignore_letters = ['¿','?', '!', '.', ',']
nlp = stanza.Pipeline('es')
for intent in intents['intents']:
for pattern in intent['patterns']:
word_list = toktok.tokenize(pattern)
words.extend(word_list)
documents.append((word_list, intent['tag']))
if intent['tag'] not in classes:
classes.append(intent['tag'])
words = [nlp(word).to_dict() for word in words if word not in ignore_letters]
palabras = []
for i in range(0,len(words)):
texto = words[i][0][0]["lemma"]
palabras.append(texto)
palabras = sorted(set(palabras))
classes = sorted(set(classes))
pickle.dump(palabras, open('palabras.pkl', 'wb'))
pickle.dump(classes, open('classes.pkl', 'wb'))
training = []
output_empty = [0] * len(classes)
for document in documents:
bag = []
word_patterns = document[0]
word_patterns = [nlp(word.lower()).to_dict() for word in word_patterns]
for word in words:
bag.append(1) if word in word_patterns else bag.append(0)
output_row = list(output_empty)
output_row[classes.index(document[1])] = 1
training.append([bag, output_row])
random.shuffle(training)
training = np.array(training, dtype="object")
train_x = list(training[:, 0])
train_y = list(training[:, 1])
model = Sequential()
model.add(Dense(128, input_shape=(len(train_x[0]),), activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(len(train_y[0]), activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
hist = model.fit(np.array(train_x), np.array(train_y), epochs=200, batch_size=5, verbose=1)
model.save('chatbotmodel.h5', hist)
print('Listo')
问题是,当我尝试使用模型预测类时,代码如下:
import random
import json
import pickle
import numpy as np
import nltk
from nltk.tokenize.toktok import ToktokTokenizer
import stanza
from tensorflow.keras.models import load_model
toktok = ToktokTokenizer()
intents = json.loads(open('intents.json').read())
words = pickle.load(open('palabras.pkl','rb'))
classes = pickle.load(open('classes.pkl', 'rb'))
model = load_model('chatbotmodel.h5')
nlp = stanza.Pipeline('es')
def clean_up_sentence(sentence):
sentence_words = toktok.tokenize(sentence)
words = [nlp(word).to_dict() for word in sentence_words]
palabras = []
for i in range(0,len(words)):
texto = words[i][0][0]["lemma"]
palabras.append(texto)
palabras = sorted(set(palabras))
return palabras
def bag_of_words(sentence):
sentences_words = clean_up_sentence(sentence)
bag = [0] * len(words)
for w in sentences_words:
for i, word in enumerate(words):
if word == w:
bag[i] = 1
return np.array(bag)
def predict_class(sentence):
bow = bag_of_words(sentence)
res = model.predict(np.array([bow]))[0]
return res
predict_class('Hola, ¿cómo te va?)
给我这个错误:
ValueError: Input 0 of layer sequential_1 is incompatible with the layer: expected axis -1 of input shape to have value 15 but received input with shape (None, 13)
知道哪里出了问题吗?因为我已经按照教程完成了几乎所有步骤。用于训练的 intents.json 数据非常简单:
{"intents": [
{"tag": "respuestaSaludo",
"patterns": ["bien","¿quien es?","¿qué desea?"],
"responses": ["Mi nombre es Juan Carlos Bellido", "Soy Juan"]
},
{"tag": "respuestaPropuesta",
"patterns": ["no","no él gracias","no por ahora, aquí","de nuevo"],
"responses": ["ok, gracias","ok"]
}
]}
编辑 1: 模型摘要():
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 128) 2048
_________________________________________________________________
dropout (Dropout) (None, 128) 0
_________________________________________________________________
dense_2 (Dense) (None, 64) 8256
_________________________________________________________________
dropout_1 (Dropout) (None, 64) 0
_________________________________________________________________
dense_3 (Dense) (None, 2) 130
=================================================================
Total params: 10,434
Trainable params: 10,434
Non-trainable params: 0
_________________________________________________________________
弓形:
def predict_class(sentence):
bow = bag_of_words(sentence)
return print(bow.shape)
predict_class('quiero ver que sucede')
输出:
(13,)
答案 0 :(得分:1)
据我所知 - 您的模型期望序列长度为 15。您正在提供 13 个令牌。
尝试用两个零附加您的序列:
bow = bag_of_words(sentence)
bow = np.concatenate((bow, np.array([0, 0])), -1)
res = model.predict(np.array([bow]))[0]