如果我有一个字符串,请说“ abc”,反之,请说“ cba”。
神经网络,尤其是编码器-解码器模型可以学习此映射吗?如果是这样,什么是实现此目标的最佳模型?
我问,因为这是结构化翻译,而不是普通机器翻译中的简单字符映射
答案 0 :(得分:2)
我怀疑神经网络会学习抽象的结构转换。由于字符串的输入长度是无限制的,因此有限的NN将没有必要的信息。 NLP流程通常用于识别小块和简单的上下文相关转换。我认为他们无法确定所需的端到端交换。
但是,我希望适用于单一维度的图像处理器会很快学会这一点。有些人可以学习如何旋转子图像。
答案 1 :(得分:1)
如果您的网络是老式的编码器/解码器模型(无需关注),则正如@Prune所说,它具有内存瓶颈(编码器维数)。因此,这样的网络不能学习反向任意大小的字符串。但是,您可以训练这样的RNN以反转有限大小的字符串。例如,以下玩具seq2seq LSTM能够反转长度最大为10的数字序列。这是训练它的方法:
from keras.models import Model
from keras.layers import Input, LSTM, Dense, Embedding
import numpy as np
emb_dim = 20
latent_dim = 100 # Latent dimensionality of the encoding space.
vocab_size = 12 # digits 0-9, 10 is for start token, 11 for end token
encoder_inputs = Input(shape=(None, ), name='enc_inp')
common_emb = Embedding(input_dim=vocab_size, output_dim=emb_dim)
encoder_emb = common_emb(encoder_inputs)
encoder = LSTM(latent_dim, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_emb)
encoder_states = [state_h, state_c]
decoder_inputs = Input(shape=(None,), name='dec_inp')
decoder_emb = common_emb(decoder_inputs)
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_emb, initial_state=encoder_states)
decoder_dense = Dense(vocab_size, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
def generate_batch(length=4, batch_size=64):
x = np.random.randint(low=0, high=10, size=(batch_size, length))
y = x[:, ::-1]
start = np.ones((batch_size, 1), dtype=int) * 10
end = np.ones((batch_size, 1), dtype=int) * 11
enc_x = np.concatenate([start, x], axis=1)
dec_x = np.concatenate([start, y], axis=1)
dec_y = np.concatenate([y, end], axis=1)
dec_y_onehot = np.zeros(shape=(batch_size, length+1, vocab_size), dtype=int)
for row in range(batch_size):
for col in range(length+1):
dec_y_onehot[row, col, dec_y[row, col]] = 1
return [enc_x, dec_x], dec_y_onehot
def generate_batches(batch_size=64, max_length=10):
while True:
length = np.random.randint(low=1, high=max_length)
yield generate_batch(length=length, batch_size=batch_size)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['categorical_accuracy'])
model.fit_generator(generate_batches(), steps_per_epoch=1000, epochs=20)
现在您可以将其应用于反转序列(我的解码器效率很低,但确实说明了原理)
input_seq = np.array([[10, 2, 1, 2, 8, 5, 0, 6]])
result = np.array([[10]])
next_digit = -1
for i in range(100):
next_digit = model.predict([input_seq, result])[0][-1].argmax()
if next_digit == 11:
break
result = np.concatenate([result, [[next_digit]]], axis=1)
print(result[0][1:])
Hoorray,它打印[6 0 5 8 2 1 2]
!
通常,您可以将这种模型视为奇怪的自动编码器(具有相反的副作用),然后选择适合自动编码器的体系结构和训练过程。关于文本自动编码器的文献很多。
此外,如果您注意建立一个编解码器模型,那么它将没有存储瓶颈,因此,原则上,可以用神经元反转 any 个长度的序列网络。但是,注意力需要二次计算时间,因此在实践中,即使是具有注意力的神经网络对于长序列也将非常无效。