sicara / tf2-yolov4

A TensorFlow 2.0 implementation of YOLOv4: Optimal Speed and Accuracy of Object Detection
MIT License
208 stars 53 forks source link

Import custom model error `ValueError: No such layer: conv2d_32` #65

Open bessszilard opened 4 years ago

bessszilard commented 4 years ago

Hello! I am trying to import a custom Yolov4 model with 5 classes. I trained the model with the darknet library. The weights are proper because I have processed with them a video already.

I used this code based on the convert_darknet_weights function.

from tf2_yolov4.anchors import YOLOV4_ANCHORS
from tf2_yolov4.model import YOLOv4
from tf2_yolov4.tools.weights import load_darknet_weights_in_yolo
import numpy as np

num_classes = 5
INPUT_SHAPE = (416, 416, 3)
output_weights_path = '/content/yolov4.h5'
_weight_path='/content/drive/My\ Drive/20200722/yolow_backup/yolov4-custom_best.weights'

model = YOLOv4(
        input_shape=INPUT_SHAPE, num_classes=num_classes, anchors=YOLOV4_ANCHORS,
        weights=None,
        training=False
)
model.predict(np.random.random((1, *INPUT_SHAPE)))
model = load_darknet_weights_in_yolo(model, darknet_weights_path=_weight_path)
model.save(output_weights_path)

And I got this error:

---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-46-94ab431f8673> in <module>()
     17 
     18 model.predict(np.random.random((1, *INPUT_SHAPE)))
---> 19 model = load_darknet_weights_in_yolo(model, darknet_weights_path=_weight_path)
     20 model.save(output_weights_path)

1 frames

/content/tf2-yolov4/tf2_yolov4/tools/weights.py in load_darknet_weights_in_yolo(yolo_model, darknet_weights_path)
     31     """
     32     sample_conv_weights = (
---> 33         yolo_model.get_layer("CSPDarknet53").get_layer("conv2d_32").get_weights()[0]
     34     )
     35 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/network.py in get_layer(self, name, index)
    561       if layer.name == name:
    562         return layer
--> 563     raise ValueError('No such layer: ' + name)
    564 
    565   @property

ValueError: No such layer: conv2d_32

What causes the error?

RaphaelMeudec commented 4 years ago

Hello @bessszilard! We check that weights are indeed updated during the conversion, hence the selection of the conv2d_32 layer to monitor that weights at the beginning and end of script are different.

Layer should be selected dynamically instead of hardcoded, and we'll do the fix soon. In the meantime, you can comment L32 and l112-120 locally to avoid the check

bessszilard commented 4 years ago

Thanks @RaphaelMeudec! I had followed your instruction and it had successfully generated a .h5 file. Although I got invalid results for the predictions with this code:

# Reload model from .h5
model_det = YOLOv4(
    input_shape=(HEIGHT, WIDTH, 3),
    anchors=YOLOV4_ANCHORS,
    num_classes=5,
    training=False,
    yolo_max_boxes=100,
    yolo_iou_threshold=0.5,
    yolo_score_threshold=0.5,
    weights='/content/yolov4.h5'
)

# Prepare image
image = tf.io.read_file(img_path)
image = tf.image.decode_image(image)
image = tf.image.resize(image, (HEIGHT, WIDTH))
images = tf.expand_dims(image, axis=0) / 255.0

boxes, scores, classes, valid_detections = model.predict(images)
print(valid_detections)

In the end, the valid_detections is [0], and the scores are zero as well:

[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0.]]

model.summary output


Model: "YOLOv4"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_8 (InputLayer)            [(None, 416, 416, 3) 0                                            
__________________________________________________________________________________________________
CSPDarknet53 (Model)            [(None, 52, 52, 256) 26652512    input_8[0][0]                    
__________________________________________________________________________________________________
YOLOv4_neck (Model)             [(None, 52, 52, 128) 15857152    CSPDarknet53[1][0]               
                                                                 CSPDarknet53[1][1]               
                                                                 CSPDarknet53[1][2]               
__________________________________________________________________________________________________
YOLOv3_head (Model)             [(None, 50, 4), (Non 21515866    YOLOv4_neck[1][0]                
                                                                 YOLOv4_neck[1][1]                
                                                                 YOLOv4_neck[1][2]                
==================================================================================================
Total params: 64,025,530
Trainable params: 63,959,226
Non-trainable params: 66,304
__________________________________________________________________________________________________
None

The .weights file is good because I tested it already with the darknet library.

Parchevskij commented 3 years ago

@bessszilard, did you solve this problem, because I have the same issue. Thank a lot!

bessszilard commented 3 years ago

No I haven't. Meanwhile I moved on other projects, so this was no longer actual.

On Thu, Mar 11, 2021, 1:29 PM Yenhenij Parchevskij @.***> wrote:

@bessszilard https://github.com/bessszilard, did you solve this problem, because I have the same issue. Thank a lot!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sicara/tf2-yolov4/issues/65#issuecomment-796701598, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALP2IWSHVYQHXVHCUMWJWHTTDCZRRANCNFSM4PIROMHQ .