experiencor / keras-yolo2

Easy training on custom dataset. Various backends (MobileNet and SqueezeNet) supported. A YOLO demo to detect raccoon run entirely in brower is accessible at https://git.io/vF7vI (not on Windows).
MIT License
1.73k stars 785 forks source link

Cannot load pretrained tiny yolo weights #375

Open nkbenamara opened 5 years ago

nkbenamara commented 5 years ago

Hi all.

I'm trying to load pretrained weights of the tiny yolo model, and it writes that the model don't fit to the number of model layers

ValueError: You are trying to load a weight file containing 16 layers into a model with 2 layers.

anyone has before fixed this problem ?

(Construction of the model)

   ###############################
    #   Construct the model 
    ###############################

    yolo = YOLO(backend             = config['model']['backend'],
                input_size          = config['model']['input_size'], 
                labels              = config['model']['labels'], 
                max_box_per_image   = config['model']['max_box_per_image'],
                anchors             = config['model']['anchors'])

(In the YOLO class (frontend.py))

        ##########################
        # Make the model
        ##########################

        # make the feature extractor layers
        input_image     = Input(shape=(self.input_size, self.input_size, 3))
        self.true_boxes = Input(shape=(1, 1, 1, max_box_per_image , 4))  

        if backend == 'Inception3':
            self.feature_extractor = Inception3Feature(self.input_size)  
        elif backend == 'SqueezeNet':
            self.feature_extractor = SqueezeNetFeature(self.input_size)        
        elif backend == 'MobileNet':
            self.feature_extractor = MobileNetFeature(self.input_size)
        elif backend == 'Full Yolo':
            self.feature_extractor = FullYoloFeature(self.input_size)

## ########################################
##the model that i want to  load ##
        elif backend == 'Tiny Yolo':
            self.feature_extractor = TinyYoloFeature(self.input_size)
############################

        elif backend == 'VGG16':
            self.feature_extractor = VGG16Feature(self.input_size)
        elif backend == 'ResNet50':
            self.feature_extractor = ResNet50Feature(self.input_size)
        else:
            raise Exception('Architecture not supported! Only support Full Yolo, Tiny Yolo, MobileNet, SqueezeNet, VGG16, ResNet50, and Inception3 at the moment!')

(backend of TinyYOLO)

class TinyYoloFeature(BaseFeatureExtractor):
    """docstring for ClassName"""
    def __init__(self, input_size):
        input_image = Input(shape=(input_size, input_size, 3))

        # Layer 1
        x = Conv2D(16, (3,3), strides=(1,1), padding='same', name='conv_1', use_bias=False)(input_image)
        x = BatchNormalization(name='norm_1')(x)
        x = LeakyReLU(alpha=0.1)(x)
        x = MaxPooling2D(pool_size=(2, 2))(x)

        # Layer 2 - 5
        for i in range(0,4):
            x = Conv2D(32*(2**i), (3,3), strides=(1,1), padding='same', name='conv_' + str(i+2), use_bias=False)(x)
            x = BatchNormalization(name='norm_' + str(i+2))(x)
            x = LeakyReLU(alpha=0.1)(x)
            x = MaxPooling2D(pool_size=(2, 2))(x)

        # Layer 6
        x = Conv2D(512, (3,3), strides=(1,1), padding='same', name='conv_6', use_bias=False)(x)
        x = BatchNormalization(name='norm_6')(x)
        x = LeakyReLU(alpha=0.1)(x)
        x = MaxPooling2D(pool_size=(2, 2), strides=(1,1), padding='same')(x)

        # Layer 7 - 8
        for i in range(0,2):
            x = Conv2D(1024, (3,3), strides=(1,1), padding='same', name='conv_' + str(i+7), use_bias=False)(x)
            x = BatchNormalization(name='norm_' + str(i+7))(x)
            x = LeakyReLU(alpha=0.1)(x)

        self.feature_extractor = Model(input_image, x)  
        self.feature_extractor.load_weights(TINY_YOLO_BACKEND_PATH)

    def normalize(self, image):
        return image / 255.

My configuration JSON File :

{
    "model" : {
        "backend":              "Tiny Yolo",
        "input_size":           416,
        "anchors":              [4.02,5.21, 5.59,9.42, 7.50,11.51, 9.96,8.74, 11.10,11.99],
        "max_box_per_image":    10,        
        "labels":               ["raccoon"]
    },

    "train": {
        "train_image_folder":   "/content/drive/My Drive/Colab Notebooks/Raccon_dataset Yolo/raccoon_dataset/train_image_folder/",
        "train_annot_folder":   "/content/drive/My Drive/Colab Notebooks/Raccon_dataset Yolo/raccoon_dataset/train_annot_folder/",

        "train_times":          10,
        "pretrained_weights":   "/content/drive/My Drive/Colab Notebooks/Raccon_dataset Yolo/tiny_yolo_backend.h5",
        "batch_size":           16,
        "learning_rate":        1e-4,
        "nb_epochs":            50,
        "warmup_epochs":        3,

        "object_scale":         5.0 ,
        "no_object_scale":      1.0,
        "coord_scale":          1.0,
        "class_scale":          1.0,

        "saved_weights_name":   "full_yolo_raccoon.h5",
        "debug":                true
    },

    "valid": {
        "valid_image_folder":   "/content/drive/My Drive/Colab Notebooks/Raccon_dataset Yolo/raccoon_dataset/valid_image_folder/",
        "valid_annot_folder":   "/content/drive/My Drive/Colab Notebooks/Raccon_dataset Yolo/raccoon_dataset/valid_annot_folder/",

        "valid_times":          1
    }
}
wikiwen commented 5 years ago

I also met the same problem. After seeing the source code, I found It's no need to write anything after "pretrained_weights" in the configuration JSON File. These weights not reconstructed will be loaded to the reconstructed yolo model (one big feature extractor layer and one small output layer). And the backend layers can be loaded pretrained weights in the file "backend.py" (it has been configed),

for example

# line 11 in the file "backend.py"
FULL_YOLO_BACKEND_PATH  = "full_yolo_backend.h5" 
TINY_YOLO_BACKEND_PATH  = "tiny_yolo_backend.h5"  
SQUEEZENET_BACKEND_PATH = "squeezenet_backend.h5"  
MOBILENET_BACKEND_PATH  = "mobilenet_backend.h5" 
INCEPTION3_BACKEND_PATH = "inception_backend.h5"  
VGG16_BACKEND_PATH      = "vgg16_backend.h5"      
RESNET50_BACKEND_PATH   = "resnet50_backend.h5"   
...
class FullYoloFeature(BaseFeatureExtractor):
...
self.feature_extractor.load_weights(FULL_YOLO_BACKEND_PATH)
clw5180 commented 5 years ago

I also met the same problem. After seeing the source code, I found It's no need to write anything after "pretrained_weights" in the configuration JSON File. These weights not reconstructed will be loaded to the reconstructed yolo model (one big feature extractor layer and one small output layer). And the backend layers can be loaded pretrained weights in the file "backend.py" (it has been configed),

for example

# line 11 in the file "backend.py"
FULL_YOLO_BACKEND_PATH  = "full_yolo_backend.h5" 
TINY_YOLO_BACKEND_PATH  = "tiny_yolo_backend.h5"  
SQUEEZENET_BACKEND_PATH = "squeezenet_backend.h5"  
MOBILENET_BACKEND_PATH  = "mobilenet_backend.h5" 
INCEPTION3_BACKEND_PATH = "inception_backend.h5"  
VGG16_BACKEND_PATH      = "vgg16_backend.h5"      
RESNET50_BACKEND_PATH   = "resnet50_backend.h5"   
...
class FullYoloFeature(BaseFeatureExtractor):
...
self.feature_extractor.load_weights(FULL_YOLO_BACKEND_PATH)

U r right. Give a 赞 to you.