实施一次性注意示例

Implementing One-Shot Attention Example

我正在尝试实现一次性注意力示例:this

如您所见,有一个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_sizeinput_sizeoutput_sizemax_out_seq_len

所以我是这样定义的:

hidden_size = 1
input_size = 1  # this is maybe 3
output_size = 1
max_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: 40396
y_test: 63

这对我来说很有意义,我可以说它看起来不错。 (我当然可能是错的)

那我fit_transform它:

fitted_x_train = scaler.fit_transform(X_train)
fitted_x_test = scaler.fit_transform(X_test) 

它产生:

x_train_fitted: 56867
x_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

也许有人之前实施过该示例,或者至少知道它应该如何工作。我显然遗漏了一些东西...

我找到了答案。

我完全错了。

hidden_size,我选的是128。

由于是seq2seq问题,输入大小应该是整个词汇表的长度,在我的例子中我又加了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_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):
    # Vectorizing each element in each sequence
    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个纪元

56000/56000 [==============================] - 79s - loss: 0.0154 - acc: 0.9955 - val_loss: 0.0030 - val_acc: 0.9991

所以它似乎工作得很好。我得尝试更困难的数据。