繁体   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