2017-02-20 74 views
16

我想要使用具有不同時間長度的序列在Keras中擬合RNN。我的數據是一個Numpy數組,其格式爲(sample, time, feature) = (20631, max_time, 24),其中max_time在運行時確定爲具有大多數時間戳的樣本可用的時間步數。我已經用0填充了每個時間序列的開頭,顯然,除了最長的一個。Keras掩蔽RNN的變化時間步驟

我最初定義我的模式是這樣的...

model = Sequential() 
model.add(Masking(mask_value=0., input_shape=(max_time, 24))) 
model.add(LSTM(100, input_dim=24)) 
model.add(Dense(2)) 
model.add(Activation(activate)) 
model.compile(loss=weibull_loglik_discrete, optimizer=RMSprop(lr=.01)) 
model.fit(train_x, train_y, nb_epoch=100, batch_size=1000, verbose=2, validation_data=(test_x, test_y)) 

爲了完整起見,這裏的損失函數的代碼:

def weibull_loglik_discrete(y_true, ab_pred, name=None): 
    y_ = y_true[:, 0] 
    u_ = y_true[:, 1] 
    a_ = ab_pred[:, 0] 
    b_ = ab_pred[:, 1] 

    hazard0 = k.pow((y_ + 1e-35)/a_, b_) 
    hazard1 = k.pow((y_ + 1)/a_, b_) 

    return -1 * k.mean(u_ * k.log(k.exp(hazard1 - hazard0) - 1.0) - hazard1) 

而這裏的自定義激活函數的代碼:

def activate(ab): 
    a = k.exp(ab[:, 0]) 
    b = k.softplus(ab[:, 1]) 

    a = k.reshape(a, (k.shape(a)[0], 1)) 
    b = k.reshape(b, (k.shape(b)[0], 1)) 

    return k.concatenate((a, b), axis=1) 

當我擬合模型並做出一些測試預測時,測試集中的每個樣本獲得完全相同的預測,這似乎很腥。

如果我刪除了遮罩層,這會讓我覺得遮罩層有問題,但事實會變得更好,但據我所知,我完全按照文檔。

是否存在與掩蔽層錯誤指定的內容?我錯過了別的嗎?

+1

我有幾點意見:1.爲什麼當'float32'的準確度實際上是'1e-7'時,你設置了一個'1e-35'常量? –

+1

就我的賞金而言,我真的只是想要一個正確使用不同長度序列的掩蔽層的例子。不要擔心網絡細節。 – Seanny123

回答

2

我無法驗證沒有實際數據,但我有與RNN類似的經驗。在我的情況下,正常化解決了這個問題。爲你的模型添加一個規範化圖層。

+0

我對此表示歉意,並感謝大家的意見。這確實是一個問題 - 我試圖將最小可行的例子拼湊在一起時跳過了正常化,但這是一個致命的錯誤。對於那些感興趣的人來說,最終的模型(不同的數據,雖然)在這裏:https://github.com/daynebatten/keras-wtte-rnn –

2

您實施遮罩的方式應該是正確的。如果您的數據形狀爲(樣本,時間步長和特徵),並且您希望掩蓋缺少數據的時間步長,並且與特徵參數的大小相同的零掩碼,則可以添加Masking(mask_value=0., input_shape=(timesteps, features))。看到這裏:keras.io/layers/core/#masking

你的模型可能太簡單了,和/或你的時代數量可能不足以讓模型區分你所有的類。試試這個模型:

model = Sequential() 
model.add(Masking(mask_value=0., input_shape=(max_time, 24))) 
model.add(LSTM(256, input_dim=24)) 
model.add(Dense(1024)) 
model.add(Dense(2)) 
model.add(Activation(activate)) 
model.compile(loss=weibull_loglik_discrete, optimizer=RMSprop(lr=.01)) 
model.fit(train_x, train_y, nb_epoch=100, batch_size=1000, verbose=2, validation_data=(test_x, test_y)) 

如果還是不行,請嘗試時期幾次(例如200,400)增加一倍,看看是否能提高的結果。