www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

OpenPose, PNASNet 5 для Конкурса классификации поз (Fastai)

Дата публикации Aug 25, 2019

Недавно я участвовал в местном конкурсе искусственного интеллекта, в котором участвовал 15 человек. Это был мой первый в мире конкурс искусственного интеллекта, и опыт был унизительным. Моя команда заняла вторую строчку, основанную на точности модели, креативности и командной работе. Я определенно рекомендую учащимся посещать соревнования или хакатоны, поскольку они служат отличной сетевой платформой и тренировочной площадкой для оттачивания ваших технических навыков. Здесь я проведу вас через процесс создания модели, который в конечном итоге помог нам достичь высокой точности 83% в окончательном наборе испытаний.


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

Позы были;

ChairPose, ChildPose, Dabbing, HandGun, HandShake, HulkSmash, KoreanHeart, KungfuCrane, KungfuSalute, Салют, WarriorPose, EaglePose, Нагрудный, HighKneel и Человек-паук

В соответствии с условиями конкурса мы не имеем права выпускать набор данных. Следовательно, все изображения, показанные ниже, были сделаны нами во время соревнования.

Слева направо - KoreanHeart, KungfuCrane, рукопожатие

Каждый класс в наборе обучающих данных содержит приблизительно 100 изображений, в то время как в наборе проверки было 25 изображений каждого класса. Это сравнительно небольшой объем данных для задачи классификации 15 классов, что объясняет необходимость увеличения набора данных с помощью наших собственных изображений.

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

С тяжелой ссылкой из этогосайтМы сгенерировали ключевые точки каждого изображения, используя предварительно обученную модель MPII.

cwd = os.getcwd()# Specify the paths for the 2 files
protoFile = "{}/pose_deploy_linevec_faster_4_stages.prototxt".format(cwd)
weightsFile = "{}/pose_iter_160000.caffemodel".format(cwd)
nPoints = 15
POSE_PAIRS = [[0,1], [1,2], [2,3], [3,4], [1,5], [5,6], [6,7], [1,14], [14,8], [8,9], [9,10], [14,11], [11,12], [12,13] ]

# Read the network into Memory
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)frameWidth = 640
frameHeight = 480
threshold = 0.1# Forward training set into OpenPose model to generate outputinWidth = 299
inHeight = 299m = train_images.shape[0]
train_outputs = np.zeros((1,44,38,38))for i in range(m):
inpBlob = cv2.dnn.blobFromImage(train_images[i], 1.0/255, (inWidth, inHeight),(0, 0, 0), swapRB=True, crop=False)net.setInput(inpBlob)
output = net.forward()
train_outputs = np.vstack((train_outputs,output))


outputs = np.delete(train_outputs,(0),axis=0)
H = train_outputs.shape[2]
W = train_outputs.shape[3]
print(train_outputs.shape)# Generate keypoints for training set
m = 973
H = 38
W = 38train_points = np.zeros((m,15,2))for sample in range(m):
for i in range(nPoints):
# confidence map of corresponding body's part.
probMap = train_outputs[sample, i, :, :]# Find global maxima of the probMap.
minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)# Scale the point to fit on the original image
x = (frameWidth * point[0]) / W
y = (frameHeight * point[1]) / H
if prob > threshold :
train_points[sample,i,0] = int(x)
train_points[sample,i,1] = int(y)

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

# Processed images with sticks on original image
train_processed = np.copy(train_images).astype(np.uint8)for sample in range(m):
for point in range(nPoints):
if train_points[sample,point,0] !=0 and train_points[sample,point,1] !=0 :
cv2.circle(train_processed[sample], (int(train_points[sample,point,0]), int(train_points[sample,point,1])), 10, (255,255,0), thickness=-1, lineType=cv2.FILLED)

# draw lines
for pair in POSE_PAIRS:
partA = pair[0]
partB = pair[1]if train_points[sample,partA,0] != 0 and train_points[sample,partA,1] != 0 and train_points[sample,partB,0] != 0 and train_points[sample,partB,1] != 0:
cv2.line(train_processed[sample], (int(train_points[sample,partA,0]),int(train_points[sample,partA,1]))
, (int(train_points[sample,partB,0]),int(train_points[sample,partB,1])), (255,255,0), 3)# Processed images with sticks on a black backgroundtrain_processed_grey = np.zeros((m,train_images.shape[1],train_images.shape[2],1)).astype(np.uint8)for sample in range(m):
for point in range(nPoints):
if train_points[sample,point,0] !=0 and train_points[sample,point,1] !=0 :
cv2.circle(train_processed_grey[sample], (int(train_points[sample,point,0]), int(train_points[sample,point,1])), 10, (1), thickness=50, lineType=cv2.FILLED)

# draw lines
for pair in POSE_PAIRS:
partA = pair[0]
partB = pair[1]if train_points[sample,partA,0] != 0 and train_points[sample,partA,1] != 0 and train_points[sample,partB,0] != 0 and train_points[sample,partB,1] != 0:
cv2.line(train_processed_grey[sample], (int(train_points[sample,partA,0]),int(train_points[sample,partA,1]))
, (int(train_points[sample,partB,0]),int(train_points[sample,partB,1])), (1), 3)

На этом этапе мы получили 3 разных набора данных;

  1. Исходное изображение
  2. Исходное изображение + скелет
  3. Скелет с пустым фоном

Transfer Learning позволяет нам обучать глубокие нейронные сети, используя значительно меньше данных, чем обычно требуется для обучения алгоритма с нуля. Это также часто приводит к более высокой точности модели, поскольку информация из большого набора данных передавалась и обучалась, чтобы вписываться в наши данные. Для этого соревнования моя команда решила проверить производительность 3 предварительно обученных моделей, а именно ResNet-50, ResNeXt-101 и PNASnet-5. Все модели были построены с использованием библиотеки fastai.

import fastai
from fastai.metrics import error_ratefrom torchvision.models import *
import pretrainedmodels
from fastai.callbacks.tracker import SaveModelCallback
from fastai.vision import *
from fastai.vision.models import *
from fastai.vision.learner import model_metabs = 8# Importing of datasetdata = ImageDataBunch.from_folder(base_dir,train='train',valid='val', ds_tfms = get_transforms(), size =299, bs=bs).normalize(imagenet_stats)#ResNet-50
models.resnet50#ResNeXt-101def resnext101_64x4d(pretrained=True):
pretrained = 'imagenet' if pretrained else None
model = pretrainedmodels.resnext101_64x4d(pretrained=pretrained)
all_layers = list(model.children())
return nn.Sequential(*all_layers[0], *all_layers[1:])#PASNet-5def identity(x): return xdef pnasnet5large(pretrained=True):
pretrained = 'imagenet' if pretrained else None
model = pretrainedmodels.pnasnet5large(pretrained=pretrained, num_classes=1000)
model.logits = identity
return nn.Sequential(model)# Training of modellearn = cnn_learner(data, model, metrics = accuracy)learn.fit(20,callbacks=[SaveModelCallback(learn,monitor='accuracy',every="improvement",name ="top_acc")])learn.lr_find()
learn.recorder.plot()learn.unfreeze()
learn.fit_one_cycle(5,callbacks=[SaveModelCallback(learn,monitor='accuracy',every="improvement",name="top_acc_1")])

Всего было построено 9 моделей, каждая из которых прошла предварительную подготовку с использованием созданного нами индивидуального набора данных. Ниже приведены результаты;

Для окончательного набора тестов мы прогнозировали классификацию неизвестного набора данных с использованием модели PNASnet-5, обученной на исходной модели, и достигли точности 83%, заняв 3-е место в конкурсе.


И вот она, классификация позы человека с использованием предварительно обученной модели PNASnet-5. Вызывает разочарование тот факт, что извлечение возможностей OpenPose не улучшило точность модели, но я считаю, что мы справились хорошо, учитывая ограничения по времени конкуренции. Для тех, кто хотел бы знать, как PNASnet-5 работает намного лучше, чем другие предварительно обученные модели, ниже приводится краткое изложение алгоритмов, выполненных авторами.

https://cs.jhu.edu/~cxliu/posters/pnas_poster.pdf

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map