输入与聊天机器人预测模型的层不兼容
Input incompatible with the layer for chatbot prediction model
这是我的培训模型,我几乎遵循本教程 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')
问题是,当我尝试使用模型通过以下代码预测 class 时:
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.summary():
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
_________________________________________________________________
bow.shape:
def predict_class(sentence):
bow = bag_of_words(sentence)
return print(bow.shape)
predict_class('quiero ver que sucede')
输出:
(13,)
据我了解 - 您的模型期望序列长度为 15。您正在输入 13 个标记。
尝试在序列中附加两个零:
bow = bag_of_words(sentence)
bow = np.concatenate((bow, np.array([0, 0])), -1)
res = model.predict(np.array([bow]))[0]
这是我的培训模型,我几乎遵循本教程 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')
问题是,当我尝试使用模型通过以下代码预测 class 时:
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.summary():
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
_________________________________________________________________
bow.shape:
def predict_class(sentence):
bow = bag_of_words(sentence)
return print(bow.shape)
predict_class('quiero ver que sucede')
输出:
(13,)
据我了解 - 您的模型期望序列长度为 15。您正在输入 13 个标记。
尝试在序列中附加两个零:
bow = bag_of_words(sentence)
bow = np.concatenate((bow, np.array([0, 0])), -1)
res = model.predict(np.array([bow]))[0]