ã·ã¹ãã ã®æ¦è¦å³
æ©æ¢°å¦ç¿ã¢ãã«ã®æ§ç¯
è¨ç·´ãã¼ã¿ã®åé
ä»åç§ãã¡ãç«ã¡åããã¿ã¹ã¯ã¯、å
¥åããããã¼ã®ã·ã¼ã±ã³ã¹ããã¦ã¼ã¶ã¼ãæå³ããæåãäºæ¸¬ãããã¨ã§ã。ãªã³ã©ã¤ã³ææ¸ãæåèªèã«ä¼¼ãã¿ã¹ã¯ã§ã¯ãããã®ã®、ãã®å¤ãã¯ãã³ã¿ãã¬ãããã¿ããã¹ã¯ãªã¼ã³ã§ã®å
¥åãåæã¨ãã¦ãã¾ã。ãã®ãã、ãã¼ãã¼ãã®ããã«ä½è§£å度ã®å
¥åã«å¯¾å¿ããæ©æ¢°å¦ç¿ã¢ãã«ãæ§ç¯ããããã«ã¯、ä¸ããè¨ç·´ãã¼ã¿ãåéããå¿
è¦ãããã¾ãã。
ãã¼ã¿ãåéãããã、ç§ãã¡ã¯ã¾ããã¼ã¿åéç¨ã®ã¦ã§ãã¢ããªãã¤ãããã¨ããå§ãã¾ãã。å
¥åããæåãæå®ãã¦ãã¼ãã¼ãä¸ã«ãã®æåãæ¸ããã¨ã§、å
¥åããããã¼ã®ã·ã¼ã±ã³ã¹ãä¿åãããã·ã³ãã«ãªã¢ããªã§ã。å¹ççãªãã¼ã¿åéã®ããã«、æ
£ããæ¹ã«ã¯ç»é¢ãã¿ãããããã¨ã§å
¥åçµäºãå¤å®ããå¾
ã¡æéãã¹ãããããæ©è½ãæè¼ãã¾ãã。ãã®çµæ、ããç´ã®æ¹ã«ãªã㨠1 åéãããç´ 60 åã®ãã¼ã¿ãå
¥åãããã¨ãå¯è½ã«ãªã、é«éãªãã¼ã¿åéãå¯è½ã«ãªãã¾ãã。
人æã«ãããã¼ã¿å
¥åã«ã¯ãã¹ãã¤ããã®ã§ã。ç°å¸¸ãªãã¼ã¿ããã°ããè¦ã¤ãã¦åãé¤ãããã、å
¥åã·ã¼ã±ã³ã¹ã®å¯è¦åã¤ã³ã¿ã¼ãã§ã¤ã¹ãå®è£
ãã¾ãã。ä»ã«ãå
¥åãã¼ã¿æ°ã«ãã Contributor ã©ã³ãã³ã°ãåæåã®ç´¯è¨ãã¼ã¿æ°ã®è¡¨ç¤ºãªã©、ãã¼ã¿ã®å
¥åãã¢ããã¼ãããç´°ããªä»çµã¿ãæè¼ãã¦ãã¾ã。
ãªãªã¼ã¹åã«ã¯ç¤¾å
ã§çè·¡ãã¼ã¿åéä¼ãå®æ½ã、æå¿ã® Google 社å¡ã«ãã¼ã¿å
¥åãæä¼ã£ã¦ãããã¾ãã。ãã®çµæ、ç´ 4 ä¸ 6000 件ã®è¨ç·´ãã¼ã¿ãåéãããã¨ãã§ãã¾ãã。åéããããã¼ã¿ã¯
GitHub ã«ã¦å
¬éãã¦ãã¾ã。ãã¼ã¿æ§é ã®è©³ç´°ã«ã¤ãã¦ã¯
README ãã覧ãã ãã。
ãã¼ã¿ã®åå¦ç
è¨ç·´ã«ä½¿ããã¼ã¿ã¯、以ä¸ã®ãããªå
¥åããããã¼ã®ã·ã¼ã±ã³ã¹ã«ãã£ã¦è¡¨ç¾ããã¾ã。以ä¸ã¯ã²ãããªã®「ã」ãå
¥åãããä¸ä¾ã§、åã¿ãã«ã¯ keydown ã¤ãã³ããçºçãããã¼ã¨çºçããæéãããªç§ã§è¡¨ãã¦ãã¾ã。ããã§ã¯è¤æ°ã®ãã¼ãåæã«æ¼ãããéã® keydown ã¤ãã³ã㨠keyup ã¤ãã³ãã®å¯¾å¿ãç¹å®ããç
©éããé¿ãããã、ããã§ã¯ keydown ã¤ãã³ãã®ã¿ã使ã£ã¦ãã¾ã。
[( "e" , 0 ), ( "d" , 55 ), ( "c" , 102 ), ( "u" , 428 ), ( "j" , 507 )]
ç§ãã¡ã¯ãã®ã·ã¼ã±ã³ã¹ãã¼ã¿ããé«ç²¾åº¦ã«æåãäºæ¸¬ããæ©æ¢°å¦ç¿ã¢ãã«ã模索ãã¾ãã。ãã®éç¨ã§ãã¼ãã¼ãä¸ã§ã®ãã¼ã®ä½ç½®ããã¼ã ã¨æ°ã¥ã、ã·ã¼ã±ã³ã¹ãã¼ã¿ãç»åæ
å ±ã«å¤æãã¦ç³ã¿è¾¼ã¿ãã¥ã¼ã©ã«ãããã¯ã¼ã¯(Convolutional Neural Network)ãé©ç¨ãããã¨ã«ãã¾ãã。以ä¸ã§ã¯、ã·ã¼ã±ã³ã¹ãã¼ã¿ããç»åæ
å ±ãæ½åºããå
·ä½çãªæ¹æ³ã«ã¤ãã¦èª¬æãã¾ã。
ã¾ã、ã·ã¼ã±ã³ã¹ãã¼ã¿ã«å«ã¾ããåãã¼æ
å ±ã JIS ãã¼ãã¼ãã® QWERTY é
åãåæã¨ã㦠x, y 座æ¨æ
å ±ã«å¤æãã¾ã。
QWERTY ãã¼é
å㨠x, y 座æ¨ç³»ã®å¯¾å¿
å
ã»ã©ã®「ã」ã®ä¾ã§ã¯、ã·ã¼ã±ã³ã¹ã以ä¸ã®ããã«å¤æããã¾ã。
[(( 2.5 , 1 ), 0 ), (( 3.0 , 2 ), 55 ), (( 3.5 , 3 ), 102 ), (( 6.5 , 1 ), 428 ), (( 7.0 , 2 ), 507 )]
次ã«、x, y 座æ¨ã«å¯¾ã㦠min-max æ£è¦åãæ½ã、åãã¼ã® x, y 座æ¨ã 0 ãã 1 ã®éã«åãã¾ã。ãã®çµæ、ã·ã¼ã±ã³ã¹ãã¼ã¿ã¯ä»¥ä¸ã®ããã«å¤æããã¾ã。
[(( 0.00 , 0.00 ), 0 ), (( 0.11 , 0.50 ), 55 ), (( 0.22 , 1.00 ), 102 ), (( 0.89 , 0.00 ), 428 ), (( 1.00 , 0.50 ), 507 )]
æå¾ã«、ã·ã¼ã±ã³ã¹å
ã®åç¹ãé ã
ã«ã¤ãªããããã«ãã¦、16px åæ¹ã®æ£æ¹å½¢ã®ãã£ã³ãã¹ã®ä¸ã«æåãã¾ã。
「ã」ãæç»ããä¾
æããã¼ãã¼ãããé¢ããåºéã«ã¤ãã¦ã¯、ã¦ã¼ã¶ã¼ã®æã®åããç¹å¾´éã«çµã¿è¾¼ãããã«ååã®æ¿ãã®ç·ã§æç»ãã¦ãã¾ã [1]。ç©çææ¸ãå
¥åã§ã¯、æããã¼ãã¼ãããé¢ãããã¨ã keydown ã¤ãã³ãããç¹å®ããå¿
è¦ãããã¾ã。ããã§ã¯ keydown ã¤ãã³ããçºçããééã«çç®ã、ãããã¼éã® keydown ã¤ãã³ãã®ééãä»ã®ééãããææã«å¤§ããå ´åã«ã¯æãé¢ãããã®ã¨å¤å®ãã¦ãã¾ã。
MobileNet ã«ããã¢ãã«ã®è»½éå
ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ã¢ãã«ã«ããèªè精度ãåä¸ããããã«ã¯、ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ãå¤å±¤ã«ãã¦è¡¨ç¾åãåä¸ãããã¨ãæå¹ã§ã。ä¸æ¹ã§、ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ãå¤å±¤ã«ããã¨å¦ç¿ãã¹ããã©ã¡ã¼ã¿ã¼ã®æ°ãå¢ãã¦ãã¾ã、ã¢ãã«ã®ãã¡ã¤ã«ãµã¤ãºã大ãããªã£ã¦ãã¾ãã¾ã。å¦ç¿æ¸ã¿ã¢ãã«ã Raspberry Pi Zero ã®ãããªçµã¿è¾¼ã¿åãã¢ã¸ã¥ã¼ã«ã§ä½¿ããã¨ã、ãã©ã¦ã¶ã«ãã¦ã³ãã¼ããã¦ä½¿ããã¨ãèããã¨、ã¢ãã«ã®ãã¡ã¤ã«ãµã¤ãºã大ãããªã£ã¦ãã¾ããã¨ã¯å¥½ã¾ããããã¾ãã。
ããã§ç§ãã¡ã¯ Google ãæå±ãã軽éãªãã¥ã¼ã©ã«ãããã¯ã¼ã¯ã¢ãã«、MobileNet ã«ç¨ãããã¦ããåé¢å¼ç³ã¿è¾¼ã¿å±¤ (separable convolutional layer) ãå¿ç¨ãããã¨ã§ã¢ãã«ã®è»½éåãå³ãã¾ãã。åé¢å¼ç³ã¿è¾¼ã¿å±¤ã¯、ç³ã¿è¾¼ã¿æ¼ç®ã空éæ¹åã®ç³ã¿è¾¼ã¿ (depth-wise convolution) ã¨ãã£ã³ãã«æ¹åã®ç³ã¿è¾¼ã¿ (point-wise convolution) ã«åãããã¨ã«ãã£ã¦、å¦ç¿ãããã©ã¡ã¼ã¿ã¼ã®æ°ãæ¸ããã¾ã [2]。åé¢å¼ç³ã¿è¾¼ã¿å±¤ã使ããã¨ã«ãã£ã¦、é常ã®ç³ã¿è¾¼ã¿å±¤ã«ããå®è£
ã§ã¯æ° MB ã«ãªã£ã¦ãã¾ãã¢ãã«ã®ãã¡ã¤ã«ãµã¤ãºã、åç¨åº¦ã®ç²¾åº¦ãç¶æããªããã 150 ãããã¤ãç¨åº¦ã«ã¾ã§æ¸ãããã¨ãã§ãã¾ãã。ããã«ãã、å¾è¿°ãããã¼ãã¦ã§ã¢ã¨ãã©ã¦ã¶ã§ã®é«éãªã¢ãã«ã®èªã¿è¾¼ã¿ãå¯è½ã«ãªãã¾ãã。
ãã¡ã¤ã³ç¥èã®æ´»ç¨
ä¸è¨ã®æ¹æ³ã ãã§ãæåãèªèããæ©æ¢°å¦ç¿ã¢ãã«ãæ§ç¯ã§ãããã®ã®、精度ã®é¢ã§èª²é¡ãæ®ãã¾ãã。ãã¨ãã°、åç´ã«ã¹ããã¼ã¯ãç»åæ
å ±ã«å¤æããã ãã§ã¯、å³ããå·¦ã«æ¸ãããç·ã¨、å·¦ããå³ã«æ¸ãããç·ãåºå¥ã§ããªããªãã¾ã。ã¾ã、ãã¼ãã¼ãããä¸ããããä½ç½®æ
å ±ã¯ä½è§£å度ã®ãã、æ¬æ¥ã¯ç°ãªãç·ãéãªã£ã¦æåããã¦ãã¾ããã¨ããã°ãã°ã§ã。ãããã£ããã¼ã¿ã®åå¦çã§è½ã¡ã¦ãã¾ãæ
å ±ãåå ã¨ãªã£ã¦、æºè¶³ãã精度ãéæãããã¨ãã§ãã¾ããã§ãã。ããã§ã¯、ãããã®èª²é¡ã解決ããããã«å°å
¥ãã工夫ãç´¹ä»ãã¾ã。
ã¾ã、ç§ãã¡ã¯æåãæ§æããç·ã 8 æ¹åã«å解ããæ¹åå解ç¹å¾´ (directional feature) ãå°å
¥ãã¾ãã。æ¹åå解ç¹å¾´ã¯ææ¸ãæåèªèã«ãããéè¦ãªãã¡ã¤ã³ç¥èã®ã²ã¨ã¤ã§ãã、å
¥åãã¼ã¿ãã¹ãã¼ã¹ã«ãããã¨ã§å°ããªç»åã®ä¸ã«ãå¹ççã«æ
å ±ãä¿æã§ãããã¨ãç¥ããã¦ãã¾ã [1]。ç§ãã¡ã¯、åä¸ã®ãã£ã³ãã«ã«ç»åæ
å ±ãå¤æããã®ã§ã¯ãªã、æ¹åå解ãæ½ããã¨ã§ 8 ãã£ã³ãã«ã®ç»åã«å¤æããã¢ããã¼ããæ¡ç¨ãã¾ãã。
「ã」ã¨æ¸ãããã¹ããã¼ã¯ã®æ¹åå解ç¹å¾´
æ¹åå解ç¹å¾´ãæ¡ç¨ãã¦ã、ä½è§£å度ã®ããã«éãªã£ã¦ãã¾ãç·ã«ã¤ãã¦ã¯èª²é¡ãæ®ãã¾ãã。ãã¨ãã°「ã¯」ã¨「ã»」ã¯ç»æ°ãç°ãªããã®ã®、「ã»」ã® 3 ç»ç®ã 2 ç»ç®ã¨éãªã£ã¦ãã¾ããã¨ãå¤ã観測ããã¾ãã。ãã®ãããªèª²é¡ã解決ããããã«ã¯、æ¸ãå§ãããæ¸ãçµããã¾ã§ã®ã©ã®ã¿ã¤ãã³ã°ã§ç·ãæ¸ãããã®ã、ã¨ããæ
å ±ãæå¹ã«åãã¨èãã¾ãã。
ããã§å°å
¥ããã®ãæéçç¹å¾´(temporal feature)ã§ã。æ¹åå解ç¹å¾´ã表ã 8 ãã£ã³ãã«ã«å ãã¦、ã ãã ãç·ãèããªãç»åã¨ã ãã ãç·ãæ¿ããªãç»åãå ãããã¨ã§、å
¨ä½çãªæéå¤åã表ããç¹å¾´ãå°å
¥ãã¾ãã。æ¢åã® 8 ãã£ã³ãã«ã«å ãã¦ãã® 2 ãã£ã³ãã«ãå ãããã¨ã§、ãããªã精度åä¸ãå®ç¾ãã¾ãã。
「ã」ã¨æ¸ãããã¹ããã¼ã¯ã®æéçç¹å¾´
ä¸å³ã«、åç¹å¾´éãå©ç¨ããã¨ãã®æ£ç¢ºåº¦ã®æ¯è¼ã示ãã¾ã。æ¹åå解ç¹å¾´、æéçç¹å¾´ã¨ãã«æåèªè精度ã®åä¸ã«å¹æããããã¨ã確ããããã¾ãã。æ¹åå解ç¹å¾´ãçã®åãã表ããã¨ã§å±æçãªæéæ
å ±ãçµã¿è¾¼ã¿、æéçç¹å¾´ãæ¸ãå§ãããæ¸ãçµããã¾ã§ã®å¤åã表ããã¨ã§å¤§åçãªæéæ
å ±ãçµã¿è¾¼ããã¨ã§、精度åä¸ã«è²¢ç®ãã¦ããã¨èãããã¾ã。
確èªç¨ãã¼ã¿ã»ããã«ãããåç¹å¾´éã®æç¡ã«ããæ£ç¢ºåº¦ã®æ¯è¼
以ä¸ã®ç¹å¾´éãå°å
¥ããçµæ、æçµçãªæ©æ¢°å¦ç¿ã¢ãã«ã¯ 16px åæ¹ã®æ£æ¹å½¢ã®ãã£ã³ãã¹ã«å¯¾ã㦠8 ã¤ã®æ¹åå解ç¹å¾´ã¨ 2 ã¤ã®æéçç¹å¾´ãæç»ããè¨ 10 ãã£ã³ãã«ãããªãç»åãå
¥åã¨ãã¦åãåããã®ã«ãªãã¾ãã。MobileNet ã®ãããã¯ã¼ã¯æ§æãå
ã«ãã¦、ã§ããã ãå°ãªã層ã®æ°ã§é«ã精度ãå®ç¾ããæ§æã模索ããçµæ、以ä¸ã®ãããã¯ã¼ã¯æ§æã«è³ãã¾ãã。
ç³ã¿è¾¼ã¿å±¤(ã«ã¼ãã«: 3x3、ãã£ã«ã¿æ°: 32、ã¹ãã©ã¤ã: 2、æ´»æ§åé¢æ°: Relu)
åé¢å¼ç³ã¿è¾¼ã¿å±¤(ã«ã¼ãã«: 3x3、ãã£ã«ã¿æ°: 64、ã¹ãã©ã¤ã: 1、æ´»æ§åé¢æ°: Relu)
åé¢å¼ç³ã¿è¾¼ã¿å±¤(ã«ã¼ãã«: 3x3、ãã£ã«ã¿æ°: 128、ã¹ãã©ã¤ã: 2、æ´»æ§åé¢æ°: Relu)
åé¢å¼ç³ã¿è¾¼ã¿å±¤(ã«ã¼ãã«: 3x3、ãã£ã«ã¿æ°: 128、ã¹ãã©ã¤ã: 1、æ´»æ§åé¢æ°: Relu)
å
¨çµå層
ä»åã®è¨ç·´ç¨ããã°ã©ã ã¯
nazoru-input ããã±ã¼ã¸ ã¨ã㦠PyPi ã§å
¬éããã¦ãã¾ã。以ä¸ã®ããã«
nazoru-input ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã、è¨ç·´ãã¼ã¿ãæå®ãã¦
nazoru-training ã³ãã³ããå®è¡ãããã¨ã§、ãæå
ã®ç°å¢ã§ãæ©æ¢°å¦ç¿ã¢ãã«ãæ§ç¯ã§ãã¾ã。ä»åç¨ããè¨ç·´ãã¼ã¿ã¯
https://github.com/google/mozc-devices/raw/master/mozc-nazoru/data/strokes.zip ãããã¦ã³ãã¼ãã§ãã¾ã。
$ pip install nazoru - input
$ nazoru - training ./ data / strokes . zip
ãã®
nazoru-training ã¯æ¨æºç㪠TensorFlow ã® API ãå©ç¨ãã¦å®è£
ããã¦ãã¾ãã®ã§、ç°¡åã«ã«ã¹ã¿ãã¤ãºãã¦å©ç¨ãã¦ããã ãã¾ã。ãã¤ãã¼ãã©ã¡ã¼ã¿ã¼ãå
¥åãã¼ã¿ã»ãããã³ãã³ãã©ã¤ã³ãªãã·ã§ã³ã§å¤æ´ãããã¨ãå¯è½ã§ã。詳ããã¯
nazoru-training --help ã³ãã³ããåç
§ãã¦ãã ãã。
ãã¼ãã¦ã§ã¢ã§ã®æ¨è«
ãã®ããã«ãã¦æ§ç¯ããæ©æ¢°å¦ç¿ã¢ãã«ãã¦ã¼ã¶ã¼ãæ軽ã«ä½¿ããããã«ããã«ã¯ã©ãããã°ããã、ãã¼ã å
ã§æ´»çºãªè°è«ããªããã¾ãã。ãã½ã³ã³ãã¹ãã¼ããã©ã³ã«ç¹å¥ãªã½ããã¦ã§ã¢ãã¤ã³ã¹ãã¼ã«ãããã¨ãªããæ°ã«å
¥ãã®ãã¼ãã¼ãã§ããã«ç©çææ¸ãå
¥åã使ããããã«ãããã、ç§ãã¡ã¯å¦ç¿æ¸ã¿ã¢ãã«ãçµã¿è¾¼ãã ãã¼ãã¦ã§ã¢「ç©çææ¸ãã³ã³ãã¼ã¿ã¼」ã製ä½ãããã¨ã«ãã¾ãã。ãã®ç©çææ¸ãã³ã³ãã¼ã¿ã¼ã¯、è¨ç·´æ¸ã¿ã¢ãã«ã使ã£ã¦æ¨è«ããããã°ã©ã ã Raspberry Pi Zero ã«ã¤ã³ã¹ãã¼ã«ãããã®ã§ã。ããã§ã¯、ç©çææ¸ãã³ã³ãã¼ã¿ã¼ãæ§ç¯ããæé ã説æãã¾ã。
æ¨è«ç¨ããã°ã©ã ã¯è¨ç·´ç¨ããã°ã©ã ã¨åæ§ã«
nazoru-input ããã±ã¼ã¸ ã«å«ã¾ãã¦ãã¾ã。
nazoru-input ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã
nazoru-input ã³ãã³ããå®è¡ãããã¨ã§、ãææã¡ã®ã³ã³ãã¥ã¼ã¿ãã¤ãã£ã¦ç°¡åã«ç©çææ¸ãå
¥åã試ããã¨ãã§ãã¾ã。
$ pip install nazoru - input
$ nazoru - input
æ¨è«ã®æ©è½ãæ軽ã«æ¡å¼µãã¦éãã§ããã ããããã«、API ãã·ã³ãã«ã«ãã¦ããã¾ã。以ä¸ã®ãããªã³ã¼ããæ¸ãã ãã§å¦ç¿æ¸ã¿ã¢ãã«ãå©ç¨ããæ¨è«ãã§ãã¾ã。詳ããã¯
nazoru-input ã®ã³ã¼ã ãåèã«ãã¦ãã ãã。
from nazoru import get_default_graph_path
from nazoru . core import NazoruPredictor
predictor = NazoruPredictor ( get_default_graph_path ())
# [(key, ms_from_first_input)]
sample_input = [( 'e' , 0 ), ( 'd' , 100 ), ( 'c' , 200 ), ( 'v' , 300 ),
( 'u' , 800 ), ( 'j' , 900 )]
results = predictor . predict_top_n ( sample_input , 5 )
for result in results :
print ( 'kana: %s, key: %s, probability: %.3f' % result )
ç©çææ¸ãã³ã³ãã¼ã¿ã¼ã¯ Raspberry Pi Zero ã«
nazoru-input ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã、USB ã§æ¥ç¶ããããã¼ãã¼ãããåãåã£ããã¼æ
å ±ãæ¨è«ããã°ã©ã ã«ãã£ã¦æåã«å¤æ、Bluetooth ã§åºåãããã¨ã«ãã£ã¦å®è£
ããã¦ãã¾ã。ãã®ãã¡、ãã¼å
¥åããæåã«å¤æããé¨åã¯åºæ¿ããªãã¦ãã試ãããã ããã®ã§、ã家åºã«ãã Raspberry Pi ã«
nazoru-input ããã±ã¼ã¸ãå
¥ããã ãã§æ軽ã«ææ¸ãæ©è½ãå©ç¨ããããã°ã©ã ãå®è£
ãããã¨ãã§ãã¾ã。
ã¾ã、ä»åã¯ç©çææ¸ãã³ã³ãã¼ã¿ã¼ã®ããã«è£½ä½ããåºæ¿ã®è¨è¨å³ã®
CAD ãã¼ã¿ ãå
¬éãã¾ãã。ãã®åºæ¿ã«ã¯ Bluetooth éä¿¡ã®ããã®ã¢ã¸ã¥ã¼ã«ãã¹ãã¼ã¿ã¹è¡¨ç¤ºã®ããã® LED ãæè¼ããã¦ãã、Raspberry Pi ã«æ¥ç¶ãããã¨ã§ãã½ã³ã³ãã¹ãã¼ããã©ã³ã« Bluetooth ãéãã¦æåãéä¿¡ãããã¨ãå¯è½ã«ãªãã¾ã。å©ç¨ããé¨å㯠Raspberry Pi Zero ã RN42 ã¨ãã£ãé販ãåºé ã§è³¼å
¥ã§ãããã®ã«éå®ãã¾ãã。Raspberry Pi Zero ãå©ç¨ãããã¨ã§å¤§ããã®å¶ç´ãå°ãããã¾ããã®ã§、ãã¾ãã¾ãªå½¢ç¶ã®ããã¤ã¹ã«çµã¿è¾¼ããã¨ãå¯è½ã§ã。CAD ãã¼ã¿ãç·¨éãããã¨ã§、èªç±ã«æ©è½ãå¤æ´、追å ããåºæ¿ãä½è£½å¯è½ã§ã。
ããã«、å
¬éããã¦ããåºæ¿ã«ã¯æ¡å¼µæ§ãããããããã«æªæ¥ç¶ã®ããã、SPI・I2C æ¥ç¶ç¨ã®ã³ãã¯ã¿、UART ã®ããã®åæå¯è½ãªãã¿ã¼ã³ãç¨æãã¦ããã¾ã。ããã«ãã、ã¢ã¼ãåãæ¿ãã¹ã¤ãããå®è£
ããã、SPI・I2C æ¥ç¶ã®ãã£ã¹ãã¬ã¤ã«ãã£ã¦è»è·¡ã表示ãããªã©ã®æ¡å¼µãå¯è½ã§ã。
ç©çææ¸ãã³ã³ãã¼ã¿ã¼ã®ããªã³ãåºæ¿å³é¢
ãã©ã¦ã¶ã§ã®æ¨è«
ãæå
ã«ç©çææ¸ãã³ã³ãã¼ã¿ã¼ããªãçãã¾ã«ããæ軽ã«ç©çææ¸ãå
¥åã楽ããã§ããã ããã、ç§ãã¡ã¯ãã©ã¦ã¶ä¸ã§æ©æ¢°å¦ç¿ã¢ãã«ãåä½ãããã¢ãæ§ç¯ãã¾ãã。TensorFlow ã§å¦ç¿ããã¢ãã«ã
TensorFlow.js ã«ç§»æ¤ãããã¨ã§ãã©ã¦ã¶ä¸ã§ã®æ¨è«ãå®ç¾ãã¦ãã¾ã。
è¨ç·´ç¨ããã°ã©ã
nazoru-training ã¯è¨ç·´æ¸ã¿ã¢ãã«ã SavedModel å½¢å¼ã§åºåãã¾ã。SavedModel å½¢å¼ã§ä¿åãããè¨ç·´æ¸ã¿ã¢ãã«ã TensorFlow.js ã§èªã¿è¾¼ãã«ã¯、
TensorFlow.js converter ã使ã£ã¦ Web-friendly format ã«å¤æããå¿
è¦ãããã¾ã。TensorFlow.js converter ã¯å¤æã®ããã®ã¹ã¯ãªããã¨、å¤ææ¸ã¿ã¢ãã«ãèªã¿è¾¼ã Javascript API ãæä¾ããã©ã¤ãã©ãªã§ã。以ä¸ã®ã³ãã³ãã®ããã« tensorflowjs ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ãã¦
tensorflowjs_converter ã³ãã³ããå®è¡ãããã¨ã§、è¨ç·´æ¸ã¿ã¢ãã«ãå¤æãã¾ã。ãã®é、å¤æããã¢ãã«ã®å½¢å¼(ãã®å ´å㯠SavedModel ãªã®ã§ tf_saved_model)、åºå層ã«ç¸å½ãããã¼ãã®åå(
nazoru-training ã®ããã©ã«ãè¨å®ã§ã¯
Nazorunet/Predictions/Reshape_1 )ãæå®ãã¾ã。
$ pip install tensorflowjs
$ tensorflowjs_converter \
-- input_format = tf_saved_model \
-- output_node_names = 'Nazorunet/Predictions/Reshape_1' \
/ nazorunet / saved_model \
/ nazorunet / web_model
å¤æãæåããã¨、tensorflowjs_converter ã¯ä»¥ä¸ã® 3 種é¡ã®ãã¡ã¤ã«ãåºåãã¾ã。
web_model.pb (the dataflow graph)
weights_manifest.json (weight manifest file)
group1-shard\*of\* (collection of binary weight files)
ãããã¯ã¼ã¯ãæ§æããåãã©ã¡ã¼ã¿ã¼ã®éã¿ã¯ group1-shard\*of\* ã«è¨è¿°ãã、ã¢ãã«ã®å¤§ããã«å¿ãã¦åãã¡ã¤ã«ã 4MB ã«åã¾ãããã«ã·ã£ã¼ãã£ã³ã°ããã¾ã。ãã®å·¥å¤«ã«ãã、ãã©ã¦ã¶ã«ãããã¯ã¼ã¯ãã¡ã¤ã«ããã£ãã·ã¥ããã¾ã。
ãã¨ã¯
tfjs-converter npm ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã、以ä¸ã®ããã«ã¢ãã«ãèªã¿è¾¼ãã°ãã©ã¦ã¶ã§ã®æ¨è«ãã§ãã¾ã。
import * as tfc from '@tensorflow/tfjs-core' ;
import { loadFrozenModel } from '@tensorflow/tfjs-converter' ;
const model = await loadFrozenModel (
'/nazorunet/web_model.pb' ,
'/nazorunet/weights_manifest.json' );
// Gets a canvas or image element.
const inputImage = document . getElementById ( 'input-image' );
const result = model . execute ({ input : tfc . fromPixels ( inputImage )});
// Returns predicted probabilities for each class in a float array.
const probs = result . dataSync ();
console . log ( probs ) // Float32Array(88) [...]
ã¢ããªã±ã¼ã·ã§ã³ã«ãã£ã¦ã¯ãã©ã¦ã¶ä¸ã§é«é »åº¦ã§æ¨è«ãç¹°ãè¿ããã¨ãèãããããã、TensorFlow.js ã¯å¹ççã«ã¡ã¢ãªã管çããããã®ä¾¿å©ãªã¡ã½ãããç¨æãã¦ãã¾ã。詳ããã¯
Core Concepts in TensorFlow.js ããåç
§ãã ãã。
ã¾ã¨ã
以ä¸、Gboard ç©çææ¸ãå
¥åãã¼ã¸ã§ã³ãæ¯ããæ©æ¢°å¦ç¿æè¡ãç´¹ä»ãã¾ãã。
「æ©æ¢°å¦ç¿ã¢ãã«ã®æ§ç¯」ã§ã¯、å¹ççã«è¨ç·´ãã¼ã¿ãåéããä»çµã¿ã®éè¦æ§ã«ã¤ãã¦è¿°ã¹ã¾ãã。ããã¾ã§ã«ãªãã¿ã¹ã¯ã«åãçµãå ´å、ããããå¦ç¿ã®ããã®ãã¼ã¿ããªãå ´é¢ãçããããã¾ãã。ãã®ãããªå ´å、ãã¼ã¿åéãå¹ççã«è¡ãããã®ä»çµã¿ã¥ãã、ã¤ã³ã¿ã¼ãã§ã¤ã¹ã®æ§ç¯ãéè¦ã«ãªãã¾ã。
ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ãå¤å±¤ã«ãã¦è¡¨ç¾åãè±ãã«ãããã¨ããã¾ãã¾ãªã¿ã¹ã¯ã解ãä¸ã§æåã§ããä¸æ¹、æ©æ¢°å¦ç¿å¿ç¨ã®å ´ã Raspberry Pi ãã¯ããã¨ããå°åè¨ç®æ©ããã©ã¦ã¶ãªã©ã«åºãã£ã¦ãããã¨ãèããã¨、é«ã精度ãä¿æããªãããã§ããã ã軽éã§ã·ã³ãã«ãªæ©æ¢°å¦ç¿ã¢ãã«ãæ§ç¯ãããã¨ã¯ç¡è¦ã§ããªã課é¡ã§ã。MobileNet ãã¯ããã¨ãã軽éã®ãããã¯ã¼ã¯ã¢ãã«ãæ¡ç¨ãããã¨、ãã¼ã¿ã®åå¦çã«é©åãªãã¡ã¤ã³ç¥èãæ´»ç¨ãã¦ã¢ãã«ã®ãµã¤ãºãä¿æããªããã精度ãåä¸ãããã¨ã、ãã®ãããªèª²é¡ã«å¿ããä¸ã§æå¹ã§ãããã¨ã示ãã¾ãã。
「ãã¼ãã¦ã§ã¢ã§ã®æ¨è«」ã§ã¯、ä»åæ§ç¯ããæ©æ¢°å¦ç¿ã¢ãã«ã«ããæ¨è«ã®æ¹æ³ã説æãã¾ãã。Raspberry Pi ã使ã£ãããã¤ã¹ã®æ¡å¼µæ¹æ³ã«ã¤ãã¦ãè¿°ã¹、æ¨è«ããã°ã©ã ã«åããã¦ããã¤ã¹ã®æ¯ãèããã«ã¹ã¿ãã¤ãºããæ¹æ³ãç´¹ä»ãã¾ãã。
「ãã©ã¦ã¶ã§ã®æ¨è«」ã§ã¯、TensorFlow.js ã使ã£ã¦ãã©ã¦ã¶ã§æ¨è«ããæ¹æ³ã説æãã¾ãã。TensorFlow.js Converter ã使ããã¨ã§ç°¡åã«è¨ç·´æ¸ã¿ã¢ãã«ã®ç§»æ¤ãã§ãããã¨、å
·ä½ç㪠Javascript API ã®ä½¿ç¨æ¹æ³ã«ã¤ãã¦è¿°ã¹ã¾ãã。
ä»åã®è¨äºã、ãã¾ãã¾ãªãã©ãããã©ã¼ã ããµãã¼ãããæ©æ¢°å¦ç¿ã·ã¹ãã æ§ç¯ã®åèã¨ãªãã°å¹¸ãã§ã。ããã¦、Gboard ç©çææ¸ããã¼ã¸ã§ã³ãä»å¾ã®æåå
¥åã®ããã¡ã¯ã・ã¹ã¿ã³ãã¼ãã«ãªãæ¥ããããã¨ãé¡ãã¾ã。
åèæç®
[1] Zhang, Xu-Yao, Yoshua Bengio, and Cheng-Lin Liu. "Online and offline handwritten chinese character recognition: A comprehensive study and new benchmark." Pattern Recognition 61 (2017): 348-360.
[2] Howard, Andrew G., et al. "Mobilenets: Efficient convolutional neural networks for mobile vision applications." arXiv preprint arXiv:1704.04861 (2017).
Written by:
-
Shuhei Iitsuka - UX Engineer (Machine learning)
-
Makoto Shimazu - Software Engineer (Hardware, System design)
Google æ¥æ¬èªå
¥åãã¼ã ã¯、4 æ 1 æ¥ã« Gboard ç©çææ¸ããã¼ã¸ã§ã³ ãçºè¡¨ãã¾ãã。ãã¼ãã¼ãã®ä¸ã«æ¸ãããæåãèå¥ãããã¨ã§、å¾æ¥ã®ãã¼ãã¼ãã®ä½¿ãæ¹ã«åãããªãç´æçãªæåå
¥åãå®ç¾ãã¾ã。ããããã§ãã¼ãã¼ãä¸ã®ãã¼ãæ¢ãã¦ãã¼ã¨ãªã ãã¨ã¯ããã¾ãã。
ãã®è£½åã®è£å´ã«ã¯、ã¾ãã¾ãã®ç²¾åº¦ã®æåèªèãå®ç¾ããæ©æ¢°å¦ç¿æè¡ãæ´»ç¨ããã¦ãã¾ã。ä¸å³ã«、ä»åæ§ç¯ããæ©æ¢°å¦ç¿ã·ã¹ãã ã®æ¦è¦ã示ãã¾ã。æ¬è¨äºã§ã¯ Gboard ç©çææ¸ããã¼ã¸ã§ã³ã«å©ç¨ããã¦ããæ©æ¢°å¦ç¿æè¡ã«ã¤ãã¦、「æ©æ¢°å¦ç¿ã¢ãã«ã®æ§ç¯」「ãã¼ãã¦ã§ã¢ã§ã®æ¨è«」「ãã©ã¦ã¶ã§ã®æ¨è«」ã¨é ã追ã£ã¦ç´¹ä»ãã¦ããã¾ã。
ã·ã¹ãã ã®æ¦è¦å³
æ©æ¢°å¦ç¿ã¢ãã«ã®æ§ç¯
è¨ç·´ãã¼ã¿ã®åé
ä»åç§ãã¡ãç«ã¡åããã¿ã¹ã¯ã¯、å
¥åããããã¼ã®ã·ã¼ã±ã³ã¹ããã¦ã¼ã¶ã¼ãæå³ããæåãäºæ¸¬ãããã¨ã§ã。ãªã³ã©ã¤ã³ææ¸ãæåèªèã«ä¼¼ãã¿ã¹ã¯ã§ã¯ãããã®ã®、ãã®å¤ãã¯ãã³ã¿ãã¬ãããã¿ããã¹ã¯ãªã¼ã³ã§ã®å
¥åãåæã¨ãã¦ãã¾ã。ãã®ãã、ãã¼ãã¼ãã®ããã«ä½è§£å度ã®å
¥åã«å¯¾å¿ããæ©æ¢°å¦ç¿ã¢ãã«ãæ§ç¯ããããã«ã¯、ä¸ããè¨ç·´ãã¼ã¿ãåéããå¿
è¦ãããã¾ãã。
ãã¼ã¿ãåéãããã、ç§ãã¡ã¯ã¾ããã¼ã¿åéç¨ã®ã¦ã§ãã¢ããªãã¤ãããã¨ããå§ãã¾ãã。å
¥åããæåãæå®ãã¦ãã¼ãã¼ãä¸ã«ãã®æåãæ¸ããã¨ã§、å
¥åããããã¼ã®ã·ã¼ã±ã³ã¹ãä¿åãããã·ã³ãã«ãªã¢ããªã§ã。å¹ççãªãã¼ã¿åéã®ããã«、æ
£ããæ¹ã«ã¯ç»é¢ãã¿ãããããã¨ã§å
¥åçµäºãå¤å®ããå¾
ã¡æéãã¹ãããããæ©è½ãæè¼ãã¾ãã。ãã®çµæ、ããç´ã®æ¹ã«ãªã㨠1 åéãããç´ 60 åã®ãã¼ã¿ãå
¥åãããã¨ãå¯è½ã«ãªã、é«éãªãã¼ã¿åéãå¯è½ã«ãªãã¾ãã。
人æã«ãããã¼ã¿å
¥åã«ã¯ãã¹ãã¤ããã®ã§ã。ç°å¸¸ãªãã¼ã¿ããã°ããè¦ã¤ãã¦åãé¤ãããã、å
¥åã·ã¼ã±ã³ã¹ã®å¯è¦åã¤ã³ã¿ã¼ãã§ã¤ã¹ãå®è£
ãã¾ãã。ä»ã«ãå
¥åãã¼ã¿æ°ã«ãã Contributor ã©ã³ãã³ã°ãåæåã®ç´¯è¨ãã¼ã¿æ°ã®è¡¨ç¤ºãªã©、ãã¼ã¿ã®å
¥åãã¢ããã¼ãããç´°ããªä»çµã¿ãæè¼ãã¦ãã¾ã。
ãªãªã¼ã¹åã«ã¯ç¤¾å
ã§çè·¡ãã¼ã¿åéä¼ãå®æ½ã、æå¿ã® Google 社å¡ã«ãã¼ã¿å
¥åãæä¼ã£ã¦ãããã¾ãã。ãã®çµæ、ç´ 4 ä¸ 6000 件ã®è¨ç·´ãã¼ã¿ãåéãããã¨ãã§ãã¾ãã。åéããããã¼ã¿ã¯ GitHub ã«ã¦å
¬éãã¦ãã¾ã。ãã¼ã¿æ§é ã®è©³ç´°ã«ã¤ãã¦ã¯ README ãã覧ãã ãã。
ãã¼ã¿ã®åå¦ç
è¨ç·´ã«ä½¿ããã¼ã¿ã¯、以ä¸ã®ãããªå
¥åããããã¼ã®ã·ã¼ã±ã³ã¹ã«ãã£ã¦è¡¨ç¾ããã¾ã。以ä¸ã¯ã²ãããªã®「ã」ãå
¥åãããä¸ä¾ã§、åã¿ãã«ã¯ keydown ã¤ãã³ããçºçãããã¼ã¨çºçããæéãããªç§ã§è¡¨ãã¦ãã¾ã。ããã§ã¯è¤æ°ã®ãã¼ãåæã«æ¼ãããéã® keydown ã¤ãã³ã㨠keyup ã¤ãã³ãã®å¯¾å¿ãç¹å®ããç
©éããé¿ãããã、ããã§ã¯ keydown ã¤ãã³ãã®ã¿ã使ã£ã¦ãã¾ã。
[( "e" , 0 ), ( "d" , 55 ), ( "c" , 102 ), ( "u" , 428 ), ( "j" , 507 )]
ç§ãã¡ã¯ãã®ã·ã¼ã±ã³ã¹ãã¼ã¿ããé«ç²¾åº¦ã«æåãäºæ¸¬ããæ©æ¢°å¦ç¿ã¢ãã«ã模索ãã¾ãã。ãã®éç¨ã§ãã¼ãã¼ãä¸ã§ã®ãã¼ã®ä½ç½®ããã¼ã ã¨æ°ã¥ã、ã·ã¼ã±ã³ã¹ãã¼ã¿ãç»åæ
å ±ã«å¤æãã¦ç³ã¿è¾¼ã¿ãã¥ã¼ã©ã«ãããã¯ã¼ã¯(Convolutional Neural Network)ãé©ç¨ãããã¨ã«ãã¾ãã。以ä¸ã§ã¯、ã·ã¼ã±ã³ã¹ãã¼ã¿ããç»åæ
å ±ãæ½åºããå
·ä½çãªæ¹æ³ã«ã¤ãã¦èª¬æãã¾ã。
ã¾ã、ã·ã¼ã±ã³ã¹ãã¼ã¿ã«å«ã¾ããåãã¼æ
å ±ã JIS ãã¼ãã¼ãã® QWERTY é
åãåæã¨ã㦠x, y 座æ¨æ
å ±ã«å¤æãã¾ã。
QWERTY ãã¼é
å㨠x, y 座æ¨ç³»ã®å¯¾å¿
å
ã»ã©ã®「ã」ã®ä¾ã§ã¯、ã·ã¼ã±ã³ã¹ã以ä¸ã®ããã«å¤æããã¾ã。
[(( 2.5 , 1 ), 0 ), (( 3.0 , 2 ), 55 ), (( 3.5 , 3 ), 102 ), (( 6.5 , 1 ), 428 ), (( 7.0 , 2 ), 507 )]
次ã«、x, y 座æ¨ã«å¯¾ã㦠min-max æ£è¦åãæ½ã、åãã¼ã® x, y 座æ¨ã 0 ãã 1 ã®éã«åãã¾ã。ãã®çµæ、ã·ã¼ã±ã³ã¹ãã¼ã¿ã¯ä»¥ä¸ã®ããã«å¤æããã¾ã。
[(( 0.00 , 0.00 ), 0 ), (( 0.11 , 0.50 ), 55 ), (( 0.22 , 1.00 ), 102 ), (( 0.89 , 0.00 ), 428 ), (( 1.00 , 0.50 ), 507 )]
æå¾ã«、ã·ã¼ã±ã³ã¹å
ã®åç¹ãé ã
ã«ã¤ãªããããã«ãã¦、16px åæ¹ã®æ£æ¹å½¢ã®ãã£ã³ãã¹ã®ä¸ã«æåãã¾ã。
「ã」ãæç»ããä¾
æããã¼ãã¼ãããé¢ããåºéã«ã¤ãã¦ã¯、ã¦ã¼ã¶ã¼ã®æã®åããç¹å¾´éã«çµã¿è¾¼ãããã«ååã®æ¿ãã®ç·ã§æç»ãã¦ãã¾ã [1]。ç©çææ¸ãå
¥åã§ã¯、æããã¼ãã¼ãããé¢ãããã¨ã keydown ã¤ãã³ãããç¹å®ããå¿
è¦ãããã¾ã。ããã§ã¯ keydown ã¤ãã³ããçºçããééã«çç®ã、ãããã¼éã® keydown ã¤ãã³ãã®ééãä»ã®ééãããææã«å¤§ããå ´åã«ã¯æãé¢ãããã®ã¨å¤å®ãã¦ãã¾ã。
MobileNet ã«ããã¢ãã«ã®è»½éå
ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ã¢ãã«ã«ããèªè精度ãåä¸ããããã«ã¯、ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ãå¤å±¤ã«ãã¦è¡¨ç¾åãåä¸ãããã¨ãæå¹ã§ã。ä¸æ¹ã§、ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ãå¤å±¤ã«ããã¨å¦ç¿ãã¹ããã©ã¡ã¼ã¿ã¼ã®æ°ãå¢ãã¦ãã¾ã、ã¢ãã«ã®ãã¡ã¤ã«ãµã¤ãºã大ãããªã£ã¦ãã¾ãã¾ã。å¦ç¿æ¸ã¿ã¢ãã«ã Raspberry Pi Zero ã®ãããªçµã¿è¾¼ã¿åãã¢ã¸ã¥ã¼ã«ã§ä½¿ããã¨ã、ãã©ã¦ã¶ã«ãã¦ã³ãã¼ããã¦ä½¿ããã¨ãèããã¨、ã¢ãã«ã®ãã¡ã¤ã«ãµã¤ãºã大ãããªã£ã¦ãã¾ããã¨ã¯å¥½ã¾ããããã¾ãã。
ããã§ç§ãã¡ã¯ Google ãæå±ãã軽éãªãã¥ã¼ã©ã«ãããã¯ã¼ã¯ã¢ãã«、MobileNet ã«ç¨ãããã¦ããåé¢å¼ç³ã¿è¾¼ã¿å±¤ (separable convolutional layer) ãå¿ç¨ãããã¨ã§ã¢ãã«ã®è»½éåãå³ãã¾ãã。åé¢å¼ç³ã¿è¾¼ã¿å±¤ã¯、ç³ã¿è¾¼ã¿æ¼ç®ã空éæ¹åã®ç³ã¿è¾¼ã¿ (depth-wise convolution) ã¨ãã£ã³ãã«æ¹åã®ç³ã¿è¾¼ã¿ (point-wise convolution) ã«åãããã¨ã«ãã£ã¦、å¦ç¿ãããã©ã¡ã¼ã¿ã¼ã®æ°ãæ¸ããã¾ã [2]。åé¢å¼ç³ã¿è¾¼ã¿å±¤ã使ããã¨ã«ãã£ã¦、é常ã®ç³ã¿è¾¼ã¿å±¤ã«ããå®è£
ã§ã¯æ° MB ã«ãªã£ã¦ãã¾ãã¢ãã«ã®ãã¡ã¤ã«ãµã¤ãºã、åç¨åº¦ã®ç²¾åº¦ãç¶æããªããã 150 ãããã¤ãç¨åº¦ã«ã¾ã§æ¸ãããã¨ãã§ãã¾ãã。ããã«ãã、å¾è¿°ãããã¼ãã¦ã§ã¢ã¨ãã©ã¦ã¶ã§ã®é«éãªã¢ãã«ã®èªã¿è¾¼ã¿ãå¯è½ã«ãªãã¾ãã。
ãã¡ã¤ã³ç¥èã®æ´»ç¨
ä¸è¨ã®æ¹æ³ã ãã§ãæåãèªèããæ©æ¢°å¦ç¿ã¢ãã«ãæ§ç¯ã§ãããã®ã®、精度ã®é¢ã§èª²é¡ãæ®ãã¾ãã。ãã¨ãã°、åç´ã«ã¹ããã¼ã¯ãç»åæ
å ±ã«å¤æããã ãã§ã¯、å³ããå·¦ã«æ¸ãããç·ã¨、å·¦ããå³ã«æ¸ãããç·ãåºå¥ã§ããªããªãã¾ã。ã¾ã、ãã¼ãã¼ãããä¸ããããä½ç½®æ
å ±ã¯ä½è§£å度ã®ãã、æ¬æ¥ã¯ç°ãªãç·ãéãªã£ã¦æåããã¦ãã¾ããã¨ããã°ãã°ã§ã。ãããã£ããã¼ã¿ã®åå¦çã§è½ã¡ã¦ãã¾ãæ
å ±ãåå ã¨ãªã£ã¦、æºè¶³ãã精度ãéæãããã¨ãã§ãã¾ããã§ãã。ããã§ã¯、ãããã®èª²é¡ã解決ããããã«å°å
¥ãã工夫ãç´¹ä»ãã¾ã。
ã¾ã、ç§ãã¡ã¯æåãæ§æããç·ã 8 æ¹åã«å解ããæ¹åå解ç¹å¾´ (directional feature) ãå°å
¥ãã¾ãã。æ¹åå解ç¹å¾´ã¯ææ¸ãæåèªèã«ãããéè¦ãªãã¡ã¤ã³ç¥èã®ã²ã¨ã¤ã§ãã、å
¥åãã¼ã¿ãã¹ãã¼ã¹ã«ãããã¨ã§å°ããªç»åã®ä¸ã«ãå¹ççã«æ
å ±ãä¿æã§ãããã¨ãç¥ããã¦ãã¾ã [1]。ç§ãã¡ã¯、åä¸ã®ãã£ã³ãã«ã«ç»åæ
å ±ãå¤æããã®ã§ã¯ãªã、æ¹åå解ãæ½ããã¨ã§ 8 ãã£ã³ãã«ã®ç»åã«å¤æããã¢ããã¼ããæ¡ç¨ãã¾ãã。
「ã」ã¨æ¸ãããã¹ããã¼ã¯ã®æ¹åå解ç¹å¾´
æ¹åå解ç¹å¾´ãæ¡ç¨ãã¦ã、ä½è§£å度ã®ããã«éãªã£ã¦ãã¾ãç·ã«ã¤ãã¦ã¯èª²é¡ãæ®ãã¾ãã。ãã¨ãã°「ã¯」ã¨「ã»」ã¯ç»æ°ãç°ãªããã®ã®、「ã»」ã® 3 ç»ç®ã 2 ç»ç®ã¨éãªã£ã¦ãã¾ããã¨ãå¤ã観測ããã¾ãã。ãã®ãããªèª²é¡ã解決ããããã«ã¯、æ¸ãå§ãããæ¸ãçµããã¾ã§ã®ã©ã®ã¿ã¤ãã³ã°ã§ç·ãæ¸ãããã®ã、ã¨ããæ
å ±ãæå¹ã«åãã¨èãã¾ãã。
ããã§å°å
¥ããã®ãæéçç¹å¾´(temporal feature)ã§ã。æ¹åå解ç¹å¾´ã表ã 8 ãã£ã³ãã«ã«å ãã¦、ã ãã ãç·ãèããªãç»åã¨ã ãã ãç·ãæ¿ããªãç»åãå ãããã¨ã§、å
¨ä½çãªæéå¤åã表ããç¹å¾´ãå°å
¥ãã¾ãã。æ¢åã® 8 ãã£ã³ãã«ã«å ãã¦ãã® 2 ãã£ã³ãã«ãå ãããã¨ã§、ãããªã精度åä¸ãå®ç¾ãã¾ãã。
「ã」ã¨æ¸ãããã¹ããã¼ã¯ã®æéçç¹å¾´
ä¸å³ã«、åç¹å¾´éãå©ç¨ããã¨ãã®æ£ç¢ºåº¦ã®æ¯è¼ã示ãã¾ã。æ¹åå解ç¹å¾´、æéçç¹å¾´ã¨ãã«æåèªè精度ã®åä¸ã«å¹æããããã¨ã確ããããã¾ãã。æ¹åå解ç¹å¾´ãçã®åãã表ããã¨ã§å±æçãªæéæ
å ±ãçµã¿è¾¼ã¿、æéçç¹å¾´ãæ¸ãå§ãããæ¸ãçµããã¾ã§ã®å¤åã表ããã¨ã§å¤§åçãªæéæ
å ±ãçµã¿è¾¼ããã¨ã§、精度åä¸ã«è²¢ç®ãã¦ããã¨èãããã¾ã。
確èªç¨ãã¼ã¿ã»ããã«ãããåç¹å¾´éã®æç¡ã«ããæ£ç¢ºåº¦ã®æ¯è¼
以ä¸ã®ç¹å¾´éãå°å
¥ããçµæ、æçµçãªæ©æ¢°å¦ç¿ã¢ãã«ã¯ 16px åæ¹ã®æ£æ¹å½¢ã®ãã£ã³ãã¹ã«å¯¾ã㦠8 ã¤ã®æ¹åå解ç¹å¾´ã¨ 2 ã¤ã®æéçç¹å¾´ãæç»ããè¨ 10 ãã£ã³ãã«ãããªãç»åãå
¥åã¨ãã¦åãåããã®ã«ãªãã¾ãã。MobileNet ã®ãããã¯ã¼ã¯æ§æãå
ã«ãã¦、ã§ããã ãå°ãªã層ã®æ°ã§é«ã精度ãå®ç¾ããæ§æã模索ããçµæ、以ä¸ã®ãããã¯ã¼ã¯æ§æã«è³ãã¾ãã。
ç³ã¿è¾¼ã¿å±¤(ã«ã¼ãã«: 3x3、ãã£ã«ã¿æ°: 32、ã¹ãã©ã¤ã: 2、æ´»æ§åé¢æ°: Relu)
åé¢å¼ç³ã¿è¾¼ã¿å±¤(ã«ã¼ãã«: 3x3、ãã£ã«ã¿æ°: 64、ã¹ãã©ã¤ã: 1、æ´»æ§åé¢æ°: Relu)
åé¢å¼ç³ã¿è¾¼ã¿å±¤(ã«ã¼ãã«: 3x3、ãã£ã«ã¿æ°: 128、ã¹ãã©ã¤ã: 2、æ´»æ§åé¢æ°: Relu)
åé¢å¼ç³ã¿è¾¼ã¿å±¤(ã«ã¼ãã«: 3x3、ãã£ã«ã¿æ°: 128、ã¹ãã©ã¤ã: 1、æ´»æ§åé¢æ°: Relu)
å
¨çµå層
ä»åã®è¨ç·´ç¨ããã°ã©ã 㯠nazoru-input ããã±ã¼ã¸ ã¨ã㦠PyPi ã§å
¬éããã¦ãã¾ã。以ä¸ã®ããã« nazoru-input ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã、è¨ç·´ãã¼ã¿ãæå®ã㦠nazoru-training ã³ãã³ããå®è¡ãããã¨ã§、ãæå
ã®ç°å¢ã§ãæ©æ¢°å¦ç¿ã¢ãã«ãæ§ç¯ã§ãã¾ã。ä»åç¨ããè¨ç·´ãã¼ã¿ã¯ https://github.com/google/mozc-devices/raw/master/mozc-nazoru/data/strokes.zip ãããã¦ã³ãã¼ãã§ãã¾ã。
$ pip install nazoru - input
$ nazoru - training ./ data / strokes . zip
ãã® nazoru-training ã¯æ¨æºç㪠TensorFlow ã® API ãå©ç¨ãã¦å®è£
ããã¦ãã¾ãã®ã§、ç°¡åã«ã«ã¹ã¿ãã¤ãºãã¦å©ç¨ãã¦ããã ãã¾ã。ãã¤ãã¼ãã©ã¡ã¼ã¿ã¼ãå
¥åãã¼ã¿ã»ãããã³ãã³ãã©ã¤ã³ãªãã·ã§ã³ã§å¤æ´ãããã¨ãå¯è½ã§ã。詳ãã㯠nazoru-training --help ã³ãã³ããåç
§ãã¦ãã ãã。
ãã¼ãã¦ã§ã¢ã§ã®æ¨è«
ãã®ããã«ãã¦æ§ç¯ããæ©æ¢°å¦ç¿ã¢ãã«ãã¦ã¼ã¶ã¼ãæ軽ã«ä½¿ããããã«ããã«ã¯ã©ãããã°ããã、ãã¼ã å
ã§æ´»çºãªè°è«ããªããã¾ãã。ãã½ã³ã³ãã¹ãã¼ããã©ã³ã«ç¹å¥ãªã½ããã¦ã§ã¢ãã¤ã³ã¹ãã¼ã«ãããã¨ãªããæ°ã«å
¥ãã®ãã¼ãã¼ãã§ããã«ç©çææ¸ãå
¥åã使ããããã«ãããã、ç§ãã¡ã¯å¦ç¿æ¸ã¿ã¢ãã«ãçµã¿è¾¼ãã ãã¼ãã¦ã§ã¢「ç©çææ¸ãã³ã³ãã¼ã¿ã¼」ã製ä½ãããã¨ã«ãã¾ãã。ãã®ç©çææ¸ãã³ã³ãã¼ã¿ã¼ã¯、è¨ç·´æ¸ã¿ã¢ãã«ã使ã£ã¦æ¨è«ããããã°ã©ã ã Raspberry Pi Zero ã«ã¤ã³ã¹ãã¼ã«ãããã®ã§ã。ããã§ã¯、ç©çææ¸ãã³ã³ãã¼ã¿ã¼ãæ§ç¯ããæé ã説æãã¾ã。
æ¨è«ç¨ããã°ã©ã ã¯è¨ç·´ç¨ããã°ã©ã ã¨åæ§ã« nazoru-input ããã±ã¼ã¸ ã«å«ã¾ãã¦ãã¾ã。nazoru-input ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã nazoru-input ã³ãã³ããå®è¡ãããã¨ã§、ãææã¡ã®ã³ã³ãã¥ã¼ã¿ãã¤ãã£ã¦ç°¡åã«ç©çææ¸ãå
¥åã試ããã¨ãã§ãã¾ã。
$ pip install nazoru - input
$ nazoru - input
æ¨è«ã®æ©è½ãæ軽ã«æ¡å¼µãã¦éãã§ããã ããããã«、API ãã·ã³ãã«ã«ãã¦ããã¾ã。以ä¸ã®ãããªã³ã¼ããæ¸ãã ãã§å¦ç¿æ¸ã¿ã¢ãã«ãå©ç¨ããæ¨è«ãã§ãã¾ã。詳ãã㯠nazoru-input ã®ã³ã¼ã ãåèã«ãã¦ãã ãã。
from nazoru import get_default_graph_path
from nazoru . core import NazoruPredictor
predictor = NazoruPredictor ( get_default_graph_path ())
# [(key, ms_from_first_input)]
sample_input = [( 'e' , 0 ), ( 'd' , 100 ), ( 'c' , 200 ), ( 'v' , 300 ),
( 'u' , 800 ), ( 'j' , 900 )]
results = predictor . predict_top_n ( sample_input , 5 )
for result in results :
print ( 'kana: %s, key: %s, probability: %.3f' % result )
ç©çææ¸ãã³ã³ãã¼ã¿ã¼ã¯ Raspberry Pi Zero ã« nazoru-input ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã、USB ã§æ¥ç¶ããããã¼ãã¼ãããåãåã£ããã¼æ
å ±ãæ¨è«ããã°ã©ã ã«ãã£ã¦æåã«å¤æ、Bluetooth ã§åºåãããã¨ã«ãã£ã¦å®è£
ããã¦ãã¾ã。ãã®ãã¡、ãã¼å
¥åããæåã«å¤æããé¨åã¯åºæ¿ããªãã¦ãã試ãããã ããã®ã§、ã家åºã«ãã Raspberry Pi ã« nazoru-input ããã±ã¼ã¸ãå
¥ããã ãã§æ軽ã«ææ¸ãæ©è½ãå©ç¨ããããã°ã©ã ãå®è£
ãããã¨ãã§ãã¾ã。
ã¾ã、ä»åã¯ç©çææ¸ãã³ã³ãã¼ã¿ã¼ã®ããã«è£½ä½ããåºæ¿ã®è¨è¨å³ã® CAD ãã¼ã¿ ãå
¬éãã¾ãã。ãã®åºæ¿ã«ã¯ Bluetooth éä¿¡ã®ããã®ã¢ã¸ã¥ã¼ã«ãã¹ãã¼ã¿ã¹è¡¨ç¤ºã®ããã® LED ãæè¼ããã¦ãã、Raspberry Pi ã«æ¥ç¶ãããã¨ã§ãã½ã³ã³ãã¹ãã¼ããã©ã³ã« Bluetooth ãéãã¦æåãéä¿¡ãããã¨ãå¯è½ã«ãªãã¾ã。å©ç¨ããé¨å㯠Raspberry Pi Zero ã RN42 ã¨ãã£ãé販ãåºé ã§è³¼å
¥ã§ãããã®ã«éå®ãã¾ãã。Raspberry Pi Zero ãå©ç¨ãããã¨ã§å¤§ããã®å¶ç´ãå°ãããã¾ããã®ã§、ãã¾ãã¾ãªå½¢ç¶ã®ããã¤ã¹ã«çµã¿è¾¼ããã¨ãå¯è½ã§ã。CAD ãã¼ã¿ãç·¨éãããã¨ã§、èªç±ã«æ©è½ãå¤æ´、追å ããåºæ¿ãä½è£½å¯è½ã§ã。
ããã«、å
¬éããã¦ããåºæ¿ã«ã¯æ¡å¼µæ§ãããããããã«æªæ¥ç¶ã®ããã、SPI・I2C æ¥ç¶ç¨ã®ã³ãã¯ã¿、UART ã®ããã®åæå¯è½ãªãã¿ã¼ã³ãç¨æãã¦ããã¾ã。ããã«ãã、ã¢ã¼ãåãæ¿ãã¹ã¤ãããå®è£
ããã、SPI・I2C æ¥ç¶ã®ãã£ã¹ãã¬ã¤ã«ãã£ã¦è»è·¡ã表示ãããªã©ã®æ¡å¼µãå¯è½ã§ã。
ç©çææ¸ãã³ã³ãã¼ã¿ã¼ã®ããªã³ãåºæ¿å³é¢
ãã©ã¦ã¶ã§ã®æ¨è«
ãæå
ã«ç©çææ¸ãã³ã³ãã¼ã¿ã¼ããªãçãã¾ã«ããæ軽ã«ç©çææ¸ãå
¥åã楽ããã§ããã ããã、ç§ãã¡ã¯ãã©ã¦ã¶ä¸ã§æ©æ¢°å¦ç¿ã¢ãã«ãåä½ãããã¢ãæ§ç¯ãã¾ãã。TensorFlow ã§å¦ç¿ããã¢ãã«ã TensorFlow.js ã«ç§»æ¤ãããã¨ã§ãã©ã¦ã¶ä¸ã§ã®æ¨è«ãå®ç¾ãã¦ãã¾ã。
è¨ç·´ç¨ããã°ã©ã nazoru-training ã¯è¨ç·´æ¸ã¿ã¢ãã«ã SavedModel å½¢å¼ã§åºåãã¾ã。SavedModel å½¢å¼ã§ä¿åãããè¨ç·´æ¸ã¿ã¢ãã«ã TensorFlow.js ã§èªã¿è¾¼ãã«ã¯、TensorFlow.js converter ã使ã£ã¦ Web-friendly format ã«å¤æããå¿
è¦ãããã¾ã。TensorFlow.js converter ã¯å¤æã®ããã®ã¹ã¯ãªããã¨、å¤ææ¸ã¿ã¢ãã«ãèªã¿è¾¼ã Javascript API ãæä¾ããã©ã¤ãã©ãªã§ã。以ä¸ã®ã³ãã³ãã®ããã« tensorflowjs ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã㦠tensorflowjs_converter ã³ãã³ããå®è¡ãããã¨ã§、è¨ç·´æ¸ã¿ã¢ãã«ãå¤æãã¾ã。ãã®é、å¤æããã¢ãã«ã®å½¢å¼(ãã®å ´å㯠SavedModel ãªã®ã§ tf_saved_model)、åºå層ã«ç¸å½ãããã¼ãã®åå(nazoru-training ã®ããã©ã«ãè¨å®ã§ã¯ Nazorunet/Predictions/Reshape_1 )ãæå®ãã¾ã。
$ pip install tensorflowjs
$ tensorflowjs_converter \
-- input_format = tf_saved_model \
-- output_node_names = 'Nazorunet/Predictions/Reshape_1' \
/ nazorunet / saved_model \
/ nazorunet / web_model
å¤æãæåããã¨、tensorflowjs_converter ã¯ä»¥ä¸ã® 3 種é¡ã®ãã¡ã¤ã«ãåºåãã¾ã。
web_model.pb (the dataflow graph)
weights_manifest.json (weight manifest file)
group1-shard\*of\* (collection of binary weight files)
ãããã¯ã¼ã¯ãæ§æããåãã©ã¡ã¼ã¿ã¼ã®éã¿ã¯ group1-shard\*of\* ã«è¨è¿°ãã、ã¢ãã«ã®å¤§ããã«å¿ãã¦åãã¡ã¤ã«ã 4MB ã«åã¾ãããã«ã·ã£ã¼ãã£ã³ã°ããã¾ã。ãã®å·¥å¤«ã«ãã、ãã©ã¦ã¶ã«ãããã¯ã¼ã¯ãã¡ã¤ã«ããã£ãã·ã¥ããã¾ã。
ãã¨ã¯ tfjs-converter npm ããã±ã¼ã¸ãã¤ã³ã¹ãã¼ã«ã、以ä¸ã®ããã«ã¢ãã«ãèªã¿è¾¼ãã°ãã©ã¦ã¶ã§ã®æ¨è«ãã§ãã¾ã。
import * as tfc from '@tensorflow/tfjs-core' ;
import { loadFrozenModel } from '@tensorflow/tfjs-converter' ;
const model = await loadFrozenModel (
'/nazorunet/web_model.pb' ,
'/nazorunet/weights_manifest.json' );
// Gets a canvas or image element.
const inputImage = document . getElementById ( 'input-image' );
const result = model . execute ({ input : tfc . fromPixels ( inputImage )});
// Returns predicted probabilities for each class in a float array.
const probs = result . dataSync ();
console . log ( probs ) // Float32Array(88) [...]
ã¢ããªã±ã¼ã·ã§ã³ã«ãã£ã¦ã¯ãã©ã¦ã¶ä¸ã§é«é »åº¦ã§æ¨è«ãç¹°ãè¿ããã¨ãèãããããã、TensorFlow.js ã¯å¹ççã«ã¡ã¢ãªã管çããããã®ä¾¿å©ãªã¡ã½ãããç¨æãã¦ãã¾ã。詳ãã㯠Core Concepts in TensorFlow.js ããåç
§ãã ãã。
ã¾ã¨ã
以ä¸、Gboard ç©çææ¸ãå
¥åãã¼ã¸ã§ã³ãæ¯ããæ©æ¢°å¦ç¿æè¡ãç´¹ä»ãã¾ãã。
「æ©æ¢°å¦ç¿ã¢ãã«ã®æ§ç¯」ã§ã¯、å¹ççã«è¨ç·´ãã¼ã¿ãåéããä»çµã¿ã®éè¦æ§ã«ã¤ãã¦è¿°ã¹ã¾ãã。ããã¾ã§ã«ãªãã¿ã¹ã¯ã«åãçµãå ´å、ããããå¦ç¿ã®ããã®ãã¼ã¿ããªãå ´é¢ãçããããã¾ãã。ãã®ãããªå ´å、ãã¼ã¿åéãå¹ççã«è¡ãããã®ä»çµã¿ã¥ãã、ã¤ã³ã¿ã¼ãã§ã¤ã¹ã®æ§ç¯ãéè¦ã«ãªãã¾ã。
ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ãå¤å±¤ã«ãã¦è¡¨ç¾åãè±ãã«ãããã¨ããã¾ãã¾ãªã¿ã¹ã¯ã解ãä¸ã§æåã§ããä¸æ¹、æ©æ¢°å¦ç¿å¿ç¨ã®å ´ã Raspberry Pi ãã¯ããã¨ããå°åè¨ç®æ©ããã©ã¦ã¶ãªã©ã«åºãã£ã¦ãããã¨ãèããã¨、é«ã精度ãä¿æããªãããã§ããã ã軽éã§ã·ã³ãã«ãªæ©æ¢°å¦ç¿ã¢ãã«ãæ§ç¯ãããã¨ã¯ç¡è¦ã§ããªã課é¡ã§ã。MobileNet ãã¯ããã¨ãã軽éã®ãããã¯ã¼ã¯ã¢ãã«ãæ¡ç¨ãããã¨、ãã¼ã¿ã®åå¦çã«é©åãªãã¡ã¤ã³ç¥èãæ´»ç¨ãã¦ã¢ãã«ã®ãµã¤ãºãä¿æããªããã精度ãåä¸ãããã¨ã、ãã®ãããªèª²é¡ã«å¿ããä¸ã§æå¹ã§ãããã¨ã示ãã¾ãã。
「ãã¼ãã¦ã§ã¢ã§ã®æ¨è«」ã§ã¯、ä»åæ§ç¯ããæ©æ¢°å¦ç¿ã¢ãã«ã«ããæ¨è«ã®æ¹æ³ã説æãã¾ãã。Raspberry Pi ã使ã£ãããã¤ã¹ã®æ¡å¼µæ¹æ³ã«ã¤ãã¦ãè¿°ã¹、æ¨è«ããã°ã©ã ã«åããã¦ããã¤ã¹ã®æ¯ãèããã«ã¹ã¿ãã¤ãºããæ¹æ³ãç´¹ä»ãã¾ãã。
「ãã©ã¦ã¶ã§ã®æ¨è«」ã§ã¯、TensorFlow.js ã使ã£ã¦ãã©ã¦ã¶ã§æ¨è«ããæ¹æ³ã説æãã¾ãã。TensorFlow.js Converter ã使ããã¨ã§ç°¡åã«è¨ç·´æ¸ã¿ã¢ãã«ã®ç§»æ¤ãã§ãããã¨、å
·ä½ç㪠Javascript API ã®ä½¿ç¨æ¹æ³ã«ã¤ãã¦è¿°ã¹ã¾ãã。
ä»åã®è¨äºã、ãã¾ãã¾ãªãã©ãããã©ã¼ã ããµãã¼ãããæ©æ¢°å¦ç¿ã·ã¹ãã æ§ç¯ã®åèã¨ãªãã°å¹¸ãã§ã。ããã¦、Gboard ç©çææ¸ããã¼ã¸ã§ã³ãä»å¾ã®æåå
¥åã®ããã¡ã¯ã・ã¹ã¿ã³ãã¼ãã«ãªãæ¥ããããã¨ãé¡ãã¾ã。
åèæç®
[1] Zhang, Xu-Yao, Yoshua Bengio, and Cheng-Lin Liu. "Online and offline handwritten chinese character recognition: A comprehensive study and new benchmark." Pattern Recognition 61 (2017): 348-360.
[2] Howard, Andrew G., et al. "Mobilenets: Efficient convolutional neural networks for mobile vision applications." arXiv preprint arXiv:1704.04861 (2017).
Written by:
- Shuhei Iitsuka - UX Engineer (Machine learning)
- Makoto Shimazu - Software Engineer (Hardware, System design)