【问题标题】:Input for LSTM modelLSTM 模型的输入
【发布时间】:2022-01-28 21:31:03
【问题描述】:

我正在尝试训练一个用于字符串预测的 LSTM 模型,特别是国际象棋移动。

我有一个非常大的数据集,其中包含字符串形式的国际象棋游戏。 数据集中游戏的形式为:

"W1.d4 B1.d5 W2.c4 B2.e6 W3.Nc3 B3.Nf6 W4.cxd5 B4.exd5 W5.Bg5 B5.Be7 W6.e3 B6.Ne4 W7.Bxe7 B7.Nxc3 W8.Bxd8 B8.Nxd1 W9.Bxc7 B9.Nxb2 W10. Rb1 B10.Nc4 W11.Bxc4 B11.dxc4 W12.Ne2 B12.O-O W13.Nc3 B13.b6 W14.d5 B14.Na6 W15.Bd6 B15.Rd8 W16.Ba3 B16.Bb7 W17.e4 B17.f6 W18. Ke2 B18.Nc7 W19.Rhd1 B19.Ba6 W20.Ke3 B20.Kf7 W21.g4 B21.g5 W22.h4 B22.h6 W23.Rh1 B23.Re8 W24.f3 B24.Bb7 W25.hxg5 B25.fxg5 W26.d6 B26. Nd5+ W27.Nxd5 B27.Bxd5 W28.Rxh6 B28.c3 W29.d7 B29.Re6 W30.Rh7+ B30.Kg8 W31.Rbh1 B31.Bc6 W32.Rh8+ B32.Kf7 W33.Rxa8 B33.Bxd7 W34.Rh7+"

我将游戏的每一步都解析并转换为整数。 在我的解析中,我只保留了移动,所以我删除了点之前的部分。
例如:

W1.d4 -> d4

所以每个整数对应一个动作,在我的数据集中我有 10045 个动作。 然后游戏变成:

[10045, 10045, 10045, 10045, 10045, 10045, 10045, 10045, 3379, 9178, 2967, 905, 6732, 9052, 5734, 7150, 6300, 5585, 2801, 824, 8392, 8968, 7976, 2156, 6775, 4410, 8345, 8029, 147, 5845, 4001, 5841, 6732, 4705, 9178, 1665, 9409, 6930, 4521, 8954, 6215, 7726, 7911, 5083, 4407, 5130, 6021, 7516, 5226, 5166, 8667, 9410, 6636, 2068, 2892, 8954, 1455, 10033, 7335, 3543, 3103, 9571, 3619, 4810, 774, 1877, 7597, 701, 2050, 509, 8585, 7516, 803, 2158, 7597] 

请注意,移动 10045 用于填充匹配并将它们全部带到相同的长度。此外,我没有棋盘的状态,所以我只打算使用字符串序列来预测移动。

所以每个整数对应一个动作,在我的数据集中我有 10045 个动作。

{'Qcxe6+': '0', 'Rhg5': '1', 'R1xc4+': '2', 'Qcxf3+': '3', ... }

完成后,我继续为我的模型创建 X_train 和 Y_train。 我将比赛分成 5 个时间步长,并决定暂时只参加 5 场比赛。 然后,在创建我的 X_train 时,我将这 5 场比赛按时间步长相加,就好像它是一个大批次一样。然后我通过将 X_train 除以可用移动数 (10045) 来标准化我的 X_train。
我的 X_train 中的一个示例:

[[[0.33638626182180187]
  [0.9011448481831758]
  [0.295370831259333]
  [0.09009457441513191]
  [0.6434046789447486]]

 [[0.9011448481831758]
  [0.295370831259333]
  [0.09009457441513191]
  [0.6434046789447486]
  [0.9136884021901444]]

 [[0.295370831259333]
  [0.09009457441513191]
  [0.6434046789447486]
  [0.9136884021901444]
  [0.6701841712294674]]

 ...

 [[0.3886510701841712]
  [0.8913887506222001]
  [0.40159283225485315]
  [0.6532603285216526]
  [0.21682429069188652]]

 [[0.8913887506222001]
  [0.40159283225485315]
  [0.6532603285216526]
  [0.21682429069188652]
  [0.44649079143852666]]

 [[0.40159283225485315]
  [0.6532603285216526]
  [0.21682429069188652]
  [0.44649079143852666]
  [0.9367844698855152]]]

完成此操作后,我将继续创建 Y_tain,其中将包含 X_train 中匹配的每个时间步的标签。 我选择用 baseN 编码对这些标签进行编码,更准确地说是在 base 5 中,因为我有 10045 个不同的移动,所以在 Y 中移动用 6 位编码,因此使用 6 个整数的列表。
我的 Y_tain 的一个例子:

[[2 4 3 2 0 4]
 [2 0 3 4 1 3]
 [1 4 1 3 4 1]
 ...
 [1 2 0 4 2 1]
 [3 0 0 1 2 1]
 [2 3 4 1 3 3]]

所以我的 X_train 和 Y_strain 形状是:

print(X.shape, Y.shape)
(350, 5, 1) (350, 6)

我的型号代码是:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from keras.preprocessing.sequence import pad_sequences
from keras.layers import Embedding, LSTM, Dense, Dropout
from keras.preprocessing.text import Tokenizer
from keras.callbacks import EarlyStopping
from keras.models import Sequential

model = Sequential()
model.add(LSTM(256, input_shape=(X.shape[1], X.shape[2]), return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(256))
model.add(Dropout(0.2))
model.add(Dense(Y.shape[1], activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam')

filepath="weights-improvement-{epoch:02d}-{loss:.4f}-bigger.hdf5"
checkpoint = tf.keras.callbacks.ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min')
callbacks_list = [checkpoint]
model.fit(X, Y, epochs=100, batch_size=5, callbacks=callbacks_list)

以这种方式处理数据是否正确? 我应该将匹配项分成 X_train 中的列表吗?我的意思是, X_train 应该是一个列表列表(匹配列表),并且在每场比赛中,我都有超过比赛的 5 个时间步长的列表?我对 Y_train 也有同样的问题,我尝试将标签分成不同的列表,就像我对 X_train 所做的那样,但我无法传递 3D 中的标签列表。

我是不是做错了什么?

【问题讨论】:

    标签: python tensorflow keras lstm shapes


    【解决方案1】:

    在不完全了解域的情况下,我会说:

    1:我会将标签设为单个值而不是整数列表,

    2:“移动”是否包含整个棋盘的布局?如果是这样,那么理论上一个动作是独立于匹配的,因为可以说棋盘布局应该是通用的......但是,如果你试图预测人类玩家的下一步动作,那么考虑匹配和策略可能是有意义的。

    3:在生成 x_train 时,很难看出您是否松散了上下文。 有趣的项目!

    【讨论】:

    • 感谢@Anynamer 并感谢您对我的项目的兴趣,我已按照您的建议添加了一些有关我的上下文的信息。我试图将数字转换为 baseN 但作为整数而不是整数列表。所以 Y_train 的形状现在是 (350,) 但我的模型没有学习,它无法计算损失并给我损失:0.0000e+00。你有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 2022-11-11
    • 2018-01-05
    • 2020-02-27
    • 2016-11-09
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2017-10-05
    相关资源
    最近更新 更多