[原創] 如何取出 tf.layers.dense 定義的全連接層的weight和bias參數值
TensorFlow版本:1.14.0
Python版本:3.6.8
在TensorFlow中,tf.layers.dense 定義了一個全連接層,其實現的是(來自官方文檔):
This layer implements the operation: outputs = activation(inputs * kernel + bias) Where activation is the activation function passed as the activation argument (if not None), kernel is a weights matrix created by the layer, and bias is a bias vector created by the layer (only if use_bias is True).
意思就是它實現了 y = activation(x * kernel + bias) 的操作,其中,activation是激活函數。在這裏,kernel 就是指我們通常所說的 weight,它被TF稱爲 kernel 而不是 weight。因此,如果你想從這個模型裏取出weight參數的話,就要注意它的名字了,否則會讀不到這個參數。
下面我們就來看具體的例子。
下面這段代碼的邏輯非常簡單,它幹了下面這些事情:
* 創建了一個非常簡單的2層全連接網絡
* 訓練網絡
* 訓練完成後把它保存成checkpoint格式的模型文件
* 從保存的checkpoint讀取模型裏第一層的 weight 和 bias 參數值,打印出來
文章來源:https://www.codelast.com/
import tensorflow as tf import numpy as np LAYER_1_NAME = 'layer1' # 第一層的名字 LAYER_2_NAME = 'layer2' # 第二層的名字 # 創建一個非常簡單的神經網絡,它有兩層 x = tf.placeholder(shape=[None, 2], dtype=tf.float32) layer1 = tf.layers.dense(x, 5, activation=tf.nn.sigmoid, name=LAYER_1_NAME) layer2 = tf.layers.dense(layer1, 2, activation=tf.nn.sigmoid, name=LAYER_2_NAME) loss = tf.reduce_mean((layer2 - x) ** 2) optimizer = tf.train.AdamOptimizer(0.01).minimize(loss) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) x_values = np.random.normal(0, 1, (5000, 2)) # 生成用於輸入的隨機數 for step in range(1000): _, loss_value = sess.run([optimizer, loss], feed_dict={x: x_values}) if step % 100 == 0: print("step: %d, loss: %f" % (step, loss_value)) # 把模型保存成checkpoint saver = tf.compat.v1.train.Saver() save_path = saver.save(sess, './checkpoint/model.ckpt') print("model saved in path: %s" % save_path, flush=True) # 讀取剛保存的checkpoint reader = tf.train.NewCheckpointReader(save_path) weights = reader.get_tensor(LAYER_1_NAME + '/kernel') # weight的名字,是由對應層的名字,加上默認的"kernel"組成的 bias = reader.get_tensor(LAYER_1_NAME + '/bias') # bias的名字 print(weights) print(bias) # 如果想打印模型中的所有參數名和參數值的話,把下面幾行取消註釋 # var_to_shape_map = reader.get_variable_to_shape_map() # for key in var_to_shape_map: # print("tensor name: ", key) # print(reader.get_tensor(key))
文章來源:https://www.codelast.com/
上面程序的輸出:
step: 0, loss: 1.166642
step: 100, loss: 0.764896
step: 200, loss: 0.659553
step: 300, loss: 0.622590
step: 400, loss: 0.604577
step: 500, loss: 0.595308
step: 600, loss: 0.590193
step: 700, loss: 0.587147
step: 800, loss: 0.585213
step: 900, loss: 0.583916
model saved in path: ./checkpoint/model.ckpt
[[-3.0937738 3.6378026 0.91563785 -1.2663897 -0.09645918]
[ 0.727915 0.22842272 -2.656725 -2.0831287 -3.4844823 ]]
[ 0.906906 -1.6009021 0.46897942 0.75946033 1.4348172 ]
注意,在取某一層的 weight 參數值的時候,我們用了以下方法:
weights = reader.get_tensor(LAYER_1_NAME + '/kernel')
這裏,weight 的名字,是類似於 "layer1/kernel" 這樣的字符串,其中,"layer1"就是在用 tf.layers.dense() 創建網絡的一個layer的時候,設置的 "name=xxx" 裏的名字。前面已經說過了,TF 裏把 weight 叫做 kernel,所以這裏的 weight 名是 "layer1/kernel" 而不是 "layer1/weight"!