本文へスキップ

01 / 05 · 2019.07 — 2020.07

北京雲上作科技有限公司

AI × 教育分野でのアルゴリズム実装とフルスタック開発。Mask R-CNN + ResNet による授業行動のリアルタイム分析・警告、社内のデータ注釈・学習基盤の構築、オンライン授業モニタリングの統計バックエンド、顔認証、スクリーンショット認識サービスを担当した。

職種
ソフトウェア開発エンジニア
業種
AI × 教育
所在地
北京
チーム
5名
在籍
1年1ヶ月

主な成果

  • 6 クラス

    授業中の行動分類(前を向く・うつむく・立つ・机に伏せる・横を向く・挙手)。信頼度 0.95 未満は「不確定」とし、無理に判定しない

  • 21 ルート

    オンライン授業モニタリングの統計エンジン(Tornado 約 1,650 行)。Elasticsearch の集計クエリで実装

  • 1 万枚超

    WeChat スクリーンショット認識で自ら注釈した画像数(別にアイコン 1 千枚超)

この会社での案件

PROJECTS · 4
データ注釈:Mask R-CNN で事前注釈し、Labelme では枠と行動クラスだけを修正

2019 – 2020 · フルスタックエンジニア(アルゴリズム・バックエンド・社内学習基盤) · 体制 5名

AI 授業行動分析システム

教室のカメラで生徒の授業中の行動(前を向く、うつむく、挙手、机に伏せる、横を向くなど)を認識し、顔認識で個々の生徒に対応付けて、リアルタイム警告と多階層の授業レポートを提供する。自分は 2 つのサブシステム、学校向けのリアルタイム分析・警告プラットフォームと、社内用のデータ注釈・モデル学習プラットフォームを開発した。

  • 2 段階認識:Mask R-CNN(R-101-FPN)で生徒を検出 → ResNet18 で行動分類(6 クラス、信頼度 0.95 未満は「不確定」)。検出モデルに直接分類させるより精度が高く、行動クラスの変更時も小さな分類器だけ再学習すればよい
  • リアルタイム分析:OpenCV で RTSP ストリームを読み、映像タイムスタンプが実時間より遅れたらフレームを間引いてリアルタイム性を確保。クラスごとに独立した GPU プロセスを起動し、起動前に nvidia-smi で空きメモリを確認
  • フレーム間追跡と本人識別:5 秒窓の双方向重なり率による追跡を自作。face_recognition(dlib)の 128 次元特徴をクラスの顔データベースと照合し、同一トラック内で最頻の生徒 ID を採用して、うつむき・横顔でも本人を識別
  • 机に伏せる・横を向くのリアルタイム警告:生徒の顔画像(base64)を切り出して警告に格納。最新結果とフレームごとの履歴は MongoDB に分けて保存
  • Tornado バックエンド:アカウントと 3 種のロール、警告・レポート(生徒・授業・学年・学校の 4 階層)、WeChat ミニプログラム API と外部プラットフォーム向け公開 API。プロダクトマネージャーのプロトタイプに合わせて API の項目仕様を設計
  • scikit-learn で行動データを分析し、生徒ごとの週報・月報・学期レポートを作成して保護者の WeChat ミニプログラムへ配信
  • 社内のデータ注釈・学習プラットフォーム:動画の切り出し → Mask R-CNN による事前注釈(labelme JSON 生成)→ 人手修正 → 切り抜き → データセット作成 → ResNet18 学習(再開対応、loss/精度の曲線)→ 検証。授業全体のオフライン分析がリアルタイム版の原型
  • 納品:コアの追跡アルゴリズムを Cython で .so にコンパイルし、supervisor による常駐化とドングルによるライセンス管理で、複数顧客へオンプレミス展開
  • Python
  • Tornado
  • PyTorch
  • maskrcnn-benchmark
  • face_recognition (dlib)
  • OpenCV
  • FFmpeg
  • MongoDB
  • scikit-learn
  • Cython
  • ECharts
  • jQuery

稼働デモ

  • リアルタイム分析基盤:クラス監視の一覧
  • 校長向けダッシュボード
  • 複数クラスのライブ映像

システム構成

収集層 ストリーミング & 推論層 データ層 サービス層 クライアント 教室カメラ RTSP 映像ストリーム デモ用映像ストリーム infinitevideo.sh FFmpeg でループ配信 ライブ経路(ClassDetailHandler が授業詳細を開いたときに起動) FFmpeg RTSP→RTMP 転送 nginx-rtmp rtmp://…/mytv/ H5 プレイヤー ckplayer/video.js 分析プロセスの起動 / 停止(nohup + kill、先に空きメモリを確認) GPU 推論プロセス · クラスごとに 1 つ · front_back_frame ①OpenCV で読み込み + フレーム間引き制御 映像タイムスタンプが実時間より遅れたらフレームを飛ばしてリアルタイム性を確保 ②Mask R-CNN(R-101-FPN)で生徒を検出 「人」のみ残す · 信頼度 ≥ 0.7 · 重なり枠の除去(0.8) ③ResNet18 行動分類(6 クラス) 1 人分の画像を正方形に補完 → 224×224 · 信頼度 < 0.95 は「不確定」 ④face_recognition で生徒を識別 CNN で顔位置 → 128 次元特徴 → クラスの顔 DB と照合 ⑤フレーム間追跡 + トラック内の本人投票 5 秒窓の双方向重なり率で対応付け · トラック内で最頻の生徒 ID を採用 机に伏せる / 横を向く → 顔画像を切り出し base64 で警告に格納 書き込み MongoDB realtimewarning クラスごとの最新フレーム結果 record_pics フレームごとの履歴 pg_classes クラス・映像・顔 DB school/class/student 学校 · クラス · 生徒の台帳 students_performances 授業ごとの行動パフォーマンス bf_kaoqin … 顧客の勤怠などのカスタムデータ Tornado Web :8080 · pymongo アカウント管理 セキュア Cookie · 3 種のロール 警告システム /getfaster をポーリング レポート表示 生徒/授業/学年/学校 顧客向けカスタム画面 顧客 A · 顧客 B ミニプログラム API xcx.py 外部向け公開 API jyd_api.py Amaze UI · ECharts 校長 / 教師 ブラウザ ミニアプリ 保護者 / 教師 外部連携先 外部システム 運用と納品 supervisor が 4 プロセスを常駐化(Web · 分析 · 配信 · VPN) | Cython でコアアルゴリズムを .so 化 | ドングルでライセンス管理 | Linux + NVIDIA GPU(CUDA)
1動画の切り出し /ffmpeg · /ffmpegGetVideotimes 長さ取得 → 時刻で区間を切り出し 2モデルによる自動事前注釈 /labelme · infer2labelme_mask Mask R-CNN → labelme JSON を生成 3人手で修正 labelme デスクトップツール 枠と行動クラスだけを修正 4切り抜きと分類 /cutimg · /gray 枠ごとに 1 人分を切り抜き、行動別のフォルダへ 5データセット作成 /dataset · DataSet.py クラスフォルダが 0 から連番かを検査 6分類モデルの学習 /train · resnet_trainer ResNet18 · SGD · 50 エポック · 再開対応 7モデル検証 /behavior · test_jr2_fang しきい値を調整してバッチ評価 8授業全体のオフライン分析 /upVideo · class_recognition 追跡→クラスタリング→本人識別→登録 ↓ ResNet 分類モデル .pth を出力し、リアルタイム基盤へ配備 ↓ アルゴリズムは後にリアルタイム版へ 補助機能:クラス・映像ストリーム管理(/addClass /modifyClassStream /removeClass)· 生徒と顔写真の管理(/addStu /modifyStu /removeStu)· モデルとフォルダの閲覧(/getMaskmodel /getFolder)
授業映像の素材 カメラ録画 / 現地収集 Backend 学習プラットフォーム 注釈 · データセット作成 · 学習 · 検証 モデルファイル detector.pth (Mask R-CNN) classifier.pth リアルタイム分析プラットフォーム リアルタイム推論 · 警告 · レポート 稼働後も新しい授業映像が生まれ、新たな学習データとして還流
オンライン英会話の授業画面(教師・生徒はモザイク処理済み)

2020 · 統計エンジンのバックエンド、管理画面のフロントエンド、アルゴリズム分析に参画

AI 診断型オンライン授業モニタリングシステム

オンライン英会話の授業(コロナ禍で授業がオンラインに切り替わったため)で教師・生徒の音声と映像をリアルタイムに収集し、ASR / CV / VAD で構造化。レッドライン行動(中国語での発話、教師の話しすぎ、生徒の参加不足、画面からの離脱、黒画面・切断)を準リアルタイムで警告し、教育品質指標のレポートを本部/支社/校舎、講座、教師、生徒の多軸で比較・ランキングする。

  • 統計エンジンのバックエンド(Tornado、約 1,650 行・21 ルート):授業/教師/生徒の一覧・詳細・履歴トレンド、授業態度の時系列カーブ、模範授業 TopN
  • Elasticsearch クエリ:bool + terms + range の組み合わせ、terms 集計に avg サブ集計をネスト(授業ごとの教師の平均 happy 確率・語数・話速)、大きな結果は scan / scroll で走査。CV と ASR の複数ソースをアプリ層で統合して並べ替え
  • 管理画面のフロントエンド(vue-element-admin 4.4):ロール別の動的ルーティング権限、データ大画面、授業/教師/生徒の一覧と詳細、ランキング、トレンド、絞り込み。ECharts で可視化、Docker 化と複数環境設定
  • アルゴリズム分析に参画:生徒の発話比率・まとまった表現・感情のポジティブ度から約 30 秒の「ハイライト」区間を抽出し、ノイズ・教材音声の混入・保護者の同席などの異常も印付け。保護者向けの学習状況レポートに利用
  • Python
  • Tornado
  • Elasticsearch
  • Redis
  • Vue 2
  • Element UI
  • ECharts
  • MQTT
  • Docker
  • Alibaba Cloud

システム構成

収集から警告表示までの経路
収集側 接続 · 保存 · イベント 構造化アルゴリズム(gRPC) 検索 · 分析 · 表示 ブラウザ <video> web-video-capture.js 毎秒 1 フレーム · 音声は 10 秒ごと 上り約 30kbps · 負荷 <5% IOAuthProxy 認可サービス :9001 Aliyun OSS パブリッククラウド MinIO オンプレミス配備 Notification Hub OSS トリガー → MNS ASR Worker日英音声のテキスト化 CV Worker顔の位置/向き/表情 Sound (VAD)発話の開始・終了と長さ Elasticsearch時系列ストアとして利用 Analyse TaskQueue Analyse Enginestats_engine :9002 ReportDB+ ClassDB 時間割 管理 バックエンド Vue MQTT イベントキュー 1883 / 8083 / 8084 トークン申請 webpwebm レッドライン事象 WebSocket でプッシュ → 教師画面に警告

2020 · アルゴリズムとサービスの開発

FaceID 顔認証・顔検索

オンライン教育のお客様向けの顔認証:授業動画の映像から出演している生徒が本人かを確認し、全件・増分・指定人の顔検索で「1 人が複数アカウント」「複数人で 1 アカウント」を見つける。

  • 推論フロー:ランダムフレーム抽出 → YuFaceDetectNet による検出と 5 点ランドマーク → アフィン変換で整列 → 遮蔽・姿勢ぼけ・年齢の 3 モデルでフィルタ → ResNet18 で特徴抽出しコサイン類似度で照合。最年少の顔(17 歳未満)を採用して生徒本人を特定し保護者を除外
  • 複数フレームワークの混在推論:検出・特徴抽出は PyTorch、遮蔽・姿勢・年齢は MXNet Gluon、すべて CPU で実行。v1.0 から v3.4 まで継続改善(dlib 68 点 + Laplacian ぼけ検出 → モデル・整列の刷新 → 品質モデル 3 種の追加 → 全件検索と動画検証の書き直し)
  • Redis に特徴を保存し、全体・増分・指定人の 3 種類の検索に対応。全件の総当たり比較はコードのコメントで約 4,000 万回と見積もり
  • 商用ライセンス制御:呼び出し回数・有効期限・日次上限を AES 暗号化して Redis に保存、SETNX で分散ロック、デバイス SN を検証。コアモジュールは Cython で .so にして納品
  • 設定は「コマンドライン引数 > 環境変数 > JSON / YAML」の優先順位で読み込み。Docker で配備し、ビルド時に OSS からモデル重みを取得
  • Python
  • PyTorch
  • MXNet
  • dlib
  • ResNet18
  • Redis
  • Cython
  • Docker
  • OSS

システム構成

顔認証・検索の推論フロー(v3)
動画 授業動画ファイル ランダムフレーム抽出 320×240 に縮小 顔検出 YuFaceDetectNet · PyTorch 5 点ランドマーク アフィン整列 顔ごとに実施 品質フィルタ(MXNet Gluon · CPU) 遮蔽 目/鼻/口 > 0.5 は除外 姿勢・ぼけ ヨー・ピッチ・ロール・ぼけの超過は除外 年齢 最年少(17 歳未満)で生徒を特定 ResNet18 特徴 PyTorch · コサイン類似度 照合と保存 初回:特徴を登録 Redis hash に保存 以降:本人確認/検索 全体 · 増分 · 指定人 ライセンス制御 + Cython 納品 AES 上限 · SETNX ロック · .so
モーメンツ広告のスクリーンショット例(人物はモザイク処理済み)

2020 · 学習・推論・サービス・配備

WeChat スクリーンショットの自動認識(モーメンツ広告の配信確認)

アップロードされた WeChat のスクリーンショットを自動認識し、モーメンツ広告の配信確認に使う。画面の種類(会話/タイムライン一覧/投稿詳細)を判定し、投稿時刻・広告文・ポスター ID・QR コードのリンク・いいね/コメント数を抽出する。

  • YOLOv5s による主検出(UI 要素 7 クラス)とルールによる画面種別の判定。スクリーンショット 1 万枚超といいね/コメントアイコン 1 千枚超を自前で注釈し、k-means でアンカーボックスを算出
  • 投稿詳細:PaddleOCR(PP-OCR、DB 検出 + CRNN 認識)でレイアウト位置から投稿時刻・広告文・ポスター ID を取得。QR コードをデコード。右下を切り出して YOLOv5 でいいね/コメントのアイコンを検出し、3 層 CNN で数字を認識
  • Tornado + PyTorch + PaddlePaddle のサービス:token と MD5 による完全性検証、nanoid によるリクエスト追跡、元画像は OSS、全結果と処理時間を Elasticsearch へ保存して本番の異常応答の調査に活用
  • PP-OCR のモデルバージョンを更新し、ポスター ID と投稿時刻の認識率を向上
  • Python
  • PyTorch
  • YOLOv5
  • PaddleOCR
  • PaddlePaddle
  • Tornado
  • Elasticsearch
  • OSS
  • Docker

システム構成

スクリーンショット認識のフロー
スクリーンショット送信Tornado POST 検証 + OSS へ保存token · MD5 · nanoid YOLOv5s による主検出7 クラスのアイコン / QR コード ルール分類対象と相対位置で判定 チャット · プラスまたは三点アイコンあり タイムライン · カメラ → 公開範囲を検出 その他 投稿詳細 · QR コードの詳細画面での相対位置 PaddleOCR(DB 検出 + CRNN 認識) 位置から投稿時刻 · QR との相対位置から本文 「ID」キーワードからポスター ID QR コードのデコード 検出枠を切り出し → URL を取得 いいね数 / コメント数 右下を切り出し → YOLOv5 でアイコンを検出 → 3 層 CNN で数字を認識(検証 98.25%) JSON を集約して返却 · 全結果と処理時間を Elasticsearch へ · 独自エラーコード(212 / 218 …)

システムデータフロー

抽象的な図示・内部の詳細は含みません
  1. 教室カメラ

    RTSP のライブ映像

  2. OpenCV で読み込み

    遅れたらフレームを間引く

  3. Mask R-CNN で検出

    生徒の位置・信頼度 0.7 以上

    ▲ 担当範囲

  4. ResNet18 行動分類

    6 クラス・伏せ/横向きで警告

    ▲ 担当範囲

  5. 顔認識 + 追跡

    128 次元特徴・トラック内で投票

    ▲ 担当範囲

  6. MongoDB → Tornado

    リアルタイム警告・レポート・ミニプログラム

ここで学んだこと

卒業後は AI × 教育の業界に入社。学生の立場を離れ、実務の中でより多くの言語を使い、学びました。業務ロジックの中で PyTorch による物体検出・分類(Mask R-CNN、ResNet)を実装し、Web サービスには Tornado を採用。社内のフロントエンドも HTML / JS / CSS から Vue へ移行し、計算機科学の知識が広がりました。

授業行動の分析では「問題を分ける」ことを学びました。まず人を検出してから行動を分類し、判断が不確かなときは無理に決めず別枠にする。フレーム間の追跡とトラック内の投票で単一フレームの弱さを補い、フレームの間引きでリアルタイム性を守る。納品に関わる工程も初めて体系的に経験しました。Cython によるソース保護、supervisor による常駐化、複数顧客へのオンプレミス展開、そしてオンライン授業モニタリングでの Elasticsearch 集計クエリです。

TECH STACK

  • Python
  • PyTorch
  • Mask R-CNN
  • ResNet
  • YOLOv5
  • MXNet
  • PaddleOCR
  • dlib
  • Tornado
  • Elasticsearch
  • MongoDB
  • Redis
  • Cython
  • Vue 2
  • Docker