keras小技巧——获取某一个网络层的输出方式
前言:
keras默认提供了如何获取某一个层的某一个节点的输出,但是没有提供如何获取某一个层的输出的接口,所以有时候我们需要获取某一个层的输出,则需要自己编写代码,但是鉴于keras高层封装的特性,编写起来实际上很简单,本文提供两种常见的方法来实现,基于上一篇文章的模型和代码:keras自定义回调函数查看训练的loss和accuracy
一、模型加载以及各个层的信息查看
从前面的定义可知,参见上一篇文章,一共定义了8个网络层,定义如下:
model.add(Convolution2D(filters=6,kernel_size=(5,5),padding='valid',input_shape=(img_rows,img_cols,1),activation='tanh')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Convolution2D(filters=16,kernel_size=(5,5),padding='valid',activation='tanh')) model.add(MaxPooling2D(pool_size=(2,2))) model.add(Flatten()) model.add(Dense(120,activation='tanh')) model.add(Dense(84,activation='tanh')) model.add(Dense(n_classes,activation='softmax'))
这里每一个层都没有起名字,实际上最好给每一个层取一个名字,所以这里就使用索引来访问层,如下:
forindexinrange(8): layer=model.get_layer(index=index) #layer=model.layers[index]#这样获取每一个层也是一样的 print(model) '''运行结果如下:''' 
当然由于model.laters是一个列表,所以可以一次性打印出所有的层信息,即
print(model.layers)#打印出所有的层
二、模型的加载
准备测试数据
#训练参数
learning_rate=0.001
epochs=10
batch_size=128
n_classes=10
#定义图像维度reshape
img_rows,img_cols=28,28
#加载keras中的mnist数据集分为60,000个训练集,10,000个测试集
(x_train,y_train),(x_test,y_test)=mnist.load_data()
#将图片转化为(samples,width,height,channels)的格式
x_train=x_train.reshape(x_train.shape[0],img_rows,img_cols,1)
x_test=x_test.reshape(x_test.shape[0],img_rows,img_cols,1)
#将X_train,X_test的数据格式转为float32
x_train=x_train.astype('float32')
x_test=x_test.astype('float32')
#将X_train,X_test归一化0-1
x_train/=255
x_test/=255
#输出0-9转换为ont-hot形式
y_train=np_utils.to_categorical(y_train,n_classes)
y_test=np_utils.to_categorical(y_test,n_classes)
模型的加载
model=keras.models.load_model('./models/lenet5_weight.h5')
注意事项:
keras的每一个层有一个input和output属性,但是它是只针对单节点的层而言的哦,否则就不需要我们再自己编写输出函数了,
如果一个层具有单个节点(i.e.如果它不是共享层),你可以得到它的输入张量、输出张量、输入尺寸和输出尺寸:
layer.input layer.output layer.input_shape layer.output_shape
如果层有多个节点(参见:层节点和共享层的概念),您可以使用以下函数:
layer.get_input_at(node_index) layer.get_output_at(node_index) layer.get_input_shape_at(node_index) layer.get_output_shape_at(node_index)
三、获取某一个层的输出的方法定义
3.1第一种实现方法
defget_output_function(model,output_layer_index): ''' model:要保存的模型 output_layer_index:要获取的那一个层的索引 ''' vector_funcrion=K.function([model.layers[0].input],[model.layers[output_layer_index].output]) definner(input_data): vector=vector_funcrion([input_data])[0] returnvector returninner #现在仅仅测试一张图片 #选择一张图片,选择第一张 x=np.expand_dims(x_test[1],axis=0)#[1,28,28,1]的形状 get_feature=get_output_function(model,6)#该函数的返回值依然是一个函数哦,获取第6层输出 feature=get_feature(x)#相当于调用定义在里面的inner函数 print(feature) '''运行结果为 [[-0.99986297-0.9988328-0.92734740.9101525-0.9054705-0.95798373 0.99112430.785768030.996761560.39356467-0.9724135-0.74534595 0.8527011-0.9968267-0.9420816-0.32765102-0.416675780.99942905 0.923337940.7565034-0.38416263-0.9942410.37816170.9621943 0.94439460.9671554-0.01000021-0.9984282-0.96650964-0.9925837 -0.48193568-0.9749565-0.797695160.96518310.9678705-0.9444472 0.94056740.97538495-0.12366439-0.99737820.058035210.9159217 -0.96270710.998981540.99429387-0.9859090.5787794-0.9789403 -0.943168940.99996440.91568230.46314353-0.015821020.98359734 0.5586145-0.973606350.990580440.9995654-0.98007330.99942625 0.8786553-0.99920930.99916387-0.51418770.999706150.28427476 0.865893840.7649907-0.99860460.9999706-0.98924680.99854743 -0.86872625-0.99973230.98981035-0.87805724-0.9999373-0.7842255 -0.97456616-0.97237325-0.7295630.987189350.9992022-0.5294769]] '''
但是上面的实现方法似乎不是很简单,还有更加简单的方法,思想来源与keras中,可以将整个模型model也当成是层layer来处理,实现如下面。
3.2第二种实现方法
importkeras
importnumpyasnp
fromkeras.datasetsimportmnist
fromkeras.modelsimportModel
model=keras.models.load_model('./models/lenet5_weight.h5')
#选择一张图片,选择第一张
x=np.expand_dims(x_test[1],axis=0)#[1,28,28,1]的形状
#将模型作为一个层,输出第7层的输出
layer_model=Model(inputs=model.input,outputs=model.layers[6].output)
feature=layer_model.predict(x)
print(feature)
'''运行结果为:
[[-0.99986297-0.9988328-0.92734740.9101525-0.9054705-0.95798373
0.99112430.785768030.996761560.39356467-0.9724135-0.74534595
0.8527011-0.9968267-0.9420816-0.32765102-0.416675780.99942905
0.923337940.7565034-0.38416263-0.9942410.37816170.9621943
0.94439460.9671554-0.01000021-0.9984282-0.96650964-0.9925837
-0.48193568-0.9749565-0.797695160.96518310.9678705-0.9444472
0.94056740.97538495-0.12366439-0.99737820.058035210.9159217
-0.96270710.998981540.99429387-0.9859090.5787794-0.9789403
-0.943168940.99996440.91568230.46314353-0.015821020.98359734
0.5586145-0.973606350.990580440.9995654-0.98007330.99942625
0.8786553-0.99920930.99916387-0.51418770.999706150.28427476
0.865893840.7649907-0.99860460.9999706-0.98924680.99854743
-0.86872625-0.99973230.98981035-0.87805724-0.9999373-0.7842255
-0.97456616-0.97237325-0.7295630.987189350.9992022-0.5294769]]
'''
可见和上面的结果是一样的,
总结:
由于keras的层与模型之间实际上的转化关系,所以提供了非常灵活的输出方法,推荐使用第二种方法获得某一个层的输出。总结为以下几个主要的步骤(四步走):
importkeras
importnumpyasnp
fromkeras.datasetsimportmnist
fromkeras.modelsimportModel
#第一步:准备输入数据
x=np.expand_dims(x_test[1],axis=0)#[1,28,28,1]的形状
#第二步:加载已经训练的模型
model=keras.models.load_model('./models/lenet5_weight.h5')
#第三步:将模型作为一个层,输出第7层的输出
layer_model=Model(inputs=model.input,outputs=model.layers[6].output)
#第四步:调用新建的“曾模型”的predict方法,得到模型的输出
feature=layer_model.predict(x)
print(feature)
以上这篇keras小技巧——获取某一个网络层的输出方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
