2016-05-19 6 views
6

के लिए केरास/थेनो के साथ एक बहुत ही सरल एलएसटीएम को कॉन्फ़िगर कैसे करें मैं एक सरल प्रतिगमन कार्य के लिए केरास एलएसटीएम को कॉन्फ़िगर करने के लिए संघर्ष कर रहा हूं। आधिकारिक पृष्ठ पर कुछ बहुत ही बुनियादी स्पष्टीकरण है: Keras RNN documentationरीग्रेशन

लेकिन पूरी तरह से समझने के लिए, उदाहरण डेटा के साथ उदाहरण कॉन्फ़िगरेशन अत्यंत उपयोगी होगा।

मुझे केवल केरास-एलएसटीएम के साथ रिग्रेशन के लिए उदाहरण मिल गए हैं। अधिकांश उदाहरण वर्गीकरण (पाठ या छवियों) के बारे में हैं। मैंने एलएसटीएम उदाहरणों का अध्ययन किया है जो केरा वितरण के साथ आते हैं और एक उदाहरण मैंने Google खोज के माध्यम से पाया: http://danielhnyk.cz/ यह कुछ अंतर्दृष्टि प्रदान करता है, हालांकि लेखक स्वीकार करते हैं कि दृष्टिकोण काफी स्मृति-अक्षम है, क्योंकि डेटा नमूने बहुत अनावश्यक रूप से संग्रहीत किए जाने चाहिए।

हालांकि, एक टिप्पणीकर्ता (ताहा) द्वारा एक सुधार शुरू किया गया था, डेटा भंडारण अभी भी अनावश्यक है, मुझे संदेह है कि यह केरास डेवलपर्स द्वारा किया जाने वाला तरीका है।

मैंने कुछ सरल उदाहरण अनुक्रमिक डेटा डाउनलोड किया है, जो याहू वित्त से स्टॉक डेटा होता है। यह याहू से वित्त 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 

तालिका एप्पल स्टॉक से अधिक का डेटा 8900 में इस तरह के लाइनें शामिल हैं स्वतंत्र रूप से उपलब्ध है। प्रत्येक दिन के लिए 7 कॉलम = डेटा पॉइंट हैं। मूल्य भविष्यवाणी करने के लिए "AdjClose" है, जो दिन

के अंत में मूल्य है तो लक्ष्य पिछले कुछ दिनों के अनुक्रम के आधार पर अगले दिन के लिए AdjClose भविष्यवाणी करने के लिए, हो सकता है हो सकता है । (यह शायद असंभव के बगल में है, लेकिन यह देखना हमेशा अच्छा होता है कि उपकरण चुनौतीपूर्ण परिस्थितियों में कैसे व्यवहार करता है।)

मुझे लगता है कि यह एलएसटीएम के लिए एक बहुत ही मानक भविष्यवाणी/प्रतिगमन मामला होना चाहिए और आसानी से अन्य समस्या डोमेन में स्थानांतरित होना चाहिए।

तो, न्यूनतम अनावश्यकता के लिए डेटा को स्वरूपित किया जाना चाहिए (X_train, y_train) और मैं केवल एक एलएसटीएम परत और कुछ छिपे न्यूरॉन्स के साथ अनुक्रमिक मॉडल कैसे प्रारंभ करूं?

सधन्यवाद, थियो

पुनश्च: मैं इस कोडिंग शुरू कर दिया:

... 
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) 

अब तक, डेटा तैयार है। कोई अनावश्यकता नहीं है। अब सवाल यह है कि इस डेटा पर केरास एलएसटीएम मॉडल/प्रशिक्षण प्रक्रिया का वर्णन कैसे करें।

संपादित करें 3:

यहाँ आवर्तक नेटवर्क के लिए आवश्यक 3 डी डेटा संरचना के साथ अद्यतन कोड है। (लॉरिट द्वारा जवाब देखें)। हालांकि यह काम नहीं करता है।

संपादित करें 4: सक्रियण ('सिग्मोइड') के बाद अतिरिक्त कॉमा को हटा दिया गया है, सही तरीके से Y_train आकार दिया गया है। अभी भी वही त्रुटि।

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) 
वहाँ

अभी भी डेटा के साथ समस्या हो रहा है, Keras का कहना है:

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 

उत्तर

1

तुम अब भी LSTM के लिए डेटा को खिलाने से पहले एक preprocessing कदम याद कर रहे हैं।आपको यह तय करना होगा कि पिछले दिन के AdjClose की गणना में आप कितने पिछले डेटा नमूने (पिछले दिन) शामिल करना चाहते हैं। ऐसा करने के तरीके पर मेरा उत्तर here देखें। आपका डेटा तब आकार का 3-आयामी होना चाहिए (nb_samples, nb_included_previous_days, विशेषताएं)।

फिर आप एक आउटपुट के साथ एक मानक एलएसटीएम परत में 3 डी फ़ीड कर सकते हैं। यह मान आप y_train से तुलना कर सकते हैं और त्रुटि को कम करने का प्रयास कर सकते हैं। रिग्रेशन के लिए उचित हानि फ़ंक्शन चुनना याद रखें, उदा। मतलब चुकता त्रुटि।

+0

तो जुड़ा हुआ उदाहरण की तुलना में, मेरे मामले में नमूनों की संख्या 1. होगा मैं केवल उत्पादन सबसे हाल ही में 5 आदानों/timesteps का उपयोग कर भविष्यवाणी करने के लिए चाहते हैं, अपने डेटा के आकार होना चाहिए (8900 , 5, 6)। क्या इसका मतलब डेटा संग्रहित करने के लिए लगभग 5 का रिडंडेंसी कारक नहीं है ?! –

+0

हां, यह करता है। इस उदाहरण में, अनावश्यकता कोई समस्या नहीं होनी चाहिए, क्योंकि फ्लोट्स के एक (8900, 5, 6) डेटासेट में केवल 1 एमबी रैम है। बड़े डेटासेट (विशेष रूप से जिनके पास अधिक सुविधाएं हैं) के साथ काम करते समय, आप वास्तविक मानों के लिए लुकअप टेबल का उपयोग करने पर विचार करना चाहेंगे और केवल उन्हें अपने एलएसटीएम के इनपुट में संदर्भित करना चाहेंगे। केरा एंबेडिंग परत आपको ऐसा करने में मदद कर सकती है। – Lorrit

+0

ठीक है, अगर अनावश्यकता टालने योग्य नहीं है, तो हो। मैंने आपके कोड का उपयोग प्रीप्रोसेस X_train और Y_train पर किया है। X_train का प्रत्येक नमूना अब 4 टाइमस्टेप्स और 5 फीचर्स का अनुक्रम है। और तदनुसार 4 वाई-मान (उदाहरण के रूप में आउटपुट - प्रत्येक टाइमस्टेप के लिए) हैं। कृपया अद्यतन कोड देखें। यह काम नहीं करता। केरास कहते हैं, "इनपुट 0 परत lstm_1 के साथ असंगत है: अपेक्षित ndim = 3, मिला ndim = 2"; बीटीडब्ल्यू, डेटा याहू फाइनेंस से मुक्त रूप से उपलब्ध है- gartance.yahoo.com/table.csv?s=AAPL&a=11&b=12&c=1980&d=04&e=23&f=2016&g=d&ignore=.csv –

2

आपकी मॉडल परिभाषा में आपने एलएसटीएम परत से पहले एक घन परत रखी। आपको घने परत पर टाइमडिस्ट्रिब्यूटेड परत का उपयोग करने की आवश्यकता है।

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 = Sequential([ 
    TimeDistributed(Dense(8, input_dim=nb_features, Activation='softmax')), 
    LSTM(4, dropout_W=0.2, dropout_U=0.2), 
    Dense(1), 
    Activation('sigmoid') 
]) 
0

सुनिश्चित नहीं हैं कि अगर यह अभी भी प्रासंगिक है, लेकिन कैसे डॉ जेसन पर समय श्रृंखला की भविष्यवाणी के लिए LSTM नेटवर्क का उपयोग करने का एक बढ़िया उदाहरण है परिवर्तित करने का प्रयास ब्राउनलीज ब्लॉग here

मैंने तीन शोर चरण पर एक उदाहरण तैयार किया जिसमें विभिन्न आयामों के साथ साइनसॉइड को स्थानांतरित किया गया। बाजार डेटा नहीं, लेकिन मुझे लगता है, आप मानते हैं कि एक स्टॉक दूसरे के बारे में कुछ कहता है।

import numpy 
import matplotlib.pyplot as plt 
import pandas 
import math 
from keras.models import Sequential 
from keras.layers import Dense 
from keras.layers import LSTM 
from keras.layers import Reshape 
from sklearn.preprocessing import MinMaxScaler 
from sklearn.metrics import mean_squared_error 
# generate sine wavepip 
def make_sine_with_noise(_start, _stop, _step, _phase_shift, gain): 
    x = numpy.arange(_start, _stop, step = _step) 
    noise = numpy.random.uniform(-0.1, 0.1, size = len(x)) 
    y = gain*0.5*numpy.sin(x+_phase_shift) 
    y = numpy.add(noise, y) 
    return x, y 
# convert an array of values into a dataset matrix 
def create_dataset(dataset, look_back=1, look_ahead=1): 
    dataX, dataY = [], [] 
    for i in range(len(dataset) - look_back - look_ahead - 1): 
     a = dataset[i:(i + look_back), :] 
     dataX.append(a) 
     b = dataset[(i + look_back):(i + look_back + look_ahead), :] 
     dataY.append(b) 
    return numpy.array(dataX), numpy.array(dataY) 
# fix random seed for reproducibility 
numpy.random.seed(7) 
# generate sine wave 
x1, y1 = make_sine_with_noise(0, 200, 1/24, 0, 1) 
x2, y2 = make_sine_with_noise(0, 200, 1/24, math.pi/4, 3) 
x3, y3 = make_sine_with_noise(0, 200, 1/24, math.pi/2, 20) 
# plt.plot(x1, y1) 
# plt.plot(x2, y2) 
# plt.plot(x3, y3) 
# plt.show() 
#transform to pandas dataframe 
dataframe = pandas.DataFrame({'y1': y1, 'y2': y2, 'x3': y3}) 
dataset = dataframe.values 
dataset = dataset.astype('float32') 
# normalize the dataset 
scaler = MinMaxScaler(feature_range=(0, 1)) 
dataset = scaler.fit_transform(dataset) 
#split into train and test sets 
train_size = int(len(dataset) * 0.67) 
test_size = len(dataset) - train_size 
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:] 
# reshape into X=t and Y=t+1 
look_back = 10 
look_ahead = 5 
trainX, trainY = create_dataset(train, look_back, look_ahead) 
testX, testY = create_dataset(test, look_back, look_ahead) 
print(trainX.shape) 
print(trainY.shape) 
# reshape input to be [samples, time steps, features] 
trainX = numpy.reshape(trainX, (trainX.shape[0], trainX.shape[1], trainX.shape[2])) 
testX = numpy.reshape(testX, (testX.shape[0], testX.shape[1], testX.shape[2])) 
# create and fit the LSTM network 
model = Sequential() 
model.add(LSTM(look_ahead, input_shape=(trainX.shape[1], trainX.shape[2]), return_sequences=True)) 
model.add(LSTM(look_ahead, input_shape=(look_ahead, trainX.shape[2]))) 
model.add(Dense(trainY.shape[1]*trainY.shape[2])) 
model.add(Reshape((trainY.shape[1], trainY.shape[2]))) 
model.compile(loss='mean_squared_error', optimizer='adam') 
model.fit(trainX, trainY, epochs=1, batch_size=1, verbose=1) 
# make prediction 
trainPredict = model.predict(trainX) 
testPredict = model.predict(testX) 

#save model 
model.save('my_sin_prediction_model.h5') 

trainPredictPlottable = trainPredict[::look_ahead] 
trainPredictPlottable = [item for sublist in trainPredictPlottable for item in sublist] 
trainPredictPlottable = scaler.inverse_transform(numpy.array(trainPredictPlottable)) 
# create single testPredict array concatenating every 'look_ahed' prediction array 
testPredictPlottable = testPredict[::look_ahead] 
testPredictPlottable = [item for sublist in testPredictPlottable for item in sublist] 
testPredictPlottable = scaler.inverse_transform(numpy.array(testPredictPlottable)) 
# testPredictPlottable = testPredictPlottable[:-look_ahead] 
# shift train predictions for plotting 
trainPredictPlot = numpy.empty_like(dataset) 
trainPredictPlot[:, :] = numpy.nan 
trainPredictPlot[look_back:len(trainPredictPlottable)+look_back, :] = trainPredictPlottable 
# shift test predictions for plotting 
testPredictPlot = numpy.empty_like(dataset) 
testPredictPlot[:, :] = numpy.nan 
testPredictPlot[len(dataset)-len(testPredictPlottable):len(dataset), :] = testPredictPlottable 
# plot baseline and predictions 
dataset = scaler.inverse_transform(dataset) 
plt.plot(dataset, color='k') 
plt.plot(trainPredictPlot) 
plt.plot(testPredictPlot) 
plt.show() 
संबंधित मुद्दे