Non riesco a configurare un KSTS LSTM per una semplice attività di regressione. C'è una spiegazione molto semplice nella pagina ufficiale: Keras RNN documentationCome configurare un LSTM molto semplice con Keras/Theano per la regressione
Ma per comprendere appieno, le configurazioni di esempio con i dati di esempio sarebbero estremamente utili.
Ho appena trovato esempi di regressione con Keras-LSTM. La maggior parte degli esempi riguarda la classificazione (testo o immagini). Ho studiato gli esempi LSTM forniti con la distribuzione di Keras e un esempio che ho trovato attraverso la ricerca di Google: http://danielhnyk.cz/ Offre alcune informazioni, sebbene l'autore ammetta che l'approccio è abbastanza inefficiente dalla memoria, poiché gli esempi di dati devono essere archiviati in modo molto ridondante.
Sebbene un miglioramento sia stato introdotto da un commentatore (Taha), l'archiviazione dei dati è ancora ridondante, dubito che questo sia il modo in cui doveva essere realizzato dagli sviluppatori di Keras.
Ho scaricato alcuni semplici dati sequenziali di esempio, che sono i dati di borsa della finanza di Yahoo. E 'disponibile gratuitamente da Yahoo Finance Data
Date, Open, High, Low, Close, Volume, Adj Close
2016-05-18, 94.160004, 95.209999, 93.889999, 94.559998, 41923100, 94.559998
2016-05-17, 94.550003, 94.699997, 93.010002, 93.489998, 46507400, 93.489998
2016-05-16, 92.389999, 94.389999, 91.650002, 93.879997, 61140600, 93.879997
2016-05-13, 90.00, 91.669998, 90.00, 90.519997, 44188200, 90.519997
La tabella è costituita da più di 8900 tali linee di dati Stock Apple. Ci sono 7 colonne = punti dati per ogni giorno. Il valore di predire sarebbe "AdjClose", che è il valore alla fine della giornata
Quindi l'obiettivo sarebbe quello di prevedere il AdjClose per il giorno successivo, in base alla sequenza di un precedente pochi giorni . (Probabilmente è quasi impossibile, ma è sempre bene vedere come si comporta uno strumento in condizioni difficili.)
Penso che questo dovrebbe essere un caso di predizione/regressione molto standard per LSTM e facilmente trasferibile ad altri domini problematici.
Quindi, come devono essere formattati i dati (X_train, y_train) per la ridondanza minima e come inizializzare il modello sequenziale con un solo strato LSTM e un paio di neuroni nascosti?
Cordiali saluti, Theo
PS: ho iniziato la codifica questo:
...
X_train
Out[6]:
array([[ 2.87500000e+01, 2.88750000e+01, 2.87500000e+01,
2.87500000e+01, 1.17258400e+08, 4.31358010e-01],
[ 2.73750019e+01, 2.73750019e+01, 2.72500000e+01,
2.72500000e+01, 4.39712000e+07, 4.08852011e-01],
[ 2.53750000e+01, 2.53750000e+01, 2.52500000e+01,
2.52500000e+01, 2.64320000e+07, 3.78845006e-01],
...,
[ 9.23899994e+01, 9.43899994e+01, 9.16500015e+01,
9.38799973e+01, 6.11406000e+07, 9.38799973e+01],
[ 9.45500031e+01, 9.46999969e+01, 9.30100021e+01,
9.34899979e+01, 4.65074000e+07, 9.34899979e+01],
[ 9.41600037e+01, 9.52099991e+01, 9.38899994e+01,
9.45599976e+01, 4.19231000e+07, 9.45599976e+01]], dtype=float32)
y_train
Out[7]:
array([ 0.40885201, 0.37884501, 0.38822201, ..., 93.87999725,
93.48999786, 94.55999756], dtype=float32)
Finora, i dati sono pronti. Non è stata introdotta alcuna ridondanza. Ora la domanda è, come descrivere un modello/processo di addestramento KST LSTM su questi dati.
EDIT 3:
Ecco il codice aggiornato con la struttura di dati 3D necessari per reti ricorrenti. (Vedi risposta di Lorrit). Non funziona, però.
EDIT 4: rimossa la virgola extra dopo l'attivazione ('sigmoid'), sagomata Y_train nel modo corretto. Ancora lo stesso errore.
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation, LSTM
nb_timesteps = 4
nb_features = 5
batch_size = 32
# load file
X_train = np.genfromtxt('table.csv',
delimiter=',',
names=None,
unpack=False,
dtype=None)
# delete the first row with the names
X_train = np.delete(X_train, (0), axis=0)
# invert the order of the rows, so that the oldest
# entry is in the first row and the newest entry
# comes last
X_train = np.flipud(X_train)
# the last column is our Y
Y_train = X_train[:,6].astype(np.float32)
Y_train = np.delete(Y_train, range(0,6))
Y_train = np.array(Y_train)
Y_train.shape = (len(Y_train), 1)
# we don't use the timestamps. convert the rest to Float32
X_train = X_train[:, 1:6].astype(np.float32)
# shape X_train
X_train.shape = (1,len(X_train), nb_features)
# Now comes Lorrit's code for shaping the 3D-input-data
# http://stackoverflow.com/questions/36992855/keras-how-should-i-prepare-input-data-for-rnn
flag = 0
for sample in range(X_train.shape[0]):
tmp = np.array([X_train[sample,i:i+nb_timesteps,:] for i in range(X_train.shape[1] - nb_timesteps + 1)])
if flag==0:
new_input = tmp
flag = 1
else:
new_input = np.concatenate((new_input,tmp))
X_train = np.delete(new_input, len(new_input) - 1, axis = 0)
X_train = np.delete(X_train, 0, axis = 0)
X_train = np.delete(X_train, 0, axis = 0)
# X successfully shaped
# free some memory
tmp = None
new_input = None
# split data for training, validation and test
# 50:25:25
X_train, X_test = np.split(X_train, 2, axis=0)
X_valid, X_test = np.split(X_test, 2, axis=0)
Y_train, Y_test = np.split(Y_train, 2, axis=0)
Y_valid, Y_test = np.split(Y_test, 2, axis=0)
print('Build model...')
model = Sequential([
Dense(8, input_dim=nb_features),
Activation('softmax'),
LSTM(4, dropout_W=0.2, dropout_U=0.2),
Dense(1),
Activation('sigmoid')
])
model.compile(loss='mse',
optimizer='RMSprop',
metrics=['accuracy'])
print('Train...')
print(X_train.shape)
print(Y_train.shape)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=15,
validation_data=(X_test, Y_test))
score, acc = model.evaluate(X_test, Y_test,
batch_size=batch_size)
print('Test score:', score)
print('Test accuracy:', acc)
Ci
sembra ancora essere un problema con i dati, Keras dice:
Using Theano backend.
Using gpu device 0: GeForce GTX 960 (CNMeM is disabled, cuDNN not available)Build model...
Traceback (most recent call last):
File "<ipython-input-1-3a6e9e045167>", line 1, in <module>
runfile('C:/Users/admin/Documents/pycode/lstm/lstm5.py', wdir='C:/Users/admin/Documents/pycode/lstm')
File "C:\Users\admin\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 699, in runfile
execfile(filename, namespace)
File "C:\Users\admin\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 74, in execfile
exec(compile(scripttext, filename, 'exec'), glob, loc)
File "C:/Users/admin/Documents/pycode/lstm/lstm5.py", line 79, in <module>
Activation('sigmoid')
File "d:\git\keras\keras\models.py", line 93, in __init__
self.add(layer)
File "d:\git\keras\keras\models.py", line 146, in add
output_tensor = layer(self.outputs[0])
File "d:\git\keras\keras\engine\topology.py", line 441, in __call__
self.assert_input_compatibility(x)
File "d:\git\keras\keras\engine\topology.py", line 382, in assert_input_compatibility
str(K.ndim(x)))
Exception: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=2
Quindi rispetto all'esempio legata, nel mio caso il numero di campioni sarebbe 1. Se solo voglio prevedere l'output utilizzando le più recenti 5 ingressi/Timesteps, la forma dei miei dati dovrebbe essere (8900 , 5, 6). Questo non significa un fattore di ridondanza di quasi 5 per la memorizzazione dei dati ?! –
Sì, lo fa. In questo esempio, la ridondanza non dovrebbe essere un problema, dal momento che un dataset (8900, 5, 6) di float occupa solo circa 1Mb di RAM. Quando si lavora con insiemi di dati più grandi (specialmente quelli che hanno più funzioni), si potrebbe prendere in considerazione l'utilizzo di una tabella di ricerca per i valori effettivi e solo fare riferimento ad essi nell'input del proprio LSTM. Il livello di incorporamento di Keras può aiutarti a farlo. – Lorrit
Ok, se la ridondanza non è evitabile, così sia. Ho usato il tuo codice per preelaborare X_train e Y_train ora. Ogni campione di X_train è ora una sequenza di 4 timestep e 5 funzioni. E ci sono 4 valori Y (come output di esempio - uno per ogni timestep), di conseguenza. Si prega di consultare il codice aggiornato. Non funziona. Keras dice "Input 0 non compatibile con layer lstm_1: expected ndim = 3, found ndim = 2"; Btw, i dati sono liberamente disponibili da Yahoo Finance real-chart.finance.yahoo.com/table.csv?s=AAPL&a=11&b=12&c=1980&d=04&e=23&f=2016&g=d&ignore=.csv –