Как вручную получить тот же вывод, что и model.predict () в керасе - PullRequest
1 голос
/ 09 мая 2019

Я пытаюсь воспроизвести через Numpy вывод, который я получу, используя Keras 'model.predict().Мои уровни модели keras следующие:

_________________________________________________________________
Layer (type)                 Output Shape              Param    
=================================================================
main_input (InputLayer)      (None, 10, 76)            0         
_________________________________________________________________
masking (Masking)            (None, 10, 76)            0         
_________________________________________________________________
rnn (SimpleRNN)              [(None, 64), (None, 64)]  9024      
_________________________________________________________________
dropout_15 (Dropout)         (None, 64)                0         
_________________________________________________________________
dense1 (Dense)               (None, 64)                4160      
_________________________________________________________________
denseoutput (Dense)          (None, 1)                 65        
=================================================================
Total params: 13,249
Trainable params: 13,249
Non-trainable params: 0

Второй вывод слоя SimpleRNN - это состояние, возвращаемое return_state=True.

Я пробовал 2 разных подхода.Сначала я вычислил WXt + Us + b , где W - это ядро, Xt - это ввод, U - рекуррентное ядро., s - это состояние, полученное через return_state=True, а b - это смещение.Это вернуло результат, аналогичный полученному с помощью predict() (функция mult_1).

После этого я попробовал аналогичный подход с функцией mult_2, но получил худшие результаты, чем с mult_1.

def mult_1(X):
    X = ma.masked_values(X, -99)
    s = (model.predict(X)[1])

    W = (model.get_weights()[0])
    U = (model.get_weights()[1])
    b = (model.get_weights()[2])

    Wx = np.dot(X[:,-1,:], W)
    Us = np.dot(s,U)

    output = Wx + Us + b

    return np.tanh(output)

def mult2(X):
    max_habitantes = X.shape[1]
    i = 0
    s_0 = np.ones((X.shape[0], 64)) # initial state
    X = ma.masked_values(X, -99)

    while i < 10:
        Xt = X[:,i,:]
        if i == 0:
            s = s_0
        else:
            s = output

        W = (model.get_weights()[0])
        U = (model.get_weights()[1])
        b = (model.get_weights()[2])

        Wx = np.dot(Xt, W)
        Us = np.dot(s,U)

        output = np.tanh(Wx + Us +b)
        i = i+1

    return output

Прогнозы несколько схожи, хотя и ничем не отличаются от прогнозов predict().Я делаю некоторые умножения неправильно?

1 Ответ

0 голосов
/ 17 мая 2019

Вы должны использовать массив нулей в качестве начального состояния для rnn в mult_2.Следующие два фрагмента кода дают один и тот же результат:

x = np.random.rand(1,10,76)

Использование Keras model.predict ()

inputs = Input(shape=(10,76), dtype=np.float32)
_, state = SimpleRNN(units=64, return_state=True)(inputs)
out_drop = Dropout(0.2)(state)
out_d1 = Dense(64, activation='tanh')(out_drop)
out = Dense(1, activation='tanh')(out_d1)

model = Model(inputs, out)

In [1]: model.predict(x) Out[1]: array([[-0.82426485]]

Использование NumPyфункция для прогнозирования:

def rnn_pred(X):
    """
    Same as your mult_2 func. but with zero init. for rnn initial state
    """
    W = (model.get_weights()[0])
    U = (model.get_weights()[1])
    b = (model.get_weights()[2])

    max_habitantes = X.shape[1]
    i = 0
    s_0 = np.zeros((X.shape[0], 64)) # initial state

    while i < 10:
        Xt = X[:,i,:]
        if i == 0:
            s = s_0
        else:
            s = output

        Wx = np.dot(Xt, W)
        Us = np.dot(s,U)

        output = np.tanh(Wx+Us+b)
        i = i+1

    return output

def dense_pred(rnn_out):
    U_d1 = (model.get_weights()[3]) # dense64 weights
    b_d1 = (model.get_weights()[4]) # dense64 bias
    U_d2 = (model.get_weights()[5]) # dense1 weights
    b_d2 = (model.get_weights()[6]) # dense1 bias

    out1 = np.dot(rnn_out, U_d1) + b_d1
    out1 = np.tanh(out1)
    out2 = np.dot(out1, U_d2) + b_d2
    out2 = np.tanh(out2)
    return out2

In [2]: dense_pred(rnn_pred(x)) Out[2]: array([[-0.82426485]])

...