Developers.IO 2019 in Tokyoで「スティーブン・セガール出演作品の邦題に『沈黙』がつくかどうか判別する機械学習モデルを作ろうとしてみた」を話しました #cmdevio

こんにちは。大阪オフィスの玉井です。

2019年11月1日に開催されたDevelopers.IO 2019 in Tokyoにて「スティーブン・セガール出演作品の邦題に「沈黙」がつくかどうか判別する機械学習モデルを作ろうとしてみた」というテーマで登壇しました。

今作は、Developers.IO 2019の名古屋、大阪に続く3作目という位置づけであり、この東京においてセガール3部作は完結致しました。

資料(今作、沈黙の分析3)

※登壇時の資料にはスティーブン・セガールが写っている画像を使用していますが、上記の資料では省いています。

前前作(沈黙の分析)

前作(沈黙の分析2)

資料の補足

超概要

第三次AIブームの昨今、機械学習の技術に関する情報は非常に多く発信されており、やる気があれば1から機械学習の技術を学ぶことも難しくなくなってきました。

しかし、その機械学習の技術を実際にどう使うのか(どう使ったのか)という話はまだまだ少ないように思えます。というわけで、今回は多くの方に馴染みがあるアクション俳優のデータを使って、実際に機械学習をやってみた経験談をお話しました。

私自身は機械学習エンジニアでもなんでもないのですが、そんな素人が機械学習にチャレンジしてみたらどうなったのか?というお話になっています。

資料に掲載されている情報のリンク

前作からの変更部分

Amazon Rekognition登場

前作(大阪での登壇)の次回予告で「東京では画像認識をやるかも??」とか調子こいたこと言ってしまったので、3作目となる今回では「Amazon Rekognitionを使用してセガール映画のポスター画像を分析する」という課題にチャレンジしてみました。

実は、私は当初から「映画ポスターの中でセガールの顔が占めている面積が多いほど、邦題に『沈黙』がつきやすくなるのではないか?」という仮説を抱いており、この仮説を証明する良いチャンスでもありました。この仮説を証明する手っ取り早い方法として、同じ大阪オフィスかつ同じ部署の機械学習エンジニアに教えてもらったのがAmazon Rekognitionです。

Amazon Rekognitionは画像や動画を投げるだけで、写っている人物や物を認識してくれるフルマネージドサービスです。詳細は下記をどうぞ。

上記のような感じで、マネジメントコンソール上で画像をアップするだけで、その画像に写っている人間等を認識してくれます。「有名人の認識」という機能を使うと、「人間」というだけでなく「スティーブン・セガール」であることまで認識してくれます。

下記は「沈黙の奪還」という作品のポスターに対して「有名人の認識」を行った結果です。

{
    "CelebrityFaces": [
        {
            "Urls": [
                "www.imdb.com/name/nm0000219"
            ],
            "Name": "Steven Seagal",
            "Id": "306kb5B",
            "Face": {
                "BoundingBox": {
                    "Width": 0.1666666716337204,
                    "Height": 0.11600928008556366,
                    "Left": 0.35333332419395447,
                    "Top": 0.3921113610267639
                },
                "Confidence": 99.98019409179688,
                "Landmarks": [
                    {
                        "Type": "eyeLeft",
                        "X": 0.4076979458332062,
                        "Y": 0.4413428008556366
                    },
                    {
                        "Type": "eyeRight",
                        "X": 0.4605356752872467,
                        "Y": 0.437404990196228
                    },
                    {
                        "Type": "nose",
                        "X": 0.4332691431045532,
                        "Y": 0.46129152178764343
                    },
                    {
                        "Type": "mouthLeft",
                        "X": 0.41788941621780396,
                        "Y": 0.4865615665912628
                    },
                    {
                        "Type": "mouthRight",
                        "X": 0.4603853225708008,
                        "Y": 0.4842248857021332
                    }
                ],
                "Pose": {
                    "Roll": -6.0212297439575195,
                    "Yaw": -5.97119665145874,
                    "Pitch": 4.950545787811279
                },
                "Quality": {
                    "Brightness": 38.580078125,
                    "Sharpness": 39.035926818847656
                }
            },
            "MatchConfidence": 84.0
        }
    ],
    "UnrecognizedFaces": [
        {
            "BoundingBox": {
                "Width": 0.1433333307504654,
                "Height": 0.09976798295974731,
                "Left": 0.6600000262260437,
                "Top": 0.42227378487586975
            },
            "Confidence": 99.9994125366211,
            "Landmarks": [
                {
                    "Type": "eyeLeft",
                    "X": 0.7099087238311768,
                    "Y": 0.460042804479599
                },
                {
                    "Type": "eyeRight",
                    "X": 0.7554613947868347,
                    "Y": 0.4651806950569153
                },
                {
                    "Type": "nose",
                    "X": 0.7297780513763428,
                    "Y": 0.4782559871673584
                },
                {
                    "Type": "mouthLeft",
                    "X": 0.7081437110900879,
                    "Y": 0.49809226393699646
                },
                {
                    "Type": "mouthRight",
                    "X": 0.7436582446098328,
                    "Y": 0.5014099478721619
                }
            ],
            "Pose": {
                "Roll": 8.761550903320312,
                "Yaw": -2.230868339538574,
                "Pitch": 10.222929000854492
            },
            "Quality": {
                "Brightness": 66.42154693603516,
                "Sharpness": 39.035926818847656
            }
        },
        {
            "BoundingBox": {
                "Width": 0.10999999940395355,
                "Height": 0.07424593716859818,
                "Left": 0.5833333134651184,
                "Top": 0.26450115442276
            },
            "Confidence": 99.8419189453125,
            "Landmarks": [
                {
                    "Type": "eyeLeft",
                    "X": 0.6214009523391724,
                    "Y": 0.296705037355423
                },
                {
                    "Type": "eyeRight",
                    "X": 0.654813289642334,
                    "Y": 0.2948194146156311
                },
                {
                    "Type": "nose",
                    "X": 0.653618335723877,
                    "Y": 0.3095405399799347
                },
                {
                    "Type": "mouthLeft",
                    "X": 0.624782145023346,
                    "Y": 0.3255947530269623
                },
                {
                    "Type": "mouthRight",
                    "X": 0.6511809229850769,
                    "Y": 0.3246209919452667
                }
            ],
            "Pose": {
                "Roll": -8.516427040100098,
                "Yaw": 39.905948638916016,
                "Pitch": 1.3620352745056152
            },
            "Quality": {
                "Brightness": 64.26207733154297,
                "Sharpness": 12.911775588989258
            }
        }
    ],
    "OrientationCorrection": "ROTATE_0"
}

BoundingBoxというのが、その人物の顔を囲った範囲になります。これのHeightWidthをかければ、セガールの顔の面積が算出できるというわけです。

ただ、50枚以上ある画像をいちいちGUIでやっていては日が暮れてしまうので、私はAWS CLIを使いました。予め登録S3に画像を配置しておき、コマンドを実行すると、S3に配置してある画像に対して、Rekognitionを実行することができます。

aws rekognition recognize-celebrities --image "S3Object={Bucket=xxxxx,Name=xxxxx.jpg}" --region ap-northeast-1

これをバッチスクリプトでまわしました。コードを書くのに慣れている方は別途SDKを使ってPythonスクリプトでやっちゃってもいいと思います。

結果は?

詳細はスライドを見ていただければと思いますが、結論からいうと、セガールの顔が占める割合と、邦題に「沈黙」がつくかどうかはほとんど関係ないという結果になりました。

機械学習というのは「苦労して得たデータが全然役に立たなかった」「またデータの前処理かたやり直しだ」ということが往々にしてあります。機械学習は何でもすぐに解決してくれるような魔法ではなく、非常に泥臭い作業の上に成り立っているということを、私はセガールを通して伝えたつもりです。

端折った部分めっちゃ多い

前作(大阪での登壇)と同じく、時間制限が厳し目なのに、さらに追加要素を足しちゃったもんだから、とっても多くの部分を省略しました。特に映画データを海外APIから取得する部分の苦労話はもっと話したかったのですが、本質とはズレるので、詳細はスライドをみてください。

反応

縁もゆかりもない東京という土地で一体どれだけセガールが受け入れられるのか不安でしたが、聴講者のみなさんは、非常に暖かく受け入れてくれました。スライドにもある通り、この発表から3日後にはアメリカ出張の予定なのですが、セガールの想いと共に渡米できそうです。

ディレクターズカット版の噂

Developers.IO 2019では、開催地に関係なく、セッション時間が40分ということで、この沈黙の分析では多くの部分を省いて登壇しました。

今のところ予定はありませんが、もしかしたらこの資料の全てを一切省略することなく全部話し切る時間無制限一本勝負セッション…ディレクターズカット版「沈黙の分析」が上映される…か…も…?