编码器-解码器 LSTM 模型给出 'nan' 损失和预测
Encoder-Decoder LSTM model gives 'nan' loss and predictions
我正在尝试创建一个基本的编码器-解码器模型来训练聊天机器人。 X 包含问题或人类对话,Y 包含机器人答案。我已将序列填充到输入和输出句子的最大大小。 X.shape = (2363, 242, 1) 和 Y.shape = (2363, 144, 1)。但是在训练期间,所有时期的损失值都为 'nan',而预测给出的数组的所有值为 'nan'。我尝试使用 'rmsprop' 优化器而不是 'adam'。我不能使用损失函数 'categorical_crossentropy' 因为输出不是单热编码而是一个序列。我的代码究竟有什么问题?
型号
model = Sequential()
model.add(LSTM(units=64, activation='relu', input_shape=(X.shape[1], 1)))
model.add(RepeatVector(Y.shape[1]))
model.add(LSTM(units=64, activation='relu', return_sequences=True))
model.add(TimeDistributed(Dense(units=1)))
print(model.summary())
model.compile(optimizer='adam', loss='mean_squared_error')
hist = model.fit(X, Y, epochs=20, batch_size=64, verbose=2)
model.save('encoder_decoder_model_epochs20.h5')
数据准备
def remove_punctuation(s):
s = s.translate(str.maketrans('','',string.punctuation))
s = s.encode('ascii', 'ignore').decode('ascii')
return s
def prepare_data(fname):
word2idx = {'PAD': 0}
curr_idx = 1
sents = list()
for line in open(fname):
line = line.strip()
if line:
tokens = remove_punctuation(line.lower()).split()
tmp = []
for t in tokens:
if t not in word2idx:
word2idx[t] = curr_idx
curr_idx += 1
tmp.append(word2idx[t])
sents.append(tmp)
sents = np.array(pad_sequences(sents, padding='post'))
return sents, word2idx
human = 'rdany-conversations/human_text.txt'
robot = 'rdany-conversations/robot_text.txt'
X, input_vocab = prepare_data(human)
Y, output_vocab = prepare_data(robot)
X = X.reshape((X.shape[0], X.shape[1], 1))
Y = Y.reshape((Y.shape[0], Y.shape[1], 1))
首先检查您的输入中没有任何 NaN。如果不是这种情况,则可能 梯度爆炸 。标准化您的输入(MinMax 或 Z 缩放),尝试较小的学习率,裁剪梯度,尝试不同的权重初始化。
我正在尝试创建一个基本的编码器-解码器模型来训练聊天机器人。 X 包含问题或人类对话,Y 包含机器人答案。我已将序列填充到输入和输出句子的最大大小。 X.shape = (2363, 242, 1) 和 Y.shape = (2363, 144, 1)。但是在训练期间,所有时期的损失值都为 'nan',而预测给出的数组的所有值为 'nan'。我尝试使用 'rmsprop' 优化器而不是 'adam'。我不能使用损失函数 'categorical_crossentropy' 因为输出不是单热编码而是一个序列。我的代码究竟有什么问题?
型号
model = Sequential()
model.add(LSTM(units=64, activation='relu', input_shape=(X.shape[1], 1)))
model.add(RepeatVector(Y.shape[1]))
model.add(LSTM(units=64, activation='relu', return_sequences=True))
model.add(TimeDistributed(Dense(units=1)))
print(model.summary())
model.compile(optimizer='adam', loss='mean_squared_error')
hist = model.fit(X, Y, epochs=20, batch_size=64, verbose=2)
model.save('encoder_decoder_model_epochs20.h5')
数据准备
def remove_punctuation(s):
s = s.translate(str.maketrans('','',string.punctuation))
s = s.encode('ascii', 'ignore').decode('ascii')
return s
def prepare_data(fname):
word2idx = {'PAD': 0}
curr_idx = 1
sents = list()
for line in open(fname):
line = line.strip()
if line:
tokens = remove_punctuation(line.lower()).split()
tmp = []
for t in tokens:
if t not in word2idx:
word2idx[t] = curr_idx
curr_idx += 1
tmp.append(word2idx[t])
sents.append(tmp)
sents = np.array(pad_sequences(sents, padding='post'))
return sents, word2idx
human = 'rdany-conversations/human_text.txt'
robot = 'rdany-conversations/robot_text.txt'
X, input_vocab = prepare_data(human)
Y, output_vocab = prepare_data(robot)
X = X.reshape((X.shape[0], X.shape[1], 1))
Y = Y.reshape((Y.shape[0], Y.shape[1], 1))
首先检查您的输入中没有任何 NaN。如果不是这种情况,则可能 梯度爆炸 。标准化您的输入(MinMax 或 Z 缩放),尝试较小的学习率,裁剪梯度,尝试不同的权重初始化。