На практике даже в НЛП вы видите, что RNN и CNN часто конкурентоспособны. Вот обзорная статья 2017 года, которая показывает это более подробно. Теоретически, это может быть тот случай, когда RNN лучше справляются со всей сложностью и последовательностью языка, но на практике большее препятствие обычно правильно обучает сеть, а RNN являются привередливыми.
Другая проблема, которая может иметь шанс на работу, заключается в том, чтобы посмотреть на проблему, подобную проблеме сбалансированных скобок (либо с простыми скобками в строках, либо с круглыми скобками вместе с другими символами отвлечения). Это требует последовательной обработки входных данных и отслеживания некоторого состояния, и его легче изучить с помощью LSTM, чем с FFN.
Обновление:
Некоторые данные, которые выглядят последовательными, на самом деле могут не обрабатываться последовательно. Например, даже если вы предоставляете последовательность чисел для добавления, так как сложение коммутативно, FFN будет работать так же хорошо, как и RNN. Это также может относиться ко многим проблемам со здоровьем, когда доминирующая информация не носит последовательного характера. Предположим, что каждый год курение пациента измеряется. С поведенческой точки зрения траектория важна, но если вы прогнозируете, будет ли у пациента развиваться рак легкого, в прогнозе будет доминировать только количество лет, в течение которых пациент курил (может быть ограничено последними 10 годами для FFN).
Итак, вы хотите усложнить задачу с игрушкой и потребовать учета порядка данных. Может быть, это какой-то смоделированный временной ряд, в котором вы хотите предсказать, был ли скачок в данных, но вас не волнуют абсолютные значения, только относительный характер скачка.
Update2
Я изменил ваш код, чтобы показать случай, когда RNN работают лучше. Хитрость заключалась в том, чтобы использовать более сложную условную логику, которая более естественно моделируется в LSTM, чем FFN. Код ниже. Для 8 столбцов мы видим, что FFN обучается за 1 минуту и достигает потери проверки 6,3. Тренировка LSTM занимает в 3 раза больше времени, но окончательная потеря в валидации в 6 раз ниже на 1,06.
По мере того, как мы увеличиваем количество столбцов, LSTM имеет все большее и большее преимущество, особенно если мы добавили более сложные условия в. Для 16 столбцов потери проверки FFN составляют 19 (и вы можете более четко увидеть тренировочную кривую в качестве модели). не может мгновенно соответствовать данным). Для сравнения LSTM тренируется в 11 раз дольше, но потери при проверке в 0,31 раза меньше, чем в FFN! Вы можете поиграть с еще большими матрицами, чтобы увидеть, насколько далеко эта тенденция будет расширяться.
from keras import models
from keras import layers
from keras.layers import Dense, LSTM
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import time
matplotlib.use('Agg')
np.random.seed(20180908)
rows = 20500
cols = 10
# Randomly generate Z
Z = 100*np.random.uniform(0.05, 1.0, size = (rows, cols))
larger = np.max(Z[:, :cols/2], axis=1).reshape((rows, 1))
larger2 = np.max(Z[:, cols/2:], axis=1).reshape((rows, 1))
smaller = np.min((larger, larger2), axis=0)
# Z is now the max of the first half of the array.
Z = np.append(Z, larger, axis=1)
# Z is now the min of the max of each half of the array.
# Z = np.append(Z, smaller, axis=1)
# Combine and shuffle.
#Z = np.concatenate((Z_sum, Z_avg), axis = 0)
np.random.shuffle(Z)
## Training and validation data.
split = 10000
X_train = Z[:split, :-1]
X_valid = Z[split:, :-1]
Y_train = Z[:split, -1:].reshape(split, 1)
Y_valid = Z[split:, -1:].reshape(rows - split, 1)
print(X_train.shape)
print(Y_train.shape)
print(X_valid.shape)
print(Y_valid.shape)
print("Now setting up the FNN")
## FNN model.
tick = time.time()
# Define model.
network_fnn = models.Sequential()
network_fnn.add(layers.Dense(32, activation = 'relu', input_shape = (X_train.shape[1],)))
network_fnn.add(Dense(1, activation = None))
# Compile model.
network_fnn.compile(optimizer = 'adam', loss = 'mean_squared_error')
# Fit model.
history_fnn = network_fnn.fit(X_train, Y_train, epochs = 500, batch_size = 128, verbose = False,
validation_data = (X_valid, Y_valid))
tock = time.time()
print()
print(str('%.2f' % ((tock - tick) / 60)) + ' minutes.')
print("Now evaluating the FNN")
loss_fnn = history_fnn.history['loss']
val_loss_fnn = history_fnn.history['val_loss']
epochs_fnn = range(1, len(loss_fnn) + 1)
print("train loss: ", loss_fnn[-1])
print("validation loss: ", val_loss_fnn[-1])
plt.plot(epochs_fnn, loss_fnn, 'black', label = 'Training Loss')
plt.plot(epochs_fnn, val_loss_fnn, 'red', label = 'Validation Loss')
plt.title('FNN: Training and Validation Loss')
plt.legend()
plt.show()
plt.scatter(Y_train, network_fnn.predict(X_train), alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('training points')
plt.show()
plt.scatter(Y_valid, network_fnn.predict(X_valid), alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('valid points')
plt.show()
print("LSTM")
## LSTM model.
X_lstm_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
X_lstm_valid = X_valid.reshape(X_valid.shape[0], X_valid.shape[1], 1)
tick = time.time()
# Define model.
network_lstm = models.Sequential()
network_lstm.add(layers.LSTM(32, activation = 'relu', input_shape = (X_lstm_train.shape[1], 1)))
network_lstm.add(layers.Dense(1, activation = None))
# Compile model.
network_lstm.compile(optimizer = 'adam', loss = 'mean_squared_error')
# Fit model.
history_lstm = network_lstm.fit(X_lstm_train, Y_train, epochs = 500, batch_size = 128, verbose = False,
validation_data = (X_lstm_valid, Y_valid))
tock = time.time()
print()
print(str('%.2f' % ((tock - tick) / 60)) + ' minutes.')
print("now eval")
loss_lstm = history_lstm.history['loss']
val_loss_lstm = history_lstm.history['val_loss']
epochs_lstm = range(1, len(loss_lstm) + 1)
print("train loss: ", loss_lstm[-1])
print("validation loss: ", val_loss_lstm[-1])
plt.plot(epochs_lstm, loss_lstm, 'black', label = 'Training Loss')
plt.plot(epochs_lstm, val_loss_lstm, 'red', label = 'Validation Loss')
plt.title('LSTM: Training and Validation Loss')
plt.legend()
plt.show()
plt.scatter(Y_train, network_lstm.predict(X_lstm_train), alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title('training')
plt.show()
plt.scatter(Y_valid, network_lstm.predict(X_lstm_valid), alpha = 0.1)
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.title("validation")
plt.show()