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
,就能重新設定權重。