Мотивация

Документ DeepPose — один из фундаментальных документов HPE (Human Pose Estimation), основанный на глубоком обучении. Мне, как студенту HPE, просматривающему предыдущие статьи о HPE, пришлось прочитать этот документ.

Что такое HPE

Оценка позы — это задача прогнозирования поз человека путем определения суставов на основе 2D/3D-кадров. Мы можем подойти к этой проблеме по-разному, например, регрессия против обнаружения, нисходящий против восходящего, генеративный против дискриминационного. Различные варианты и методы HPE будут описаны в последующих статьях этой серии об оценке позы.

Подготовка данных (LSP-Extended)

Набор данных LSP будет использоваться для обучения нашей модели. Загрузите zip-архив по ссылке и разархивируйте файл. Набор данных содержит папку изображений с 10 000 изображений спортсменов, каждое из которых имеет разный размер изображения. Соединения изображений помечены в файлеjoints.mat как пиксельные координаты каждого пикселя. Мы изменим форму всех изображений до единого размера (220, 220) и объединим все изображения в файл numpy.

import cv2
import os
import matplotlib.pyplot as plt
import numpy as np
import scipy.io
import progressbar
base_directory='YOUR DIRECTORY TO DATA\\lspet_dataset\\images'
images_directory=os.listdir(base_directory)
target_size=(220,220)
resized_images=[]
resized_poses=[]
original_scale=[]
poses=scipy.io.loadmat('YOUR DIRECTORY TO DATA \\lspet_dataset\\joints.mat')['joints']
for idx,x in progressbar.progressbar(enumerate(images_directory)):
    path=os.path.join(base_directory,x)
    
    image = plt.imread(path)
    height,width=image.shape[0],image.shape[1]
    scale_w,scale_h=220/width,220/height
    original_scale.append([width,height])
    
    resized_poses.append([poses[:,0,idx]*scale_w*2-1,poses[:,1,idx]*scale_h*2-1])
    
    image=cv2.resize(image,target_size,interpolation=cv2.INTER_AREA)
    resized_images.append(image)
resized_images=np.array(resized_images)
resized_poses=np.array(resized_poses)
original_scale=np.array(original_scale)
np.save('Leeds Sports Dataset NPY.npy',resized_images[:9000])
np.save('Resized Poses.npy',resized_poses[:9000])
np.save('Image scale.npy',original_scale[:9000])
np.save('Leeds Sports Dataset NPY Test.npy',resized_images[9000:])
np.save('Resized Poses Test.npy',resized_poses[9000:])
np.save('Image scale Test.npy',original_scale[9000:])

Координаты пикселей позы были масштабированы в [-1, 1] в соответствии с размером изображения. После всех этапов предварительной обработки данные сохраняются в один файл .npy. Мне пришлось преобразовать данные в объединенные файлы, потому что для большого количества файлов загрузка на гугл диск (для использования colab) займет неопределенное время.

Определение модели

Мы определим архитектуру базовой модели, представленную в документе DeepPose, с помощью Tensorflow Keras. Модель представляет собой модель AlexNet с 28 выходными данными, каждый из которых регрессирует координаты суставов на изображении. Конкретные гиперпараметры модели (например, размер фильтра) определены в документе. Для удобства слой нормализации локального отклика был заменен пакетной нормализацией.

def define_model(self):
  #Changes made on model architecture
  #LRN->BN, Pooling->Strided Convolution
  model=tf.keras.models.Sequential()
  model.add(tf.keras.layers.Conv2D(48,11,(4,4),padding='same',input_shape=(220,220,3)))
  model.add(tf.keras.layers.BatchNormalization())
  model.add(tf.keras.layers.ReLU())
  model.add(tf.keras.layers.Conv2D(128,5,(2,2),padding='same'))
  model.add(tf.keras.layers.BatchNormalization())
  model.add(tf.keras.layers.ReLU())
  model.add(tf.keras.layers.Conv2D(192,3,(2,2),padding='same',activation='relu'))
  model.add(tf.keras.layers.Conv2D(192,3,(1,1),padding='same',activation='relu'))
  model.add(tf.keras.layers.Conv2D(192,3,(1,1),padding='same',activation='relu'))
  model.add(tf.keras.layers.MaxPooling2D())
  model.add(tf.keras.layers.Flatten())
  model.add(tf.keras.layers.Dense(4096,activation='relu'))
  model.add(tf.keras.layers.Dropout(0.4))
  model.add(tf.keras.layers.Dense(4096,activation='relu'))
  model.add(tf.keras.layers.Dropout(0.4))
  model.add(tf.keras.layers.Dense(28,activation='linear'))
  return model

Поскольку проблема оценки позы в статье DeepPose рассматривается как проблема регрессии, мы применяем исходную ошибку MSE для обучения. Более подробная информация и полный код представлены в colab link.

Оценка модели

Базовая модель не смогла упорядочить данные и привела к переоснащению. Параметры отсева уже установлены высокими, но, похоже, требуется более высокий штраф за регуляризацию. Каскад регрессоров позы, представленный в статье, не был успешно реализован, и это тоже может быть причиной. График потерь при валидации очень жуткий и требует дополнительного анализа.