【问题标题】:How to manually obtain the same output as model.predict() in keras如何在keras中手动获取与model.predict()相同的输出
【发布时间】:2019-05-09 20:22:00
【问题描述】:

我正在尝试通过 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() 的预测没有太大区别。我做错了一些乘法吗?

【问题讨论】:

    标签: python python-3.x numpy keras recurrent-neural-network


    【解决方案1】:

    您应该使用一个零数组作为 mult_2 中 rnn 的初始状态。 下面两个sn-ps的代码会给你同样的结果:

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

    【讨论】:

    • 这是问题之一。主要问题是我使用 -99 作为掩码值而不是 0,并且 keras 在预测时将这些值更改为 0。当我将 -99 更改为 0 时,它起作用了。
    猜你喜欢
    • 2020-10-24
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多