如何使用最新的 MobileNet (v3) 进行目标检测?

Posted

技术标签:

【中文标题】如何使用最新的 MobileNet (v3) 进行目标检测?【英文标题】:How To Use The Latest MobileNet (v3) for Object Detection? 【发布时间】:2020-04-11 17:15:59 【问题描述】:

我一直在尝试使用最新的 MobileNet MobileNet_v3 来运行对象检测。您可以从此处找到 Google 的预训练模型,例如我正在尝试使用的模型“ssd_mobilenet_v3_large_coco”:https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md

我不知道这些新模型是如何获取图像数据输入的,我在网上也找不到任何关于此的深入文档。以下 java 代码总结了我如何尝试从我可以在线收集的有限数量中提供模型(特别是使用 TensorFlow Lite 的 .tflite 模型)图像数据,但该模型仅返回 10^-20 阶的预测置信度,所以它从不真正识别任何东西。我认为我一定做错了。

//Note that the model takes a 320 x 320 image


//Get image data as integer values
private int[] intValues;
intValues = new int[320 * 320];
private Bitmap croppedBitmap = null;
croppedBitmap = Bitmap.createBitmap(320, 320, Config.ARGB_8888);
croppedBitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());

//create ByteBuffer as input for running ssd_mobilenet_v3
private ByteBuffer imgData;
imgData = ByteBuffer.allocateDirect(320 * 320 * 3);
imgData.order(ByteOrder.nativeOrder());

//fill Bytebuffer
//Note that & 0xFF is for just getting the last 8 bits, which converts to RGB values here
imgData.rewind();
for (int i = 0; i < inputSize; ++i) 
  for (int j = 0; j < inputSize; ++j) 
    int pixelValue = intValues[i * inputSize + j];
    // Quantized model
    imgData.put((byte) ((pixelValue >> 16) & 0xFF));
    imgData.put((byte) ((pixelValue >> 8) & 0xFF));
    imgData.put((byte) (pixelValue & 0xFF));
  


// Set up output buffers
private float[][][] output0;
private float[][][][] output1;
output0 = new float[1][2034][91];
output1 = new float[1][2034][1][4];

//Create input HashMap and run the model
Object[] inputArray = imgData;
Map<Integer, Object> outputMap = new HashMap<>();
outputMap.put(0, output0);
outputMap.put(1, output1);
tfLite.runForMultipleInputsOutputs(inputArray, outputMap);

//Examine Confidences to see if any significant detentions were made
for (int i = 0; i < 2034; i++) 
  for (int j = 0; j < 91; j++) 
    System.out.println(output0[0][i][j]);
  

【问题讨论】:

【参考方案1】:

我已经想出了如何通过一些额外的努力来完成这项工作。

您必须下载预训练模型并自己重新创建 .tflite 文件,才能让它们与提供的 android 代码一起工作。以下由 Tensorflow 团队编写的指南向您展示了如何重新创建 .tflite 文件,以使它们具有与 android 对象检测代码所接受的相同的输入/输出格式:

https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/running_on_mobile_tensorflowlite.md

这样,您几乎不需要更改为对象检测提供的任何 android 代码。您唯一需要手动指定的(在创建 .tflite 文件时和在用于对象检测的 android 代码中)是对象检测模型的分辨率。

因此,对于分辨率为 320x320 的 mobilenet_v3,在将模型转换为 .tflite 文件时,请使用标志“--input_shapes=1,320,320,3”。然后,在 android 代码中设置变量“TF_OD_API_INPUT_SIZE = 320”。这些是您需要进行的唯一更改。

理论上,这适用于任何(且仅适用于)ssd 模型,但我目前仅使用 mobilenet_v2 对其进行了测试,因为它更容易开始工作,并且 v2 和 v3 之间的差异可以忽略不计。

【讨论】:

知道为什么动物园的 .tflite 模型似乎不起作用吗?我有同样的问题,只有 gettig 10^-15 分数,但输入也应该是量化的 320x320 rgb 缓冲区,对吧?

以上是关于如何使用最新的 MobileNet (v3) 进行目标检测?的主要内容,如果未能解决你的问题,请参考以下文章

MobileNet vs SqueezeNet vs ResNet50 vs Inception v3 vs VGG16

MobileNetV1 V2 V3网络理解+pytorch源码

Python使用mobilenet的预训练模型进行预测

FasterNet:CVPR2023年最新的网络,基于部分卷积PConv,性能远超MobileNet,MobileVit

在CentOS7上安装和使用ZooKeeper最新版本(V3.4.11)

初识STM32--MDK5下使用V3.5库新建工程