如何从权重/偏倚中复制Keras模型?

时间:2019-11-21 20:15:20

标签: python tensorflow machine-learning keras

我想使用Keras ML模型的权重和偏差在另一个没有安装Keras(也不能安装)的程序中进行数学预测。

我有一个简单的MLP模型,用于拟合数据。我正在使用Keras和TensorFlow后端在Python中运行;现在,我正在使用一个输入层,1个隐藏层和1个输出层。所有层都是RELU,我的优化器是adam,损失函数是mean_squared_error。

据我了解,各层获得的权重应以数学形式使用:

(SUM (w*i)) + b

总和是所有权重和输入的总和,b是神经元的偏差。例如,假设我有一个形状为(33,64)的输入层。有33个输入和64个神经元。我将获得一个矢量输入(昏暗的33)和一个矢量输出(昏暗的64)。这将使每个SUM 33项* 33权重,并且输出将是所有64个SUM加64个偏差(分别)。

在我的情况下,下一层是32个神经元,将执行相同的操作,但具有64个输入和32个输出。我的输出层为单个值,因此输入32为输出1。

我已经编写了代码来尝试模拟该模型。这是进行单个预测的代码段:

    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的答案标记为正确,即使这样在我的代码中无法正常工作(我可能在某处缺少了import语句)。关键是激活功能。我使用的是RELU,所以我不应该传递任何负值。而且,jhso显示了一种不使用循环而是简单地进行矩阵乘法的好方法(我不知道Python是这样做的)。现在,我只需要弄清楚如何用c ++做到这一点!

1 个答案:

答案 0 :(得分:1)

我认为在进行机器学习时熟悉线性代数是很好的。当我们拥有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 形式的简单矩阵乘法。这样可以大大简化您的代码:

input*weights

我猜测您使用了哪种激活功能。我也不确定您的数据的结构,只需确保要素/权重始终是乘法的内部维度即可。如果您输入的是(Bx10),权重是(10x64),那么Airplane.java就足够了,并且会产生形状为(Bx64)的输出。