简体   繁体   中英

Manually assigning weights for Conv2d layer

I have a model that has many conv2d layers. I converted the model to the Tflite model. After converting I get the weights of single conv2d. The shape of weights looks like this

# code
w2 = get_variable(interpreter, 1)
print(w2.shape)

# output
(16, 3, 3, 3)

w2 is the weight of the conv2d layer which I got from tflite model.

# 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]],

Now the the weights as I got from the model file using command 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 ],

I tried to methods to convert w2(16,3,3,3) to the shape that I want 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]],

What I want is the correct method to transform my weight w2 in order to assign it to my layers.

TFlite changes Conv2D weights shape for optimization reasons. I have not been able to find it in the docs, but here , on the last comment, they explain the difference between "standard" and "lite" tensorflow shape implementations:

In standard tensorflow, Conv2D weight shape is HWIO, meaning (filter_height, filter_width, input_channels, output_channels) .

TFlite implementation is OHWI, meaning (output_channels, filter_height, filter_width, input_channels) .

To solve your issue we need to reorder the axes. Intutively to go from OHWI to HWIO we just need to move the "O" from OHWI to the last index(3), and the rest of axes should go to a lower index:

Index:      0    1    2    3
            O    H    W    I

Reordering axes we have

New index:  1    2    3    0
            H    W    I    O

To do so we can use tf.transpose but specifying how we want to swap the axes, as just discussed:

tf.transpose(tf.constant(w2), (1,2,3,0) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM