【发布时间】: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