您好,登錄后才能下訂單哦!
這篇文章主要講解了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'))
這里每一個層都沒有起名字,實際上最好給每一個層取一個名字,所以這里就使用索引來訪問層,如下:
for index in range(8): layer=model.get_layer(index=index) # layer=model.layers[index] # 這樣獲取每一個層也是一樣的 print(model) '''運行結果如下: <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> '''
當然由于 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.h6')
注意事項:
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 第一種實現方法
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 # 現在僅僅測試一張圖片 #選擇一張圖片,選擇第一張 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.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 ]] '''
但是上面的實現方法似乎不是很簡單,還有更加簡單的方法,思想來源與keras中,可以將整個模型model也當成是層layer來處理,實現如下面。
3.2 第二種實現方法
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) '''運行結果為: [[-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 ]] '''
可見和上面的結果是一樣的,
總結:
由于keras的層與模型之間實際上的轉化關系,所以提供了非常靈活的輸出方法,推薦使用第二種方法獲得某一個層的輸出。總結為以下幾個主要的步驟(四步走):
import keras import numpy as np from keras.datasets import mnist from keras.models import Model # 第一步:準備輸入數據 x= np.expand_dims(x_test[1],axis=0) #[1,28,28,1] 的形狀 # 第二步:加載已經訓練的模型 model=keras.models.load_model('./models/lenet5_weight.h6') # 第三步:將模型作為一個層,輸出第7層的輸出 layer_model = Model(inputs=model.input, outputs=model.layers[6].output) # 第四步:調用新建的“曾模型”的predict方法,得到模型的輸出 feature=layer_model.predict(x) print(feature)
看完上述內容,是不是對keras中如何獲取某一個網絡層的輸出有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。