You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

训练好的RNN集成Hangman游戏guess函数时索引错误修复求助

问题修复:Hangman游戏RNN嵌入层索引错误

错误原因

你的Tokenizer未将游戏中的空白字符-纳入词汇表,导致Tokenizer遇到-时返回**-1**(未知token默认值),而嵌入层仅配置处理[0,26)范围的索引,因此触发越界错误。

修复方案

1. 训练阶段更新Tokenizer,添加-字符

在Tokenizer初始化时,显式将-加入词汇表,确保它被分配合法索引;同时配置oov_token处理其他未知字符。

2. 游戏集成时统一字符映射逻辑

确保游戏传入模型的字符串(含-)能被正确转换为模型可识别的索引,同时过滤已猜字符避免无效预测。

完整修复代码

训练RNN模型代码

import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense
import pickle

# 加载25万单词数据集(替换为你的数据集路径)
with open("250k_words.txt", "r") as f:
    words = [line.strip().lower() for line in f.readlines()]

# 关键:Tokenizer添加'-'字符,配置oov_token处理未知字符
tokenizer = Tokenizer(char_level=True, oov_token="<OOV>")
# 手动将'-'加入词汇表
tokenizer.word_index['-'] = len(tokenizer.word_index) + 1
tokenizer.index_word[len(tokenizer.word_index)] = '-'

# 拟合词汇表
tokenizer.fit_on_texts(words)

# 准备训练数据:预测下一个字符,用'-'填充固定长度
max_len = 10
X, y = [], []
for word in words:
    padded_word = word.ljust(max_len, '-')
    for i in range(len(padded_word)-1):
        X.append(padded_word[:i+1])
        y.append(padded_word[i+1])

# 转换为模型可接受的序列格式
X_seq = tokenizer.texts_to_sequences(X)
X_pad = np.array([np.pad(seq, (max_len - len(seq), 0), mode='constant') for seq in X_seq])
y_seq = np.array([tokenizer.word_index[c] for c in y])

# 构建模型:嵌入层输入尺寸为词汇表大小+1(索引从1开始)
vocab_size = len(tokenizer.word_index) + 1
model = Sequential([
    Embedding(input_dim=vocab_size, output_dim=32, input_length=max_len),
    LSTM(64),
    Dense(vocab_size, activation='softmax')
])

model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_pad, y_seq, epochs=5, batch_size=256)

# 保存模型和Tokenizer
model.save("hangman_rnn.h5")
with open("tokenizer.pkl", "wb") as f:
    pickle.dump(tokenizer, f)

Hangman游戏集成代码

import numpy as np
from tensorflow.keras.models import load_model
import pickle

# 加载预训练模型和Tokenizer
model = load_model("hangman_rnn.h5")
with open("tokenizer.pkl", "rb") as f:
    tokenizer = pickle.load(f)

max_len = 10

def guess(current_state):
    # 统一处理输入:转小写、填充到固定长度
    processed_state = current_state.lower().ljust(max_len, '-')
    # 转换为模型可接受的序列
    seq = tokenizer.texts_to_sequences([processed_state])
    padded_seq = np.array([np.pad(seq[0], (max_len - len(seq[0]), 0), mode='constant')])
    # 预测字符概率
    pred_probs = model.predict(padded_seq, verbose=0)[0]
    # 过滤已猜字符和'-',仅保留未猜字母
    forbidden_chars = set(current_state.replace('-', ''))
    forbidden_chars.add('-')
    char_probs = []
    for idx, prob in enumerate(pred_probs):
        char = tokenizer.index_word.get(idx, '')
        if char not in forbidden_chars and char.isalpha():
            char_probs.append((prob, char))
    # 返回概率最高的字符
    char_probs.sort(reverse=True, key=lambda x: x[0])
    return char_probs[0][1] if char_probs else 'a'

# 测试示例
if __name__ == "__main__":
    # 模拟游戏初始状态(比如目标单词是"apple")
    current_state = "-----"
    print(f"当前状态: {current_state}")
    guessed_char = guess(current_state)
    print(f"模型猜测字符: {guessed_char}")

关键修复点说明

  • 词汇表扩展:手动添加-到Tokenizer词汇表,避免被识别为未知字符;oov_token处理其他意外字符。
  • 训练数据对齐:用-填充单词到固定长度,让模型学习空白字符的上下文逻辑。
  • 输入标准化:游戏状态统一转小写、填充长度,避免格式或长度不匹配问题。
  • 预测过滤:排除已猜字符和-,确保模型返回有效猜测。

内容的提问来源于stack exchange,提问作者Saumya Dwivedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:42:50