自拍图像的图像识别

数据挖掘 机器学习 图像分类 计算机视觉
2021-09-14 21:12:14

我开发了一个 Android 应用程序,让任何人都可以将百科全书(桥梁、博物馆、菜肴、风景、绘画等)的图片上传到 Wikimedia Commons。

不幸的是,5% 的用户觉得上传自己的自拍很有趣。所以我想以编程方式检查图片是否是自拍,如果可能,警告他们自拍是题外话。

作为一个数据集,我有:

  • 1000 张我认为不受欢迎的自拍照。它在一定程度上是主观的,但通常这样的照片会显示从一臂远的距离和随机背景拍摄的一两张人脸。
  • 1000 张不是自拍的照片(桥梁、博物馆、菜肴等,任何东西)。Tricky:这也包括名人的照片,通常它们很容易与自拍区分开来,因为这些人距离较远。如果您看到伸出的手臂,则可以确定这是自拍。

所有照片都是用智能手机(数百种不同型号)拍摄的,它们是 2MB 到 5MB 的 JPG 文件,具有各种尺寸和比例,纵向或横向模式。

我必须只使用开源,并且生成的检测代码必须在不到一秒的时间内在低端 Android 手机上运行。

这项任务需要什么方法和步骤?

4个回答

我会去转移学习的方式。这个想法是采用网络,它已经在大型数据集上进行了训练,并开发了许多可以重复使用的卷积过滤器。TensorFlow中有一些可用。您在 ImageNet 上进行预训练的网络,砍掉负责对这些过滤器进行分类的最后一层,并用您自己的替换它。这样一来,您实际上并不需要拥有那么多数据来达到开创性的分数。

检查这些链接:

您还可以提供自己的顶层来更改输入形状。

base_model = MobileNetV2(
    weights="imagenet",
    include_top=False,
    input_shape=(HEIGTH, WIDTH, DEPTH)
)

您可以选择是否重新训练网络。

base_model.trainable = False

现在只需使用基本模型实例化一个新模型并添加最终层。

model = Sequential(base_model)

model.add(Flatten())

model.add(Dense(units=1024))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dropout(rate=0.25))

model.add(Dense(units=1024))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Dropout(rate=0.25))

model.add(Dense(units=len(encoder.classes_)))
model.add(Activation('softmax'))

然后像往常一样编译模型。

model.compile(
    loss='categorical_crossentropy',
    optimizer=Adam(
        learning_rate=0.0001
    ),
    metrics=['accuracy']
)

请注意,您必须选择正确数量的最终密集层及其形状。您仍然需要对其进行微调:使用哪个激活函数,是否应该进行权重衰减,以哪个速率,什么优化器,什么学习率等。

为此,您无需经历自己创建模型的痛苦。使用 MTCNN 检测人脸并继续操作。

对于后代,将面部大小和位置与图像进行比较并做出最佳决定。

图像识别技术的实现 有很多开源库可用于图像识别和分类。您可以使用“TensorFlow”库进行图像识别,并且可以与您的 Android 应用程序集成。

最好的方法是使用like

  1. 使用 U-Net(Mobile Net)预训练的迁移学习模型。
  2. 具有预定义权重的 VGG 面。

带有 U-Net 的移动网络

def create_model(trainable=True):
    model = MobileNet(input_shape=(IMAGE_HEIGHT, IMAGE_WIDTH, 3), include_top=False, alpha=ALPHA, weights="imagenet")

    for layer in model.layers:
        layer.trainable = trainable

    block1 = model.get_layer("conv_pw_5_relu").output
    block2 = model.get_layer("conv_pw_11_relu").output
    block3 = model.get_layer("conv_pw_13_relu").output

    x = Concatenate()([UpSampling2D()(block3), block2])
    x = Concatenate()([UpSampling2D()(x), block1])

    x = Conv2D(1, kernel_size=1, activation="sigmoid")(x)
    x = Reshape((HEIGHT_CELLS, WIDTH_CELLS))(x)

    return Model(inputs=model.input, outputs=x)

具有预定义权重的 VGG-Face

from keras_vggface.vggface import VGGFace
model=VGGFace(weights_path)
model.summary()