我正在尝试实现一个一次性注意力示例:这个
如你所见,有一个data/train_arithmetic.tsv
文件,里面有X中的算术运算(2+70)和Y中的结果(72)。
我理解这个示例代码:
model = Sequential()model.add(Bidirectional(GRU(hidden_size, return_sequences=True), merge_mode='concat', input_shape=(None, input_size)))model.add(Concurrence())model.add(RepeatVector(max_out_seq_len + 1))model.add(GRU(hidden_size * 2, return_sequences=True))model.add(TimeDistributed(Dense(output_dim=output_size, activation="softmax")))model.compile(loss="categorical_crossentropy", optimizer="rmsprop")
但我不是很确定这个示例中hidden_size
、input_size
、output_size
和max_out_seq_len
的值应该是什么。
所以我定义了如下:
hidden_size = 1input_size = 1 # 这可能应该是3output_size = 1max_out_seq_len = 1
然后我得到了x-y_train和x-y_set:
X_train, X_test, Y_train, Y_test = train_test_split(data_set[:, 0:1], data_set[:, 1], test_size=0.25, random_state=87)
使用了np.random.seed
和所有相关设置。
我打印出来确认,结果是:
x_train: ['38620+1776']x_test: ['11+52']y_train: 40396y_test: 63
对我来说,这看起来很有道理,我可以说它看起来不错。(当然,我可能错了)
然后我对其进行了fit_transform处理:
fitted_x_train = scaler.fit_transform(X_train)fitted_x_test = scaler.fit_transform(X_test)
结果是:
x_train_fitted: 56867x_test_fitted: 12870
这看起来又不错了。
我使用了常规的EarlyStopping
:
early_stop_criteria = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=20, verbose=0, mode='auto')
然后尝试进行拟合:
model_fitted = model.fit(fitted_x_train, Y_train, epochs=1000, verbose=0, batch_size=X_train.shape[0], initial_epoch=0, callbacks=[early_stop_criteria], validation_split=0.2)
但我得到了这个错误:
ValueError: Error when checking input: expected bidirectional_1_input to have 3 dimensions, but got array with shape (75000, 1)
这对我来说是有道理的,因为它在等待11
+ +
+ 52
,而不是仅仅11+52
。但我现在完全不知道该怎么办了…
也许我整个方法都是错的,可能有其他实现它的方法,或者我走在正确的道路上,我只需要得到(75000, 3)的分割,这对我来说似乎并不简单,因为可能有-11+52
也许有人之前实现过这个示例,或者至少知道它应该如何工作。我显然错过了什么…
回答:
我找到了答案。
我完全错了。
我选择了128作为hidden_size
。
因为这是一个序列到序列的问题,输入大小应该是整个词汇表的长度,在我的情况下,我增加了2,因为有’ZERO’和’UNKNOWN’。
输出大小与输入大小相同。
max_out_seq_len
是句子中最长长度的长度。
因为这是一个注意力问题,这段代码:
X_train, X_test, Y_train, Y_test = train_test_split(data_set[:, 0:1], data_set[:, 1],test_size=0.25, random_state=87)
没有意义。
所以我改成了这样:
X_train, X_test, Y_train, Y_test = train_test_split(data_set[:, 0:], [str(i[0].split("\t", 1)[1]) for i in data_set[:]], test_size=0.3, random_state=87)
x看起来是这样的:x_train: ['1-116\t-115']
,y看起来是这样的:y_train: -115
这也是一个错误:
model_fitted = model.fit(fitted_x_train, Y_train, epochs=1000, verbose=0, batch_size=X_train.shape[0], initial_epoch=0, callbacks=[early_stop_criteria], validation_split=0.2)
应该改成这样:
model_output = model.fit(x_sequences, y_sequences, epochs=10000, verbose=1, batch_size=BATCH_SIZE, initial_epoch=0, callbacks=[early_stop_criteria], validation_split=0.2)
其中BATCH_SIZE = 128
我得到错误是因为Bidirectional
需要一个3D数组。
所以我解决了这个问题:
def process_data(word_sentences, max_len, word_to_ix): # 将每个序列中的每个元素向量化 sequences = np.zeros((len(word_sentences), max_len, len(word_to_ix))) for i, sentence in enumerate(word_sentences): for j, word in enumerate(sentence): sequences[i, j, word] = 1. return sequences
我对注意力机制很感兴趣,这就是为什么"1+1\t2" => "2"
使用GitHub仓库的数据,在第6个Epoch时,我得到了:
56000/56000 [==============================] - 79s - loss: 0.0154 - acc: 0.9955 - val_loss: 0.0030 - val_acc: 0.9991
所以看起来效果很好。我得尝试使用更复杂的数据。