[PYTHON] Lancement d'un service Web pour noter les caractères manuscrits à l'aide de DeepLearning

En tant que passe-temps, j'ai personnellement développé un service Web dont l'IA évalue automatiquement la lisibilité des caractères lorsque je les écris à la main sur un navigateur, et je l'ai publié il y a environ deux semaines: détendu:

Application de notation de caractères manuscrits Letters-AI

Les technologies de base sont la reconnaissance d'image de DeepLearning et l'implémentation frontale de Preact. Dans cet article, nous décrirons ** la présentation du service, les détails techniques et les impressions ** concernant l'application développée.

Aperçu du service

Introduction de la fonction

En raison du petit nombre de pages et du poids léger, il est probablement plus rapide de jeter un œil à l'application pour les fonctionnalités, mais je vais vous expliquer les fonctionnalités avec des captures d'écran, y compris un aperçu de la technologie utilisée.

Notation des caractères manuscrits depuis la première page

letters_demo_01.gif

――Sur la première page, un cadre dans lequel vous pouvez écrire des caractères s'affiche et vous pouvez écrire des caractères.

Affichage des résultats de notation des caractères écrits jusqu'à présent

letters_demo_02_2.gif

Affichage d'exemples de meilleurs scores

letters_demo_03.gif

――Si vous ne pouvez pas obtenir un score élevé, vous pouvez afficher un exemple du type de caractères que vous devez écrire pour obtenir un score élevé.

Contexte / objectif du développement

Le but de ce développement est double.

  1. Ce serait amusant s'il y avait une application qui marquerait des caractères manuscrits
  2. Je voulais créer une application Web qui applique DeepLearning

À la suite de son développement, je suis satisfait car je les ai satisfaits tous les deux pour le moment. Je pense qu'il n'y a pas de service qui offre les mêmes fonctions que celui développé cette fois. (Non, je n'ai pas tellement enquêté sur d'autres services ...)

Points de blocage

Mouvement léger

Fondamentalement, il est censé être utilisé sur les smartphones et les tablettes, j'ai donc essayé de faire bouger l'affichage initial, etc. Plus précisément, nous prenons des mesures telles que rendre les fichiers frontaux aussi légers que possible.

Garantie du nombre de types de caractères de notation

La cible de notation est un total de 3175 caractères, y compris hiragana, katakana, kanji, romaji et nombres, qui sont souvent utilisés en japonais, et nous l'avons fait presque couvrir les caractères couramment utilisés au Japon [^ char_types].

S'il ne s'agit que de nombres, il peut être facilement préparé en utilisant le jeu de données MNIST, et il existe différents jeux de données avec uniquement des caractères alphanumériques, mais il comprend des hiragana, des katakana, des kanji, des mélanges de caractères alphanumériques et d'autres caractères alphanumériques. Il était difficile de créer un ensemble de données comprenant des majuscules et des minuscules.

[^ char_types]: la répartition comprend 75 caractères hiragana, 71 caractères katakana, 2967 caractères kanji, 52 caractères romaji et 10 chiffres.

Détails techniques

Vue d'ensemble de l'architecture

Letters_architecture (1).png

Technologie / langage / outils utilisés

l'extrémité avant

Preact est une version légère du framework de type React. Il est implémenté presque tel quel, mais incroyablement léger [^ preact_gzip]. Je n'étais pas submergé par React, donc je n'ai eu aucun problème avec Preact [^ preact_api].

[^ preact_gzip]: environ 3 Ko avec gzip. Étonnant. [^ preact_api]: L'API de hook de composant fonctionnel peut être utilisée normalement dans Preact, et il y a aussi un routeur pour Preact.

Back end

Étant donné que la partie d'apprentissage automatique utilise Python3 + Keras, Python est sélectionné en raison de son affinité et de sa commodité pour le backend qui doit effectuer un traitement d'inférence en temps réel. Flask est sélectionné simplement parce qu'il est léger et facile à utiliser, mais comme il y a des moments où vous souhaitez effectuer un traitement asynchrone même sur un serveur d'applications sur Python, allez sur FastAPI. Je pense également à le remplacer. Il n'y a pas de raison particulière de choisir Nginx, uWSGI, mais fondamentalement, les serveurs d'applications comme Flask ne sont pas optimisés pour le comportement du front-end Web dans les environnements de production, ils sont donc mieux adaptés à ces utilisations et à Flask. J'utilise juste quelque chose qui a une forte affinité.

Partie apprentissage automatique

L'apprentissage et le raisonnement utilisent le cadre d'apprentissage en profondeur Keras.

Infrastructure telle que l'environnement d'exécution

J'utilise GCP en général (je n'utilise aucun service cloud autre que GCP). Le serveur backend utilise «Google Compute Engine», l'emplacement de stockage des fichiers image, etc. utilise «Google Cloud Storage» et l'équilibreur de charge utilise «Google Cloud Load Balancing». J'étais inquiet à propos de «Google Cloud Load Balancing» car les frais mensuels sont d'environ 2700 yens (au 23 mars 2020), ce qui est relativement cher, mais il gère le certificat automatiquement, ou par hasard. Je me sentais rassuré de pouvoir augmenter le nombre d'instances lorsque le nombre d'accès augmentait, j'ai donc décidé de l'utiliser une fois.

Le déploiement est exécuté dans le flux suivant avec le conteneur Docker comme unité de lancement.

  1. Créez le frontal dans l'environnement de développement
  2. Créez une image de conteneur avec un code pré-construit et exécutable
  3. Poussez l'image de conteneur créée vers un registre de conteneurs privé
  4. Créez un modèle d'instance basé sur l'image du conteneur transféré
  5. Mettez à jour le groupe d'instances en fonction du modèle d'instance

Il y a beaucoup de katakana ... w Je ne pense pas à mettre à jour les données d'entraînement jusqu'à présent, j'utilise donc un modèle qui a déjà été formé.

Autres outils et services pris en charge

Inkscape C'est un logiciel gratuit qui offre presque les mêmes fonctions qu'Adobe Illustrator. Utilisé pour créer des logos et des icônes.

** Faisons Fabicon favicon.ico! ** Ceci est très pratique lors de la création de lots de favicon qui prennent en charge différentes tailles et formats.

EZGIF.COM - Animated GIF editor and GIF maker Il s'agit d'un service pratique pour convertir la vidéo de démonstration de l'application en GIF lorsque vous souhaitez la télécharger sur Twitter sur Qiita. J'ai essayé plusieurs services similaires, mais j'ai personnellement trouvé que ce service était le plus pratique en raison de la flexibilité de la conversion et du temps de traitement.

Wikitionary Afin de créer une liste de kanji, je voulais classer par notes apprises à l'école, j'ai donc collecté des données. Nous avons déjà acquis des données telles que les lectures, le nombre total de courses et les chefs de service, mais nous n'implémentons actuellement pas de fonctions de classification / recherche d'affichage en les utilisant.

Données utilisées pour former des modèles d'apprentissage automatique

ETL Character Database(ETL CDB) Caractères manuscrits (+ petite quantité de caractères imprimés) Il s'agit d'un ensemble de données d'images. Il s'agit d'un ensemble de données composé d'environ 3200 types de caractères utilisés au Japon et de 1 115 065 données d'image. Les types de caractères se composent de hiragana, katakana, kanji, caractères alphanumériques et symboles, mais n'incluent pas les lettres minuscules dans l'alphabet latin (romaji). De plus, ETLCDB est un ensemble de données qui est un peu difficile à gérer à partir des points suivants.

--Chaque ensemble de données est constitué de données binaires avec un format de longueur fixe, pas de JSON ou XML moderne.

J'ai créé et publié script Python pour extraire les images de tous les ensembles de données ETLCDB. Prenez les données d'image brutes des données binaires sur l'ensemble de données et enregistrez chaque code en tant que répertoire au format PNG afin qu'il puisse être traité comme une étiquette de point de code Unicode. L'ensemble de données peut être utilisé gratuitement, mais veuillez noter qu'il dit «Veuillez nous contacter pour les conditions d'utilisation commerciale».

The EMNIST Datset Il s'agit d'un jeu de données de caractères manuscrites fourni par le NIST (American National Institute of Standards and Technology). Il y a 814255 images pour les 62 caractères, y compris le cas et les chiffres romaji. Notez que MNIST, qui apparaît souvent dans les didacticiels d'apprentissage en profondeur, est un sous-ensemble de cet ensemble de données. Le CDB ETL mentionné ci-dessus contient de nombreux caractères, mais il n'y a pas de données en caractères romains inférieurs. Cependant, je voulais vraiment inclure tous les caractères alphanumériques comme cibles de score, j'ai donc ajouté un ensemble de données qui incluait tous les caractères romains comme données d'entraînement.

Code source etc.

La source de base est disponible sur GitHub Repository. Cependant, certains fichiers nécessaires à l'exécution de l'application, tels que les modèles entraînés, ne sont pas placés sur GitHub, de sorte que l'environnement d'exécution ne peut pas être reproduit tel quel en tant qu'environnement de développement.

Impressions

Ce que j'ai ressenti en jouant avec l'application

Maintenant, tout à coup, c'est un sujet sans rapport, mais pouvez-vous déchiffrer le sens de la phrase suivante? (* Légèrement changé depuis la publication)

** «Uguchi Uriki Nirikiko Yu» **

mushimegane_boy.png

sashimi_maguro_ootoro.png kani_ashi.png

Je suis désolé de mettre une image inutile pour que vous ne puissiez pas voir la bonne réponse tout de suite: suer:

Et il n'y a même pas une seule lettre pour ceux qui pensent que l'image est un crochet complet et que c'est une notation katakana de "retourné pour fondre" ... La bonne réponse est la suivante, et en fait c'est juste une liste de caractères qui ne tiennent pas du tout comme une phrase.

卜: Eau ** 卜 ** Ana's ** "卜" ** Bouche: ** Bouche ** Inflammation interne, ** Bouche ** Coin ** «Bouche» ** Puissance: ** Puissance **, ** Puissance ** ** «Puissance» ** Deux: ** deux ** Kotamagawa, ** deux ** distribution à terme ** "deux" ** Ingénierie: ** Ingénierie ** Pendant le processus, ** Ingénierie **, Saito ** Engineering ** ** «Engineering» ** Soirée: ** Soirée **, ** Soirée **, ** Soirée ** Nourriture ** "Soirée" ** (Si vous copiez et effectuez une recherche Google, vous constaterez qu'ils sont tous des kanji.)

Peu de gens peuvent probablement reconnaître correctement tous les personnages. Si tel est le cas, il s'avère que ** "s'il s'agit d'une impression correcte, tout caractère peut être reconnu et lu par des humains" n'est pas vrai ** [^ miss_read]. Par exemple, lorsqu'on vous demande de lire à haute voix l'indication "Kou", s'il n'y a pas d'indication, vous ne pouvez répondre que "soit" Kou "de construction ou" E "(e) de Katakana". Je me demande si cela peut être fait [^ e_font]. En d'autres termes, ** il peut être très difficile de distinguer par un seul caractère **.

[^ miss_read]: Si ce n'est pas simplement une erreur de lecture ... [^ e_font]: En fonction de la police, il peut y avoir des polices / personnes qui peuvent faire la distinction entre les kanji et les katakana.

De plus, si la question «Pouvez-vous déchiffrer la signification de la phrase suivante?» Au début de cette section est ** «Qu'est-ce qui est écrit pour chaque caractère dans la chaîne de caractères suivante?» **, la vue est également différente. Je pense qu'il y a beaucoup de gens qui sont différents.

Comme on le dit souvent, lorsque j'étudie ou que j'expérimente l'apprentissage automatique, en particulier l'apprentissage en profondeur, je suis souvent convaincu que ** la perception humaine est susceptible d'être dépendante du contexte **. Il y a. Cette reconnaissance de caractère est un exemple typique, et lorsque nous lisons un caractère, nous ne reconnaissons et distinguons pas seulement la figure de ce personnage seul, mais "quel type de caractère est écrit autour de lui" Il repose en grande partie sur "des informations qui peuvent être qualifiées de contexte" telles que "quels types de mots et d'éléments morphologiques sont utilisés" et "quels types de mots y sont naturellement écrits" ** Tu peux voir ça.

Dans l'application développée cette fois, la reconnaissance d'image est effectuée et la notation est effectuée sans utiliser aucune information de contexte, il y a donc pas mal de caractères qui sont difficiles à obtenir des scores élevés. Les cinq caractères ci-dessus sont des exemples typiques, mais il existe d'autres caractères tels que 0 (numéro zéro) et O (alphabet latin O) qui sont difficiles à obtenir un score élevé car il est difficile de reconnaître le caractère seul. Il y en a un certain nombre.

Dans le développement lié à l'apprentissage automatique, je travaille souvent en pensant à «comment les humains reconnaissent», mais il est très intéressant de s'y plonger purement, et je suis surpris de la qualité du cerveau humain. Il y en a souvent. De plus, je pense qu'il existe de nombreux indices dans cette perspective, tels que "ce que l'IA peut et ne peut pas faire pour le moment".

Personnellement, non seulement les mots, mais aussi les informations contextuelles ont atteint un niveau qui peut être analysé par traitement du langage naturel, et je pense que l'apprentissage en profondeur multimodal se développera de manière significative dans les prochaines années. Je pense que l'IA sera naturellement capable de faire des inférences très précises après avoir lu le contexte. Grâce à ces avancées, je pense que la soi-disant «IA intelligente» sera réalisée dans un avenir pas trop lointain.

Difficulté de libération dans le développement personnel

Dans le développement personnel, il est très difficile de décider combien vous devez gagner et libérer, contrairement au cas où la date de livraison est fixée par contrat, etc. comme les affaires. Que ce soit pour les affaires ou pour les loisirs, si vous avez fait beaucoup de développement logiciel, vous le saurez, mais au milieu du développement, en plus des bugs à corriger, il y a des améliorations et des fonctionnalités qui, à mon avis, devraient être présentes. Sortez innombrables. Même dans ce développement personnel, il y a encore de nombreuses fonctionnalités qui ont été ajoutées et des points à améliorer ...

Dans de telles circonstances, il est très difficile de décider "jusqu'où nous pouvons le diffuser". Je pense que la chose la plus importante dans une telle situation est ** une forte volonté de "l'amener absolument au monde" **.

Il semble être utilisé comme un slogan au sein de Facebook ** "Done is better than perfect" ** "Le logiciel n'est jamais en parfait état. C'est pourquoi nous l'avons sorti avec un sens de la rapidité et avons continué à l'améliorer petit à petit. Il est important de continuer "** Il semble que l'arrière-plan soit l'intention [^ facebook]. Comme le caractérise ce mot, il est nécessaire d'abandonner dans une certaine mesure lors de la libération. Cependant, d'un autre côté, on dit souvent qu'il faut beaucoup de temps à un utilisateur qui est parti une fois pour revenir, et il est assez difficile de publier facilement des produits de mauvaise qualité dans le monde et d'interférer avec la fierté en tant qu'ingénieur. C'est difficile.

Dans cet esprit, après tout, même dans le développement personnel, il est préférable de définir une ** date de sortie (définir une date de sortie à l'avance afin que tout y soit publié **). Je me demande s'il y en a un ces jours-ci (il y a peut-être d'autres bons moyens ... Si vous le savez, je veux vraiment le savoir, alors faites-le moi savoir ...!)

J'ai plus de réflexions et de réflexions sur cette "difficulté dans le timing de la sortie", donc j'aimerais écrire un article séparé sous forme de poème.

[^ facebook]: The Hacker Way - Facebook a le texte original. C'est une très belle phrase.

finalement

À Tokyo, il est difficile de sortir de la maison en raison de fortes chutes de neige en raison de la demande de ne pas sortir, et j'espère que vous pourrez jouer même un peu si vous le souhaitez. Il y a encore de nombreuses imperfections et cela peut ne pas être fonctionnellement suffisant, mais j'espère que vous l'apprécierez!

Récemment, j'ai commencé à faire Twitter en détail, donc si vous le souhaitez, veuillez suivre Compte Twitter m (_ _) m

Recommended Posts

Lancement d'un service Web pour noter les caractères manuscrits à l'aide de DeepLearning
Créer une application Web avec Flask ②
Créer une application Web avec Flask ①
Créer une application Web avec Flask ③
Créer une application Web avec Flask ④
Impressions d'utilisation de Flask pendant un mois
Créer un service Web avec Docker + Flask
Flask-Créer un service Web avec SQLAlchemy + PostgreSQL
Créer une carte Web en utilisant Python et GDAL
Conseils pour utiliser Elastic Search de manière efficace
Faisons un module pour Python en utilisant SWIG