アイコン探しって、結構大変じゃないですか?
開発をしていると、アイコンが必要になります。
しかし、たまに 検索するための名前がわからない という問題が起きる...
例えば、メニューに使われる「⋯」のアイコン。
なんて検索すればいいかわからない...
作ったアプリ
手書きアイコン検索アプリ iconow
アイコンの名前がわからなくて探せない...という問題を解決するため、手書きで検索できるようにしたアプリです。
みんな大好き FontAwesome と、Web や Flutter のアイコンに採用されている Material Icon を検索できます。
iOS
Android
使用した技術
- Flutter
- Firebase
- Authentication
- Firestore
- AWS
- Lambda
- ECR
- API Gateway
- DynamoDB
- S3
- Serverless
- Docker
- TensorFlow
フロントエンドについて
フロントエンドは Flutter を使っています。
iOS、Android を同時に開発できる Flutter はやはり非常に強力です。
状態管理は Riverpod + freezed + StateNotifier を採用しました。
ユーザー管理周りは Firebase を使っています。
技術的な点では、今回のアプリの肝である手書き部分にこだわりました。
画面をなぞったところを検知し、そのポジションを Riverpod
で管理することによって、高速かつ軽量に手書きが実現できます。
また、手書きの基本的な Undo、Redo 機能も実装しています。
詳しい実装方法は以下の記事に書いています。
バックエンドについて
画像を受け取り、それを学習モデルに解析させ結果を送る API を作成しています。
学習モデルが動くコンテナを構築しておき、それを ECR にあげて Lambda で展開し、API Gateway で接続する構成です。
CircleCI と Serverless を用いて GitHub にあげたときに自動展開できるようにしました。
詳しくは以下の記事に書いています。
また、DynamoDB や S3 は学習モデルのログを保存するために使っています。
機械学習について
特に苦労したところ。
基本的に、機械学習は大量のデータを学習させることで汎用性を高め、精度を上げます。
つまり、学習データが少ないと精度が上がらないのです。
しかし、このアプリは製作者が2人しかいないため、大量の手書きデータを用意するのは不可能でした。
というわけで、考え方を変えて精度ではなく汎化性能を重要視しました。
検索結果には推論結果の 1位 から 20位 までくらいを出して、その中からユーザーに判断してもらうという作戦です。
これなら1位をズバッと当てられなくとも、検索アプリとしては成り立ちます!
まずは似ているアイコンの画像をグループ分けし、グループをターゲットとします。
そしてこれらをもとに手書きして、教師データを作成しました。1グループにつき 5~20枚ほど手書きしています。
教師データの画像はぐにゃぐにゃにしたもので 100倍に水増ししておきました。これにより汎化性能が大幅に向上しました。
そして、学習時には「上下/左右移動」「カットアウト」「回転」「ズーム」「スキュー」などの DataAugmentation を使っています。(フリップは矢印などのアイコンに悪影響のため使っていません。また、グレースケールとして処理しているため色の DA は使っていません。)
モデルは、ドロップアウトの確率を多めに設定し、畳み込みを広く取ることで、損失率を出来るだけ抑えるネットワークを構築しています。
開発者
バックエンド, 機械学習担当
フロントエンド担当
さいごに
使ってみての感想やご意見、バグ報告などありましたら、ぜひコメント欄にお願いします!