如何从权重和偏差中重现Keras模型?

我想使用来自Keras机器学习模型的权重和偏差,在没有安装Keras(并且无法安装)的另一个程序中创建一个数学预测函数。

我有一个简单的多层感知机模型,用于拟合数据。我在Python中运行,使用的后端是Keras和TensorFlow;目前,我使用了一个输入层、一个隐藏层和一个输出层。所有层都使用RELU激活函数,我的优化器是adam,损失函数是均方误差。

据我所知,层的权重应该以数学形式使用,如下所示:

(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):       # 这是输入层。       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])       # 这是隐藏层。       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])       # 这是输出层。       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”是通过以下方式获得的:

    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的答案标记为正确,尽管它在我的代码中没有正常工作(我可能遗漏了某个导入语句)。关键在于激活函数。我使用的是RELU,所以我不应该传递任何负值。此外,jhso展示了一种不使用循环而直接进行矩阵乘法的好方法(我不知道Python可以这样做)。现在我只需要弄清楚如何在c++中实现它!


回答:

我认为在处理机器学习时熟悉线性代数是很好的。当我们有一个形式为sum(matrix elem times another matrix elem)的方程时,通常是简单地进行矩阵乘法,形式为matrix1 * matrix2.T。这大大简化了你的代码:

def modelR(weights, biases, data):   # 这是输入层。   y = np.matmul(data,weights[0])+biases[0][None,:]    y_act = relu(y) #在这里也可以使用dropout或任何其他函数   z = np.matmul(y_act,weights[1])+biases[1][None,:]   z_act = relu(z) #在这里也可以使用dropout和任何其他函数   p = np.matmul(z_act,weights[2])+biases[2][None,:]   p_act = sigmoid(p)      return p_act

我对你使用的激活函数做了一个猜测。我也不确定你的数据是如何组织的,只需确保特征/权重始终是乘法的内维度,即,如果你的输入是(Bx10)而你的权重是(10×64),那么input*weights就足够了,并且将产生形状为(Bx64)的输出。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注