Как распознавать мимику людей с Керасом?

искусственный интеллект Keras Нейронные сети Kaggle
Как распознавать мимику людей с Керасом?

В 2013 году Kaggle организовала соревнование по распознаванию выражений лица, в котором участники должны были построить модель для распознавания 7 видов выражений лица человека. Хотя прошло уже несколько лет и одни результаты исследований появлялись один за другим, это по-прежнему очень интересная тема. В этой статье я (автор Сефик Серенгил — прим. переводчика) покажу, как использовать Keras для распознавания мимики людей.

набор данных

В нашем тренировочном наборе и тестовом наборе по-прежнему используется набор данных Fec2013, использовавшийся в соревновании Kaggle в том году, нажмитездесьможет быть получен. Сжатый размер набора данных составляет 92 МБ, а несжатая версия — 295 МБ. Набор данных содержит 28 000 тренировочных фотографий и 30 000 тестовых фотографий. Каждая фотография хранится в формате 48 X 48 пикселей. Чистый набор данных содержит пиксели изображения (48 X 48 = 2304 значения), выражение лица на каждом изображении и тип использования (для обучения или тестирования).

После загрузки набора данных в локальную папку данных используйте следующий код для чтения содержимого набора данных:

with open("/data/fer2013.csv") as f:
    content = f.readlines()
 
lines = np.array(content)
 
num_of_instances = lines.size
print("number of instances: ",num_of_instances)

процесс изучения

В последние годы методы глубокого обучения доминировали в исследованиях компьютерного зрения, и даже академические конференции по компьютерному зрению превратились в семинары по глубокому обучению. Здесь мы будем использовать сверточные нейронные сети в глубоком обучении для выполнения этой задачи. Затем мы воспользуемся бэкендом TensorFlow для построения сверточной нейронной сети с помощью Keras.

Теперь, когда мы загрузили набор данных локально, теперь мы можем хранить обучающие и тестовые наборы как выделенные переменные.

x_train, y_train, x_test, y_test = [], [], [], []
 
for i in range(1,num_of_instances):
 emotion, img, usage = lines[i].split(",")
 
 val = img.split(" ")
 pixels = np.array(val, 'float32')
 
 emotion = keras.utils.to_categorical(emotion, num_classes)
 
 if 'Training' in usage:
     y_train.append(emotion)
     x_train.append(pixels)
 elif 'PublicTest' in usage:
     y_test.append(emotion)
     x_test.append(pixels)

Затем постройте архитектуру сверточной нейронной сети:

model = Sequential()
 
#第一个卷积层
model.add(Conv2D(64, (5, 5), activation='relu', input_shape=(48,48,1)))
model.add(MaxPooling2D(pool_size=(5,5), strides=(2, 2)))
 
#第二个卷积层
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(AveragePooling2D(pool_size=(3,3), strides=(2, 2)))
 
#第三个卷积层
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(AveragePooling2D(pool_size=(3,3), strides=(2, 2)))
 
model.add(Flatten())
 
#全连接神经网络
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.2))
 
model.add(Dense(num_classes, activation='softmax'))

После построения модели приступаем к обучению нейронной сети. Чтобы сократить время обучения, я предпочитаю случайным образом выбирать обучающий набор для обучения модели, что является причиной использования fit_generator в Keras. Опять же, функция потерь будет кросс-энтропийной, так как наша задача — проблема мультиклассовой классификации.

gen = ImageDataGenerator()
train_generator = gen.flow(x_train, y_train, batch_size=batch_size)
 
model.compile(loss='categorical_crossentropy'
    , optimizer=keras.optimizers.Adam()
    , metrics=['accuracy']
)
 
model.fit_generator(train_generator, steps_per_epoch=batch_size, epochs=epochs)

После выполнения функции подгонки мы оцениваем модель:

train_score = model.evaluate(x_train, y_train, verbose=0)
print('Train loss:', train_score[0])
print('Train accuracy:', 100*train_score[1])
 
test_score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', test_score[0])
print('Test accuracy:', 100*test_score[1])

Чтобы не переобучать, я в итоге получаю следующие результаты, но когда я увеличиваю количество эпох, происходит переобучение:

Test loss: 2.27945706329
Test accuracy: 57.4254667071
 
Train loss: 0.223031098232
Train accuracy: 92.0512731201

Окончательная построенная модель распознавания выражения лица имеет точность 57%.

Протестируйте модель с пользовательскими фотографиями

Теперь мы пытаемся заставить модель распознавать выражения лица на фотографиях, которые мы нашли сами, потому что частота ошибок в тестовом наборе сама по себе мало о чем говорит.

img = image.load_img("/data/pablo.png", grayscale=True, target_size=(48, 48))
 
x = image.img_to_array(img)
x = np.expand_dims(x, axis = 0)
 
x /= 255
 
custom = model.predict(x)
emotion_analysis(custom[0])
 
x = np.array(x, 'float32')
x = x.reshape([48, 48]);
 
plt.gray()
plt.imshow(x)
plt.show()

Храните выражения лица в виде числовых значений и маркируйте их от 0 до 6. Keras сгенерирует выходной массив, включающий эти 7 различных оценок выражений. Мы можем визуализировать прогнозы для каждого выражения в виде гистограммы.

def emotion_analysis(emotions):
    objects = ('angry', 'disgust', 'fear', 'happy', 'sad', 'surprise', 'neutral')
    y_pos = np.arange(len(objects))
 
    plt.bar(y_pos, emotions, align='center', alpha=0.5)
    plt.xticks(y_pos, objects)
    plt.ylabel('percentage')
    plt.title('emotion')
 
    plt.show()

Если вы видели сериал Netflix «Нарко», вы должны быть знакомы с этой фотографией. Фотография ниже была сделана, когда наркобарон Пабло Эскобар был арестован и заключен в тюрьму. Узнав эту фотографию с моделью, которую мы только что построили, видно, что Пабло был в то время в очень хорошем настроении.

Затем мы использовали второе фото, «старика» Марлона Брандо Корлеоне в «Крестном отце», когда он увидел тело своего сына. Результаты теста показали, что модель также могла распознавать огорченное и грустное выражение лица Корлеоне.

Я также хотел проверить выражение гнева, и когда дело доходит до гнева, «Росомаха» Хью Джекмана является типичным примером, это он. Я выбрал образ ярости Росомахи из Людей Икс. Результаты испытаний показали большой успех.

Наконец, бросьте вызов модели на сложное фото:улыбка Моны Лизы. Художники до сих пор не понимают настроения героев «Моны Лизы» Леонардо да Винчи. После идентификации с нашей моделью видно, что Мона Лиза в то время была в очень мирном и естественном настроении.

Эпилог

В этой статье мы строим сверточную нейронную сеть для распознавания выражений лица человека. Точность окончательной модели составляет 57%, что приемлемо, поскольку самый высокий показатель точности в конкурсе Kaggle составил 34%. Точность может быть дополнительно улучшена, если лица на обнаруженном изображении обрабатываются вместо обработки всего изображения. Поэтому перед запуском нейронной модели я немного обрезал лица на изображении. Я планирую обучить готовую модель в Inception для выполнения этой задачи в следующий раз и поделюсь ею с вами, когда придет время.

нажмитездесьПосмотрите код этого проекта.


Добро пожаловать, чтобы следовать за нами, учебные ресурсы, учебные пособия по искусственному интеллекту, интерпретация документов, интересные проекты, все, что вы хотите увидеть, здесь!