簡體   English   中英

如何從權重/偏差中重現 Keras model?

[英]How to reproduce a Keras model from the weights/biases?

I want to use the weights and biases from a Keras ML model to make a mathematical prediction function in another program that does not have Keras installed (and cannot).

我有一個簡單的 MLP model 用於擬合數據。 我正在使用 Keras 和 TensorFlow 后端在 Python 中運行; 目前,我正在使用一個輸入層、1 個隱藏層和 1 個 output 層。 所有層都是RELU,我的優化器是adam,損失function是mean_squared_error。

據我了解,我為圖層獲得的權重應該以以下形式在數學上使用:

(SUM (w*i)) + b

其中總和是所有權重和輸入的總和,b 是神經元上的偏差。 例如,假設我有一個形狀為 (33, 64) 的輸入層。 有 33 個輸入和 64 個神經元。 我將有一個昏暗 33 的向量輸入和一個昏暗 64 的向量 output。這將使每個 SUM 33 個項 * 33 個權重,並且 output 將是所有 64 個 SUM 加上 64 個偏差(分別)。

下一層,在我的例子中是 32 個神經元,將做同樣的事情,但有 64 個輸入和 32 個輸出。 我擁有的 output 層變為單個值,因此輸入 32 和 output 1。

我編寫了代碼來嘗試模仿 model。 這是進行單個預測的片段:

    def modelR(weights, biases, data):
       # This is the input layer.
       y = []
       for i in range(len(weights[0][0])):
           x = np.zeros(len(weights[0][0]))
           for j in range(len(data)):
               x[i] += weights[0][j][i]*data[j]
           y.append(x[i]+biases[0][i])

       # This is the hidden layer.
       z = []
       for i in range(len(weights[1][0])):
           x = np.zeros(len(weights[1][0]))
           for j in range(len(y)):
               x[i] += weights[1][j][i]*y[j]
           z.append(x[i]+biases[1][i])

       # This is the output layer.
       p = 0.0
       for i in range(len(z)):
           p += weights[-1][i][0]*z[i]
       p = p+biases[-1][0]

       return p

需要明確的是,“權重”和“偏差”是通過以下方式得出的:

    weights = []
    biases = []
    for i in range(len(model.layers)):
       weights.append(model.layers[i].get_weights()[0])
       biases.append(model.layers[i].get_weights()[1])

    weights = np.asarray(weights)
    biases = np.asarray(biases)

所以第一個輸入的第一個神經元的第一個權重是 weight[0][0][0],第二個神經元的第一個輸入的第一個權重是 weight[0][1][0],依此類推。這可能是錯誤的,這可能是我卡住的地方。 但這很有意義,因為我們要從 (1 x 33) 向量到 (1 x 64) 向量,所以我們應該有一個 (33 x 64) 矩陣。

關於我哪里出錯的任何想法? 謝謝!

編輯:發現答案我將 jhso 的答案標記為正確,即使它在我的代碼中不能正常工作(我可能在某處缺少導入語句)。 關鍵是激活 function。 我使用的是 RELU,所以我不應該傳遞任何負值。 此外,jhso 展示了一種不使用循環而是簡單地進行矩陣乘法的好方法(我不知道 Python 做過)。 現在我只需要弄清楚如何在 C++ 中做到這一點!

我認為在使用機器學習時熟悉線性代數是件好事。 當我們有一個sum(matrix elem times another matrix elem)形式的方程時,它通常是一個簡單的矩陣乘法,形式為matrix1 * matrix2.T 這大大簡化了您的代碼:

def modelR(weights, biases, data):
   # This is the input layer.
   y = np.matmul(data,weights[0])+biases[0][None,:] 
   y_act = relu(y) #also dropout or any other function you use here
   z = np.matmul(y_act,weights[1])+biases[1][None,:]
   z_act = relu(z) #also dropout and any other function you use here
   p = np.matmul(z_act,weights[2])+biases[2][None,:]
   p_act = sigmoid(p)   
   return p_act

我猜測您使用的是哪個激活 function。 我也不確定您的數據是如何構造的,只要確保特征/權重始終是乘法的內部維度,即。 如果您的輸入是 (Bx10) 並且您的權重是 (10x64),那么input*weights就足夠了,並且會產生一個形狀為 (Bx64) 的 output。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM