Blog

2022.05.09

Engineering

「初めてから学べるプログラミング教育サービス」PlaygramのAI教材開発

Takuya Sato

本記事は、2021年インターンシップで勤務した小寺俊希さんによる寄稿です。

PFN2021夏季インターンシップに参加させて頂きました、東京大学大学院修士2年の小寺俊希と申します。大学では 杉山・横矢・石田研究室 において強化学習の研究に取り組んでいます。

このインターンシップでは「機械学習を題材としたプログラミング教育教材の開発」をテーマに開発を行いました。より具体的には、PFNが提供している子ども向けプログラミング学習アプリ Playgram™️ に機械学習のコンテンツを導入することを目標に、1ヶ月半の間、開発作業に取り組みました。以前より興味を持っていた教育分野において実務的な開発を行う中で、教育に対する理解を深めるとともに、企業・組織における開発者の心得を学ぶことができました。

このブログでは、PFN2021夏季インターンシップにおける開発の経験についてご紹介したいと思います。

概要

このブログは以下のような構成になっています。

  • Playgram
    • 子ども向けプログラミング学習アプリPlaygramについて紹介しています。
  • 開発テーマ
    • インターンシップの開発テーマやその背景について説明しています。
  • 開発内容
    • インターンシップにおいて企画・開発した内容をまとめています。こちらは「チャプター・ステージ構成企画」「コンポーネント作成」「AIモジュール実装」「ステージ実装」の4パートに分かれています。
  • 所感
  • 謝辞

Playgram

はじめに、今回私が開発に携わったPlaygramというアプリについて簡単にご紹介します。

Playgram は子ども向けプログラミング学習アプリです。Playgramでは、可愛らしいキャラクターと綺麗なグラフィックスで楽しくプログラミング学習をすることができます。プログラミングの基本的な文法からコンピュータサイエンスの基礎まで幅広い内容の教材が用意されており、プログラミングに初めて取り組むという子も、より熱心にコンピュータサイエンスを勉強したいという子も楽しめるようになっています。最近では 日本e-Learning大賞を受賞した ということで話題になりました。

Playgramには「ミッションモード」「アドバンスモード」「クリエイトモード」という3つの学習モードがあります。ミッションモードでは基礎的なプログラミングを、アドバンスモードではより発展的なプログラミングやコンピュータサイエンスの基礎を学習することができます。クリエイトモードではミッションモードやアドバンスモードで学んだことを活用しながらオリジナルのプログラムを作成することができます。ミッションモードで学んだあとにアドバンスモードやクリエイトモードに進むことで、プログラミングやコンピュータサイエンスの理解を深めることができるという形になっています。

開発テーマ

今回のインターンシップではアドバンスモードに導入予定の「AIチャプター」の教材を企画・開発することになりました。

機械学習を含むAI関連技術が世の中で使われるようになった現在、そのAIと呼ばれているものについて知っておくことは非常に重要なことです。しかし、AI関連技術を組み込んだプログラミング(以下AIプログラミングと呼びます)の教材で、プログラミング初心者を対象とするものはほとんどありません。多くはPythonなどの言語を使ったテキストコーディングに慣れていることを前提としており、プログラミングを勉強し始めたばかりの人やビジュアルプログラミングしか経験したことがないという人にとってはかなり難易度が高いです。

こうした状況を踏まえ、Playgram開発チームはプログラミング初心者向けのAIプログラミングの教材を提供したいと考えました。それがAIチャプターと呼ばれるものになります。今回のインターンシップにおいて、私はAIチャプターの最初の学習コンテンツの開発を進めました。

なお、以下において「AI」という言葉を使う場合には「機械学習技術(特に深層学習技術)に基づいたAI」を指していることを付記しておきます。

開発内容

今回のインターンシップにおいて企画・開発した内容を「チャプター・ステージ構成企画」「コンポーネント作成」「AIモジュール実装」「ステージ実装」の4ステップに分けて詳細に説明したいと思います。

1. チャプター・ステージ構成企画

私が取り組んだのはPlaygramの「手書き文字認識」チャプターの企画・開発です。

今回、Playgramのアドバンスモードの中に「AIプログラミング」というカテゴリを新しく導入することになりました。「AIプログラミング」カテゴリはその名の通り、AIについて理解を深めることをテーマとしたカテゴリです。各カテゴリにはチャプターと呼ばれる学習単位がありますが、私が開発した「手書き文字認識」チャプターは「AIプログラミング」カテゴリの重要な入口となる、1つ目のチャプターということになります。

AIプログラミングはPlaygramに初めて導入される内容なので、カリキュラムに関する議論から始めることになりました。私が参画した時点で「AIプログラミング」カテゴリ全体の学習目標やベースとなるカリキュラムが既に提案されていたので、それを踏まえてどのようにチャプターを展開していくかを考えました。

その学習目標というのが「『データを与えて訓練すると、AIはそのデータから何かを学習し、未知のデータに対しても良い推論ができるようになる』ことを理解する」というものです。これはAIを開発する立場の人だけでなく、大多数のAIを利用する立場の人も最低限知っておくべき内容だと思っています。なお、Playgramが子ども(特に小学生)をターゲットとしているということもあり、この学習目標にはAIの数理的背景を理解することは含まれていません。

「AIプログラミング」カテゴリの大目標は上記の内容で固まっていましたが、それを達成するための中目標・小目標に関しては議論の最中というところでした。そこで今回のインターンシップでは、後続のコンテンツも意識しながら、自身が担当する「手書き文字認識」チャプター(以下AIチャプター1と呼びます)の学習目標を定め、より詳細なステージ構成の案を作成していきました。

議論の結果、最終的なAIチャプター1の学習目標は「『訓練済みのAIモデルは高度に “知的な” 推論を実行できる』ことを理解する」になりました。端的に言えば「AIモデルの推論の枠組みを理解する」ということです。AIプログラミングの導入となるチャプターとして位置づけられるので、まずはAIの “すごさ” を感覚的に理解してもらうことを目指しました。

題材とする機械学習タスクの選定には非常に時間がかかりましたが、結局のところ MNISTデータセット を用いた手書き文字画像認識をテーマとすることにしました。画像認識タスクを解くには高度に “知的な” 処理が必要になること、深層学習技術を利用すれば比較的易しいタスクであること、そして推論結果の妥当性が検証しやすい(推論結果を見ればAIモデルが “すごい” かどうか判定できる)ことなどがその理由です。AIを学び始める子どもをターゲットにしていることを踏まえ、そうしたユーザにAIプログラミングをもっと勉強したいと思わせるようなコンテンツになるよう努力しました。

AIチャプター1の方向性を考えることと並行して、AIチャプター1に含まれるステージの構成についても考えました。詳細は割愛しますが、どのステージでも看板に書かれた手書き文字のラベルを推論するというプログラムを記述することが課題となっています。成果物のところで1ステージのプレビューを載せているので、そちらを参考にしてもらえると嬉しいです。

AIチャプター1の特徴は、あらかじめ用意された手書き文字画像だけではなく、ユーザの手書き文字に対しても推論を試すことができるということです。こうしたインタラクティブなシステムはユーザの知的好奇心をくすぐりますし、それによってより深くAIについて理解してもらえるのではないかと思っています。

例えば「AIモデルが正答できる / 誤答してしまうデータにはどんな傾向があるか?」と考えて実験をしてみることはとても面白い遊び方であり、かつ興味深い研究になると思います。これ以外にも私たち開発者が想像もしないようなリサーチクエスチョンが生まれる可能性を秘めているという点で、インタラクティブなシステムは教育において非常に重要な仕組みの1つだと私は信じています。

このようにしてAIチャプターの学習目標や具体的なステージ構成案を考えるところから始まりましたが、議論が収束して方向性が固まるまでに2週間を使ってしまいました。というのも、教材に含める情報(何を伝えるか)やその表現(どう伝えるか)を洗練させるのに時間がかかったからです。

子どもやプログラミング初心者をターゲットとする場合には、多少の厳密性や網羅性を欠いたとしても簡潔さやわかりやすさが求められるということはなんとなく理解していたものの、何をどう伝えるかを決めるのは想像以上に難しいことがわかりました。これまでは設計された学校のカリキュラムに従って勉強する側の人間だったので、カリキュラムを設計する側の視点を持つことができたのは非常に良い経験でした。

2. コンポーネント作成

チャプター・ステージ構成のデザインが終わったらそれをPlaygramの開発環境であるUnity/C#上で実装することになりますが、その前段階として実装に必要なコンポーネントの調達を行いました。

多くはこれまでのチャプターで作成されたものを再利用することができましたが、今回はユーザが自由にお絵描きができる(その描画結果をAIモデルに入力できる)ツールが必要となったので、新しく「お絵描きウィンドウ」というUIオブジェクトを実装しました。ステージ上の看板オブジェクトをタップするとお絵描きウィンドウがポップアップされ、そこにお絵描きするとそれが看板に反映されるというシンプルな機能が実装されています。

お絵描きウィンドウのプレビューがこちらです。できあがったものを見ると特に実装上難しいことはないように思えますが、Playgramのプロジェクトが非常に大きく、その上Unity/C#に不得手であったために実装にそれなりに時間を使ってしまいました。お絵描きウィンドウを含めすべてのコンポーネントを調達するのに1〜2週間程度を要しました。

お絵描きウィンドウをはじめとするアセットのデザインに関してはそのほとんどをデザイナーさんにお願いしました。私が提示したふわっとしたイメージをこれだけ綺麗なデザインにまとめるデザイナーさんはすごいなと率直に思いました。

3. AIモジュール実装

コンポーネント作成・ステージ実装と並行する形でAIモジュールの実装を行いました。

AIプログラミングのコンテンツがPlaygramに導入されるのは初めてということで、今回の開発ではAIプログラミングを実現するためのモジュールを一から作成する必要がありました。より詳細には「Playgram上で深層学習技術を用いた機械学習モデルの訓練および推論を実行できるようにしたい」という機能要件を満たすようなシステムを構成する必要がありました。ということで、まずはじめに「どのような方針でAIモジュールを実装するか」についてメンターの方々と議論を交わしました。

先に結論を述べますと、最終的な方針としては「Playgramアプリ上に単体で動作するAIモジュールを載せる。そのAIモジュールはfrom scratchで実装する」ということになりました。最終的な方針だけを見てもこのアプローチを採用する理由がよくわからないと思うので、この結論に至るまでの議論の一部をこのブログに残しておきたいと思います。

Unity/C#で実装されたPlaygramアプリの上で深層学習を動作させるための方法としては次の3つがあると考えました。

  • A) 深層学習専用サーバを利用する
  • B) UnityのプラグインであるBarracudaを利用する
  • C) C#の深層学習モジュールを利用する

この3つの方法の概要および長所・短所を順に説明していきます。

A) 深層学習専用サーバを利用する

最もシンプルな方法として、Playgram管理サーバに深層学習用のAPIを用意し、Playgramアプリ(クライアント)がそのAPIを叩くことで深層学習を行うというものがあります。クライアントが深層学習を実行しようとする際、クライアントはAPIを用いてサーバにリクエストを送信し、サーバはそのリクエストにしたがって深層学習を実行した上で結果をクライアントに返す、という流れで処理が進んでいきます。

最大のメリットは、PyTorch/Tensorflow などの非常に便利な深層学習のライブラリが自由に使えることです。C#のような深層学習が不得意な言語を無理に使うことなく、Pythonのような深層学習の得意な言語を使って実装することで、実装コストを小さくすることができます。さらに、深層学習というかなり重い処理をサーバが受け持つことによって、ユーザの端末スペックによらず快適にアプリを動作させることができると考えられます。

一方、サーバに深層学習を実行させるという方法には大きなデメリットもあります。当然ながら、大量のクライアントからかなり重い処理がサーバに投げられれば、個々のクライアントの負荷は減る反面、サーバの負荷は莫大になります。ユーザ数が増加したり、より処理コストが高い深層学習を実行したりするようになれば、それに耐えられるようサーバをスケールさせる必要も出てくるでしょう。そうなればサーバ運用にかかる金銭的なコストが膨らんでいくことが予想されます。

B) UnityのプラグインであるBarracudaを利用する

既に発明された道具を利用してUnityアプリ上で深層学習を実行することを考えると、Unityパッケージである Barracuda が筆頭候補に挙げられるかと思います。Barracudaは、 ONNX と呼ばれるフォーマットに埋め込まれた訓練済みのニューラルネットワークの推論を高速に実行するためのライブラリです。Barracudaを利用するためには訓練済みの深層学習モデルが必要となりますが、それはPyTorch/Tensorflowなどを用いて構築することになります。

Barracudaを採用するメリットとしては、実装コストが小さい上にパフォーマンスも非常に高いことが挙げられます。それほど最適化されていない自作のUnity/C#ライブラリと比較すれば、非常に良いパフォーマンスを期待できます。

ただ、最も大きな問題はBarracudaが推論ライブラリであるという点です。Barracudaは深層学習モデルの訓練はサポートされていないため、訓練を行う場合には管理サーバにリクエストを投げることになるかと思います。その場合、方法A「深層学習専用サーバを利用する」と同じ問題を抱えることになります。一般に深層学習モデルの訓練は推論よりも圧倒的に重い処理であるため、推論だけをクライアントが担当してもサーバの負荷はほとんど変わらないでしょう。

それどころか、Barracudaを利用するためには訓練済みの深層モデルが必要になるため、それをネットワークを介して送受信するのに非常に大きな通信コストがかかります。深層学習モデルの構成によりますが、1つのモデルにつき数MB〜数百MB単位のデータが送受信されることになります。これはサーバにとってもクライアントにとっても望ましくありません。

C) C#の深層学習モジュールを利用する

方法A「深層学習専用サーバを利用する」および方法B「Barracudaを利用する」では管理サーバが深層学習モデルの訓練を行うようになっていました。それらとは異なるアプローチとして、深層学習モデルの訓練・推論をすべて各ユーザ端末のPlaygramアプリ上で完結させるということを考えました。すなわち、C#で書かれた深層学習モジュールをPlaygramアプリに載せ、クライアント側でモデルの訓練も推論も行ってしまうという方法です。

クライアント側で深層学習を実行することのメリットは明らかで、管理サーバに負荷がかからないことが最も大きいと思います。また、深層学習モジュールがすべてC#プログラムで書かれていれば、かなり柔軟に開発を進めていくことができるでしょう。

少し問題になるのは、深層学習のパフォーマンスがユーザ端末のスペックに依存してしまうことです。一般にユーザ端末のスペックはそれほど高くないので、それに合わせてモデルの構造やデータセットのサイズなどを調整する必要があります。

それよりも問題なのは、そもそも深層学習モデルの訓練・推論を実行できる便利なライブラリが見当たらないということです。少し探してみましたが、2021年8月時点において広く使われているライブラリは見つかりませんでした※。となると自分で一から実装するしかないのですが、最低限の動作を保証するだけでもかなりの工数を必要としますし、ユーザ端末で満足に動くように最適化するのはさらに追加の工数がかかるでしょう。

※2022年5月時点では他の方法が見つかっており、別の形で公表する予定です。

ここまでPlaygramアプリ上で深層学習を動作させるためのアプローチについて見てきました。今回は方法C「C#の深層学習モジュールを利用する」を採用することになりましたが、その決定を下す背景事情をまとめておきます。

  • Playgramのユーザ数を考えると、ユーザから送信される大量の深層学習実行リクエストを管理サーバで処理するのは現実的ではない。深層学習実行リクエストを処理するためには追加で大きな金銭的コストが発生する。
  • インターンシップに応募する際に提出した インターンシップ課題 において非常に小さなC#深層学習モジュールを作成していたため、その知見を活用することができる。

インターンシップ課題について補足しておくと、私が応募した教育系分野の課題は「Unityでアルファベット手書き文字認識ができる機械学習アプリを作成せよ」というもので、その実装のためにC#の深層学習モジュールを開発しました。MNISTのような手書き文字認識タスクではCNN (Convolutional Neural Network) のような複雑なモデルを使わずともFCNN (Fully-Connected Neural Network) のような単純なモデルで十分な精度を出すことができることを経験的に知っていたということもあり、今回はFCNN関連機構の実装のみを行いました。

ちなみに、このインターンシップ課題では以下のような機械学習アプリを作成しました。UI/UXデザインが全く洗練されていませんが、その点に関しては大目に見て頂けると幸いです。

自作のC#深層学習モジュールには動作速度などの問題もありましたが、少なくともAIチャプター1の開発ではそれほどクリティカルではないことも確認できました。こうした理由から、自作のC#深層学習モジュールをユーザ端末のPlaygramアプリに内包させ、ユーザ端末上で深層学習を行うスタイルを採用することになりました。

少し長くなってしまいましたが、一言でまとめると「自作のC#深層学習モジュールをPlaygramアプリに組み込んだ」ということになります。このパートは文字数こそ多いですが、開発時間自体は他のパートと同じくらいだと思います。

4. ステージ実装

チャプター・ステージ構成企画およびコンポーネントの準備が完了した後、ユーザがプレイするステージを実装しました。

企画書に従ってステージにコンポーネントを配置していく形で機械的に実装していくことができるはずでしたが、実際にはステージを実装しながら企画を微調整したり必要なコンポーネントを追加補充したりしていました。企画・実装準備の段階で把握しておくべき作業が実装の段階で明らかになるのはあまり好ましいことではないかもしれませんが、そういう経験をしたことで企画・実装準備の重要性を再認識することができました。ステージ実装の段階まで進んで、ようやくPlaygramの開発にほんの少しだけ馴染めたような気がしました。

成果物

ここまでインターンシップのPlaygram開発について振り返ってきました。この開発記録のまとめとして、1ヶ月半の成果を共有したいと思います。

上の画像はインターンシップの最終発表会でも使用したAIチャプター1のプレビューです。こちらは開発環境(Unity Editor)上で動作確認をしたときの様子です。

このインターンシップで開発したAIチャプター1ですが、Education Teamの皆さんによる調整作業を経て、2021年12月末にPlaygramのチャプターとしてリリースすることができました!下の画像はユーザ端末上での動作確認の様子で、リリース前の調整作業においてAIモデルの外観やステージの説明などが改善されています。

Playgramは『プログラミング教育 HALLO powered by Playgram x やる気スイッチ』における学習教材として利用して頂いていますが、このAIチャプター1も早速多くの生徒の皆さんにプレイして頂いているということでとても嬉しく思います。

実際にプレイした生徒の皆さんからは「(手書き文字を)認識できるのすごいね」「どれだけやっても読み取ってくれない〜!」といった感想を頂きました。AIは “すごい” ものだと私も思いますが、決して万能というわけではありません。生徒の皆さんにAIの可能性と限界を感じてもらうことができたようで、AIプログラミングの導入として良いコンテンツになったのではないかと思います。

それと同時に、ユーザにとってブラックボックスなシステムであるAIを活用する際には、そのユーザに合わせた支援や説明を行うことが重要だと改めて感じました。今回のAIチャプター1に関して言えば、手書き文字のサンプルを提示したり、AIが推論を行った際にその確信度をフィードバックしたりすることでより取り組みやすい教材になったかもしれないと思っています。今後AIを活用したサービスの開発を行う際には、ユーザの視点で考えるという姿勢を忘れないようにしたいですね。

さて、今回のインターンシップではチャプター・ステージ構成の企画から実装までをほぼ完成させることはできましたが、リリースするためにはそれ以外にもいくつかの手順を踏む必要がありました。「調整作業」と一言で済ませてしまいましたが、決して少なくない量の作業があったと推察しています。中途半端な状態でインターンシップを終えてしまいましたが、こうして綺麗な形に整えてリリースしてくださったEducation Teamの皆さんにはとても感謝しています。

所感

数多くのユーザに提供されているサービスの開発に携わるという経験は今回が初めてで、本当にたくさんのことを学ばせて頂きました。経験値の少ない自分が開発したものが世の中で広く使われるというのは恐縮ですが、少しでも多くの人のお役に立てば良いなと思っています。

このインターンシップに応募したのは教育とITの融合領域、いわゆるEdTechに興味があったからだったのですが、今回実際のEdTech事業における開発の様子を垣間見ることができて非常に楽しかったです。

インターンシップ応募当時はUnity/C#でアプリ開発をした経験もなく、インターンシップが始まってからもUnity/C#と格闘する日々が続きましたが、ともあれPlaygram AIチャプター1の大部分を自分の手で作り切ることができて非常に嬉しいです。この経験をまたどこかで活かせたら良いなと思っています。

謝辞

こうして開発を進めることができたのは、メンターとして指導してくださった佐藤さん・西澤さん、開発に関して様々なアドバイスをしてくださった中島さんのおかげです。またEducation Teamの皆さんにも温かく迎え入れて頂いたことで、インターンシップ期間をとても楽しく過ごすことができました。そして、今回のインターンシップにおいてPFNの社員の皆様には大変お世話になりました。ありがとうございました!

  • Twitter
  • Facebook