2017-02-20 7 views
16

Próbuję dopasować RNN w Keras za pomocą sekwencji, które mają różne długości czasu. Moje dane znajdują się w tablicy Numpy w formacie (sample, time, feature) = (20631, max_time, 24), gdzie max_time jest określany w czasie wykonywania jako liczba kroków dostępnych dla próbki z największą liczbą znaczników czasu. Wprowadziłem początek każdej serii czasowej z 0, z wyjątkiem najdłuższej, oczywiście.Keras Maskowanie dla RNN z różnymi czasami Kroki

Ja początkowo zdefiniowany tak jak mój model ...

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

Dla kompletności, oto kod dla funkcji straty:

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) 

A oto kod dla funkcji niestandardowej aktywacyjnym :

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) 

Kiedy dopasowuję model i wykonuję przewidywania testowe, każda próbka w zestawie testowym otrzymuje dokładnie taką samą prognozę, która wydaje się podejrzana.

Rzeczy się poprawią, jeśli usunę warstwę maskującą, co powoduje, że myślę, że coś jest nie tak z warstwą maskującą, ale z tego co wiem, dokładnie śledziłem dokumentację.

Czy jest coś niewłaściwie określonego w warstwie maskującej? Czy brakuje mi czegoś innego?

+1

Mam kilka uwag: 1. dlaczego ustawiłeś stałą "1e-35", gdy dokładność 'float32' wynosi faktycznie' 1e-7'? –

+1

Jeśli chodzi o moją nagrodę, po prostu chcę mieć przykład prawidłowego użycia warstwy maskującej dla sekwencji o różnych długościach. Nie martw się o specyfikę sieci. – Seanny123

Odpowiedz

2

Nie mogłem sprawdzić poprawności bez rzeczywistych danych, ale miałem podobne doświadczenie z RNN. W moim przypadku normalizacja rozwiązała problem. Dodaj warstwę normalizacyjną do swojego modelu.

+0

Przepraszam za to, że jestem WOLNY i doceniam wkład każdego. To był rzeczywiście problem - pominąłem normalizację, próbując zhakować razem minimalny możliwy przykład, ale był to fatalny błąd. Dla zainteresowanych, wynikowy model (inne dane, choć) jest tutaj: https://github.com/daynebatten/keras-wtte-rnn –

2

Sposób zaimplementowania maskowania powinien być poprawny. Jeśli masz dane o kształcie (sample, timesteps, features) i chcesz maskować timesteps bez danych z maską zerową o tym samym rozmiarze co argument features, dodajesz Masking(mask_value=0., input_shape=(timesteps, features)). Zobacz tutaj: keras.io/layers/core/#masking

Twój model może być zbyt prosty i/lub liczba epok może być niewystarczająca, aby model mógł rozróżnić wszystkie klasy. Spróbuj tego modelu:

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

Jeśli to nie zadziała, spróbuj podwojenie epok kilka razy (na przykład 200, 400) i sprawdzić, czy to poprawia wyniki.