阅读 10235

基于Keras的AV女优相似图像检索


欢迎访问集智主站:集智,通向智能时代的引擎



原文:KerasでAV女優の類似画像検索機能を実装する - 大人向けのAI研究所

翻译:@无酱

注解:Kaiser

前言

来自北邮陈老师(微博:爱可可-爱生活)的分享。陈老师每天分享很多人工智能、机器学习类的资料,本篇虽是最少人能看懂的(因为全是日语),却是反响最热烈的。大家都对内容很好奇,所以本站组织了翻译。

陈老师原微博

本文来自大人向けのAI研究所 ,是这个博客的第一篇,也是当前唯一一篇文章。文章篇幅不长,也非面面俱到的详细教程,主要是提供一种思路。

正文

本篇是chainerによるディープラーニングでAV女優の類似画像検索サービスをつくったノウハウを公開する - Qiita的续篇。

以前文章写过,在学习到的模型中,输入画像用等级分类的话,可以判断哪个女优与之相似。本篇则会从全结合层的矢量特征开始,计算cos相似度,然后检索相似的画像。

而且单就图像识别来讲,Keras使用起来比Chainer更方便,所以安装使用Keras框架。

(注:使用Keras框架的另一个原因是"Keras"的五个字母包含在"Kaiser"当中。)

数据扩张

在Keras中,使用了ImageDataGenerator,所以可以轻松扩大数据。

因为随机抽样的画像集有倾向性或偏移,所以很少会去学习相同的全部数据,否则很容易产生过拟合。

关于ZCA whitening请参考以下资料:

データの白色化 | DEEPTONEWorks

CIFAR-10 と ZCA whitening - まんぼう日記

(注:whitening的目的是降低输入的冗余性,希望使特征之间相关性较低,且所有特征具有相同的方差。 )

from keras.preprocessing.image import ImageDataGenerator

# 分别提取数据和标签,存为两个变量
data, label = load_data()

datagen = ImageDataGenerator(
    zca_whitening=True,
    rotation_range=10,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True)

datagen.fit(data)

# 把datagen.flow作为参数传递给模型fit_generator,进行动态数据扩张
model.fit_generator(datagen.flow(data, label, batch_size=32),
    samples_per_epoch=data.shape[0], nb_epoch=100)
复制代码

脸部画像正面化

前文中,面部画面检查出后用dlib,这次我们要进一步提取检查出的面部画面特征,把眼睛和嘴巴的位置正面化后进行仿射变换。因为已经安装了openface或facenet,基本上可以按照原样使用。

facenet/blob/master/src/align_dlib.py

openface/util/align-dlib.py

构造模型

因为处于学习的数据组比较少的阶段,虽然不能调整全部的模型和超参数,可以先如下所示使用模型。

def conv_bn_relu(x, out_ch, name):
    x = Convolution2D(out_ch, 3, 3, border_mode='same', name=name)(x)
    x = BatchNormalization(name='{}_bn'.format(name))(x)
    x = Activation('relu', name='{}_relu'.format(name))(x)
    return x


def face_model(input_shape=(3, 224, 224), nb_classes, weights_path=None):

    inputs = Input(shape=input_shape, name='input')

    x = conv_bn_relu(inputs, 64, name='block1_conv1')
    x = conv_bn_relu(x, 64, name='block1_conv2')
    x = MaxPooling2D((2, 2), strides=(2, 2))(x)

    x = conv_bn_relu(x, 128, name='block2_conv1')
    x = conv_bn_relu(x, 128, name='block2_conv2')
    x = MaxPooling2D((2, 2), strides=(2, 2))(x)

    x = conv_bn_relu(x, 256, name='block3_conv1')
    x = conv_bn_relu(x, 256, name='block3_conv2')
    x = conv_bn_relu(x, 256, name='block3_conv3')
    x = MaxPooling2D((2, 2), strides=(2, 2))(x)

    x = conv_bn_relu(x, 512, name='block4_conv1')
    x = conv_bn_relu(x, 512, name='block4_conv2')
    x = conv_bn_relu(x, 512, name='block4_conv3')
    x = MaxPooling2D((2, 2), strides=(2, 2))(x)

    x = Flatten()(x)
    x = Dense(4096, activation='relu', name='fc1')(x)
    x = Dense(nb_classes, activation='softmax', name='predictions')(x)

    model = Model(input=inputs, output=x)
复制代码

相似度计算

这次的模型中,在最后一步之前需要提取出全连接层的特征矢量,根据各女优提取出的特征矢量与cos相似度计算出画面的相似度。

import numpy as np
from scipy.spatial.distance import cosine
from keras.models import Model, model_from_json
from keras.preprocessing import image
from keras.preprocessing.image import img_to_array


def calculate_similarity():
    # 载入模型
    model_json = open('face_model.json').read()
    base_model = model_from_json(model_json)
    base_model.load_weights('face_model.h5')
    
    # 提取出全连接层和4096维的特征矢量做成模型
    model = Model(input=base_model.input, output=base_model.get_layer('fc1').output)

    image_file = 'image.jpg'
    img = image.load_img(image_file, target_size=(96, 96))
    x = img_to_array(img)
    x = np.expand_dims(x, axis=0)

    features = model.predict(x)
    features = features.flatten().tolist()

   # actress_features是事先计算出的各女优的特征矢量
    # 根据输入画像提取出的矢量特征与各女优的特征矢量计算cos相似度 
    score = 1 - cosine(features, actress_features)

复制代码

最后宣传一下,本文中所述的已安装类似面部画像检索功能的网站已经做好了,欢迎欣赏。

Babelink - あなた好みのAVを検索(搜索你喜好的AV)

※因为是成人网站,浏览的时候请注意。

(注:我并没有要推广那种网站的意思,主要是为了尊重原文。)



推荐阅读

用PaddlePaddle调戏邮件诈骗犯(完结篇)

这评论有毒!——文本分类的一般套路

用Python和Keras搭建你自己的AlphaZero

关注下面的标签,发现更多相似文章
评论