いんちき Image Captioning(物体検出モデルと行動認識モデルを組み合わせて画像説明文章を作成する)

はじめに

以前PyTochrのImage Captioningについて書いた。
今回「いんちきImage Captioning」を作ってみた。

方法

① Object Detectionモデルで画像内の人物を探す
② 見つかった人物をそれぞれClassificationモデルで男性、女性、少年、少女、赤ちゃんに分ける
③ Action Recognitionモデルで何をしているかを判別する
②と③をただ単につなげて文章とする

使用したモデル

Object DetectionモデルとしてGluonCVで公開されている学習済み「faster_rcnn_fpn_resnet101_v1d_coco」モデルを使用した。
こちらを参照
Classificationモデルは自前でCifar-100をMobileNetに学習させたものを使用した。
こちらを参照
Action Recognitionモデルは本来動画を認識するものであるが今回は静止画を対象とした。GluonCVで公開されている学習済み「inceptionv3_kinetics400」モデルを使用した。
こちらを参照

コード

import warnings
warnings.simplefilter('ignore')
import argparse
import sys

import mxnet as mx
from mxnet import image
from gluoncv import model_zoo, data, utils
from matplotlib import pyplot as plt
from mxnet.gluon.data.vision import transforms
from mxnet.gluon import nn

parser = argparse.ArgumentParser()
parser.add_argument('img_path', type=str, help='path to the image file')
args = parser.parse_args()

img_file =args.img_path

net = model_zoo.get_model('faster_rcnn_fpn_resnet101_v1d_coco', pretrained=True, root='model')

x, img = data.transforms.presets.rcnn.load_test(img_file)

class_IDs, scores, bounding_boxs = net(x)

class_IDs = class_IDs[0].asnumpy()
scores = scores[0].asnumpy()
bounding_boxs = bounding_boxs[0].asnumpy()

n_box = class_IDs.shape[0]

persons = []
for n in range(n_box):
    if(class_IDs[n]==0 and scores[n]>0.7):
        persons.append(bounding_boxs[n])

if len(persons)==0:
    print('この写真に人は写っていません')
    sys.exit()

persons_img = []
for each_person in persons:
    xmin, ymin, xmax, ymax = [int(x) for x in each_person]
    if xmin<0:
        xmin=0
    if ymin<0:
        ymin=0
    person_img = img[ymin:ymax,xmin:xmax,:]
    persons_img.append(person_img)

finetune_net = model_zoo.get_model('mobilenet1.0', pretrained=False, root='model')

with finetune_net.name_scope():
    finetune_net.output = nn.Dense(100)
finetune_net.load_parameters('finetune.params', ctx=mx.cpu())

transform_mobilenet = transforms.Compose([
    transforms.Resize(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

person_index = [3,12,29,41,98]

boy_num = 0
baby_num = 0
girl_num = 0
man_num = 0
woman_num = 0

for img in persons_img:
    input = transform_mobilenet(mx.nd.array(img))
    output = finetune_net(input.expand_dims(0))
    index = int(output.squeeze()[person_index].argmax().asscalar())
    if index==0:
        boy_num += 1
    if index==1:
        baby_num += 1
    if index==2:
        girl_num += 1
    if index==3:
        man_num += 1
    if index==4:
        woman_num += 1

answer_list = []
if baby_num>0:
    answer_list.append('%d人の赤ちゃん'%baby_num)
if boy_num>0:
    answer_list.append('%d人の少年'%boy_num)
if girl_num>0:
    answer_list.append('%d人の少女'%girl_num)
if man_num>0:
    answer_list.append('%d人の男性'%man_num)
if woman_num>0:
    answer_list.append('%d人の女性'%woman_num)

first_sentence = 'と'.join(answer_list)

transform_inception = transforms.Compose([
    transforms.Resize((400,300)),
    transforms.CenterCrop(size=299),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

net = model_zoo.get_model('inceptionv3_kinetics400', pretrained=True, root='model')

import pandas as pd 
df = pd.read_csv('action.csv', header=None)
classes = list(df.iloc[:,2])

img = transform_inception(image.imread(img_file))
pred = net(img.expand_dims(axis=0))
id = mx.nd.argmax(pred, axis=1).astype('int').asscalar()

second_sentence = classes[id]

final_sentence = first_sentence + 'が' + second_sentence

print(final_sentence)

結果

1人の男性が凧あげをしている
f:id:touch-sp:20191107173710j:plain:w350
https://farm7.staticflickr.com/6185/6107916266_9079c606fa_z.jpg

1人の赤ちゃんと1人の女性がコンピューターを使っている
f:id:touch-sp:20191107173446j:plain:w350
http://farm3.staticflickr.com/2465/3926393821_252c11d20b_z.jpg

日本語ファイル

kinetics400データセットのクラスを自分で日本語化した。誤訳が多く含まれていると思われる。

0	abseiling		懸垂下降している
1	air_drumming		エアドラムを演奏している
2	answering_questions		質問に答えている
3	applauding		拍手喝采している
4	applying_cream		クリームを塗っている
5	archery		アーチェリーをしている
6	arm_wrestling		腕相撲をしている
7	arranging_flowers		花を生けている
8	assembling_computer		コンピューターを組み立てている
9	auctioning		オークションをしている
10	baby_waking_up		赤ちゃんを起こしている
11	baking_cookies		クッキーを焼いている
12	balloon_blowing		風船を吹いている
13	bandaging		包帯を巻いている
14	barbequing		バーベキューをしている
15	bartending		カクテルを作っている
16	beatboxing		ビートボックスをしている
17	bee_keeping		養蜂している
18	belly_dancing		ベリーダンスを踊っている
19	bench_pressing		ベンチプレスをしている
20	bending_back		背中を曲げている
21	bending_metal		金属を曲げている
22	biking_through_snow		雪の中をサイクリングしている
23	blasting_sand		砂を吹き付けている
24	blowing_glass		ガラス吹きをしている
25	blowing_leaves		葉っぱを吹いています
26	blowing_nose		鼻をかんでいる
27	blowing_out_candles		ろうそくを吹いている
28	bobsledding		ボブスレーをしている
29	bookbinding		製本している
30	bouncing_on_trampoline		トランポリンで跳ねている
31	bowling		ボウリングしている
32	braiding_hair		髪を編んでいる
33	breading_or_breadcrumbing		パン粉をつけている
34	breakdancing		ブレークダンスを踊っている
35	brush_painting		ブラシで絵を描いている
36	brushing_hair		髪にブラシをかけている
37	brushing_teeth		歯磨きをしている
38	building_cabinet		キャビネットを作っている
39	building_shed		小屋を建てている
40	bungee_jumping		バンジージャンプをしている
41	busking		大道芸をしている
42	canoeing_or_kayaking		カヌーまたはカヤックをしている
43	capoeira		カポエイラを踊っている
44	carrying_baby		赤ちゃんを抱えている
45	cartwheeling		側方転回をしている
46	carving_pumpkin		かぼちゃを彫ってる
47	catching_fish		魚を捕まえている
48	catching_or_throwing_baseball		キャッチボールをしている
49	catching_or_throwing_frisbee		フリスビーをしている
50	catching_or_throwing_softball		ソフトボールをしている
51	celebrating		祝っている
52	changing_oil		オイルを交換している
53	changing_wheel		タイヤを交換している
54	checking_tires		タイヤをチェックしている
55	cheerleading		チアリーディングをしている
56	chopping_wood		木を割っている
57	clapping		拍手している
58	clay_pottery_making		粘土で陶器を作っている
59	clean_and_jerk		重量挙げをしている
60	cleaning_floor		床を掃除している
61	cleaning_gutters		側溝を掃除している
62	cleaning_pool		プールを掃除している
63	cleaning_shoes		靴を洗っている
64	cleaning_toilet		トイレを掃除している
65	cleaning_windows		窓を掃除している
66	climbing_a_rope		ロープを登っている
67	climbing_ladder		はしごを登っている
68	climbing_tree		木に登っている
69	contact_juggling		コンタクトジャグリングをしている
70	cooking_chicken		鶏肉を調理している
71	cooking_egg		卵を調理している
72	cooking_on_campfire		キャンプファイヤをしている
73	cooking_sausages		ソーセージを調理している
74	counting_money		お金を数えています
75	country_line_dancing		カントリーラインダンスを踊っている
76	cracking_neck		首をならしている
77	crawling_baby		はっている
78	crossing_river		川を渡っている
79	crying		泣いている
80	curling_hair		髪をカールしている
81	cutting_nails		爪を切っている
82	cutting_pineapple		パイナップルを切っている
83	cutting_watermelon		スイカを切っている
84	dancing_ballet		バレーを踊っている
85	dancing_charleston		チャールストンを踊っている
86	dancing_gangnam_style		カンナムスタイルを踊っている
87	dancing_macarena		マカレナを踊っている
88	deadlifting		デッドリフティングをしている
89	decorating_the_christmas_tree		クリスマスツリーを飾り付けしている
90	digging		穴を掘っている
91	dining		食事をしている
92	disc_golfing		ディスクゴルフをしている
93	diving_cliff		クリフダイビングをしている
94	dodgeball		ドッジボールをしている
95	doing_aerobics		エアロビクスをしている
96	doing_laundry		洗濯をしている
97	doing_nails		ネイルをしている
98	drawing		絵を描いている
99	dribbling_basketball		バスケットボールをしている
100	drinking		飲み物を飲んでいる
101	drinking_beer		ビールを飲んでいる
102	drinking_shots		ショットを飲んでいる
103	driving_car		車を運転している
104	driving_tractor		トラクターを運転している
105	drop_kicking		ドロップキックをしている
106	drumming_fingers		指先でトントンたたいている
107	dunking_basketball		バスケットボールをしている
108	dying_hair		髪を染めている
109	eating_burger		バーガーを食べている
110	eating_cake		ケーキを食べている
111	eating_carrots		にんじんを食べている
112	eating_chips		チップスを食べている
113	eating_doughnuts		ドーナツを食べている
114	eating_hotdog		ホットドッグを食べている
115	eating_ice_cream		アイスクリームを食べている
116	eating_spaghetti		スパゲッティーを食べている
117	eating_watermelon		スイカを食べている
118	egg_hunting		エッグハントをしている
119	exercising_arm		腕をエクササイズしている
120	exercising_with_an_exercise_ball		ボールを使ってエクササイズしている
121	extinguishing_fire		火を消している
122	faceplanting		うつぶせに倒れている
123	feeding_birds		鳥に餌をやっている
124	feeding_fish		魚に餌をやっている
125	feeding_goats		ヤギに餌をやっている
126	filling_eyebrows		眉毛をかいている
127	finger_snapping		指を鳴らしている
128	fixing_hair		髪を結っている
129	flipping_pancake		パンケーキをひっくり返している
130	flying_kite		凧あげをしている
131	folding_clothes		服をたたんでいる
132	folding_napkins		ナプキンをたたんでいる
133	folding_paper		紙を折っている
134	front_raises		フロントレイズをしている
135	frying_vegetables		野菜を揚げている
136	garbage_collecting		ごみを集めている
137	gargling		うがいをしている
138	getting_a_haircut		散髪している
139	getting_a_tattoo		タトゥーをいれいている
140	giving_or_receiving_award		賞を授与している(または受け取っている)
141	golf_chipping		ゴルフをしている
142	golf_driving		ゴルフをしている
143	golf_putting		ゴルフをしている
144	grinding_meat		肉を挽いている
145	grooming_dog		犬の手入れをしている
146	grooming_horse		馬の手入れをしている
147	gymnastics_tumbling		タンブリングしている
148	hammer_throw		ハンマー投げをしている
149	headbanging		ヘッドバンギングしている
150	headbutting		ヘッドバットをしている
151	high_jump		ハイジャンプをしている
152	high_kick		ハイキックをしている
153	hitting_baseball		野球をしている
154	hockey_stop		ホッケーストップをしている
155	holding_snake		蛇を抱えている
156	hopscotch		ホップスコッチをしている
157	hoverboarding		ホバーボードをしている
158	hugging		抱き合っている
159	hula_hooping		フラフープをしている
160	hurdling		障害走をしている
161	hurling_-sport-		ハーリングをしている
162	ice_climbing		アイスクライミングをしている
163	ice_fishing		アイスフィッシングをしている
164	ice_skating		アイススケートをしている
165	ironing		アイロンかけをしている
166	javelin_throw		やり投げをしている
167	jetskiing		ジェットスキーをしている
168	jogging		ジョギングしている
169	juggling_balls		ボールジャグリングをしている
170	juggling_fire		ファイヤージャグリングをしている
171	juggling_soccer_ball		サッカーボールジャグリングをしている
172	jumping_into_pool		プールに飛び込んでいる
173	jumpstyle_dancing		ジャンプスタイルダンスを踊っている
174	kicking_field_goal		フィールドゴールを蹴っている
175	kicking_soccer_ball		サッカーボールを蹴っている
176	kissing		キスをしている
177	kitesurfing		カイトサーフィンをしている
178	knitting		編み物をしている
179	krumping		クランプダンスを踊っている
180	laughing		笑っている
181	laying_bricks		レンガを積んでいる
182	long_jump		走り幅跳びをしている
183	lunge		突進している
184	making_a_cake		ケーキを作っている
185	making_a_sandwich		サンドイッチを作っている
186	making_bed		ベッドメイキングをしている
187	making_jewelry		宝石を作っている
188	making_pizza		ピザを作っている
189	making_snowman		雪だるまを作っている
190	making_sushi		寿司を作っている
191	making_tea		お茶を入れている
192	marching		行進している
193	massaging_back		背中をマッサージしている
194	massaging_feet		足をマッサージしている
195	massaging_legs		足をマッサージしている
196	massaging_person's_head		頭をマッサージしている
197	milking_cow		乳しぼりをしている
198	mopping_floor		モップで床をふいている
199	motorcycling		バイクに乗っている
200	moving_furniture		家具を動かしている
201	mowing_lawn		芝生を刈っている
202	news_anchoring		ニュースと伝えている
203	opening_bottle		ボトルを開けている
204	opening_present		プレゼントを開けている
205	paragliding		パラグライダーをしている
206	parasailing		パラセイリングをしている
207	parkour		パルクールをしている
208	passing_American_football_-in_game-		アメリカンフットボールをしている
209	passing_American_football_-not_in_game-		アメリカンフットボールをしている
210	peeling_apples		リンゴの皮をむいている
211	peeling_potatoes		ジャガイモの皮をむいている
212	petting_animal_-not_cat-		動物をかわいがっている
213	petting_cat		猫をかわいがっている
214	picking_fruit		果物を選んでいる
215	planting_trees		木を植えている
216	plastering		壁塗りしている
217	playing_accordion		アコーディオンを演奏している
218	playing_badminton		バドミントンをしている
219	playing_bagpipes		バグパイプを演奏している
220	playing_basketball		バスケットボールをしている
221	playing_bass_guitar		ベースギターを演奏している
222	playing_cards		カードゲームで遊んでいる
223	playing_cello		チェロを演奏している
224	playing_chess		チェスをしている
225	playing_clarinet		クラリネットを演奏している
226	playing_controller		コントローラーを使って遊んでいる
227	playing_cricket		クリケットをしている
228	playing_cymbals		シンバルを演奏している
229	playing_didgeridoo		ディジュリドゥを演奏している
230	playing_drums		ドラムを演奏している
231	playing_flute		フルートを演奏している
232	playing_guitar		ギターを演奏している
233	playing_harmonica		ハーモニカを演奏している
234	playing_harp		ハープを演奏している
235	playing_ice_hockey		アイスホッケーをしている
236	playing_keyboard		キーボードを演奏している
237	playing_kickball		キックボールをしている
238	playing_monopoly		モノポリーをしている
239	playing_organ		オルガンを演奏している
240	playing_paintball		ペイントボールをしている
241	playing_piano		ピアノを演奏している
242	playing_poker		ポーカーをしている
243	playing_recorder		リコーダーを演奏している
244	playing_saxophone		サックスを演奏している
245	playing_squash_or_racquetball		スカッシュをしている
246	playing_tennis		テニスをしている
247	playing_trombone		トロンボーンを演奏している
248	playing_trumpet		トランペットを演奏している
249	playing_ukulele		ウクレレを演奏している
250	playing_violin		ヴァイオリンを演奏している
251	playing_volleyball		バレーボールをしている
252	playing_xylophone		木琴を演奏している
253	pole_vault		棒高跳びをしている
254	presenting_weather_forecast		天気予報をしている
255	pull_ups		立ち上がっている
256	pumping_fist		ガッツポーズしている
257	pumping_gas		給油している
258	punching_bag		サンドバッグをパンチしている
259	punching_person_-boxing-		パンチをしている
260	push_up		腕立て伏せをしている
261	pushing_car		車を押している
262	pushing_cart		カートを押している
263	pushing_wheelchair		車いすを押している
264	reading_book		本を読んでいる
265	reading_newspaper		新聞を読んでいる
266	recording_music		音楽を録音している
267	riding_a_bike		バイクに乗っている
268	riding_camel		ラクダに乗っている
269	riding_elephant		象に乗っている
270	riding_mechanical_bull		メカニカルブルに乗っている
271	riding_mountain_bike		マウンテンバイクに乗っている
272	riding_mule		ラバに乗っている
273	riding_or_walking_with_horse		馬に乗っている(または馬と歩いている)
274	riding_scooter		スクーターに乗っている
275	riding_unicycle		一輪車に乗っている
276	ripping_paper		紙を破っている
277	robot_dancing		ロボットダンスをしている
278	rock_climbing		ロッククライミングをしている
279	rock_scissors_paper		じゃんけんしている
280	roller_skating		ローラースケートをしている
281	running_on_treadmill		ルームランナーで走っている
282	sailing		ヨットに乗っている
283	salsa_dancing		サルサダンスを踊っている
284	sanding_floor		床を磨いている
285	scrambling_eggs		卵をスクランブルしている
286	scuba_diving		スキューバダイビングをしている
287	setting_table		テーブルをセットしている
288	shaking_hands		握手している
289	shaking_head		頭を振っている
290	sharpening_knives		ナイフを研いでいる
291	sharpening_pencil		鉛筆を削っている
292	shaving_head		頭を剃っている
293	shaving_legs		足の毛を剃っている
294	shearing_sheep		羊の毛を刈っている
295	shining_shoes		靴を磨いている
296	shooting_basketball		バスケットボールをしている
297	shooting_goal_-soccer-		サッカーをしている
298	shot_put		砲丸投げをしている
299	shoveling_snow		雪かきをしている
300	shredding_paper		紙を細断している
301	shuffling_cards		トランプを切っている
302	side_kick		サイドキックをしている
303	sign_language_interpreting		手話通訳をしている
304	singing		歌っている
305	situp		座っている
306	skateboarding		スケートボードをしている
307	ski_jumping		スキージャンプをしている
308	skiing_-not_slalom_or_crosscountry-		スキをしている
309	skiing_crosscountry		クロスカントリーをしている
310	skiing_slalom		スラロームスキーをしている
311	skipping_rope		縄跳びをしている
312	skydiving		スカイダイビングをしている
313	slacklining		スラックラインをしている
314	slapping		平手打ちをしている
315	sled_dog_racing		犬ぞりレースをしている
316	smoking		煙草を吸っている
317	smoking_hookah		水タバコを吸っている
318	snatch_weight_lifting		重量挙げをしている
319	sneezing		くしゃみをしている
320	sniffing		においをかいでいる
321	snorkeling		シュノーケリングをしている
322	snowboarding		スノーボードをしている
323	snowkiting		スノーカイトをしている
324	snowmobiling		スノーモービルに乗っている
325	somersaulting		宙返りしている
326	spinning_poi		ポイを回している
327	spray_painting		スプレーペインティングをしている
328	spraying		スプレーをしている
329	springboard_diving		飛び込み板から飛び込んでいる
330	squat		スクワットしている
331	sticking_tongue_out		下を出している
332	stomping_grapes		ブドウを踏みつけている
333	stretching_arm		腕を伸ばしている
334	stretching_leg		足を伸ばしている
335	strumming_guitar		ギターをかき鳴らしている
336	surfing_crowd		クラウドサーフィンをしている
337	surfing_water		サーフィンしている
338	sweeping_floor		床を掃除している
339	swimming_backstroke		背泳ぎしている
340	swimming_breast_stroke		平泳ぎしている
341	swimming_butterfly_stroke		バタフライをしている
342	swing_dancing		スイングダンスを踊っている
343	swinging_legs		足を振っている
344	swinging_on_something		何かに揺られている
345	sword_fighting		西洋剣術をしている
346	tai_chi		太極拳をしている
347	taking_a_shower		シャワーを浴びている
348	tango_dancing		タンゴを踊っている
349	tap_dancing		タップダンスをしている
350	tapping_guitar		ギターをタップしている
351	tapping_pen		ペンタッピングをしている
352	tasting_beer		ビールを試飲している
353	tasting_food		試食している
354	testifying		証言している
355	texting		メールを送っている
356	throwing_axe		斧投げをしている
357	throwing_ball		ボールを投げている
358	throwing_discus		円盤投げをしている
359	tickling		くすぐっている
360	tobogganing		そりに乗っている
361	tossing_coin		コイントスをしている
362	tossing_salad		サラダを混ぜている
363	training_dog		犬を訓練している
364	trapezing		空中ブランコをしている
365	trimming_or_shaving_beard		ひげをそっている(または整えている)
366	trimming_trees		木を切っている
367	triple_jump		三段跳びをしている
368	tying_bow_tie		蝶ネクタイを結んでいる
369	tying_knot_-not_on_a_tie-		何かを結んでいる
370	tying_tie		ネクタイを締めている
371	unboxing		箱を開けている
372	unloading_truck		トラックから荷物を降ろしている
373	using_computer		コンピューターを使っている
374	using_remote_controller_-not_gaming-		リモコンを使っている
375	using_segway		セグウェイに乗っている
376	vault		棒高跳びをしている
377	waiting_in_line		並んでいる
378	walking_the_dog		犬の散歩をしている
379	washing_dishes		お皿を洗っている
380	washing_feet		足を洗っている
381	washing_hair		髪を洗っている
382	washing_hands		手を洗っている
383	water_skiing		水上スキーをしている
384	water_sliding		ウォータースライダーで遊んでいる
385	watering_plants		植物に水をまいている
386	waxing_back		背中をワックス脱毛している
387	waxing_chest		胸をワックス脱毛している
388	waxing_eyebrows		眉毛をワックス脱毛している
389	waxing_legs		足をワックス脱毛している
390	weaving_basket		バスケットを編んでいる
391	welding		溶接している
392	whistling		口笛を吹いている
393	windsurfing		ウインドサーフィンをしている
394	wrapping_present		プレゼントを包んでいる
395	wrestling		レスリングをしている
396	writing		字を書いている
397	yawning		あくびをしている
398	yoga		ヨガをしている
399	zumba		ズンバを踊っている

環境

Windows10 Pro
Python 3.7.5
GPUなし
certifi==2019.9.11
chardet==3.0.4
cycler==0.10.0
gluoncv==0.5.0
graphviz==0.8.4
idna==2.6
kiwisolver==1.1.0
matplotlib==3.1.1
mxnet==1.6.0b20191004
numpy==1.16.5
opencv-python==4.1.1.26
pandas==0.25.3
Pillow==6.2.0
pyparsing==2.4.2
python-dateutil==2.8.0
pytz==2019.3
requests==2.18.4
scipy==1.3.1
six==1.12.0
tqdm==4.36.1
urllib3==1.22