python - 如何从权重/偏差中重现 Keras 模型?
问题描述
我想使用 Keras ML 模型中的权重和偏差在另一个没有安装 Keras(并且不能)的程序中进行数学预测函数。
我有一个简单的 MLP 模型,用于拟合数据。我在 Python 中运行 Keras 和 TensorFlow 后端;现在,我正在使用一个输入层、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 的答案标记为正确,即使它在我的代码中无法正常工作(我可能在某处缺少导入语句)。关键是激活功能。我使用的是 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
我猜测您使用的是哪个激活函数。我也不确定您的数据是如何构造的,只要确保特征/权重始终是乘法的内部维度,即。如果您的输入是 (Bx10) 并且您的权重是 (10x64) 那么input*weights
就足够了,并且会产生形状 (Bx64) 的输出。
推荐阅读
- java - 使用带有 java gui 的链表将文本字段的内容保存在 List 中
- android - 语音识别的不同模型
- python - 数组不是本地的,而变量是本地的
- gcc - grep 如何使用行的开头和结尾
- python - 是什么让 python 元组不可变。它们是如何在内存中实现的?
- c - 哪种计算 sockaddr_un 结构大小的方法是正确的?
- bash - 使用 AWK 创建基于一个文件的文件夹和基于另一个文件的文件夹中的文件
- python - 当您有太多列时融化(unpivot)Pandas 数据框?
- python - 为什么我会收到“分配前引用”错误?
- javascript - Stripe Connect 转账:资金不足