Deep Learning

Keras:取出權重與設定權重

前言

這陣子常需要把KERAS的weights取出來,然後在別的地方使用。

怕忘記先把作法記錄下來,也順便紀錄一下我自己如何執行存模型、載入模型的過程。

模型輸出與載入

這邊先假設我已經用KERAS訓練好一個模型,那我會把訓練好的模型輸出幾種檔案,等需要進行預測時,直接載入這些檔案即可。

模型架構

conv >> relu >> pool >> flat >> fc1 >> relu >> dropout >> fc2 >> softmax

from tensorflow.keras import layers
from tensorflow.keras import models

model = models.Sequential([
        layers.Conv2D(filters=16, input_shape=(28, 28, 1), kernel_size=(3,3), padding='same', name="image"),
        layers.Activation('relu'),
        layers.MaxPooling2D((2, 2)),
        layers.Flatten(),
        layers.Dense(units=64),
        layers.Activation('relu'),
        layers.Dropout(0.5),
        layers.Dense(units=10),
        layers.Activation('softmax', name="label")
    ])

Note: 為了方便查看架構的檔案,所以Activation沒有直接定義在Conv2D或是Dense之中。

輸出模型方式

  • 使用H5DF保存整個模型 (模型架構+權重)
model.save("model.h5")
  • 使用JSON保存模型架構 + H5DF保存模型權重

這個方式通常會直接使用下面的程式碼。

# 輸出模型架構
with open('archi.json', 'w') as F:
    F.write(model.to_json())

# 輸出模型權重
model.save_weights("weigths.h5")

我自己會是用JSON模組先進行處理,才會把模型架構存成JSON檔。

import json

# 
def save_json(filepath, data_dict):
    # 把 model.to_json() 的"字串"處理成"字典"
    if isinstance(data_dict, str):
        data_dict = json.loads(data_dict)
    with open(filepath, 'w') as f:
        json.dump(data_dict, f, indent=4)

# 輸出模型架構
archi = model.to_json()
save_json("archi.json", archi)

# 輸出模型權重
model.save_weights("weigths.h5")

Note: 用to_json()來輸出模型架構,得到會是字串(str),我們可以使用json模組來處理這個字串。使用loads()可以將這組字串轉成字典(dict);使用dump()可以將字典存成JSON檔,我們也可以輸入indent參數來自動縮排,這樣到時也可以直接在記事本裡看,不然正常只會看到一行文字。

載入模型方式

  • 載入H5DF模型
from tensorflow.keras import models

# 載入模型
archi = open("archi.json").read()
model = models.load_model("model.h5")
  • 載入JSON模型架構並載入權重
from tensorflow.keras import models

# 載入模型架構
archi = open("archi.json").read()
model = models.model_from_json(archi)

# 載入模型權重
model.load_weights("weights.h5")

到這邊就完成模型載入了。接下來就是去將載入的權重取出。

取得模型的其中一層

model.layers就可以取得所有層的列表(list)。

由於我們第一層是卷積層,所以我將model.layers[0]設定成conv_layer變數。

print(model.layers)
conv_layer = model.layers[0]

取出權重

K = conv_layer.get_weights()[0]
b = conv_layer.get_weights()[1]

Note: 用get_weights()得到的權重是一個列表(list),分別存放卷積核(kernels, K)跟偏差量(bias, b)。

設定權重

weights = [K, b]
conv_layer.set_weights(weights)

Note: 用set_weights()來設定權重,輸入參數也要使用列表(list)設定。
這也表示我們可以先對weights = [K, b]這行修改,例如替換K或是b,就能重新設定權重。

留下一個回覆

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