如何提高神经网络在地标检测和识别中的准确性?
how to increase accuracy of neural network in land marks detection and recognition?
我正在研究地标检测和从相机到足球场
所以我构建了一个神经网络,但我得到的准确率很低且损失很高
x 数据是从相机拍摄的足球比赛图像
y 数据是整个场地上 29 个地标的坐标
示例:
link 数据集:
x 形状 (565, 320, 320, 3)
y 形状 (565, 29, 2)
每个地标都有两个值 x,y,不在图像中的地标取 -1
示例:
y[0]=array([[ 72., 133.],[ 39., 148.],[122., 154.],
[ 3., 163.],
[ 33., 166.],
[ -1., -1.],
[ -1., -1.],......])
注意:
我对 ( x => /255 , y => /320) 进行了归一化,使 x 的数据在 0-1 和 y 的 (-1,0-1) 之间
型号:
input = tf.keras.layers.Input((320,320,3))
l = tf.keras.layers.Conv2D(128,(5,5),padding='same')(input)
l=tf.keras.layers.BatchNormalization()(l)
l=tf.keras.layers.LeakyReLU()(l)
l=tf.keras.layers.MaxPool2D()(l)
l = tf.keras.layers.Conv2D(64,(5,5),padding='same')(l)
l=tf.keras.layers.BatchNormalization()(l)
l=tf.keras.layers.LeakyReLU()(l)
l=tf.keras.layers.MaxPool2D()(l)
l = tf.keras.layers.Conv2D(32,(5,5),padding='same')(l)
l=tf.keras.layers.BatchNormalization()(l)
l=tf.keras.layers.LeakyReLU()(l)
l=tf.keras.layers.MaxPool2D()(l)
l=tf.keras.layers.Flatten()(l)
l=tf.keras.layers.Dense(256,activation='tanh')(l)
l=tf.keras.layers.Dense(128,activation='tanh')(l)
l=tf.keras.layers.Dense(29*2,activation='tanh')(l)
您的模型似乎不太适合检测物体。对于对象检测,需要更复杂的架构。你可以看看 YOLO 对象检测器,这是一个非常流行的对象检测模型。在此存储库中,有一个相当易于使用且易于重新训练的 YOLOv3 实现可用:
https://github.com/YunYang1994/TensorFlow2.0-Examples
您的模型在对象检测方面表现不佳的原因有很多。一个原因是,你似乎总是准确地预测 29 个地标,即使图像中的对象较少。此外,网络很难确定将哪个地标放置在输出中的哪个位置,因为您的输出不保留图像的结构并以无序方式呈现最终的地标预测。这就引入了如何训练模型的问题,因为你需要为特定的网络输出分配一个地标来训练它。像 YOLO 这样的模型的工作方式不同,因为它们预测图像中是否有许多规则间隔的位置的对象,并结合一个分数来告诉你检测的可信度。这解决了我刚才描述的问题,应该是您模型的良好输出。
如果您不想使用另一个存储库,而是想从头开始创建一个新模型,一个简单的方法可能如下所示:不要在模型末尾使用密集层。相反,使用卷积层,并在较早的层中额外使用较小的步幅。例如,如果你只使用 (2, 2) 的步幅并且只使用步幅两次,这应该会给你(在你的网络的某个阶段)形状为 (90, 90, n) 的卷积层,其中 n是卷积层中过滤器的数量。现在您可以设置 n=1,这基本上会为您提供一个 90x90 值数组的结果,这些值均匀分布在您的图像上。然后你可以训练模型,使用这些均匀间隔的值来预测物体在当前位置的概率,所以超过 0.5 的值将意味着在相应位置检测到物体。
我正在研究地标检测和从相机到足球场
所以我构建了一个神经网络,但我得到的准确率很低且损失很高
x 数据是从相机拍摄的足球比赛图像
y 数据是整个场地上 29 个地标的坐标
示例:
link 数据集:
x 形状 (565, 320, 320, 3)
y 形状 (565, 29, 2)
每个地标都有两个值 x,y,不在图像中的地标取 -1
示例:
y[0]=array([[ 72., 133.],[ 39., 148.],[122., 154.],
[ 3., 163.],
[ 33., 166.],
[ -1., -1.],
[ -1., -1.],......])
注意:
我对 ( x => /255 , y => /320) 进行了归一化,使 x 的数据在 0-1 和 y 的 (-1,0-1) 之间
型号:
input = tf.keras.layers.Input((320,320,3))
l = tf.keras.layers.Conv2D(128,(5,5),padding='same')(input)
l=tf.keras.layers.BatchNormalization()(l)
l=tf.keras.layers.LeakyReLU()(l)
l=tf.keras.layers.MaxPool2D()(l)
l = tf.keras.layers.Conv2D(64,(5,5),padding='same')(l)
l=tf.keras.layers.BatchNormalization()(l)
l=tf.keras.layers.LeakyReLU()(l)
l=tf.keras.layers.MaxPool2D()(l)
l = tf.keras.layers.Conv2D(32,(5,5),padding='same')(l)
l=tf.keras.layers.BatchNormalization()(l)
l=tf.keras.layers.LeakyReLU()(l)
l=tf.keras.layers.MaxPool2D()(l)
l=tf.keras.layers.Flatten()(l)
l=tf.keras.layers.Dense(256,activation='tanh')(l)
l=tf.keras.layers.Dense(128,activation='tanh')(l)
l=tf.keras.layers.Dense(29*2,activation='tanh')(l)
您的模型似乎不太适合检测物体。对于对象检测,需要更复杂的架构。你可以看看 YOLO 对象检测器,这是一个非常流行的对象检测模型。在此存储库中,有一个相当易于使用且易于重新训练的 YOLOv3 实现可用: https://github.com/YunYang1994/TensorFlow2.0-Examples
您的模型在对象检测方面表现不佳的原因有很多。一个原因是,你似乎总是准确地预测 29 个地标,即使图像中的对象较少。此外,网络很难确定将哪个地标放置在输出中的哪个位置,因为您的输出不保留图像的结构并以无序方式呈现最终的地标预测。这就引入了如何训练模型的问题,因为你需要为特定的网络输出分配一个地标来训练它。像 YOLO 这样的模型的工作方式不同,因为它们预测图像中是否有许多规则间隔的位置的对象,并结合一个分数来告诉你检测的可信度。这解决了我刚才描述的问题,应该是您模型的良好输出。
如果您不想使用另一个存储库,而是想从头开始创建一个新模型,一个简单的方法可能如下所示:不要在模型末尾使用密集层。相反,使用卷积层,并在较早的层中额外使用较小的步幅。例如,如果你只使用 (2, 2) 的步幅并且只使用步幅两次,这应该会给你(在你的网络的某个阶段)形状为 (90, 90, n) 的卷积层,其中 n是卷积层中过滤器的数量。现在您可以设置 n=1,这基本上会为您提供一个 90x90 值数组的结果,这些值均匀分布在您的图像上。然后你可以训练模型,使用这些均匀间隔的值来预测物体在当前位置的概率,所以超过 0.5 的值将意味着在相应位置检测到物体。