YOLOv3_TensorFlow icon indicating copy to clipboard operation
YOLOv3_TensorFlow copied to clipboard

How to convert our weights to Darknet weights

Open tianfengyijiu opened this issue 5 years ago • 7 comments

I have got a better result then Darknet, so how can I convert our format weights to Darknet. Thinks a lot!

tianfengyijiu avatar Jun 22 '19 02:06 tianfengyijiu

I think that might be sort of difficult.

wizyoung avatar Jun 23 '19 03:06 wizyoung

can you leave your wechat number for communication?

wizyoung avatar Jun 23 '19 09:06 wizyoung

I will try to do this just use the tf.train.NewCheckpointReader and write the value in weights file according to the name of weights. But, I do not know the order of the weights in Darknet. My wechat: 13207695819.

tianfengyijiu avatar Jun 24 '19 03:06 tianfengyijiu

I have already finished this work, and I will pull my work, but there are two problems:

  1. Maybe some layer`s name is different between this project and my
  2. After conversion, the results on the Darknet map is worse than here before conversion This is so confusedddddddddd. Do we use the moving average, if so, it may be a reason?

tianfengyijiu avatar Jun 24 '19 11:06 tianfengyijiu

Hello, I have written a code to do it for another tensorflow implementation. Maybe you can adapt it. It is inspired from the Ultralytics save_weights function

def get_var_scope(a):
    temp = a.split("/", maxsplit=-1)
    return "/".join(temp[:-1])

def get_all_conv_scopes():
    # Basically takes all the variable scopes with "/conv" without the bias / batch norm
    seen = []
    scopes = []
    for var in tf.global_variables():
        scope = get_var_scope(var.name)
        if scope not in seen and "batch_normalization" not in scope:
            scopes.append(scope)
            seen.append(scope)
    return scopes

version = np.array([0, 2, 5], dtype=np.int32)
seen = np.array([0], dtype=np.int64)  # (int64)
with open(darknet_file, 'wb') as f:
    version.tofile(f)
    seen.tofile(f)
    
    all_vars_names = [x.name for x in tf.global_variables()]
    for scope in get_all_conv_scopes():
        print(scope)
        with tf.variable_scope(scope, reuse=True):
            if scope + "/bias:0" in all_vars_names:
                sess.run(tf.get_variable('bias')).tofile(f)
            else:
                sess.run(tf.get_variable('batch_normalization/beta')).tofile(f)
                sess.run(tf.get_variable('batch_normalization/gamma')).tofile(f)
                sess.run(tf.get_variable('batch_normalization/moving_mean')).tofile(f)
                sess.run(tf.get_variable('batch_normalization/moving_variance')).tofile(f)
            weight = np.transpose(sess.run(tf.get_variable('weight')), [3,2,0,1])
            weight.tofile(f)
            print(weight.shape)
            print("")

May I ask what did you use to get a better score ?

RubenS02 avatar Jul 01 '19 09:07 RubenS02

Hello, I have modified a little your code with the corresponding layer names and I've got the same mAP importing the output weights into the ultralytics implementation. cheers

import tensorflow as tf
import re
import numpy as np


def write_bn_and_weights(weightfile, layer_name):
    write_bn(weightfile, layer_name)
    write_convweights(weightfile, layer_name)


def write_bias_and_weights(weightfile, layer_name):
    write_bias(weightfile, layer_name)
    write_convweights(weightfile, layer_name)


def write_bias(weightfile, layer_name):
    weightfile.write(reader.get_tensor(layer_name + '/biases').tobytes())


def write_bn(weightfile, layer_name):
    weightfile.write(reader.get_tensor(layer_name + '/BatchNorm/beta').tobytes())
    weightfile.write(reader.get_tensor(layer_name + '/BatchNorm/gamma').tobytes())
    weightfile.write(reader.get_tensor(layer_name + '/BatchNorm/moving_mean').tobytes())
    weightfile.write(reader.get_tensor(layer_name + '/BatchNorm/moving_variance').tobytes())


def write_convweights(weightfile, layer_name):
    # 需要将(height, width, in_dim, out_dim)转换成(out_dim, in_dim, height, width)
    conv_weights = np.transpose(reader.get_tensor(layer_name + '/weights'), [3, 2, 0, 1])
    weights.write(conv_weights.tobytes())


reader = tf.train.NewCheckpointReader('checkpoint/best_model_Epoch_14_step_119984_mAP_0.6485_loss_5.2913_lr_0.0001')

global_variables = reader.get_variable_to_shape_map()

weights = open('test3.weights', 'wb')

numpy_data = np.ndarray(shape=(3,), dtype='int32', buffer=np.array([0, 2, 0], dtype='int32'))
weights.write(numpy_data.tobytes())
weights.flush()
numpy_data = np.ndarray(shape=(1,),
                        dtype='int64',
                        buffer=np.array([320000], dtype='int64'))
weights.write(numpy_data.tobytes())
weights.flush()

write_bn_and_weights(weights, 'yolov3/darknet53_body/Conv')
for i in range(1, 52):
    write_bn_and_weights(weights, 'yolov3/darknet53_body/Conv_' + str(i))

write_bn_and_weights(weights, 'yolov3/yolov3_head/Conv')

for i in range(1, 6):
    write_bn_and_weights(weights, 'yolov3/yolov3_head/Conv_' + str(i))

write_bias_and_weights(weights, 'yolov3/yolov3_head/Conv_6')

for i in range(7, 14):
    write_bn_and_weights(weights, 'yolov3/yolov3_head/Conv_' + str(i))

write_bias_and_weights(weights, 'yolov3/yolov3_head/Conv_14')

for i in range(15, 22):
    write_bn_and_weights(weights, 'yolov3/yolov3_head/Conv_' + str(i))

write_bias_and_weights(weights, 'yolov3/yolov3_head/Conv_22')

silvestrebahi avatar Nov 13 '19 13:11 silvestrebahi

请问有从rtsp流每隔n帧跑yolov3检测实时人数的脚本吗?

bujianyiwang avatar Jan 16 '20 06:01 bujianyiwang