keras.layers. K.function 用法(keras提取中间层的输出)
https://www.laike.net/article-11-295083-0.html
使用K.function()调试keras操作
Keras的底层库使用Theano或TensorFlow,这两个库也称为Keras的后端。无论是Theano还是TensorFlow,都需要提前定义好网络的结构,也就是常说的“计算图”。
在运行前需要对计算图编译,然后才能输出结果。那这里面主要有两个问题,第一是这个图结构在运行中不能任意更改,比如说计算图中有一个隐含层,神经元的数量是100,你想动态的修改这个隐含层神经元的数量那是不可以的;第二是调试困难,keras没有内置的调试工具,所以计算图的中间结果是很难看到的,一旦最终输出跟预想不一致,很难找到问题所在。
分阶段构建你的神经网络
不要一口气把整个网络全部写完,这样很难保证中间结果的正确性。加如一个CNN文本分类模型是这样的(如下代码),应该在加了Embedding层后,停止,打印一下中间结果,看看跟embedding向量能不能对上,输出的shape对不对。对上了再进行下一步操作。
有的人觉得这样很浪费时间,但是除非你能一遍写对,否则你将花上5倍的时间发现错误。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# model parameters: embedding_dims = 50 cnn_filters = 100 cnn_kernel_size = 5 dense_hidden_dims = 200 model = Sequential() model.add(Embedding(nb_words,embedding_dims,input_length = maxlen)) model.add(Dropout( 0.5 )) model.add(Conv1D(cnn_filters, cnn_kernel_size,padding = 'valid' , activation = 'relu' )) model.add(GlobalMaxPooling1D()) model.add(Dense(dense_hidden_dims)) model.add(Dropout( 0.5 )) model.add(Activation( 'relu' )) model.add(Dense( 1 )) model.add(Activation( 'sigmoid' )) return model |
使用K.function()函数打印中间结果
function函数可以接收传入数据,并返回一个numpy数组。使用这个函数我们可以方便地看到中间结果,尤其对于变长输入的Input。
下面是官方关于function的文档。
function
keras.backend.function(inputs, outputs, updates=None)
实例化 Keras 函数。
参数
inputs: 占位符张量列表。
outputs: 输出张量列表。
updates: 更新操作列表。
**kwargs: 需要传递给 tf.Session.run 的参数。
返回
输出值为 Numpy 数组。
异常
ValueError: 如果无效的 kwargs 被传入。
例子
下面这个例子是打印一个LSTM层的中间结果,值得注意的是这个LSTM的sequence是变长的,可以看到输出的结果sequence长度分别是64和128
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import keras.backend as K from keras.layers import LSTM, Input import numpy as np I = Input (shape = ( None , 200 )) lstm = LSTM( 20 , return_sequences = True ) f = K.function(inputs = [I], outputs = [lstm(I)]) data1 = np.random.random(size = ( 2 , 64 , 200 )) print (f([data1])[ 0 ].shape) data2 = np.random.random(size = ( 2 , 128 , 200 )) print (f([data2])[ 0 ].shape) K.clear_session() # (2, 64, 20) # (2, 128, 20) |
其他的调试技巧
有频繁张量变换操作的,如dot, mat, reshape等等,记得加一行形状变化的注释,如(100, 128)--> (100, 64)
可以使用 tensorboard 查看网络的参数情况
确保你的数据没有问题,很多时候输出不对不是神经网络有问题,而是数据有问题
=========================================
from keras import backend as K
1.获取名为layer_name的层的输出
#指定输出层的名称
layer_1 = K.function([model.get_input_at(0)], [model.get_layer('layer_name').output])
f1 = layer_1([image_arr])[0]
2.获取第n层的输出
#指定输出层的序号(层号从0开始)
layer_1 = K.function([model.get_input_at(0)], [model.layers[5].output])
f1 = layer_1([image_arr])[0]
3.输入输出使用layer名称
pnet = K.function([pnet.layers['data']],[pnet.layers['conv4-2'], pnet.layers['prob1']])
rnet = K.function([rnet.layers['data']],[rnet.layers['conv5-2'], rnet.layers['prob1']])
onet = K.function([onet.layers['data']],[onet.layers['conv6-2'], onet.layers['conv6-3'], onet.layers['prob1']])
链接:https://blog.csdn.net/qq_43258953/article/details/105315476
=======================================
from keras import backend as K from keras.models import load_model models = load_model('models.hdf5') image=r'image.png' images=cv2.imread(r'image.png') image_arr = process_image(image, (224, 224, 3)) image_arr = np.expand_dims(image_arr, axis=0) layer_1 = K.function([base_model.get_input_at(0)], [base_model.get_layer('layer_name').output]) f1 = layer_1([image_arr])[0]
加载训练好并保存的网络模型
加载数据(图像),并将数据处理成array形式
指定输出层
将处理后的数据输入,然后获取输出
其中,K.function有两种不同的写法:
1. 获取名为layer_name的层的输出
layer_1 = K.function([base_model.get_input_at(0)], [base_model.get_layer(‘layer_name’).output]) #指定输出层的名称
2. 获取第n层的输出
layer_1 = K.function([model.get_input_at(0)], [model.layers[5].output]) #指定输出层的序号(层号从0开始)
https://cloud.tencent.com/developer/article/1725083
from keras import backend as K from keras.models import load_model models = load_model('models.hdf5') image=r'image.png' images=cv2.imread(r'image.png') image_arr = process_image(image, (224, 224, 3)) image_arr = np.expand_dims(image_arr, axis=0) layer_1 = K.function([base_model.get_input_at(0)], [base_model.get_layer('layer_name').output]) f1 = layer_1([image_arr])[0]
from keras import backend as K from keras.models import load_model models = load_model('models.hdf5') image=r'image.png' images=cv2.imread(r'image.png') image_arr = process_image(image, (224, 224, 3)) image_arr = np.expand_dims(image_arr, axis=0) layer_1 = K.function([base_model.get_input_at(0)], [base_model.get_layer('layer_name').output]) f1 = layer_1([image_arr])[0]