本文主要记录适用keras的mlp神经网络训练数字识别模型,提取层隐含层的参数。然后直接用这些参数来计算,预测一张数字图片。
首先看计算过程,输入是一张数字图片。27 * 19的灰度图。由于mlp模型是全连接的。这里我们直接把输入展开成一个1 * 513的向量。分别用输入矩阵乘以训练出来的参数矩阵。
用于训练的mlp模型非常简单就几行代码,三个隐含层一个激活层
model = Sequential()
model.add(Dense(513, 128))
model.add(Dense(128, 32))
model.add(Dense(32, 10))
model.add(Activation('softmax'))
训练完的模型包含两个文件。一个是模型,一个是参数。
首先直接加载模型
model = keras.models.model_from_json(open('my_model_json_str.json').read())
model.load_weights('my_model_weights.h5')
获取模型中的model.layers
debug模式下可以看到,加载出来的layers就是刚才训练的时候添加的三个隐含层一个激活层:
下一步提取每一步的参数:
for layer in model.layers:
weights = layer.get_weights()
因为这个层次比较少,自己也知道有多少层。直接可以这么拿
weight1 = layers[0].get_weights() #包含一个513 * 128的矩阵,和一个1 * 128的向量
weight2 = layers[1].get_weights() #包含一个128 * 32的矩阵,和一个1 * 32的向量
weight3 = layers[2].get_weights() #包含一个32 * 10的矩阵,和一个1 * 10的向量
debug模式下,可以看到每个weight实际上有两个元素
一个是矩阵,另一个是一个一维向量。也就是最上面那个公式中的W和b。
下面直接用输入图片(1 * 513),乘以weight1+b1的到的结果(1 * 128的矩阵),把这个结果再乘以第二层weight2+b2,得到的结果(1 * 32的矩阵)再乘以第三层weight3+b3
得到的结果即逝最终预测结果的向量(1 * 10)。
re1 = np.dot(image,weight11)+weight1[1]
re2 = np.dot(re1,weight21)+weight2[1]
re3 = np.dot(re2,weight31)+weight3[1]
debug模式下查看re3的值:
十个元素中最大的是第0个,6021。也就是说用这个模型预测的结果是0.
实际上用keras自带的预测函数预测,得到的最终结果也是一致的。只是它的结果做了归一化处理。
到这一步,keras训练模型迁移至c++ 或者是java application基本上已经算是完成了一大半,下面就是搬砖活了