溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

keras中如何獲取某一個網(wǎng)絡(luò)層的輸出

發(fā)布時間:2020-07-22 14:37:55 來源:億速云 閱讀:328 作者:小豬 欄目:開發(fā)技術(shù)

這篇文章主要講解了keras中如何獲取某一個網(wǎng)絡(luò)層的輸出,內(nèi)容清晰明了,對此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會有幫助。

前言:

keras默認(rèn)提供了如何獲取某一個層的某一個節(jié)點(diǎn)的輸出,但是沒有提供如何獲取某一個層的輸出的接口,所以有時候我們需要獲取某一個層的輸出,則需要自己編寫代碼,但是鑒于keras高層封裝的特性,編寫起來實(shí)際上很簡單,本文提供兩種常見的方法來實(shí)現(xiàn),基于上一篇文章的模型和代碼: keras自定義回調(diào)函數(shù)查看訓(xùn)練的loss和accuracy

一、模型加載以及各個層的信息查看

從前面的定義可知,參見上一篇文章,一共定義了8個網(wǎng)絡(luò)層,定義如下:

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'))

這里每一個層都沒有起名字,實(shí)際上最好給每一個層取一個名字,所以這里就使用索引來訪問層,如下:

for index in range(8):
 layer=model.get_layer(index=index)
 # layer=model.layers[index] # 這樣獲取每一個層也是一樣的
 print(model)
 
'''運(yùn)行結(jié)果如下:
<keras.engine.sequential.Sequential object at 0x0000012A4F232E10>
<keras.engine.sequential.Sequential object at 0x0000012A4F232E10>
<keras.engine.sequential.Sequential object at 0x0000012A4F232E10>
<keras.engine.sequential.Sequential object at 0x0000012A4F232E10>
<keras.engine.sequential.Sequential object at 0x0000012A4F232E10>
<keras.engine.sequential.Sequential object at 0x0000012A4F232E10>
<keras.engine.sequential.Sequential object at 0x0000012A4F232E10>
<keras.engine.sequential.Sequential object at 0x0000012A4F232E10>
'''

當(dāng)然由于 model.laters是一個列表,所以可以一次性打印出所有的層信息,即

print(model.layers) # 打印出所有的層

二、模型的加載

準(zhǔn)備測試數(shù)據(jù)

# 訓(xùn)練參數(shù)
learning_rate = 0.001
epochs = 10
batch_size = 128
n_classes = 10
 
# 定義圖像維度reshape
img_rows, img_cols = 28, 28
 
# 加載keras中的mnist數(shù)據(jù)集 分為60,000個訓(xùn)練集,10,000個測試集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
 
# 將圖片轉(zhuǎn)化為(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的數(shù)據(jù)格式轉(zhuǎn)為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轉(zhuǎn)換為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.h6')

注意事項(xiàng):

keras的每一個層有一個input和output屬性,但是它是只針對單節(jié)點(diǎn)的層而言的哦,否則就不需要我們再自己編寫輸出函數(shù)了,

如果一個層具有單個節(jié)點(diǎn) (i.e. 如果它不是共享層), 你可以得到它的輸入張量、輸出張量、輸入尺寸和輸出尺寸:

layer.input
layer.output
layer.input_shape
layer.output_shape

如果層有多個節(jié)點(diǎn) (參見: 層節(jié)點(diǎn)和共享層的概念), 您可以使用以下函數(shù):

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 第一種實(shí)現(xiàn)方法

def get_output_function(model,output_layer_index):
 '''
 model: 要保存的模型
 output_layer_index:要獲取的那一個層的索引
 '''
 vector_funcrion=K.function([model.layers[0].input],[model.layers[output_layer_index].output])
 def inner(input_data):
  vector=vector_funcrion([input_data])[0]
  return vector
 
 return inner
 
# 現(xiàn)在僅僅測試一張圖片
#選擇一張圖片,選擇第一張
x= np.expand_dims(x_test[1],axis=0) #[1,28,28,1] 的形狀
 
get_feature=get_output_function(model,6) # 該函數(shù)的返回值依然是一個函數(shù)哦,獲取第6層輸出
 
feature=get_feature(x) # 相當(dāng)于調(diào)用 定義在里面的inner函數(shù)
print(feature)
'''運(yùn)行結(jié)果為
[[-0.99986297 -0.9988328 -0.9273474 0.9101525 -0.9054705 -0.95798373
 0.9911243 0.78576803 0.99676156 0.39356467 -0.9724135 -0.74534595
 0.8527011 -0.9968267 -0.9420816 -0.32765102 -0.41667578 0.99942905
 0.92333794 0.7565034 -0.38416263 -0.994241 0.3781617 0.9621943
 0.9443946 0.9671554 -0.01000021 -0.9984282 -0.96650964 -0.9925837
 -0.48193568 -0.9749565 -0.79769516 0.9651831 0.9678705 -0.9444472
 0.9405674 0.97538495 -0.12366439 -0.9973782 0.05803521 0.9159217
 -0.9627071 0.99898154 0.99429387 -0.985909 0.5787794 -0.9789403
 -0.94316894 0.9999644 0.9156823 0.46314353 -0.01582102 0.98359734
 0.5586145 -0.97360635 0.99058044 0.9995654 -0.9800733 0.99942625
 0.8786553 -0.9992093 0.99916387 -0.5141877 0.99970615 0.28427476
 0.86589384 0.7649907 -0.9986046 0.9999706 -0.9892468 0.99854743
 -0.86872625 -0.9997323 0.98981035 -0.87805724 -0.9999373 -0.7842255
 -0.97456616 -0.97237325 -0.729563 0.98718935 0.9992022 -0.5294769 ]]
'''

但是上面的實(shí)現(xiàn)方法似乎不是很簡單,還有更加簡單的方法,思想來源與keras中,可以將整個模型model也當(dāng)成是層layer來處理,實(shí)現(xiàn)如下面。

3.2 第二種實(shí)現(xiàn)方法

import keras
import numpy as np
from keras.datasets import mnist
from keras.models import Model
 
model=keras.models.load_model('./models/lenet5_weight.h6')
 
#選擇一張圖片,選擇第一張
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)
'''運(yùn)行結(jié)果為:
[[-0.99986297 -0.9988328 -0.9273474 0.9101525 -0.9054705 -0.95798373
 0.9911243 0.78576803 0.99676156 0.39356467 -0.9724135 -0.74534595
 0.8527011 -0.9968267 -0.9420816 -0.32765102 -0.41667578 0.99942905
 0.92333794 0.7565034 -0.38416263 -0.994241 0.3781617 0.9621943
 0.9443946 0.9671554 -0.01000021 -0.9984282 -0.96650964 -0.9925837
 -0.48193568 -0.9749565 -0.79769516 0.9651831 0.9678705 -0.9444472
 0.9405674 0.97538495 -0.12366439 -0.9973782 0.05803521 0.9159217
 -0.9627071 0.99898154 0.99429387 -0.985909 0.5787794 -0.9789403
 -0.94316894 0.9999644 0.9156823 0.46314353 -0.01582102 0.98359734
 0.5586145 -0.97360635 0.99058044 0.9995654 -0.9800733 0.99942625
 0.8786553 -0.9992093 0.99916387 -0.5141877 0.99970615 0.28427476
 0.86589384 0.7649907 -0.9986046 0.9999706 -0.9892468 0.99854743
 -0.86872625 -0.9997323 0.98981035 -0.87805724 -0.9999373 -0.7842255
 -0.97456616 -0.97237325 -0.729563 0.98718935 0.9992022 -0.5294769 ]]
'''

可見和上面的結(jié)果是一樣的,

總結(jié):

由于keras的層與模型之間實(shí)際上的轉(zhuǎn)化關(guān)系,所以提供了非常靈活的輸出方法,推薦使用第二種方法獲得某一個層的輸出??偨Y(jié)為以下幾個主要的步驟(四步走):

import keras
import numpy as np
from keras.datasets import mnist
from keras.models import Model
 
# 第一步:準(zhǔn)備輸入數(shù)據(jù)
x= np.expand_dims(x_test[1],axis=0) #[1,28,28,1] 的形狀
 
# 第二步:加載已經(jīng)訓(xùn)練的模型
model=keras.models.load_model('./models/lenet5_weight.h6')
 
# 第三步:將模型作為一個層,輸出第7層的輸出
layer_model = Model(inputs=model.input, outputs=model.layers[6].output)
 
# 第四步:調(diào)用新建的“曾模型”的predict方法,得到模型的輸出
feature=layer_model.predict(x)
 
print(feature)

看完上述內(nèi)容,是不是對keras中如何獲取某一個網(wǎng)絡(luò)層的輸出有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI