allanzelener / YAD2K

YAD2K: Yet Another Darknet 2 Keras
Other
2.71k stars 877 forks source link

Load weights from darknet model #104

Open Willjay90 opened 6 years ago

Willjay90 commented 6 years ago

Hi, I'm just a newbie to machine learning and playing around your model recently. When I run with tiny-yolo cfg and tiny-yolo weights, it FAILS to detect any object. After I change the weight_header to read 20 bytes at first in yad2k.py, it works.

# tiny-yolo
# wget http://pjreddie.com/media/files/tiny-yolo.weights
# wget https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/tiny-yolo.cfg
# ./yad2k.py tiny-yolo.cfg tiny-yolo.weights model_data/tiny-yolo.h5
# ./test_yolo.py model_data/tiny-yolo.h5

 weights_header = np.ndarray(
        shape=(4, ), dtype='int32', buffer=weights_file.read(20))

However, with yolo cfg and yolo weights, it ONLY works with the 16 bytes header.

# yolo
# wget http://pjreddie.com/media/files/yolo.weights
# wget https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolo.cfg
# ./yad2k.py yolo.cfg yolo.weights model_data/yolo.h5
# ./test_yolo.py model_data/yolo.h5

weights_header = np.ndarray(
        shape=(4, ), dtype='int32', buffer=weights_file.read(16))

So, I'm looking into parser.c from darknet trying to understand how it saves weights. From my perspective, it should be 20 bytes in header, isn't it?

void save_weights_upto(network *net, char *filename, int cutoff)
{
    ...
    fwrite(&major, sizeof(int), 1, fp);            // sizeof(int): 4
    fwrite(&minor, sizeof(int), 1, fp);            // sizeof(int): 4
    fwrite(&revision, sizeof(int), 1, fp);         // sizeof(int): 4
    fwrite(net->seen, sizeof(size_t), 1, fp);      // sizeof(size_t): 8

    int i;
    for(i = 0; i < net->n && i < cutoff; ++i){
        layer l = net->layers[i];
        if(l.type == CONVOLUTIONAL || l.type == DECONVOLUTIONAL){
            save_convolutional_weights(l, fp);
        }
    ...
    ...
}

My question is, in yad2k.py, how do you know to load 16 bytes as weight_header?