首页 > 解决方案 > “Conv2D 操作目前仅支持 CPU 上的 NHWC 张量格式”尽管 NHWC 格式(YOLO 3)出错

问题描述

我正在尝试从github运行一些示例代码,以学习使用 Tensorflow 2 和 YOLO 框架。我的笔记本电脑有一个 M1000M 显卡,我从这里安装了 NVIDIA 的 CUDA 平台。

所以有问题的代码是这样的:

tf.compat.v1.disable_eager_execution()

_MODEL_SIZE = (416, 416)
_CLASS_NAMES_FILE = './data/labels/coco.names'
_MAX_OUTPUT_SIZE = 20


def main(type, iou_threshold, confidence_threshold, input_names):
    class_names = load_class_names(_CLASS_NAMES_FILE)
    n_classes = len(class_names)

    model = Yolo_v3(n_classes=n_classes, model_size=_MODEL_SIZE,
                    max_output_size=_MAX_OUTPUT_SIZE,
                    iou_threshold=iou_threshold,
                    confidence_threshold=confidence_threshold)

    if type == 'images':
        batch_size = len(input_names)
        batch = load_images(input_names, model_size=_MODEL_SIZE)
        inputs = tf.compat.v1.placeholder(tf.float32, [batch_size, *_MODEL_SIZE, 3])
        detections = model(inputs, training=False)
        saver = tf.compat.v1.train.Saver(tf.compat.v1.global_variables(scope='yolo_v3_model'))

        with tf.compat.v1.Session() as sess:
            saver.restore(sess, './weights/model.ckpt')
            detection_result = sess.run(detections, feed_dict={inputs: batch})

        draw_boxes(input_names, detection_result, class_names, _MODEL_SIZE)

        print('Detections have been saved successfully.')

在执行此操作时(也想知道为什么首先启动 detection.py 不使用 GPU),我收到错误消息:

File "C:\SDKs etc\Python 3.8\lib\site-packages\tensorflow\python\client\session.py", line 1451, in _call_tf_sessionrun
    return tf_session.TF_SessionRun_wrapper(self._session, options, feed_dict,
tensorflow.python.framework.errors_impl.UnimplementedError: The Conv2D op currently only supports the NHWC tensor format on the CPU. The op was given the format: NCHW
         [[{{node yolo_v3_model/conv2d/Conv2D}}]]

完整日志请参见此处

如果我理解正确,格式inputs = tf.compat.v1.placeholder(tf.float32, [batch_size, *_MODEL_SIZE, 3])已经是 NHWC(模型大小是 2 个数字的元组),我不知道我需要如何更改代码中的内容以使其在 CPU 上运行。

标签: tensorflowkerastensorflow2.0yolo

解决方案


如果我理解正确,inputs = tf.compat.v1.placeholder(tf.float32, [batch_size, *_MODEL_SIZE, 3]) 的格式已经是 NHWC(模型大小是 2 个数字的元组),我没有不知道我需要如何更改代码中的内容以使其在 CPU 上运行。

是的,你是。但是看这里

def __init__(self, n_classes, model_size, max_output_size, iou_threshold,
                 confidence_threshold, data_format=None):
        """Creates the model.
        Args:
            n_classes: Number of class labels.
            model_size: The input size of the model.
            max_output_size: Max number of boxes to be selected for each class.
            iou_threshold: Threshold for the IOU.
            confidence_threshold: Threshold for the confidence score.
            data_format: The input format.
        Returns:
            None.
        """
        if not data_format:
            if tf.test.is_built_with_cuda():
                data_format = 'channels_first'
            else:
                data_format = 'channels_last'

然后:

def __call__(self, inputs, training):
    """Add operations to detect boxes for a batch of input images.
    Args:
        inputs: A Tensor representing a batch of input images.
        training: A boolean, whether to use in training or inference mode.
    Returns:
        A list containing class-to-boxes dictionaries
            for each sample in the batch.
    """
    with tf.compat.v1.variable_scope('yolo_v3_model'):
        if self.data_format == 'channels_first':
            inputs = tf.transpose(inputs, [0, 3, 1, 2])

解决方案:

  1. 检查tf.test.is_built_with_cuda()是否按预期工作

  2. 如果没有 - 在创建模型时手动设置顺序:

    model = Yolo_v3(n_classes=n_classes, model_size=_MODEL_SIZE,
    max_output_size=_MAX_OUTPUT_SIZE,
    iou_threshold=iou_threshold,
    confidence_threshold=confidence_threshold,
    data_format = 'channels_last')


推荐阅读