VGG19 特徵

      在〈VGG19 特徵〉中有 1 則留言

VGG19 特徵

VGG19 總共有 16個捲積層及3個全連接層。詳細圖示如下

上圖中,共有 5 個 block, 分別為 block1~5 ,這 5 個 block 就是以前所稱的隱藏層。block1及 block2 分別有 2 個conv(捲積層)及1個maxpool,block3~5 分別有 4 個捲積層及 1 個 maxpool。最後還有 FC1, FC2, softmax 三個輸出層。另外還有一個上圖沒畫出來的,也就是最前面的輸入層 (input_1)。

5 個 block 隱藏層的作用,就是在取得每張圖片的特徵,本篇的目的就是要探討什麼叫特徵,特徵長什麼樣子。

底下代碼,使用 model.layers 可以印出輸入層,隱藏層,及輸出層共有 26 層的名稱。model.output 是使用Tensorflow 格式印出輸出層,model.outputs 則是使用字典格式印出輸出層,二者皆是同一個物件,而且只印出最後的 predictions 層。

from keras import applications
model = applications.vgg19.VGG19(weights="imagenet", include_top=True)
for i, layer in enumerate(model.layers):
    print(i+1, layer.name, layer)
print("input",model.inputs)
print("outputs",model.outputs)
print("output",model.output)
結果 : 
1 input_1 
2 block1_conv1 
3 block1_conv2 
4 block1_pool 
5 block2_conv1 
6 block2_conv2 
7 block2_pool 
8 block3_conv1 
9 block3_conv2 
10 block3_conv3 
11 block3_conv4 
12 block3_pool 
13 block4_conv1 
14 block4_conv2 
15 block4_conv3 
16 block4_conv4 
17 block4_pool 
18 block5_conv1 
19 block5_conv2 
20 block5_conv3 
21 block5_conv4 
22 block5_pool 
23 flatten 
24 fc1 
25 fc2 
26 predictions 
input [<KerasTensor: shape=(None, 224, 224, 3) dtype=float32 (created by layer 'input_1')>]
outputs [<KerasTensor: shape=(None, 1000) dtype=float32 (created by layer 'predictions')>] output KerasTensor(type_spec=TensorSpec(shape=(None, 1000), dtype=tf.float32, name=None), name='predictions/Softmax:0', description="created by layer 'predictions'")

如果 model = applications.vgg19.VGG19(weights=”imagenet”, include_top=False) 將 include_top 設為 False 時,則 23~26 的輸出層就不會產生。

from keras import applications
model = applications.vgg19.VGG19(weights="imagenet", include_top=False)
for i, layer in enumerate(model.layers):
    print(i+1, layer.name, layer)
print("input",model.inputs)
print("outputs",model.outputs)
print("output",model.output)
結果 :
1 input_1 
2 block1_conv1 
3 block1_conv2 
4 block1_pool 
5 block2_conv1 
6 block2_conv2 
7 block2_pool 
8 block3_conv1 
9 block3_conv2 
10 block3_conv3 
11 block3_conv4 
12 block3_pool 
13 block4_conv1 
14 block4_conv2 
15 block4_conv3 
16 block4_conv4 
17 block4_pool 
18 block5_conv1 
19 block5_conv2 
20 block5_conv3 
21 block5_conv4 
22 block5_pool 
outputs [<KerasTensor: shape=(None, None, None, 512) dtype=float32 (created by layer 'block5_pool')>]
output KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 512), dtype=tf.float32, name=None), name='block5_pool/MaxPool:0', description="created by layer 'block5_pool'") output KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 512), dtype=tf.float32, name=None), name='block5_pool/MaxPool:0', description="created by layer 'block5_pool'")

每層的結構

每個區塊中的每一層,比如 block1_conv1 又有 “輸入” 及 “輸出”單元。請注意,這只是每一層的接收神經元及傳遞神經元,跟整個模型最前面的輸入層及整個模型最後的輸出層,是完全不一樣的。底下代碼可印出input/output 的型態,只是目前還沒送進圖片,所以維度類似像 (None, None, None, 64) 等 4 維格式。

from keras import applications
model = applications.vgg19.VGG19(weights="imagenet", include_top=False)
for layer in model.layers:
    print(layer.name)
    print("input:", layer.input)
print("output:", layer.output) 結果 : input_1 input: KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 3), dtype=tf.float32, name='input_1'), name='input_1', description="created by layer 'input_1'") output: KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 3), dtype=tf.float32, name='input_1'), name='input_1', description="created by layer 'input_1'") block1_conv1 input: KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 3), dtype=tf.float32, name='input_1'), name='input_1', description="created by layer 'input_1'") output: KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 64), dtype=tf.float32, name=None), name='block1_conv1/Relu:0', description="created by layer 'block1_conv1'") block1_conv2 .........

特徵存取

將圖片使用 model(img),即可取得最後輸出層的特徵。不過在原本的模型中,輸出層只有 predictions 這1000 種狀況,無法取得中間 5 個 block 隱藏層所計算出來的結果。所以如果要取得中間隱藏層的資料,就必需把 block 隱藏層中的 output 傳遞神經元移到輸出層。

import keras
import tensorflow as tf
import cv2
import numpy as np
from keras import applications
model = applications.vgg19.VGG19(weights="imagenet", include_top=False)

#將隱藏層移到輸出層
outputs_dict = dict([(layer.name, layer.output) for layer in model.layers])
model = keras.Model(inputs=model.inputs, outputs=outputs_dict)

開始計算特徵

模型調整好後,就可以將圖片傳入 model(img) 或是 model.predict(img),然後特徵就會儲存到輸出層中每一捲積層的 output 中,由下面代碼可印出每一層 output 的維度。

以 block1_conv1 這層來說,其維度為 (1, 224,224,64),表示這一層的每一個特徵大小為 224*224 圖片,然後共有 64 種特徵,也就是說這一層共有 64 張 224*224 的圖片。

最後需注意一件事,將圖片傳入 model 前,需先將圖片擴展成 4 維,並進行預處理。圖片最前維加入一空白維度後,再用 preprocess_input() 對圖片預處理,將RGB 轉成 BGR格式,然後將所有點的B值減掉B的平均數,G及R亦同。如此就可以讓每個點的每個顏色值分佈在 0 的左右二邊。

底下是我們用來測試的圖片。

🔒 底下內容僅限會員閱讀。

立即登入

1 thought on “VGG19 特徵

  1. JuiKaiHsia

    老師您好
    我最近上您聯成電腦的深度學習課程
    是使用錄影檔回放的方式學習

    請問老師能否提供您網站上內容的密碼
    以利學生學習
    謝謝老師

    我的聯成電腦學號為 105724356

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *