[英]Manually assigning weights for Conv2d layer
我有一個包含許多 conv2d 層的模型。 我將模型轉換為 Tflite 模型。 轉換后我得到了單個 conv2d 的權重。 權重的形狀看起來像這樣
# code
w2 = get_variable(interpreter, 1)
print(w2.shape)
# output
(16, 3, 3, 3)
w2 是我從 tflite 模型得到的 conv2d 層的權重。
# looking at weights
tf.constant(w2)
# out
<tf.Tensor: shape=(16, 3, 3, 3), dtype=float32, numpy=
array([[[[-0.09935276, 0.02673087, 0.01329462],
[-0.15000243, 0.12058315, 0.06234892],
[-0.04185663, -0.11198951, -0.02449715]],
[[-0.01043741, 0.00516671, -0.04251045],
[ 0.09123346, -0.18056516, -0.15848799],
[ 0.13060766, -0.07997198, -0.01930575]],
[[-0.03572255, -0.01315425, 0.08955526],
[ 0.16559589, 0.03411882, 0.0018566 ],
[-0.14274003, 0.1362513 , 0.02790332]]],
[[[-0.18470907, -0.08563003, -0.1520263 ],
[-0.04288448, -0.18342438, -0.15801121],
[-0.03374813, 0.06371641, 0.03502055]],
現在是我使用命令 model.weights 從模型文件中得到的權重。
# code
model_layer = model.get_layer(index = 1)
model_layer.weights[0]
# out
<tf.Variable 'conv2d/kernel:0' shape=(3, 3, 3, 16) dtype=float32, numpy=
array([[[[-0.09935276, -0.18470907, -0.16035978, -0.00957598,
0.12404141, 0.09072036, 0.08940545, 0.16788253,
-0.09028493, -0.07161955, 0.05057701, 0.00413197,
0.12936822, 0.13274643, -0.11566465, 0.06050111],
[ 0.02673087, -0.08563003, 0.15529695, -0.16517243,
0.09419081, 0.03450985, 0.05399269, 0.06663677,
-0.1096884 , 0.11150008, -0.14434202, 0.08073789,
-0.00857992, 0.17634535, -0.1686475 , -0.02407928],
[ 0.01329462, -0.1520263 , -0.16246322, -0.06716946,
0.18214822, -0.13206367, -0.05873053, 0.13359356,
0.13813934, -0.05382906, 0.1032899 , 0.03165779,
0.01169366, -0.11587013, -0.18203613, -0.10081998]],
[[-0.15000243, -0.04288448, 0.03991991, 0.05653304,
-0.08553669, 0.0082473 , -0.12359683, -0.01954196,
0.15206149, -0.07700901, 0.10358813, 0.04298429,
0.04496023, -0.1466851 , 0.05197817, 0.1237444 ],
我嘗試將 w2(16,3,3,3) 轉換為我想要的形狀 my_w2(3,3,3,16) 的方法。
# Method 1
# code
tf.transpose(tf.constant(w2))
# out
<tf.Tensor: shape=(3, 3, 3, 16), dtype=float32, numpy=
array([[[[-0.09935276, -0.18470907, -0.16035978, -0.00957598,
0.12404141, 0.09072036, 0.08940545, 0.16788253,
-0.09028493, -0.07161955, 0.05057701, 0.00413197,
0.12936822, 0.13274643, -0.11566465, 0.06050111],
[-0.01043741, -0.01095065, -0.13822603, 0.00533092,
-0.02210169, 0.12576985, -0.1342443 , -0.15337837,
0.15577388, 0.17446613, -0.17040835, 0.08397743,
0.11096796, -0.08405711, -0.06032752, 0.01366897],
[-0.03572255, -0.07657725, -0.18410352, 0.08384639,
-0.07809233, -0.06835755, 0.12235427, 0.00525343,
0.04881094, -0.10404772, -0.16282201, -0.15634196,
-0.07554363, -0.10617974, -0.11948892, -0.07697168]],
[[-0.15000243, -0.04288448, 0.03991991, 0.05653304,
-0.08553669, 0.0082473 , -0.12359683, -0.01954196,
0.15206149, -0.07700901, 0.10358813, 0.04298429,
0.04496023, -0.1466851 , 0.05197817, 0.1237444 ],
# Method 2
# code
tf.image.transpose(tf.constant(w2))
#out
<tf.Tensor: shape=(16, 3, 3, 3), dtype=float32, numpy=
array([[[[-0.09935276, 0.02673087, 0.01329462],
[-0.01043741, 0.00516671, -0.04251045],
[-0.03572255, -0.01315425, 0.08955526]],
[[-0.15000243, 0.12058315, 0.06234892],
[ 0.09123346, -0.18056516, -0.15848799],
[ 0.16559589, 0.03411882, 0.0018566 ]],
[[-0.04185663, -0.11198951, -0.02449715],
[ 0.13060766, -0.07997198, -0.01930575],
[-0.14274003, 0.1362513 , 0.02790332]]],
[[[-0.18470907, -0.08563003, -0.1520263 ],
[-0.01095065, 0.13471746, 0.16735196],
[-0.07657725, 0.14455187, 0.07566869]],
我想要的是轉換我的權重 w2 以便將其分配給我的圖層的正確方法。
出於優化原因,TFlite 會更改 Conv2D 權重形狀。 我無法在文檔中找到它,但在這里,在最后一條評論中,他們解釋了“標准”和“精簡”張量流形狀實現之間的區別:
在標准 tensorflow 中,Conv2D 權重形狀是 HWIO,意思是(filter_height, filter_width, input_channels, output_channels)
。
TFlite 實現是 OHWI,意思是(output_channels, filter_height, filter_width, input_channels)
。
為了解決您的問題,我們需要對軸重新排序。 直觀地說,從 OHWI 到 HWIO,我們只需要將“O”從 OHWI 移動到最后一個索引 (3),其余的軸應該轉到較低的索引:
Index: 0 1 2 3
O H W I
Reordering axes we have
New index: 1 2 3 0
H W I O
為此,我們可以使用tf.transpose
但指定我們希望如何交換軸,正如剛才所討論的:
tf.transpose(tf.constant(w2), (1,2,3,0) )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.