Quick Draw Doodle Recognition: แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฃแƒ›แƒ”แƒ’แƒแƒ‘แƒ แƒ“แƒ”แƒ— R, C++ แƒ“แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒš แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒก

Quick Draw Doodle Recognition: แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฃแƒ›แƒ”แƒ’แƒแƒ‘แƒ แƒ“แƒ”แƒ— R, C++ แƒ“แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒš แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒก

แƒฐแƒ”แƒ˜ แƒฐแƒแƒ‘แƒ !

แƒ’แƒแƒกแƒฃแƒš แƒจแƒ”แƒ›แƒแƒ“แƒ’แƒแƒ›แƒแƒ–แƒ” แƒ™แƒแƒ’แƒšแƒ›แƒ แƒฃแƒ›แƒแƒกแƒžแƒ˜แƒœแƒซแƒšแƒ แƒ™แƒแƒœแƒ™แƒฃแƒ แƒกแƒก แƒฎแƒ”แƒšแƒ˜แƒ— แƒ“แƒแƒฎแƒแƒขแƒฃแƒšแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒ™แƒšแƒแƒกแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, Quick Draw Doodle Recognition, แƒ แƒแƒ›แƒ”แƒšแƒจแƒ˜แƒช, แƒกแƒฎแƒ•แƒแƒ—แƒ แƒจแƒแƒ แƒ˜แƒก, R-แƒ›แƒ”แƒชแƒœแƒ˜แƒ”แƒ แƒ—แƒ แƒฏแƒ’แƒฃแƒคแƒ›แƒ แƒ›แƒ˜แƒ˜แƒฆแƒ แƒ›แƒแƒœแƒแƒฌแƒ˜แƒšแƒ”แƒแƒ‘แƒ: แƒแƒ แƒขแƒ”แƒ› แƒ™แƒšแƒ”แƒ•แƒชแƒแƒ•แƒ, แƒคแƒ˜แƒšแƒ˜แƒžแƒ แƒ›แƒ”แƒœแƒ”แƒฏแƒ”แƒ แƒ˜ ะธ แƒแƒœแƒ“แƒ แƒ”แƒ˜ แƒแƒ’แƒฃแƒ แƒชแƒแƒ•แƒ˜. แƒฉแƒ•แƒ”แƒœ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“ แƒแƒ  แƒแƒฆแƒ•แƒฌแƒ”แƒ แƒ— แƒ™แƒแƒœแƒ™แƒฃแƒ แƒกแƒก, แƒ”แƒก แƒฃแƒ™แƒ•แƒ” แƒ’แƒแƒ™แƒ”แƒ—แƒ“แƒ แƒ‘แƒแƒšแƒ แƒžแƒฃแƒ‘แƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ.

แƒแƒ›แƒฏแƒ”แƒ แƒแƒ“ แƒ›แƒ”แƒ“แƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒ”แƒฃแƒ แƒœแƒ”แƒแƒ‘แƒแƒ› แƒแƒ  แƒ’แƒแƒแƒ›แƒแƒ แƒ—แƒšแƒ, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ“แƒ˜แƒ“แƒ˜ แƒฆแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒชแƒ“แƒ˜แƒšแƒ”แƒ‘แƒ แƒ“แƒแƒ’แƒ แƒแƒ•แƒ“แƒ, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ›แƒกแƒฃแƒ แƒก แƒกแƒแƒ–แƒแƒ’แƒแƒ“แƒแƒ”แƒ‘แƒแƒก แƒ•แƒฃแƒ—แƒฎแƒ แƒ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒ แƒ“แƒ แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒ แƒแƒ› แƒ™แƒแƒ’แƒšแƒ”แƒ–แƒ” แƒ“แƒ แƒงแƒแƒ•แƒ”แƒšแƒ“แƒฆแƒ˜แƒฃแƒ  แƒกแƒแƒฅแƒ›แƒ˜แƒแƒœแƒแƒ‘แƒแƒจแƒ˜. แƒ’แƒแƒœแƒฎแƒ˜แƒšแƒฃแƒš แƒ—แƒ”แƒ›แƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก: แƒ แƒ—แƒฃแƒšแƒ˜ แƒชแƒฎแƒแƒ•แƒ แƒ”แƒ‘แƒ แƒ’แƒแƒ แƒ”แƒจแƒ” OpenCV, JSON แƒžแƒแƒ แƒกแƒ˜แƒœแƒ’แƒ˜ (แƒ”แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ”แƒ‘แƒ˜ แƒ’แƒแƒœแƒ˜แƒฎแƒ˜แƒšแƒแƒ•แƒก C++ แƒ™แƒแƒ“แƒ˜แƒก แƒ˜แƒœแƒขแƒ”แƒ’แƒ แƒแƒชแƒ˜แƒแƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒจแƒ˜ แƒแƒœ R-แƒจแƒ˜ แƒžแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒจแƒ˜, แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— Rcpp), แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ แƒ“แƒ แƒกแƒแƒ‘แƒแƒšแƒแƒ แƒแƒ›แƒแƒฎแƒกแƒœแƒ˜แƒก แƒ“แƒแƒ™แƒ”แƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ. แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒ“แƒแƒœ แƒงแƒ•แƒ”แƒšแƒ แƒ™แƒแƒ“แƒ˜ แƒจแƒ”แƒกแƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒšแƒแƒ“ แƒจแƒ”แƒกแƒแƒคแƒ”แƒ แƒ˜แƒกแƒ˜ แƒคแƒแƒ แƒ›แƒ˜แƒ— แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒ แƒกแƒแƒชแƒแƒ•แƒ”แƒ‘แƒ˜.

แƒจแƒ˜แƒœแƒแƒแƒ แƒกแƒ˜:

  1. แƒ”แƒคแƒ”แƒฅแƒขแƒฃแƒ แƒแƒ“ แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ”แƒ— แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜ CSV-แƒ“แƒแƒœ MonetDB-แƒจแƒ˜
  2. แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒ
  3. แƒ˜แƒขแƒ”แƒ แƒแƒขแƒแƒ แƒ”แƒ‘แƒ˜ แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ˜แƒ“แƒแƒœ แƒ’แƒแƒ“แƒ›แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก
  4. แƒ›แƒแƒ“แƒ”แƒšแƒ˜แƒก แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ˜แƒก แƒจแƒ”แƒ แƒฉแƒ”แƒ•แƒ
  5. แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ
  6. แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ™แƒ”แƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ
  7. Google Cloud-แƒ–แƒ” แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ GPU-แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ
  8. แƒ˜แƒ›แƒ˜แƒก แƒœแƒแƒชแƒ•แƒšแƒแƒ“, แƒ แƒแƒ› แƒ“แƒแƒกแƒ™แƒ•แƒœแƒ

1. แƒ”แƒคแƒ”แƒฅแƒขแƒฃแƒ แƒแƒ“ แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ”แƒ— แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜ CSV-แƒ“แƒแƒœ MonetDB แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜

แƒแƒ› แƒ™แƒแƒœแƒ™แƒฃแƒ แƒกแƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜ แƒ›แƒแƒฌแƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒแƒ แƒ แƒ›แƒ–แƒ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ—, แƒแƒ แƒแƒ›แƒ”แƒ“ 340 CSV แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ— (แƒ—แƒ˜แƒ—แƒ แƒคแƒแƒ˜แƒšแƒ˜ แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒš แƒ™แƒšแƒแƒกแƒ–แƒ”), แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก JSON-แƒ”แƒ‘แƒก แƒฌแƒ”แƒ แƒขแƒ˜แƒšแƒแƒ•แƒแƒœแƒ˜ แƒ™แƒแƒแƒ แƒ“แƒ˜แƒœแƒแƒขแƒ”แƒ‘แƒ˜แƒ—. แƒแƒ› แƒฌแƒ”แƒ แƒขแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒฎแƒแƒ–แƒ”แƒ‘แƒ—แƒแƒœ แƒจแƒ”แƒ”แƒ แƒ—แƒ”แƒ‘แƒ˜แƒ— แƒ›แƒ˜แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒกแƒแƒ‘แƒแƒšแƒแƒ แƒกแƒฃแƒ แƒแƒ—แƒก 256x256 แƒžแƒ˜แƒฅแƒกแƒ”แƒšแƒ˜แƒก แƒ–แƒแƒ›แƒ˜แƒก. แƒแƒกแƒ”แƒ•แƒ” แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒแƒ แƒ˜แƒก แƒ”แƒขแƒ˜แƒ™แƒ”แƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ›แƒ˜แƒฃแƒ—แƒ˜แƒ—แƒ”แƒ‘แƒก, แƒกแƒฌแƒแƒ แƒแƒ“ แƒ˜แƒฅแƒœแƒ แƒ—แƒฃ แƒแƒ แƒ แƒกแƒฃแƒ แƒแƒ—แƒ˜แƒก แƒแƒ›แƒแƒชแƒœแƒแƒ‘แƒ แƒ™แƒšแƒแƒกแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ , แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒœแƒแƒ™แƒ แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ’แƒ แƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒ“แƒ แƒแƒก, แƒกแƒฃแƒ แƒแƒ—แƒ˜แƒก แƒแƒ•แƒขแƒแƒ แƒ˜แƒก แƒกแƒแƒชแƒฎแƒแƒ•แƒ แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒฅแƒ•แƒ”แƒงแƒœแƒ˜แƒก แƒแƒ แƒแƒกแƒแƒ˜แƒแƒœแƒ˜ แƒ™แƒแƒ“แƒ˜, แƒฃแƒœแƒ˜แƒ™แƒแƒšแƒฃแƒ แƒ˜ แƒ˜แƒ“แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ˜, แƒ“แƒ แƒแƒ˜แƒก แƒจแƒขแƒแƒ›แƒžแƒ˜. แƒ“แƒ แƒ™แƒšแƒแƒกแƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ”แƒกแƒแƒ‘แƒแƒ›แƒ”แƒ‘แƒ แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒก. แƒแƒ แƒ˜แƒ’แƒ˜แƒœแƒแƒšแƒฃแƒ แƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒ˜แƒฌแƒแƒœแƒ˜แƒก 7.4 GB แƒแƒ แƒฅแƒ˜แƒ•แƒจแƒ˜ แƒ“แƒ แƒ“แƒแƒแƒฎแƒšแƒแƒ”แƒ‘แƒ˜แƒ— 20 GB แƒจแƒ”แƒคแƒฃแƒ—แƒ•แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒกแƒ แƒฃแƒšแƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜ 240 GB-แƒก แƒจแƒ”แƒแƒ“แƒ’แƒ”แƒœแƒก. แƒแƒ แƒ’แƒแƒœแƒ˜แƒ–แƒแƒขแƒแƒ แƒ”แƒ‘แƒ›แƒ แƒ“แƒแƒ แƒฌแƒ›แƒฃแƒœแƒ“แƒœแƒ”แƒœ, แƒ แƒแƒ› แƒแƒ แƒ˜แƒ•แƒ” แƒ•แƒ”แƒ แƒกแƒ˜แƒแƒจแƒ˜ แƒ”แƒ แƒ—แƒ˜ แƒ“แƒ แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒœแƒแƒฎแƒแƒขแƒ”แƒ‘แƒ˜แƒก แƒ แƒ”แƒžแƒ แƒแƒ“แƒฃแƒชแƒ˜แƒ แƒ”แƒ‘แƒ แƒ›แƒแƒฎแƒ“แƒ, แƒ แƒแƒช แƒ˜แƒ›แƒแƒก แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก, แƒ แƒแƒ› แƒกแƒ แƒฃแƒšแƒ˜ แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒ–แƒ”แƒ“แƒ›แƒ”แƒขแƒ˜ แƒ˜แƒงแƒ. แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ  แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, 50 แƒ›แƒ˜แƒšแƒ˜แƒแƒœแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ˜แƒก แƒ’แƒ แƒแƒคแƒ˜แƒ™แƒฃแƒš แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒจแƒ˜ แƒแƒœ แƒ›แƒแƒกแƒ˜แƒ•แƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ— แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ แƒ›แƒแƒจแƒ˜แƒœแƒ•แƒ” แƒฌแƒแƒ›แƒ’แƒ”แƒ‘แƒแƒ“ แƒฉแƒแƒ˜แƒ—แƒ•แƒแƒšแƒ แƒ“แƒ แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ”แƒ— แƒจแƒ”แƒ’แƒ•แƒ”แƒ”แƒ แƒ—แƒ”แƒ‘แƒ˜แƒœแƒ แƒงแƒ•แƒ”แƒšแƒ CSV แƒคแƒแƒ˜แƒšแƒ˜ แƒแƒ แƒฅแƒ˜แƒ•แƒ˜แƒ“แƒแƒœ. train_simplified.zip แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜ แƒกแƒแƒญแƒ˜แƒ แƒ แƒ–แƒแƒ›แƒ˜แƒก แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ’แƒแƒ›แƒ˜ แƒ’แƒ”แƒœแƒ”แƒ แƒ˜แƒ แƒ”แƒ‘แƒ˜แƒ— แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒžแƒแƒ แƒขแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒ™แƒแƒ แƒ’แƒแƒ“ แƒ“แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ แƒแƒ˜แƒ แƒฉแƒ˜แƒ”แƒก DBMS-แƒแƒ“ MonetDB, แƒ™แƒ”แƒ แƒซแƒแƒ“, แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ R-แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ’แƒแƒ แƒช แƒžแƒแƒ™แƒ”แƒขแƒ˜ MonetDBLite. แƒžแƒแƒ™แƒ”แƒขแƒ˜ แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ˜แƒก แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒฉแƒแƒจแƒ”แƒœแƒ”แƒ‘แƒฃแƒš แƒ•แƒ”แƒ แƒกแƒ˜แƒแƒก แƒ“แƒ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒแƒ˜แƒฆแƒแƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒžแƒ˜แƒ แƒ“แƒแƒžแƒ˜แƒ  R แƒกแƒ”แƒกแƒ˜แƒ˜แƒ“แƒแƒœ แƒ“แƒ แƒ˜แƒฅ แƒ˜แƒ›แƒฃแƒจแƒแƒแƒ—. แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ แƒ“แƒ แƒ›แƒแƒกแƒ—แƒแƒœ แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒ แƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ“แƒ”แƒ‘แƒ แƒ”แƒ แƒ—แƒ˜ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒ—:

con <- DBI::dbConnect(drv = MonetDBLite::MonetDBLite(), Sys.getenv("DBDIR"))

แƒฉแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒจแƒ”แƒ•แƒฅแƒ›แƒœแƒแƒ— แƒแƒ แƒ˜ แƒชแƒฎแƒ แƒ˜แƒšแƒ˜: แƒ”แƒ แƒ—แƒ˜ แƒงแƒ•แƒ”แƒšแƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒ”แƒแƒ แƒ” แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜แƒก แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ’แƒแƒ“แƒ›แƒแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ (แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒแƒ, แƒ—แƒฃ แƒ แƒแƒ›แƒ” แƒแƒ แƒแƒกแƒฌแƒแƒ แƒ”แƒ“ แƒ›แƒแƒฎแƒ“แƒ”แƒ‘แƒ แƒ“แƒ แƒžแƒ แƒแƒชแƒ”แƒกแƒ˜ แƒฃแƒœแƒ“แƒ แƒ’แƒแƒœแƒแƒฎแƒšแƒ“แƒ”แƒก แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒฉแƒแƒ›แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’):

แƒชแƒฎแƒ แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ

if (!DBI::dbExistsTable(con, "doodles")) {
  DBI::dbCreateTable(
    con = con,
    name = "doodles",
    fields = c(
      "countrycode" = "char(2)",
      "drawing" = "text",
      "key_id" = "bigint",
      "recognized" = "bool",
      "timestamp" = "timestamp",
      "word" = "text"
    )
  )
}

if (!DBI::dbExistsTable(con, "upload_log")) {
  DBI::dbCreateTable(
    con = con,
    name = "upload_log",
    fields = c(
      "id" = "serial",
      "file_name" = "text UNIQUE",
      "uploaded" = "bool DEFAULT false"
    )
  )
}

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒก แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒกแƒฌแƒ แƒแƒคแƒ˜ แƒ’แƒ–แƒ แƒ˜แƒงแƒ CSV แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒžแƒ˜แƒ แƒ“แƒแƒžแƒ˜แƒ  แƒ™แƒแƒžแƒ˜แƒ แƒ”แƒ‘แƒ SQL - แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— COPY OFFSET 2 INTO tablename FROM path USING DELIMITERS ',','n','"' NULL AS '' BEST EFFORTแƒกแƒแƒ“ tablename - แƒ›แƒแƒ’แƒ˜แƒ“แƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒ˜ แƒ“แƒ path - แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒ’แƒ–แƒ. แƒแƒ แƒฅแƒ˜แƒ•แƒ—แƒแƒœ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒกแƒแƒก แƒ’แƒแƒ˜แƒ แƒ™แƒ•แƒ, แƒ แƒแƒ› แƒฉแƒแƒจแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ unzip in R แƒแƒ  แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒกแƒฌแƒแƒ แƒแƒ“ แƒแƒ แƒฅแƒ˜แƒ•แƒ˜แƒ“แƒแƒœ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒคแƒแƒ˜แƒšแƒ—แƒแƒœ, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ unzip (แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— getOption("unzip")).

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜ แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ

#' @title ะ˜ะทะฒะปะตั‡ะตะฝะธะต ะธ ะทะฐะณั€ัƒะทะบะฐ ั„ะฐะนะปะพะฒ
#'
#' @description
#' ะ˜ะทะฒะปะตั‡ะตะฝะธะต CSV-ั„ะฐะนะปะพะฒ ะธะท ZIP-ะฐั€ั…ะธะฒะฐ ะธ ะทะฐะณั€ัƒะทะบะฐ ะธั… ะฒ ะฑะฐะทัƒ ะดะฐะฝะฝั‹ั…
#'
#' @param con ะžะฑัŠะตะบั‚ ะฟะพะดะบะปัŽั‡ะตะฝะธั ะบ ะฑะฐะทะต ะดะฐะฝะฝั‹ั… (ะบะปะฐัั `MonetDBEmbeddedConnection`).
#' @param tablename ะะฐะทะฒะฐะฝะธะต ั‚ะฐะฑะปะธั†ั‹ ะฒ ะฑะฐะทะต ะดะฐะฝะฝั‹ั….
#' @oaram zipfile ะŸัƒั‚ัŒ ะบ ZIP-ะฐั€ั…ะธะฒัƒ.
#' @oaram filename ะ˜ะผั ั„ะฐะนะปะฐ ะฒะฝัƒั€ะธ ZIP-ะฐั€ั…ะธะฒะฐ.
#' @param preprocess ะคัƒะฝะบั†ะธั ะฟั€ะตะดะพะฑั€ะฐะฑะพั‚ะบะธ, ะบะพั‚ะพั€ะฐั ะฑัƒะดะตั‚ ะฟั€ะธะผะตะฝะตะฝะฐ ะธะทะฒะปะตั‡ั‘ะฝะฝะพะผัƒ ั„ะฐะนะปัƒ.
#'   ะ”ะพะปะถะฝะฐ ะฟั€ะธะฝะธะผะฐั‚ัŒ ะพะดะธะฝ ะฐั€ะณัƒะผะตะฝั‚ `data` (ะพะฑัŠะตะบั‚ `data.table`).
#'
#' @return `TRUE`.
#'
upload_file <- function(con, tablename, zipfile, filename, preprocess = NULL) {
  # ะŸั€ะพะฒะตั€ะบะฐ ะฐั€ะณัƒะผะตะฝั‚ะพะฒ
  checkmate::assert_class(con, "MonetDBEmbeddedConnection")
  checkmate::assert_string(tablename)
  checkmate::assert_string(filename)
  checkmate::assert_true(DBI::dbExistsTable(con, tablename))
  checkmate::assert_file_exists(zipfile, access = "r", extension = "zip")
  checkmate::assert_function(preprocess, args = c("data"), null.ok = TRUE)

  # ะ˜ะทะฒะปะตั‡ะตะฝะธะต ั„ะฐะนะปะฐ
  path <- file.path(tempdir(), filename)
  unzip(zipfile, files = filename, exdir = tempdir(), 
        junkpaths = TRUE, unzip = getOption("unzip"))
  on.exit(unlink(file.path(path)))

  # ะŸั€ะธะผะตะฝัะตะผ ั„ัƒะฝะบั†ะธั ะฟั€ะตะดะพะฑั€ะฐะฑะพั‚ะบะธ
  if (!is.null(preprocess)) {
    .data <- data.table::fread(file = path)
    .data <- preprocess(data = .data)
    data.table::fwrite(x = .data, file = path, append = FALSE)
    rm(.data)
  }

  # ะ—ะฐะฟั€ะพั ะบ ะ‘ะ” ะฝะฐ ะธะผะฟะพั€ั‚ CSV
  sql <- sprintf(
    "COPY OFFSET 2 INTO %s FROM '%s' USING DELIMITERS ',','n','"' NULL AS '' BEST EFFORT",
    tablename, path
  )
  # ะ’ั‹ะฟะพะปะฝะตะฝะธะต ะทะฐะฟั€ะพัะฐ ะบ ะ‘ะ”
  DBI::dbExecute(con, sql)

  # ะ”ะพะฑะฐะฒะปะตะฝะธะต ะทะฐะฟะธัะธ ะพะฑ ัƒัะฟะตัˆะฝะพะน ะทะฐะณั€ัƒะทะบะต ะฒ ัะปัƒะถะตะฑะฝัƒัŽ ั‚ะฐะฑะปะธั†ัƒ
  DBI::dbExecute(con, sprintf("INSERT INTO upload_log(file_name, uploaded) VALUES('%s', true)",
                              filename))

  return(invisible(TRUE))
}

แƒ—แƒฃ แƒ—แƒฅแƒ•แƒ”แƒœ แƒ’แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ— แƒชแƒฎแƒ แƒ˜แƒšแƒ˜แƒก แƒขแƒ แƒแƒœแƒกแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜ แƒฉแƒแƒฌแƒ”แƒ แƒแƒ›แƒ“แƒ”, แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜แƒ แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒจแƒ˜ แƒฉแƒแƒ‘แƒแƒ แƒ”แƒ‘แƒ preprocess แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ แƒ“แƒแƒฅแƒ›แƒœแƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒก.

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ—แƒแƒœแƒ›แƒ˜แƒ›แƒ“แƒ”แƒ•แƒ แƒฃแƒšแƒ˜ แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒก แƒ™แƒแƒ“แƒ˜:

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜ แƒฉแƒแƒฌแƒ”แƒ แƒ

# ะกะฟะธัะพะบ ั„ะฐะนะปะพะฒ ะดะปั ะทะฐะฟะธัะธ
files <- unzip(zipfile, list = TRUE)$Name

# ะกะฟะธัะพะบ ะธัะบะปัŽั‡ะตะฝะธะน, ะตัะปะธ ั‡ะฐัั‚ัŒ ั„ะฐะนะปะพะฒ ัƒะถะต ะฑั‹ะปะฐ ะทะฐะณั€ัƒะถะตะฝะฐ
to_skip <- DBI::dbGetQuery(con, "SELECT file_name FROM upload_log")[[1L]]
files <- setdiff(files, to_skip)

if (length(files) > 0L) {
  # ะ—ะฐะฟัƒัะบะฐะตะผ ั‚ะฐะนะผะตั€
  tictoc::tic()
  # ะŸั€ะพะณั€ะตัั ะฑะฐั€
  pb <- txtProgressBar(min = 0L, max = length(files), style = 3)
  for (i in seq_along(files)) {
    upload_file(con = con, tablename = "doodles", 
                zipfile = zipfile, filename = files[i])
    setTxtProgressBar(pb, i)
  }
  close(pb)
  # ะžัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ั‚ะฐะนะผะตั€
  tictoc::toc()
}

# 526.141 sec elapsed - ะบะพะฟะธั€ะพะฒะฐะฝะธะต SSD->SSD
# 558.879 sec elapsed - ะบะพะฟะธั€ะพะฒะฐะฝะธะต USB->SSD

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒก แƒ“แƒ แƒ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ“แƒ”แƒ‘แƒแƒ“แƒ”แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ“แƒ˜แƒกแƒ™แƒ˜แƒก แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒ›แƒแƒฎแƒแƒกแƒ˜แƒแƒ—แƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒฎแƒ”แƒ“แƒ•แƒ˜แƒ—. แƒฉแƒ•แƒ”แƒœแƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒ”แƒ แƒ—แƒ˜ SSD-แƒจแƒ˜ แƒแƒœ แƒคแƒšแƒ”แƒจ แƒ“แƒ แƒแƒ˜แƒ•แƒ˜แƒ“แƒแƒœ (แƒฌแƒงแƒแƒ แƒ แƒคแƒแƒ˜แƒšแƒ˜) SSD-แƒ›แƒ“แƒ” (DB) แƒ™แƒ˜แƒ—แƒฎแƒ•แƒแƒกแƒ แƒ“แƒ แƒฉแƒแƒฌแƒ”แƒ แƒแƒก 10 แƒฌแƒฃแƒ—แƒ–แƒ” แƒœแƒแƒ™แƒšแƒ”แƒ‘ แƒ“แƒ แƒ แƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ.

แƒ™แƒ˜แƒ“แƒ”แƒ• แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒฌแƒแƒ›แƒ˜ แƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒกแƒ•แƒ”แƒขแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒแƒก แƒ›แƒ—แƒ”แƒšแƒ˜ แƒ™แƒšแƒแƒกแƒ˜แƒก แƒšแƒ”แƒ˜แƒ‘แƒšแƒ˜แƒ— แƒ“แƒ แƒ˜แƒœแƒ“แƒ”แƒฅแƒกแƒ˜แƒก แƒกแƒ•แƒ”แƒขแƒ˜แƒ— (ORDERED INDEX) แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒœแƒแƒ›แƒ แƒ”แƒ‘แƒ˜แƒ—, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒ—แƒแƒช แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒ“แƒแƒ™แƒ•แƒ˜แƒ แƒ•แƒ”แƒ‘แƒ˜แƒก แƒœแƒ˜แƒ›แƒฃแƒจแƒ˜แƒก แƒแƒฆแƒ”แƒ‘แƒ แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒกแƒแƒก:

แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ˜แƒ—แƒ˜ แƒกแƒ•แƒ”แƒขแƒ”แƒ‘แƒ˜แƒก แƒ“แƒ แƒ˜แƒœแƒ“แƒ”แƒฅแƒกแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ

message("Generate lables")
invisible(DBI::dbExecute(con, "ALTER TABLE doodles ADD label_int int"))
invisible(DBI::dbExecute(con, "UPDATE doodles SET label_int = dense_rank() OVER (ORDER BY word) - 1"))

message("Generate row numbers")
invisible(DBI::dbExecute(con, "ALTER TABLE doodles ADD id serial"))
invisible(DBI::dbExecute(con, "CREATE ORDERED INDEX doodles_id_ord_idx ON doodles(id)"))

แƒคแƒ แƒ”แƒœแƒ˜แƒก แƒ“แƒ แƒแƒก แƒฏแƒ’แƒฃแƒคแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒก แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ˜แƒก แƒ’แƒแƒ“แƒแƒกแƒแƒญแƒ แƒ”แƒšแƒแƒ“, แƒฉแƒ•แƒ”แƒœ แƒ’แƒ•แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ“แƒ แƒ›แƒแƒ’แƒ˜แƒ“แƒ˜แƒ“แƒแƒœ แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ˜แƒ—แƒ˜ แƒ แƒ˜แƒ’แƒ”แƒ‘แƒ˜แƒก แƒแƒ›แƒแƒฆแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒฅแƒกแƒ˜แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒ›แƒ˜แƒฆแƒฌแƒ”แƒ•แƒ. doodles. แƒแƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— 3 แƒฎแƒ แƒ˜แƒ™แƒ˜. แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒ˜แƒงแƒ แƒ˜แƒ› แƒขแƒ˜แƒžแƒ˜แƒก แƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒชแƒ˜แƒ แƒ”แƒ‘แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ˜แƒœแƒแƒฎแƒแƒ•แƒก แƒ“แƒแƒ™แƒ•แƒ˜แƒ แƒ•แƒ”แƒ‘แƒ˜แƒก ID-แƒก. แƒแƒ แƒ˜แƒ’แƒ˜แƒœแƒแƒšแƒฃแƒ  แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒœแƒแƒ™แƒ แƒ”แƒ‘แƒจแƒ˜ ID-แƒ˜แƒก แƒจแƒ”แƒกแƒแƒœแƒแƒฎแƒแƒ“ แƒกแƒแƒญแƒ˜แƒ แƒ แƒขแƒ˜แƒžแƒ˜ แƒแƒ แƒ˜แƒก bigint, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ“แƒแƒ™แƒ•แƒ˜แƒ แƒ•แƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒก แƒฎแƒ“แƒ˜แƒก แƒ›แƒแƒ—แƒ˜ แƒ˜แƒ“แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒแƒ แƒ”แƒ‘แƒ˜แƒก, แƒ แƒ˜แƒ’แƒ˜แƒ—แƒ˜ แƒ แƒ˜แƒชแƒฎแƒ•แƒ˜แƒก แƒขแƒแƒšแƒ˜, แƒขแƒ˜แƒžแƒจแƒ˜ แƒ›แƒแƒ แƒ’แƒ”แƒ‘แƒแƒก int. แƒแƒ› แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒซแƒ”แƒ‘แƒœแƒ แƒ‘แƒ”แƒ•แƒ แƒแƒ“ แƒฃแƒคแƒ แƒ แƒกแƒฌแƒ แƒแƒคแƒ˜แƒ. แƒ›แƒ”แƒแƒ แƒ” แƒฎแƒ แƒ˜แƒ™แƒ˜ แƒ˜แƒงแƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ ORDERED INDEX - แƒแƒ› แƒ’แƒแƒ“แƒแƒฌแƒงแƒ•แƒ”แƒขแƒ˜แƒšแƒ”แƒ‘แƒแƒ›แƒ“แƒ” แƒ›แƒ˜แƒ•แƒ”แƒ“แƒ˜แƒ— แƒ”แƒ›แƒžแƒ˜แƒ แƒ˜แƒฃแƒšแƒแƒ“, แƒงแƒ•แƒ”แƒšแƒ แƒแƒ แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜แƒก แƒ’แƒแƒ•แƒšแƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜. แƒ›แƒ”แƒกแƒแƒ›แƒ” แƒ˜แƒงแƒ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜แƒ–แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ. แƒ›แƒ”แƒ—แƒแƒ“แƒ˜แƒก แƒแƒ แƒกแƒ˜ แƒแƒ แƒ˜แƒก แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ”แƒ แƒ—แƒฎแƒ”แƒš แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ PREPARE แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒœแƒแƒ—แƒฅแƒ•แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ’แƒแƒ›แƒ˜ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— แƒ˜แƒ›แƒแƒ•แƒ” แƒขแƒ˜แƒžแƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒกแƒแƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒกแƒ˜แƒœแƒแƒ›แƒ“แƒ•แƒ˜แƒšแƒ”แƒจแƒ˜ แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒฃแƒžแƒ˜แƒ แƒแƒขแƒ”แƒกแƒแƒ‘แƒ แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ—แƒแƒœ แƒจแƒ”แƒ“แƒแƒ แƒ”แƒ‘แƒ˜แƒ— SELECT แƒแƒฆแƒ›แƒแƒฉแƒœแƒ“แƒ แƒกแƒขแƒแƒขแƒ˜แƒกแƒขแƒ˜แƒ™แƒฃแƒ แƒ˜ แƒชแƒ“แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒคแƒแƒ แƒ’แƒšแƒ”แƒ‘แƒจแƒ˜.

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒ˜ แƒ›แƒแƒ˜แƒฎแƒ›แƒแƒ แƒก แƒแƒ แƒแƒฃแƒ›แƒ”แƒขแƒ”แƒก 450 MB แƒแƒžแƒ”แƒ แƒแƒขแƒ˜แƒฃแƒšแƒ˜ แƒ›แƒ”แƒฎแƒกแƒ˜แƒ”แƒ แƒ”แƒ‘แƒ. แƒแƒœแƒฃ, แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒ“แƒแƒ˜แƒขแƒแƒœแƒแƒ— แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒœแƒแƒ™แƒ แƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ˜แƒฌแƒแƒœแƒ˜แƒก แƒแƒ—แƒแƒ‘แƒ˜แƒ— แƒ’แƒ˜แƒ’แƒแƒ‘แƒแƒ˜แƒขแƒก, แƒ—แƒ˜แƒ—แƒฅแƒ›แƒ˜แƒก แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ  แƒกแƒแƒ‘แƒ˜แƒฃแƒฏแƒ”แƒขแƒ แƒแƒžแƒแƒ แƒแƒขแƒฃแƒ แƒแƒ–แƒ”, แƒ›แƒแƒ— แƒจแƒแƒ แƒ˜แƒก แƒ–แƒแƒ’แƒ˜แƒ”แƒ แƒ— แƒ”แƒ แƒ—แƒ‘แƒแƒ แƒข แƒ›แƒแƒฌแƒงแƒแƒ‘แƒ˜แƒšแƒแƒ‘แƒแƒ–แƒ”, แƒ แƒแƒช แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ›แƒแƒ’แƒแƒ แƒ˜แƒ.

แƒ แƒฉแƒ”แƒ‘แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ (แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ˜แƒ—แƒ˜) แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒžแƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒ’แƒแƒ–แƒแƒ›แƒ•แƒ แƒ“แƒ แƒกแƒ™แƒแƒšแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒคแƒแƒกแƒ”แƒ‘แƒ แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒ–แƒแƒ›แƒ˜แƒก แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ แƒฉแƒ”แƒ•แƒ˜แƒกแƒแƒก:

แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ˜แƒก แƒกแƒแƒแƒ แƒ˜แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ แƒœแƒ˜แƒจแƒแƒœแƒ˜

library(ggplot2)

set.seed(0)
# ะŸะพะดะบะปัŽั‡ะตะฝะธะต ะบ ะฑะฐะทะต ะดะฐะฝะฝั‹ั…
con <- DBI::dbConnect(MonetDBLite::MonetDBLite(), Sys.getenv("DBDIR"))

# ะคัƒะฝะบั†ะธั ะดะปั ะฟะพะดะณะพั‚ะพะฒะบะธ ะทะฐะฟั€ะพัะฐ ะฝะฐ ัั‚ะพั€ะพะฝะต ัะตั€ะฒะตั€ะฐ
prep_sql <- function(batch_size) {
  sql <- sprintf("PREPARE SELECT id FROM doodles WHERE id IN (%s)",
                 paste(rep("?", batch_size), collapse = ","))
  res <- DBI::dbSendQuery(con, sql)
  return(res)
}

# ะคัƒะฝะบั†ะธั ะดะปั ะธะทะฒะปะตั‡ะตะฝะธั ะดะฐะฝะฝั‹ั…
fetch_data <- function(rs, batch_size) {
  ids <- sample(seq_len(n), batch_size)
  res <- DBI::dbFetch(DBI::dbBind(rs, as.list(ids)))
  return(res)
}

# ะŸั€ะพะฒะตะดะตะฝะธะต ะทะฐะผะตั€ะฐ
res_bench <- bench::press(
  batch_size = 2^(4:10),
  {
    rs <- prep_sql(batch_size)
    bench::mark(
      fetch_data(rs, batch_size),
      min_iterations = 50L
    )
  }
)
# ะŸะฐั€ะฐะผะตั‚ั€ั‹ ะฑะตะฝั‡ะผะฐั€ะบะฐ
cols <- c("batch_size", "min", "median", "max", "itr/sec", "total_time", "n_itr")
res_bench[, cols]

#   batch_size      min   median      max `itr/sec` total_time n_itr
#        <dbl> <bch:tm> <bch:tm> <bch:tm>     <dbl>   <bch:tm> <int>
# 1         16   23.6ms  54.02ms  93.43ms     18.8        2.6s    49
# 2         32     38ms  84.83ms 151.55ms     11.4       4.29s    49
# 3         64   63.3ms 175.54ms 248.94ms     5.85       8.54s    50
# 4        128   83.2ms 341.52ms 496.24ms     3.00      16.69s    50
# 5        256  232.8ms 653.21ms 847.44ms     1.58      31.66s    50
# 6        512  784.6ms    1.41s    1.98s     0.740       1.1m    49
# 7       1024  681.7ms    2.72s    4.06s     0.377      2.16m    49

ggplot(res_bench, aes(x = factor(batch_size), y = median, group = 1)) +
  geom_point() +
  geom_line() +
  ylab("median time, s") +
  theme_minimal()

DBI::dbDisconnect(con, shutdown = TRUE)

Quick Draw Doodle Recognition: แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฃแƒ›แƒ”แƒ’แƒแƒ‘แƒ แƒ“แƒ”แƒ— R, C++ แƒ“แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒš แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒก

2. แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒ

แƒ›แƒ—แƒ”แƒšแƒ˜ แƒฏแƒ’แƒฃแƒคแƒ˜แƒก แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒ˜ แƒจแƒ”แƒ“แƒ’แƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒœแƒแƒ‘แƒ˜แƒฏแƒ”แƒ‘แƒ˜แƒกแƒ’แƒแƒœ:

  1. แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” JSON-แƒ˜แƒก แƒ’แƒแƒ แƒฉแƒ”แƒ•แƒ, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ•แƒ”แƒฅแƒขแƒแƒ แƒ”แƒ‘แƒก แƒฌแƒ”แƒ แƒขแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒ™แƒแƒแƒ แƒ“แƒ˜แƒœแƒแƒขแƒ”แƒ‘แƒ˜แƒ—.
  2. แƒกแƒแƒญแƒ˜แƒ แƒ แƒ–แƒแƒ›แƒ˜แƒก แƒกแƒฃแƒ แƒแƒ—แƒ–แƒ” (แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, 256ร—256 แƒแƒœ 128ร—128) แƒฌแƒ”แƒ แƒขแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒ™แƒแƒแƒ แƒ“แƒ˜แƒœแƒแƒขแƒ”แƒ‘แƒ–แƒ” แƒ“แƒแƒงแƒ แƒ“แƒœแƒแƒ‘แƒ˜แƒ— แƒคแƒ”แƒ แƒแƒ“แƒ˜ แƒฎแƒแƒ–แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒฎแƒแƒขแƒ•แƒ.
  3. แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒขแƒ”แƒœแƒ–แƒแƒ แƒแƒ“ แƒ’แƒแƒ“แƒแƒฅแƒชแƒ”แƒ•แƒ.

แƒžแƒ˜แƒ—แƒแƒœแƒ˜แƒก แƒ‘แƒ˜แƒ แƒ—แƒ•แƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก แƒ™แƒแƒœแƒ™แƒฃแƒ แƒกแƒ˜แƒก แƒคแƒแƒ แƒ’แƒšแƒ”แƒ‘แƒจแƒ˜, แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ แƒ›แƒแƒ’แƒ•แƒแƒ แƒ“แƒ แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒแƒ“ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— OpenCV. แƒ”แƒ แƒ—-แƒ”แƒ แƒ—แƒ˜ แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜ แƒ“แƒ แƒแƒจแƒ™แƒแƒ แƒ แƒแƒœแƒแƒšแƒแƒ’แƒ˜ R-แƒจแƒ˜ แƒแƒกแƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒ:

JSON-แƒ˜แƒก แƒขแƒ”แƒœแƒกแƒแƒ แƒจแƒ˜ แƒ™แƒแƒœแƒ•แƒ”แƒ แƒขแƒแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ R-แƒจแƒ˜

r_process_json_str <- function(json, line.width = 3, 
                               color = TRUE, scale = 1) {
  # ะŸะฐั€ัะธะฝะณ JSON
  coords <- jsonlite::fromJSON(json, simplifyMatrix = FALSE)
  tmp <- tempfile()
  # ะฃะดะฐะปัะตะผ ะฒั€ะตะผะตะฝะฝั‹ะน ั„ะฐะนะป ะฟะพ ะทะฐะฒะตั€ัˆะตะฝะธัŽ ั„ัƒะฝะบั†ะธะธ
  on.exit(unlink(tmp))
  png(filename = tmp, width = 256 * scale, height = 256 * scale, pointsize = 1)
  # ะŸัƒัั‚ะพะน ะณั€ะฐั„ะธะบ
  plot.new()
  # ะ ะฐะทะผะตั€ ะพะบะฝะฐ ะณั€ะฐั„ะธะบะฐ
  plot.window(xlim = c(256 * scale, 0), ylim = c(256 * scale, 0))
  # ะฆะฒะตั‚ะฐ ะปะธะฝะธะน
  cols <- if (color) rainbow(length(coords)) else "#000000"
  for (i in seq_along(coords)) {
    lines(x = coords[[i]][[1]] * scale, y = coords[[i]][[2]] * scale, 
          col = cols[i], lwd = line.width)
  }
  dev.off()
  # ะŸั€ะตะพะฑั€ะฐะทะพะฒะฐะฝะธะต ะธะทะพะฑั€ะฐะถะตะฝะธั ะฒ 3-ั… ะผะตั€ะฝั‹ะน ะผะฐััะธะฒ
  res <- png::readPNG(tmp)
  return(res)
}

r_process_json_vector <- function(x, ...) {
  res <- lapply(x, r_process_json_str, ...)
  # ะžะฑัŠะตะดะธะฝะตะฝะธะต 3-ั… ะผะตั€ะฝั‹ั… ะผะฐััะธะฒะพะฒ ะบะฐั€ั‚ะธะฝะพะบ ะฒ 4-ั… ะผะตั€ะฝั‹ะน ะฒ ั‚ะตะฝะทะพั€
  res <- do.call(abind::abind, c(res, along = 0))
  return(res)
}

แƒœแƒแƒฎแƒแƒ–แƒ˜ แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒฃแƒšแƒ˜ R แƒ˜แƒœแƒกแƒขแƒ แƒฃแƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— แƒ“แƒ แƒ˜แƒœแƒแƒฎแƒ”แƒ‘แƒ แƒ“แƒ แƒแƒ”แƒ‘แƒ˜แƒ— PNG-แƒจแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ˜แƒœแƒแƒฎแƒ”แƒ‘แƒ RAM-แƒจแƒ˜ (Linux-แƒ–แƒ” แƒ“แƒ แƒแƒ”แƒ‘แƒ˜แƒ—แƒ˜ R แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ”แƒ‘แƒ˜ แƒ’แƒแƒœแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒจแƒ˜ /tmp, แƒ“แƒแƒ›แƒแƒœแƒขแƒแƒŸแƒ”แƒ‘แƒฃแƒšแƒ˜ RAM-แƒจแƒ˜). แƒ”แƒก แƒคแƒแƒ˜แƒšแƒ˜ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ˜แƒ™แƒ˜แƒ—แƒฎแƒ”แƒ‘แƒ แƒกแƒแƒ›แƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒแƒœแƒ˜ แƒ›แƒแƒกแƒ˜แƒ•แƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ— 0-แƒ“แƒแƒœ 1-แƒ›แƒ“แƒ” แƒ แƒ˜แƒชแƒฎแƒ•แƒ”แƒ‘แƒ˜แƒ—. แƒ”แƒก แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ•แƒแƒœแƒ˜แƒ, แƒ แƒแƒ“แƒ’แƒแƒœ แƒฃแƒคแƒ แƒ แƒฉแƒ•แƒ”แƒฃแƒšแƒ”แƒ‘แƒ แƒ˜แƒ•แƒ˜ BMP แƒฌแƒแƒ˜แƒ™แƒ˜แƒ—แƒฎแƒ”แƒ‘แƒ แƒœแƒ”แƒ“แƒšแƒ”แƒฃแƒš แƒ›แƒแƒกแƒ˜แƒ•แƒจแƒ˜ แƒ—แƒ”แƒฅแƒ•แƒกแƒ›แƒ”แƒขแƒแƒ‘แƒ˜แƒ—แƒ˜ แƒคแƒ”แƒ แƒ˜แƒก แƒ™แƒแƒ“แƒ”แƒ‘แƒ˜แƒ—.

แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒแƒ›แƒแƒฌแƒ›แƒแƒ— แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜:

zip_file <- file.path("data", "train_simplified.zip")
csv_file <- "cat.csv"
unzip(zip_file, files = csv_file, exdir = tempdir(), 
      junkpaths = TRUE, unzip = getOption("unzip"))
tmp_data <- data.table::fread(file.path(tempdir(), csv_file), sep = ",", 
                              select = "drawing", nrows = 10000)
arr <- r_process_json_str(tmp_data[4, drawing])
dim(arr)
# [1] 256 256   3
plot(magick::image_read(arr))

Quick Draw Doodle Recognition: แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฃแƒ›แƒ”แƒ’แƒแƒ‘แƒ แƒ“แƒ”แƒ— R, C++ แƒ“แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒš แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒก

แƒ—แƒแƒ•แƒแƒ“ แƒžแƒแƒ แƒขแƒ˜แƒ แƒฉแƒแƒ›แƒแƒงแƒแƒšแƒ˜แƒ‘แƒ“แƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒœแƒแƒ˜แƒ แƒแƒ“:

res <- r_process_json_vector(tmp_data[1:4, drawing], scale = 0.5)
str(res)
 # num [1:4, 1:128, 1:128, 1:3] 1 1 1 1 1 1 1 1 1 1 ...
 # - attr(*, "dimnames")=List of 4
 #  ..$ : NULL
 #  ..$ : NULL
 #  ..$ : NULL
 #  ..$ : NULL

แƒ”แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ แƒฉแƒ•แƒ”แƒœแƒ—แƒ•แƒ˜แƒก แƒแƒ แƒแƒแƒžแƒขแƒ˜แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒฉแƒแƒœแƒ“แƒ, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ“แƒ˜แƒ“แƒ˜ แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒคแƒแƒ แƒ›แƒ˜แƒ แƒ”แƒ‘แƒแƒก แƒฃแƒฎแƒแƒ›แƒกแƒ˜ แƒ“แƒ แƒ แƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒ“แƒ แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ”แƒ— แƒ’แƒแƒ›แƒแƒ’แƒ•แƒ”แƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒœแƒ แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ™แƒแƒšแƒ”แƒ’แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒชแƒ“แƒ˜แƒšแƒ”แƒ‘แƒ แƒซแƒšแƒ˜แƒ”แƒ แƒ˜ แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—. OpenCV. แƒ˜แƒ› แƒ“แƒ แƒแƒก แƒแƒ  แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒ“แƒ แƒ›แƒ–แƒ แƒžแƒแƒ™แƒ”แƒขแƒ˜ R-แƒกแƒ—แƒ•แƒ˜แƒก (แƒแƒฎแƒšแƒ แƒแƒ  แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก), แƒแƒ›แƒ˜แƒขแƒแƒ› แƒกแƒแƒญแƒ˜แƒ แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒœแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ˜แƒœแƒ˜แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ แƒ“แƒแƒ˜แƒฌแƒ”แƒ แƒ C++-แƒจแƒ˜ R แƒ™แƒแƒ“แƒจแƒ˜ แƒ˜แƒœแƒขแƒ”แƒ’แƒ แƒ˜แƒ แƒ”แƒ‘แƒ˜แƒ—. Rcpp.

แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ˜แƒก แƒ’แƒแƒ“แƒแƒกแƒแƒญแƒ แƒ”แƒšแƒแƒ“ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ˜แƒฅแƒœแƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒžแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ”แƒ‘แƒ˜:

  1. OpenCV แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ—แƒแƒœ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒกแƒ แƒ“แƒ แƒฎแƒแƒ–แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒฎแƒแƒขแƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ  แƒ“แƒแƒ˜แƒœแƒกแƒขแƒแƒšแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ”แƒ‘แƒ˜ แƒ“แƒ แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜, แƒแƒกแƒ”แƒ•แƒ” แƒ“แƒ˜แƒœแƒแƒ›แƒ˜แƒฃแƒ แƒ˜ แƒšแƒ˜แƒœแƒ™แƒ”แƒ‘แƒ˜.

  2. xtensor แƒ›แƒ แƒแƒ•แƒแƒšแƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒแƒœ แƒ›แƒแƒกแƒ˜แƒ•แƒ”แƒ‘แƒ—แƒแƒœ แƒ“แƒ แƒขแƒ”แƒœแƒกแƒแƒ แƒ”แƒ‘แƒ—แƒแƒœ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒจแƒ”แƒ“แƒ˜แƒก แƒแƒ›แƒแƒ•แƒ” แƒกแƒแƒฎแƒ”แƒšแƒฌแƒแƒ“แƒ”แƒ‘แƒ˜แƒก R แƒžแƒแƒ™แƒ”แƒขแƒจแƒ˜. แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ˜แƒ›แƒฃแƒจแƒแƒแƒ— แƒ›แƒ แƒแƒ•แƒแƒšแƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒแƒœ แƒ›แƒแƒกแƒ˜แƒ•แƒ”แƒ‘แƒ—แƒแƒœ, แƒ แƒแƒ’แƒแƒ แƒช แƒ›แƒฌแƒ™แƒ แƒ˜แƒ•แƒ˜แƒก แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒ˜, แƒแƒกแƒ”แƒ•แƒ” แƒกแƒ•แƒ”แƒขแƒ˜แƒก แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒ˜ แƒ—แƒแƒœแƒ›แƒ˜แƒ›แƒ“แƒ”แƒ•แƒ แƒแƒ‘แƒ˜แƒ—.

  3. แƒœแƒฏแƒกแƒแƒœแƒ˜ JSON แƒ’แƒแƒกแƒแƒแƒœแƒแƒšแƒ˜แƒ–แƒ”แƒ‘แƒšแƒแƒ“. แƒ”แƒก แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ xtensor แƒแƒ•แƒขแƒแƒ›แƒแƒขแƒฃแƒ แƒแƒ“, แƒ—แƒฃ แƒ˜แƒก แƒแƒ แƒ˜แƒก แƒžแƒ แƒแƒ”แƒฅแƒขแƒจแƒ˜.

  4. RcppThread JSON-แƒ“แƒแƒœ แƒ•แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒก แƒ›แƒ แƒแƒ•แƒแƒšแƒกแƒแƒ แƒ—แƒฃแƒšแƒ˜แƒแƒœแƒ˜ แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒแƒ แƒ’แƒแƒœแƒ˜แƒ–แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ แƒแƒ› แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒ— แƒ›แƒแƒฌแƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜. แƒฃแƒคแƒ แƒ แƒžแƒแƒžแƒฃแƒšแƒแƒ แƒฃแƒšแƒ˜แƒ“แƒแƒœ Rcppแƒžแƒแƒ แƒแƒšแƒ”แƒšแƒฃแƒ แƒ˜ แƒžแƒแƒ™แƒ”แƒขแƒก, แƒกแƒฎแƒ•แƒ แƒกแƒแƒ™แƒ˜แƒ—แƒฎแƒ”แƒ‘แƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“, แƒแƒฅแƒ•แƒก แƒฉแƒแƒจแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ แƒงแƒฃแƒŸแƒ˜แƒก แƒจแƒ”แƒฌแƒงแƒ•แƒ”แƒขแƒ˜แƒก แƒ›แƒ”แƒฅแƒแƒœแƒ˜แƒ–แƒ›แƒ˜.

แƒแƒฆแƒกแƒแƒœแƒ˜แƒจแƒœแƒแƒ•แƒ˜แƒ, แƒ แƒแƒ› xtensor แƒฆแƒ•แƒ—แƒ˜แƒฃแƒ แƒ˜ แƒœแƒ˜แƒญแƒ˜ แƒแƒฆแƒ›แƒแƒฉแƒœแƒ“แƒ: แƒ’แƒแƒ แƒ“แƒ แƒ˜แƒ›แƒ˜แƒกแƒ, แƒ แƒแƒ› แƒ›แƒแƒก แƒแƒฅแƒ•แƒก แƒคแƒแƒ แƒ—แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒœแƒ˜แƒ แƒ”แƒ‘แƒ แƒ“แƒ แƒ›แƒแƒฆแƒแƒšแƒ˜ แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ, แƒ›แƒ˜แƒกแƒ˜ แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒ”แƒ‘แƒ˜ แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒกแƒแƒžแƒแƒกแƒฃแƒฎแƒ แƒแƒฆแƒ›แƒแƒฉแƒœแƒ“แƒœแƒ”แƒœ แƒ“แƒ แƒกแƒฌแƒ แƒแƒคแƒแƒ“ แƒ“แƒ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“ แƒฃแƒžแƒแƒกแƒฃแƒฎแƒ”แƒก แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ”แƒ‘แƒก. แƒ›แƒแƒ—แƒ˜ แƒ“แƒแƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ˜แƒ— แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ’แƒแƒฎแƒ“แƒ OpenCV แƒ›แƒแƒขแƒ แƒ˜แƒชแƒ”แƒ‘แƒ˜แƒก แƒขแƒ แƒแƒœแƒกแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ xtensor แƒขแƒ”แƒœแƒ–แƒแƒ แƒ”แƒ‘แƒแƒ“, แƒ˜แƒกแƒ”แƒ•แƒ” แƒ แƒแƒ’แƒแƒ แƒช 3-แƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒแƒœแƒ˜ แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒขแƒ”แƒœแƒกแƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ”แƒ แƒ—แƒ˜แƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒ–แƒ แƒกแƒฌแƒแƒ แƒ˜ แƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก 4-แƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒแƒœ แƒขแƒ”แƒœแƒ–แƒแƒ แƒจแƒ˜ (แƒ—แƒแƒ•แƒแƒ“ แƒžแƒแƒ แƒขแƒ˜แƒ).

แƒ›แƒแƒกแƒแƒšแƒ”แƒ‘แƒ˜ Rcpp, xtensor แƒ“แƒ RcppThread-แƒ˜แƒก แƒจแƒ”แƒกแƒแƒกแƒฌแƒแƒ•แƒšแƒแƒ“

https://thecoatlessprofessor.com/programming/unofficial-rcpp-api-documentation

https://docs.opencv.org/4.0.1/d7/dbd/group__imgproc.html

https://xtensor.readthedocs.io/en/latest/

https://xtensor.readthedocs.io/en/latest/file_loading.html#loading-json-data-into-xtensor

https://cran.r-project.org/web/packages/RcppThread/vignettes/RcppThread-vignette.pdf

แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ”แƒœ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ  แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒก แƒ“แƒ แƒ“แƒ˜แƒœแƒแƒ›แƒ˜แƒฃแƒ  แƒ™แƒแƒ•แƒจแƒ˜แƒ แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒแƒจแƒ˜ แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒš แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ”แƒ‘แƒ—แƒแƒœ, แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— แƒžแƒแƒ™แƒ”แƒขแƒจแƒ˜ แƒ“แƒแƒœแƒ”แƒ แƒ’แƒ˜แƒšแƒ˜ แƒ“แƒแƒœแƒแƒ›แƒแƒขแƒ˜แƒก แƒ›แƒ”แƒฅแƒแƒœแƒ˜แƒ–แƒ›แƒ˜. Rcpp. แƒ‘แƒ˜แƒšแƒ˜แƒ™แƒ”แƒ‘แƒ˜แƒกแƒ แƒ“แƒ แƒ“แƒ แƒแƒจแƒ”แƒ‘แƒ˜แƒก แƒแƒ•แƒขแƒแƒ›แƒแƒขแƒฃแƒ แƒแƒ“ แƒ›แƒแƒกแƒแƒซแƒ”แƒ‘แƒœแƒแƒ“, แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— แƒžแƒแƒžแƒฃแƒšแƒแƒ แƒฃแƒšแƒ˜ Linux แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ pkg-config.

Rcpp แƒ›แƒแƒ“แƒฃแƒšแƒ˜แƒก แƒ“แƒแƒœแƒ”แƒ แƒ’แƒ•แƒ OpenCV แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ˜แƒก แƒ’แƒแƒ›แƒแƒกแƒแƒงแƒ”แƒœแƒ”แƒ‘แƒšแƒแƒ“

Rcpp::registerPlugin("opencv", function() {
  # ะ’ะพะทะผะพะถะฝั‹ะต ะฝะฐะทะฒะฐะฝะธั ะฟะฐะบะตั‚ะฐ
  pkg_config_name <- c("opencv", "opencv4")
  # ะ‘ะธะฝะฐั€ะฝั‹ะน ั„ะฐะนะป ัƒั‚ะธะปะธั‚ั‹ pkg-config
  pkg_config_bin <- Sys.which("pkg-config")
  # ะŸั€ะพะฒั€ะตะบะฐ ะฝะฐะปะธั‡ะธั ัƒั‚ะธะปะธั‚ั‹ ะฒ ัะธัั‚ะตะผะต
  checkmate::assert_file_exists(pkg_config_bin, access = "x")
  # ะŸั€ะพะฒะตั€ะบะฐ ะฝะฐะปะธั‡ะธั ั„ะฐะนะปะฐ ะฝะฐัั‚ั€ะพะตะบ OpenCV ะดะปั pkg-config
  check <- sapply(pkg_config_name, 
                  function(pkg) system(paste(pkg_config_bin, pkg)))
  if (all(check != 0)) {
    stop("OpenCV config for the pkg-config not found", call. = FALSE)
  }

  pkg_config_name <- pkg_config_name[check == 0]
  list(env = list(
    PKG_CXXFLAGS = system(paste(pkg_config_bin, "--cflags", pkg_config_name), 
                          intern = TRUE),
    PKG_LIBS = system(paste(pkg_config_bin, "--libs", pkg_config_name), 
                      intern = TRUE)
  ))
})

แƒ›แƒแƒ“แƒฃแƒšแƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒแƒ“, แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ˜แƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒจแƒ˜ แƒจแƒ”แƒ˜แƒชแƒ•แƒšแƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ”แƒ‘แƒ˜:

Rcpp:::.plugins$opencv()$env

# $PKG_CXXFLAGS
# [1] "-I/usr/include/opencv"
#
# $PKG_LIBS
# [1] "-lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_datasets -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_line_descriptor -lopencv_optflow -lopencv_video -lopencv_plot -lopencv_reg -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_rgbd -lopencv_viz -lopencv_surface_matching -lopencv_text -lopencv_ximgproc -lopencv_calib3d -lopencv_features2d -lopencv_flann -lopencv_xobjdetect -lopencv_objdetect -lopencv_ml -lopencv_xphoto -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_photo -lopencv_imgproc -lopencv_core"

แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ˜แƒก แƒ™แƒแƒ“แƒ˜ JSON-แƒ˜แƒก แƒ’แƒแƒ แƒฉแƒ”แƒ•แƒ˜แƒกแƒ แƒ“แƒ แƒ›แƒแƒ“แƒ”แƒšแƒ–แƒ” แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒ˜แƒก แƒกแƒ”แƒ แƒ˜แƒ˜แƒก แƒ’แƒ”แƒœแƒ”แƒ แƒ˜แƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ›แƒแƒชแƒ”แƒ›แƒฃแƒšแƒ˜แƒ แƒกแƒžแƒแƒ˜แƒšแƒ”แƒ แƒ˜แƒก แƒฅแƒ•แƒ”แƒจ. แƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒ แƒ˜แƒ’แƒจแƒ˜, แƒ“แƒแƒแƒ›แƒแƒขแƒ”แƒ— แƒแƒ“แƒ’แƒ˜แƒšแƒแƒ‘แƒ แƒ˜แƒ•แƒ˜ แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜แƒก แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒกแƒแƒซแƒ”แƒ‘แƒœแƒแƒ“ (แƒกแƒแƒญแƒ˜แƒ แƒแƒ ndjson-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก):

Sys.setenv("PKG_CXXFLAGS" = paste0("-I", normalizePath(file.path("src"))))

JSON-แƒ˜แƒก แƒขแƒ”แƒœแƒกแƒแƒ แƒแƒ“ แƒ’แƒแƒ“แƒแƒฅแƒชแƒ”แƒ•แƒ˜แƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ C++-แƒจแƒ˜

// [[Rcpp::plugins(cpp14)]]
// [[Rcpp::plugins(opencv)]]
// [[Rcpp::depends(xtensor)]]
// [[Rcpp::depends(RcppThread)]]

#include <xtensor/xjson.hpp>
#include <xtensor/xadapt.hpp>
#include <xtensor/xview.hpp>
#include <xtensor-r/rtensor.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <Rcpp.h>
#include <RcppThread.h>

// ะกะธะฝะพะฝะธะผั‹ ะดะปั ั‚ะธะฟะพะฒ
using RcppThread::parallelFor;
using json = nlohmann::json;
using points = xt::xtensor<double,2>;     // ะ˜ะทะฒะปะตั‡ั‘ะฝะฝั‹ะต ะธะท JSON ะบะพะพั€ะดะธะฝะฐั‚ั‹ ั‚ะพั‡ะตะบ
using strokes = std::vector<points>;      // ะ˜ะทะฒะปะตั‡ั‘ะฝะฝั‹ะต ะธะท JSON ะบะพะพั€ะดะธะฝะฐั‚ั‹ ั‚ะพั‡ะตะบ
using xtensor3d = xt::xtensor<double, 3>; // ะขะตะฝะทะพั€ ะดะปั ั…ั€ะฐะฝะตะฝะธั ะผะฐั‚ั€ะธั†ั‹ ะธะทะพะพะฑั€ะฐะถะตะฝะธั
using xtensor4d = xt::xtensor<double, 4>; // ะขะตะฝะทะพั€ ะดะปั ั…ั€ะฐะฝะตะฝะธั ะผะฝะพะถะตัั‚ะฒะฐ ะธะทะพะฑั€ะฐะถะตะฝะธะน
using rtensor3d = xt::rtensor<double, 3>; // ะžะฑั‘ั€ั‚ะบะฐ ะดะปั ัะบัะฟะพั€ั‚ะฐ ะฒ R
using rtensor4d = xt::rtensor<double, 4>; // ะžะฑั‘ั€ั‚ะบะฐ ะดะปั ัะบัะฟะพั€ั‚ะฐ ะฒ R

// ะกั‚ะฐั‚ะธั‡ะตัะบะธะต ะบะพะฝัั‚ะฐะฝั‚ั‹
// ะ ะฐะทะผะตั€ ะธะทะพะฑั€ะฐะถะตะฝะธั ะฒ ะฟะธะบัะตะปัั…
const static int SIZE = 256;
// ะขะธะฟ ะปะธะฝะธะธ
// ะกะผ. https://en.wikipedia.org/wiki/Pixel_connectivity#2-dimensional
const static int LINE_TYPE = cv::LINE_4;
// ะขะพะปั‰ะธะฝะฐ ะปะธะฝะธะธ ะฒ ะฟะธะบัะตะปัั…
const static int LINE_WIDTH = 3;
// ะะปะณะพั€ะธั‚ะผ ั€ะตัะฐะนะทะฐ
// https://docs.opencv.org/3.1.0/da/d54/group__imgproc__transform.html#ga5bb5a1fea74ea38e1a5445ca803ff121
const static int RESIZE_TYPE = cv::INTER_LINEAR;

// ะจะฐะฑะปะพะฝ ะดะปั ะบะพะฝะฒะตั€ั‚ะธั€ะพะฒะฐะฝะธั OpenCV-ะผะฐั‚ั€ะธั†ั‹ ะฒ ั‚ะตะฝะทะพั€
template <typename T, int NCH, typename XT=xt::xtensor<T,3,xt::layout_type::column_major>>
XT to_xt(const cv::Mat_<cv::Vec<T, NCH>>& src) {
  // ะ ะฐะทะผะตั€ะฝะพัั‚ัŒ ั†ะตะปะตะฒะพะณะพ ั‚ะตะฝะทะพั€ะฐ
  std::vector<int> shape = {src.rows, src.cols, NCH};
  // ะžะฑั‰ะตะต ะบะพะปะธั‡ะตัั‚ะฒะพ ัะปะตะผะตะฝั‚ะพะฒ ะฒ ะผะฐััะธะฒะต
  size_t size = src.total() * NCH;
  // ะŸั€ะตะพะฑั€ะฐะทะพะฒะฐะฝะธะต cv::Mat ะฒ xt::xtensor
  XT res = xt::adapt((T*) src.data, size, xt::no_ownership(), shape);
  return res;
}

// ะŸั€ะตะพะฑั€ะฐะทะพะฒะฐะฝะธะต JSON ะฒ ัะฟะธัะพะบ ะบะพะพั€ะดะธะฝะฐั‚ ั‚ะพั‡ะตะบ
strokes parse_json(const std::string& x) {
  auto j = json::parse(x);
  // ะ ะตะทัƒะปัŒั‚ะฐั‚ ะฟะฐั€ัะธะฝะณะฐ ะดะพะปะถะตะฝ ะฑั‹ั‚ัŒ ะผะฐััะธะฒะพะผ
  if (!j.is_array()) {
    throw std::runtime_error("'x' must be JSON array.");
  }
  strokes res;
  res.reserve(j.size());
  for (const auto& a: j) {
    // ะšะฐะถะดั‹ะน ัะปะตะผะตะฝั‚ ะผะฐััะธะฒะฐ ะดะพะปะถะตะฝ ะฑั‹ั‚ัŒ 2-ะผะตั€ะฝั‹ะผ ะผะฐััะธะฒะพะผ
    if (!a.is_array() || a.size() != 2) {
      throw std::runtime_error("'x' must include only 2d arrays.");
    }
    // ะ˜ะทะฒะปะตั‡ะตะฝะธะต ะฒะตะบั‚ะพั€ะฐ ั‚ะพั‡ะตะบ
    auto p = a.get<points>();
    res.push_back(p);
  }
  return res;
}

// ะžั‚ั€ะธัะพะฒะบะฐ ะปะธะฝะธะน
// ะฆะฒะตั‚ะฐ HSV
cv::Mat ocv_draw_lines(const strokes& x, bool color = true) {
  // ะ˜ัั…ะพะดะฝั‹ะน ั‚ะธะฟ ะผะฐั‚ั€ะธั†ั‹
  auto stype = color ? CV_8UC3 : CV_8UC1;
  // ะ˜ั‚ะพะณะพะฒั‹ะน ั‚ะธะฟ ะผะฐั‚ั€ะธั†ั‹
  auto dtype = color ? CV_32FC3 : CV_32FC1;
  auto bg = color ? cv::Scalar(0, 0, 255) : cv::Scalar(255);
  auto col = color ? cv::Scalar(0, 255, 220) : cv::Scalar(0);
  cv::Mat img = cv::Mat(SIZE, SIZE, stype, bg);
  // ะšะพะปะธั‡ะตัั‚ะฒะพ ะปะธะฝะธะน
  size_t n = x.size();
  for (const auto& s: x) {
    // ะšะพะปะธั‡ะตัั‚ะฒะพ ั‚ะพั‡ะตะบ ะฒ ะปะธะฝะธะธ
    size_t n_points = s.shape()[1];
    for (size_t i = 0; i < n_points - 1; ++i) {
      // ะขะพั‡ะบะฐ ะฝะฐั‡ะฐะปะฐ ัˆั‚ั€ะธั…ะฐ
      cv::Point from(s(0, i), s(1, i));
      // ะขะพั‡ะบะฐ ะพะบะพะฝั‡ะฐะฝะธั ัˆั‚ั€ะธั…ะฐ
      cv::Point to(s(0, i + 1), s(1, i + 1));
      // ะžั‚ั€ะธัะพะฒะบะฐ ะปะธะฝะธะธ
      cv::line(img, from, to, col, LINE_WIDTH, LINE_TYPE);
    }
    if (color) {
      // ะœะตะฝัะตะผ ั†ะฒะตั‚ ะปะธะฝะธะธ
      col[0] += 180 / n;
    }
  }
  if (color) {
    // ะœะตะฝัะตะผ ั†ะฒะตั‚ะพะฒะพะต ะฟั€ะตะดัั‚ะฐะฒะปะตะฝะธะต ะฝะฐ RGB
    cv::cvtColor(img, img, cv::COLOR_HSV2RGB);
  }
  // ะœะตะฝัะตะผ ั„ะพั€ะผะฐั‚ ะฟั€ะตะดัั‚ะฐะฒะปะตะฝะธั ะฝะฐ float32 ั ะดะธะฐะฟะฐะทะพะฝะพะผ [0, 1]
  img.convertTo(img, dtype, 1 / 255.0);
  return img;
}

// ะžะฑั€ะฐะฑะพั‚ะบะฐ JSON ะธ ะฟะพะปัƒั‡ะตะฝะธะต ั‚ะตะฝะทะพั€ะฐ ั ะดะฐะฝะฝั‹ะผะธ ะธะทะพะฑั€ะฐะถะตะฝะธั
xtensor3d process(const std::string& x, double scale = 1.0, bool color = true) {
  auto p = parse_json(x);
  auto img = ocv_draw_lines(p, color);
  if (scale != 1) {
    cv::Mat out;
    cv::resize(img, out, cv::Size(), scale, scale, RESIZE_TYPE);
    cv::swap(img, out);
    out.release();
  }
  xtensor3d arr = color ? to_xt<double,3>(img) : to_xt<double,1>(img);
  return arr;
}

// [[Rcpp::export]]
rtensor3d cpp_process_json_str(const std::string& x, 
                               double scale = 1.0, 
                               bool color = true) {
  xtensor3d res = process(x, scale, color);
  return res;
}

// [[Rcpp::export]]
rtensor4d cpp_process_json_vector(const std::vector<std::string>& x, 
                                  double scale = 1.0, 
                                  bool color = false) {
  size_t n = x.size();
  size_t dim = floor(SIZE * scale);
  size_t channels = color ? 3 : 1;
  xtensor4d res({n, dim, dim, channels});
  parallelFor(0, n, [&x, &res, scale, color](int i) {
    xtensor3d tmp = process(x[i], scale, color);
    auto view = xt::view(res, i, xt::all(), xt::all(), xt::all());
    view = tmp;
  });
  return res;
}

แƒ”แƒก แƒ™แƒแƒ“แƒ˜ แƒฃแƒœแƒ“แƒ แƒ’แƒแƒœแƒ—แƒแƒ•แƒกแƒ“แƒ”แƒก แƒคแƒแƒ˜แƒšแƒจแƒ˜ src/cv_xt.cpp แƒ“แƒ แƒ™แƒแƒ›แƒžแƒ˜แƒšแƒแƒชแƒ˜แƒ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒ— Rcpp::sourceCpp(file = "src/cv_xt.cpp", env = .GlobalEnv); แƒแƒกแƒ”แƒ•แƒ” แƒกแƒแƒญแƒ˜แƒ แƒแƒ แƒกแƒแƒ›แƒฃแƒจแƒแƒแƒกแƒ—แƒ•แƒ˜แƒก nlohmann/json.hpp แƒกแƒแƒฅแƒแƒ แƒ—แƒ•แƒ”แƒšแƒแƒก แƒ แƒ”แƒžแƒแƒ–แƒ˜แƒชแƒ˜แƒ”แƒ‘แƒ˜. แƒ™แƒแƒ“แƒ˜ แƒ“แƒแƒงแƒแƒคแƒ˜แƒšแƒ˜แƒ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒ“:

  • to_xt - แƒจแƒแƒ‘แƒšแƒแƒœแƒฃแƒ แƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒขแƒ แƒ˜แƒชแƒ˜แƒก แƒ’แƒแƒ แƒ“แƒแƒฅแƒ›แƒœแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก (cv::Mat) แƒขแƒ”แƒœแƒ–แƒแƒ แƒ–แƒ” xt::xtensor;

  • parse_json โ€” แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒแƒแƒœแƒแƒšแƒ˜แƒ–แƒ”แƒ‘แƒก JSON แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒก, แƒแƒ›แƒแƒ˜แƒฆแƒ”แƒ‘แƒก แƒฌแƒ”แƒ แƒขแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒ™แƒแƒแƒ แƒ“แƒ˜แƒœแƒแƒขแƒ”แƒ‘แƒก แƒ“แƒ แƒแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒก แƒ›แƒแƒ— แƒ•แƒ”แƒฅแƒขแƒแƒ แƒจแƒ˜;

  • ocv_draw_lines โ€” แƒฌแƒแƒ แƒ›แƒแƒฅแƒ›แƒœแƒ˜แƒšแƒ˜ แƒฌแƒ”แƒ แƒขแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒ•แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ“แƒแƒœ แƒฎแƒแƒ–แƒแƒ•แƒก แƒ›แƒ แƒแƒ•แƒแƒšแƒคแƒ”แƒ แƒแƒ•แƒแƒœ แƒฎแƒแƒ–แƒ”แƒ‘แƒก;

  • process โ€” แƒแƒ”แƒ แƒ—แƒ˜แƒแƒœแƒ”แƒ‘แƒก แƒ–แƒ”แƒ›แƒแƒฎแƒกแƒ”แƒœแƒ”แƒ‘แƒฃแƒš แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒก แƒ“แƒ แƒแƒกแƒ”แƒ•แƒ” แƒแƒ›แƒแƒขแƒ”แƒ‘แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒกแƒแƒฎแƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒกแƒจแƒขแƒแƒ‘แƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒแƒก;

  • cpp_process_json_str - แƒจแƒ”แƒคแƒฃแƒ—แƒ•แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒ–แƒ” process, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒฎแƒ“แƒ”แƒœแƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜แƒก แƒ”แƒฅแƒกแƒžแƒแƒ แƒขแƒก R-แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒจแƒ˜ (แƒ›แƒ แƒแƒ•แƒแƒšแƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒแƒœแƒ˜ แƒ›แƒแƒกแƒ˜แƒ•แƒ˜);

  • cpp_process_json_vector - แƒจแƒ”แƒคแƒฃแƒ—แƒ•แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒ–แƒ” cpp_process_json_str, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ“แƒแƒแƒ›แƒฃแƒจแƒแƒ•แƒแƒ— แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ˜ แƒ•แƒ”แƒฅแƒขแƒแƒ แƒ˜ แƒ›แƒ แƒแƒ•แƒแƒšแƒซแƒแƒคแƒ˜แƒก แƒ แƒ”แƒŸแƒ˜แƒ›แƒจแƒ˜.

แƒ›แƒ แƒแƒ•แƒแƒšแƒคแƒ”แƒ แƒแƒ“แƒ˜ แƒฎแƒแƒ–แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒกแƒแƒฎแƒแƒขแƒแƒ“ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ˜แƒฅแƒœแƒ HSV แƒคแƒ”แƒ แƒ˜แƒก แƒ›แƒแƒ“แƒ”แƒšแƒ˜, แƒ แƒแƒกแƒแƒช แƒ›แƒแƒฐแƒงแƒ•แƒ แƒ™แƒแƒœแƒ•แƒ”แƒ แƒขแƒแƒชแƒ˜แƒ RGB-แƒ–แƒ”. แƒ›แƒแƒ“แƒ˜แƒ— แƒจแƒ”แƒ•แƒแƒ›แƒแƒฌแƒ›แƒแƒ— แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜:

arr <- cpp_process_json_str(tmp_data[4, drawing])
dim(arr)
# [1] 256 256   3
plot(magick::image_read(arr))

Quick Draw Doodle Recognition: แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฃแƒ›แƒ”แƒ’แƒแƒ‘แƒ แƒ“แƒ”แƒ— R, C++ แƒ“แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒš แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒก
แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒจแƒ”แƒ“แƒแƒ แƒ”แƒ‘แƒ R แƒ“แƒ C++-แƒจแƒ˜

res_bench <- bench::mark(
  r_process_json_str(tmp_data[4, drawing], scale = 0.5),
  cpp_process_json_str(tmp_data[4, drawing], scale = 0.5),
  check = FALSE,
  min_iterations = 100
)
# ะŸะฐั€ะฐะผะตั‚ั€ั‹ ะฑะตะฝั‡ะผะฐั€ะบะฐ
cols <- c("expression", "min", "median", "max", "itr/sec", "total_time", "n_itr")
res_bench[, cols]

#   expression                min     median       max `itr/sec` total_time  n_itr
#   <chr>                <bch:tm>   <bch:tm>  <bch:tm>     <dbl>   <bch:tm>  <int>
# 1 r_process_json_str     3.49ms     3.55ms    4.47ms      273.      490ms    134
# 2 cpp_process_json_str   1.94ms     2.02ms    5.32ms      489.      497ms    243

library(ggplot2)
# ะŸั€ะพะฒะตะดะตะฝะธะต ะทะฐะผะตั€ะฐ
res_bench <- bench::press(
  batch_size = 2^(4:10),
  {
    .data <- tmp_data[sample(seq_len(.N), batch_size), drawing]
    bench::mark(
      r_process_json_vector(.data, scale = 0.5),
      cpp_process_json_vector(.data,  scale = 0.5),
      min_iterations = 50,
      check = FALSE
    )
  }
)

res_bench[, cols]

#    expression   batch_size      min   median      max `itr/sec` total_time n_itr
#    <chr>             <dbl> <bch:tm> <bch:tm> <bch:tm>     <dbl>   <bch:tm> <int>
#  1 r                   16   50.61ms  53.34ms  54.82ms    19.1     471.13ms     9
#  2 cpp                 16    4.46ms   5.39ms   7.78ms   192.      474.09ms    91
#  3 r                   32   105.7ms 109.74ms 212.26ms     7.69        6.5s    50
#  4 cpp                 32    7.76ms  10.97ms  15.23ms    95.6     522.78ms    50
#  5 r                   64  211.41ms 226.18ms 332.65ms     3.85      12.99s    50
#  6 cpp                 64   25.09ms  27.34ms  32.04ms    36.0        1.39s    50
#  7 r                  128   534.5ms 627.92ms 659.08ms     1.61      31.03s    50
#  8 cpp                128   56.37ms  58.46ms  66.03ms    16.9        2.95s    50
#  9 r                  256     1.15s    1.18s    1.29s     0.851     58.78s    50
# 10 cpp                256  114.97ms 117.39ms 130.09ms     8.45       5.92s    50
# 11 r                  512     2.09s    2.15s    2.32s     0.463       1.8m    50
# 12 cpp                512  230.81ms  235.6ms 261.99ms     4.18      11.97s    50
# 13 r                 1024        4s    4.22s     4.4s     0.238       3.5m    50
# 14 cpp               1024  410.48ms 431.43ms 462.44ms     2.33      21.45s    50

ggplot(res_bench, aes(x = factor(batch_size), y = median, 
                      group =  expression, color = expression)) +
  geom_point() +
  geom_line() +
  ylab("median time, s") +
  theme_minimal() +
  scale_color_discrete(name = "", labels = c("cpp", "r")) +
  theme(legend.position = "bottom") 

Quick Draw Doodle Recognition: แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฃแƒ›แƒ”แƒ’แƒแƒ‘แƒ แƒ“แƒ”แƒ— R, C++ แƒ“แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒš แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒก

แƒ แƒแƒ’แƒแƒ แƒช แƒฎแƒ”แƒ“แƒแƒ•แƒ—, แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒ›แƒแƒขแƒ”แƒ‘แƒ แƒซแƒแƒšแƒ˜แƒแƒœ แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ•แƒแƒœแƒ˜ แƒแƒฆแƒ›แƒแƒฉแƒœแƒ“แƒ แƒ“แƒ R แƒ™แƒแƒ“แƒ˜แƒก แƒžแƒแƒ แƒแƒšแƒ”แƒšแƒ˜แƒ–แƒ”แƒ‘แƒ˜แƒ— C++ แƒ™แƒแƒ“แƒ˜แƒก แƒ“แƒแƒญแƒ”แƒ แƒ แƒจแƒ”แƒฃแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ.

3. แƒ˜แƒขแƒ”แƒ แƒแƒขแƒแƒ แƒ”แƒ‘แƒ˜ แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ‘แƒแƒ–แƒ˜แƒ“แƒแƒœ แƒ’แƒแƒ“แƒ›แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก

R-แƒก แƒแƒฅแƒ•แƒก แƒ“แƒแƒ›แƒกแƒแƒฎแƒฃแƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ แƒ”แƒžแƒฃแƒขแƒแƒชแƒ˜แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฏแƒ“แƒ”แƒ‘แƒ RAM-แƒจแƒ˜, แƒฎแƒแƒšแƒ Python-แƒก แƒฃแƒคแƒ แƒ แƒ›แƒ”แƒขแƒแƒ“ แƒแƒฎแƒแƒกแƒ˜แƒแƒ—แƒ”แƒ‘แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ’แƒแƒœแƒ›แƒ”แƒแƒ แƒ”แƒ‘แƒ˜แƒ—แƒ˜ แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ, แƒ แƒแƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒแƒ“ แƒ“แƒ แƒ‘แƒฃแƒœแƒ”แƒ‘แƒ แƒ˜แƒ•แƒแƒ“ แƒ’แƒแƒœแƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒแƒ— แƒ’แƒแƒ แƒ” แƒ’แƒแƒ›แƒแƒ—แƒ•แƒšแƒ”แƒ‘แƒ˜ (แƒ’แƒแƒ›แƒแƒ—แƒ•แƒšแƒ”แƒ‘แƒ˜ แƒ’แƒแƒ แƒ” แƒ›แƒ”แƒฎแƒกแƒ˜แƒ”แƒ แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—). แƒฉแƒ•แƒ”แƒœแƒ—แƒ•แƒ˜แƒก แƒ™แƒšแƒแƒกแƒ˜แƒ™แƒฃแƒ แƒ˜ แƒ“แƒ แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒ˜ แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜ แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ˜แƒก แƒ™แƒแƒœแƒขแƒ”แƒฅแƒกแƒขแƒจแƒ˜ แƒแƒ แƒ˜แƒก แƒฆแƒ แƒ›แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒšแƒ˜ แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ’แƒ แƒแƒ“แƒ˜แƒ”แƒœแƒขแƒฃแƒšแƒ˜ แƒ“แƒแƒฆแƒ›แƒแƒ แƒ—แƒ˜แƒก แƒ›แƒ”แƒ—แƒแƒ“แƒ˜แƒ—, แƒ’แƒ แƒแƒ“แƒ˜แƒ”แƒœแƒขแƒ˜แƒก แƒ›แƒ˜แƒแƒฎแƒšแƒแƒ”แƒ‘แƒ˜แƒ— แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒš แƒกแƒแƒคแƒ”แƒฎแƒฃแƒ แƒ–แƒ” แƒ“แƒแƒ™แƒ•แƒ˜แƒ แƒ•แƒ”แƒ‘แƒ˜แƒก แƒ›แƒชแƒ˜แƒ แƒ” แƒœแƒแƒฌแƒ˜แƒšแƒ˜แƒก แƒแƒœ แƒ›แƒ˜แƒœแƒ˜-แƒกแƒ”แƒ แƒ˜แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—.

Python-แƒจแƒ˜ แƒ“แƒแƒฌแƒ”แƒ แƒ˜แƒš แƒฆแƒ แƒ›แƒ แƒกแƒฌแƒแƒ•แƒšแƒ”แƒ‘แƒ˜แƒก แƒฉแƒแƒ แƒฉแƒแƒ”แƒ‘แƒก แƒแƒฅแƒ•แƒ— แƒกแƒžแƒ”แƒชแƒ˜แƒแƒšแƒฃแƒ แƒ˜ แƒ™แƒšแƒแƒกแƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ”แƒœ แƒ˜แƒขแƒ”แƒ แƒแƒขแƒแƒ แƒ”แƒ‘แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ–แƒ” แƒ“แƒแƒงแƒ แƒ“แƒœแƒแƒ‘แƒ˜แƒ—: แƒชแƒฎแƒ แƒ˜แƒšแƒ”แƒ‘แƒ˜, แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜ แƒกแƒแƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒ”แƒ‘แƒจแƒ˜, แƒแƒ แƒแƒ‘แƒ˜แƒ—แƒ˜ แƒคแƒแƒ แƒ›แƒแƒขแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ.แƒจ. แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒ— แƒ›แƒ–แƒ แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ”แƒ‘แƒ˜ แƒแƒœ แƒ“แƒแƒฌแƒ”แƒ แƒแƒ— แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒ˜ แƒ™แƒแƒœแƒ™แƒ แƒ”แƒขแƒฃแƒšแƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. R-แƒจแƒ˜ แƒจแƒ”แƒ’แƒ•แƒ˜แƒซแƒšแƒ˜แƒ แƒ•แƒ˜แƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒแƒ— แƒžแƒ˜แƒ—แƒแƒœแƒ˜แƒก แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ˜แƒก แƒงแƒ•แƒ”แƒšแƒ แƒ›แƒแƒฎแƒแƒกแƒ˜แƒแƒ—แƒ”แƒ‘แƒšแƒ˜แƒ— แƒ™แƒ”แƒ แƒแƒก แƒ—แƒแƒ•แƒ˜แƒกแƒ˜ แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒ‘แƒ”แƒฅแƒ”แƒœแƒ“แƒ”แƒ‘แƒ˜แƒ— แƒแƒ›แƒแƒ•แƒ” แƒกแƒแƒฎแƒ”แƒšแƒฌแƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ—แƒแƒ•แƒ˜แƒก แƒ›แƒฎแƒ แƒ˜แƒ• แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒ—แƒแƒ•แƒ–แƒ” แƒ‘แƒแƒ“แƒ”แƒ”แƒ‘แƒ˜. แƒ”แƒก แƒฃแƒ™แƒแƒœแƒแƒกแƒ™แƒœแƒ”แƒšแƒ˜ แƒ˜แƒ›แƒกแƒแƒฎแƒฃแƒ แƒ”แƒ‘แƒก แƒชแƒแƒšแƒ™แƒ” แƒ•แƒ แƒชแƒ”แƒš แƒกแƒขแƒแƒขแƒ˜แƒแƒก; แƒ˜แƒก แƒแƒ แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒฃแƒจแƒ•แƒแƒ— แƒžแƒ˜แƒ—แƒแƒœแƒ˜แƒก แƒ™แƒแƒ“แƒ˜ R-แƒ“แƒแƒœ, แƒแƒ แƒแƒ›แƒ”แƒ“ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒ“แƒแƒ˜แƒขแƒแƒœแƒแƒ— แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜ R แƒ“แƒ Python แƒกแƒ”แƒกแƒ˜แƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก, แƒแƒ•แƒขแƒแƒ›แƒแƒขแƒฃแƒ แƒแƒ“ แƒจแƒ”แƒแƒกแƒ แƒฃแƒšแƒแƒ— แƒงแƒ•แƒ”แƒšแƒ แƒกแƒแƒญแƒ˜แƒ แƒ แƒขแƒ˜แƒžแƒ˜แƒก แƒ™แƒแƒœแƒ•แƒ”แƒ แƒขแƒแƒชแƒ˜แƒ.

แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ•แƒ—แƒแƒ•แƒ˜แƒกแƒฃแƒคแƒšแƒ“แƒ˜แƒ— แƒงแƒ•แƒ”แƒšแƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ˜แƒก RAM-แƒจแƒ˜ แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒก แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒแƒ–แƒ” MonetDBLite-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒงแƒ•แƒ”แƒšแƒ โ€žแƒœแƒ”แƒ แƒ•แƒฃแƒšแƒ˜ แƒฅแƒกแƒ”แƒšแƒ˜แƒกโ€œ แƒกแƒแƒ›แƒฃแƒจแƒแƒ แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ“แƒ”แƒ‘แƒ แƒแƒ แƒ˜แƒ’แƒ˜แƒœแƒแƒšแƒฃแƒ แƒ˜ แƒ™แƒแƒ“แƒ˜แƒ— Python-แƒจแƒ˜, แƒฉแƒ•แƒ”แƒœ แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒฃแƒœแƒ“แƒ แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒแƒ— แƒ˜แƒขแƒ”แƒ แƒแƒขแƒแƒ แƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ–แƒ”, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ›แƒ–แƒแƒ“ แƒแƒ แƒแƒคแƒ”แƒ แƒ˜แƒ. แƒแƒกแƒ”แƒ—แƒ˜ แƒกแƒ˜แƒขแƒฃแƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒแƒœ R แƒแƒœ Python-แƒจแƒ˜. แƒ›แƒแƒก แƒแƒ แƒกแƒ”แƒ‘แƒ˜แƒ—แƒแƒ“ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒแƒ แƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒแƒฅแƒ•แƒก: แƒ›แƒแƒœ แƒฃแƒœแƒ“แƒ แƒ“แƒแƒแƒ‘แƒ แƒฃแƒœแƒแƒก แƒกแƒ”แƒ แƒ˜แƒ”แƒ‘แƒ˜ แƒ’แƒแƒฃแƒ—แƒแƒ•แƒ”แƒ‘แƒ”แƒš แƒชแƒ˜แƒ™แƒšแƒจแƒ˜ แƒ“แƒ แƒจแƒ”แƒ˜แƒœแƒแƒฎแƒแƒก แƒ›แƒ˜แƒกแƒ˜ แƒ›แƒ“แƒ’แƒแƒ›แƒแƒ แƒ”แƒแƒ‘แƒ แƒ’แƒแƒ›แƒ”แƒแƒ แƒ”แƒ‘แƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก (แƒ”แƒก แƒฃแƒ™แƒแƒœแƒแƒกแƒ™แƒœแƒ”แƒšแƒ˜ R-แƒจแƒ˜ แƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ“แƒ”แƒ‘แƒ แƒฃแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒกแƒ˜ แƒ’แƒ–แƒ˜แƒ— แƒ“แƒแƒฎแƒฃแƒ แƒ•แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—). แƒแƒ“แƒ แƒ” แƒกแƒแƒญแƒ˜แƒ แƒ แƒ˜แƒงแƒ R แƒ›แƒแƒกแƒ˜แƒ•แƒ”แƒ‘แƒ˜แƒก แƒ›แƒ™แƒแƒคแƒ˜แƒแƒ“ แƒ’แƒแƒ“แƒแƒฅแƒชแƒ”แƒ•แƒ แƒ˜แƒขแƒ”แƒ แƒแƒขแƒแƒ แƒ˜แƒก แƒจแƒ˜แƒ’แƒœแƒ˜แƒ—, แƒ›แƒแƒ’แƒ แƒแƒ› แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒแƒ›แƒŸแƒแƒ›แƒ˜แƒœแƒ“แƒ”แƒšแƒ˜ แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒ™แƒ”แƒ แƒแƒก แƒ—แƒ•แƒ˜แƒ—แƒแƒœ แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒก.

แƒขแƒ แƒ”แƒœแƒ˜แƒœแƒ’แƒ˜แƒกแƒ แƒ“แƒ แƒ•แƒแƒšแƒ˜แƒ“แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒ›แƒ”แƒแƒ แƒ”แƒ‘แƒแƒ“แƒ˜ แƒแƒฆแƒ›แƒแƒฉแƒœแƒ“แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜:

Iterator แƒขแƒ แƒ”แƒœแƒ˜แƒœแƒ’แƒ˜แƒกแƒ แƒ“แƒ แƒ•แƒแƒšแƒ˜แƒ“แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก

train_generator <- function(db_connection = con,
                            samples_index,
                            num_classes = 340,
                            batch_size = 32,
                            scale = 1,
                            color = FALSE,
                            imagenet_preproc = FALSE) {
  # ะŸั€ะพะฒะตั€ะบะฐ ะฐั€ะณัƒะผะตะฝั‚ะพะฒ
  checkmate::assert_class(con, "DBIConnection")
  checkmate::assert_integerish(samples_index)
  checkmate::assert_count(num_classes)
  checkmate::assert_count(batch_size)
  checkmate::assert_number(scale, lower = 0.001, upper = 5)
  checkmate::assert_flag(color)
  checkmate::assert_flag(imagenet_preproc)

  # ะŸะตั€ะตะผะตัˆะธะฒะฐะตะผ, ั‡ั‚ะพะฑั‹ ะฑั€ะฐั‚ัŒ ะธ ัƒะดะฐะปัั‚ัŒ ะธัะฟะพะปัŒะทะพะฒะฐะฝะฝั‹ะต ะธะฝะดะตะบัั‹ ะฑะฐั‚ั‡ะตะน ะฟะพ ะฟะพั€ัะดะบัƒ
  dt <- data.table::data.table(id = sample(samples_index))
  # ะŸั€ะพัั‚ะฐะฒะปัะตะผ ะฝะพะผะตั€ะฐ ะฑะฐั‚ั‡ะตะน
  dt[, batch := (.I - 1L) %/% batch_size + 1L]
  # ะžัั‚ะฐะฒะปัะตะผ ั‚ะพะปัŒะบะพ ะฟะพะปะฝั‹ะต ะฑะฐั‚ั‡ะธ ะธ ะธะฝะดะตะบัะธั€ัƒะตะผ
  dt <- dt[, if (.N == batch_size) .SD, keyby = batch]
  # ะฃัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ัั‡ั‘ั‚ั‡ะธะบ
  i <- 1
  # ะšะพะปะธั‡ะตัั‚ะฒะพ ะฑะฐั‚ั‡ะตะน
  max_i <- dt[, max(batch)]

  # ะŸะพะดะณะพั‚ะพะฒะบะฐ ะฒั‹ั€ะฐะถะตะฝะธั ะดะปั ะฒั‹ะณั€ัƒะทะบะธ
  sql <- sprintf(
    "PREPARE SELECT drawing, label_int FROM doodles WHERE id IN (%s)",
    paste(rep("?", batch_size), collapse = ",")
  )
  res <- DBI::dbSendQuery(con, sql)

  # ะะฝะฐะปะพะณ keras::to_categorical
  to_categorical <- function(x, num) {
    n <- length(x)
    m <- numeric(n * num)
    m[x * n + seq_len(n)] <- 1
    dim(m) <- c(n, num)
    return(m)
  }

  # ะ—ะฐะผั‹ะบะฐะฝะธะต
  function() {
    # ะะฐั‡ะธะฝะฐะตะผ ะฝะพะฒัƒัŽ ัะฟะพั…ัƒ
    if (i > max_i) {
      dt[, id := sample(id)]
      data.table::setkey(dt, batch)
      # ะกะฑั€ะฐัั‹ะฒะฐะตะผ ัั‡ั‘ั‚ั‡ะธะบ
      i <<- 1
      max_i <<- dt[, max(batch)]
    }

    # ID ะดะปั ะฒั‹ะณั€ัƒะทะบะธ ะดะฐะฝะฝั‹ั…
    batch_ind <- dt[batch == i, id]
    # ะ’ั‹ะณั€ัƒะทะบะฐ ะดะฐะฝะฝั‹ั…
    batch <- DBI::dbFetch(DBI::dbBind(res, as.list(batch_ind)), n = -1)

    # ะฃะฒะตะปะธั‡ะธะฒะฐะตะผ ัั‡ั‘ั‚ั‡ะธะบ
    i <<- i + 1

    # ะŸะฐั€ัะธะฝะณ JSON ะธ ะฟะพะดะณะพั‚ะพะฒะบะฐ ะผะฐััะธะฒะฐ
    batch_x <- cpp_process_json_vector(batch$drawing, scale = scale, color = color)
    if (imagenet_preproc) {
      # ะจะบะฐะปะธั€ะพะฒะฐะฝะธะต c ะธะฝั‚ะตั€ะฒะฐะปะฐ [0, 1] ะฝะฐ ะธะฝั‚ะตั€ะฒะฐะป [-1, 1]
      batch_x <- (batch_x - 0.5) * 2
    }

    batch_y <- to_categorical(batch$label_int, num_classes)
    result <- list(batch_x, batch_y)
    return(result)
  }
}

แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒจแƒ”แƒกแƒแƒงแƒ•แƒแƒœแƒแƒ“ แƒ˜แƒฆแƒ”แƒ‘แƒก แƒชแƒ•แƒšแƒแƒ“แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒกแƒ—แƒแƒœ, แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฎแƒแƒ–แƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ, แƒ™แƒšแƒแƒกแƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ, แƒฏแƒ’แƒฃแƒคแƒ˜แƒก แƒ–แƒแƒ›แƒ, แƒ›แƒแƒกแƒจแƒขแƒแƒ‘แƒ˜ (scale = 1 แƒจแƒ”แƒ”แƒกแƒแƒ‘แƒแƒ›แƒ”แƒ‘แƒ 256x256 แƒžแƒ˜แƒฅแƒกแƒ”แƒšแƒ˜แƒแƒœแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒแƒก, scale = 0.5 - 128x128 แƒžแƒ˜แƒฅแƒกแƒ”แƒšแƒ˜), แƒคแƒ”แƒ แƒ˜แƒก แƒ›แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ”แƒšแƒ˜ (color = FALSE แƒแƒ™แƒแƒœแƒ™แƒ แƒ”แƒขแƒ”แƒ‘แƒก แƒ แƒ”แƒœแƒ“แƒ”แƒ แƒ˜แƒ แƒ”แƒ‘แƒแƒก แƒœแƒแƒชแƒ แƒ˜แƒกแƒคแƒ”แƒ  แƒคแƒ”แƒ แƒ”แƒ‘แƒจแƒ˜ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒแƒก color = TRUE แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ˜ แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ˜แƒšแƒ˜แƒ แƒแƒฎแƒแƒš แƒคแƒ”แƒ แƒจแƒ˜) แƒ“แƒ แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ แƒ˜ แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ˜แƒก แƒ˜แƒœแƒ“แƒ˜แƒ™แƒแƒขแƒแƒ แƒ˜ แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ  แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒœแƒ˜ แƒแƒ แƒ˜แƒแƒœ imagenet-แƒ–แƒ”. แƒ”แƒก แƒฃแƒ™แƒแƒœแƒแƒกแƒ™แƒœแƒ”แƒšแƒ˜ แƒกแƒแƒญแƒ˜แƒ แƒแƒ แƒ˜แƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ› แƒ›แƒแƒฎแƒ“แƒ”แƒก แƒžแƒ˜แƒฅแƒกแƒ”แƒšแƒ˜แƒก แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒกแƒจแƒขแƒแƒ‘แƒ˜แƒ แƒ”แƒ‘แƒ [0, 1] แƒ˜แƒœแƒขแƒ”แƒ แƒ•แƒแƒšแƒ˜แƒ“แƒแƒœ [-1, 1] แƒ˜แƒœแƒขแƒ”แƒ แƒ•แƒแƒšแƒแƒ›แƒ“แƒ”, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒแƒ“แƒ แƒ›แƒ˜แƒฌแƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒ•แƒแƒ แƒฏแƒ˜แƒจแƒ˜แƒก แƒ“แƒ แƒแƒก. แƒ™แƒ”แƒ แƒแƒก แƒ›แƒแƒ“แƒ”แƒšแƒ”แƒ‘แƒ˜.

แƒ’แƒแƒ แƒ” แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒ˜แƒก แƒขแƒ˜แƒžแƒ˜แƒก แƒจแƒ”แƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒแƒก, แƒชแƒฎแƒ แƒ˜แƒšแƒก data.table แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ˜แƒ— แƒจแƒ”แƒ แƒ”แƒฃแƒšแƒ˜ แƒฎแƒแƒ–แƒ˜แƒก แƒœแƒแƒ›แƒ แƒ”แƒ‘แƒ˜แƒ— samples_index แƒ“แƒ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒœแƒแƒ›แƒ แƒ”แƒ‘แƒ˜, แƒ›แƒ แƒ˜แƒชแƒฎแƒ•แƒ”แƒšแƒ˜ แƒ“แƒ แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒฅแƒกแƒ˜แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ, แƒแƒกแƒ”แƒ•แƒ” SQL แƒ’แƒแƒ›แƒแƒฎแƒแƒขแƒฃแƒšแƒ”แƒ‘แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ˜แƒ“แƒแƒœ แƒ’แƒแƒ“แƒ›แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒ’แƒแƒ แƒ“แƒ แƒแƒ›แƒ˜แƒกแƒ, แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒœแƒ•แƒกแƒแƒ–แƒฆแƒ•แƒ แƒ”แƒ— แƒจแƒ˜แƒ’แƒœแƒ˜แƒ— แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒกแƒฌแƒ แƒแƒคแƒ˜ แƒแƒœแƒแƒšแƒแƒ’แƒ˜ keras::to_categorical(). แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— แƒ—แƒ˜แƒ—แƒฅแƒ›แƒ˜แƒก แƒงแƒ•แƒ”แƒšแƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ˜ แƒ•แƒแƒ แƒฏแƒ˜แƒจแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒœแƒแƒฎแƒ”แƒ•แƒแƒ แƒ˜ แƒžแƒ แƒแƒชแƒ”แƒœแƒขแƒ˜ แƒ“แƒแƒ•แƒขแƒแƒ•แƒ”แƒ— แƒ•แƒแƒšแƒ˜แƒ“แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ”แƒžแƒแƒฅแƒ˜แƒก แƒ–แƒแƒ›แƒ แƒจแƒ”แƒ›แƒแƒ˜แƒคแƒแƒ แƒ’แƒšแƒ”แƒ‘แƒแƒ“แƒ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜แƒ— steps_per_epoch แƒ แƒแƒชแƒ แƒ“แƒแƒ แƒ”แƒ™แƒ”แƒก keras::fit_generator()แƒ“แƒ แƒ›แƒ“แƒ’แƒแƒ›แƒแƒ แƒ”แƒแƒ‘แƒ if (i > max_i) แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ“แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ•แƒแƒšแƒ˜แƒ“แƒแƒชแƒ˜แƒ˜แƒก แƒ˜แƒขแƒ”แƒ แƒแƒขแƒแƒ แƒ–แƒ”.

แƒจแƒ˜แƒ“แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒจแƒ˜, แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ˜แƒœแƒ“แƒ”แƒฅแƒกแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒซแƒ˜แƒ”แƒ‘แƒ แƒฎแƒ“แƒ”แƒ‘แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒžแƒแƒ แƒขแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ”แƒ‘แƒ˜ แƒ˜แƒขแƒ•แƒ˜แƒ แƒ—แƒ”แƒ‘แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ˜แƒ“แƒแƒœ แƒ›แƒ แƒ˜แƒชแƒฎแƒ•แƒ”แƒšแƒ˜แƒก แƒ’แƒแƒ–แƒ แƒ“แƒ˜แƒ—, JSON แƒžแƒแƒ แƒกแƒ˜แƒ แƒ”แƒ‘แƒ (แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ cpp_process_json_vector(), แƒ“แƒแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ C++) แƒ“แƒ แƒœแƒแƒฎแƒแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒ˜ แƒ›แƒแƒกแƒ˜แƒ•แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ. แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ˜แƒฅแƒ›แƒœแƒ”แƒ‘แƒ แƒ”แƒ แƒ—แƒ˜ แƒชแƒฎแƒ”แƒšแƒ˜ แƒ•แƒ”แƒฅแƒขแƒแƒ แƒ”แƒ‘แƒ˜ แƒ™แƒšแƒแƒกแƒ˜แƒก แƒ”แƒขแƒ˜แƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜แƒ—, แƒ›แƒแƒกแƒ˜แƒ•แƒ”แƒ‘แƒ˜ แƒžแƒ˜แƒฅแƒกแƒ”แƒšแƒ˜แƒก แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ”แƒ‘แƒ˜แƒ— แƒ“แƒ แƒšแƒ”แƒ˜แƒ‘แƒšแƒ”แƒ‘แƒ˜ แƒ’แƒแƒ”แƒ แƒ—แƒ˜แƒแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒกแƒ˜แƒแƒจแƒ˜, แƒ แƒแƒช แƒแƒ แƒ˜แƒก แƒ“แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒ˜แƒก แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ. แƒกแƒแƒ›แƒฃแƒจแƒแƒแƒก แƒ“แƒแƒกแƒแƒฉแƒฅแƒแƒ แƒ”แƒ‘แƒšแƒแƒ“ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— แƒชแƒฎแƒ แƒ˜แƒšแƒ”แƒ‘แƒจแƒ˜ แƒ˜แƒœแƒ“แƒ”แƒฅแƒกแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ data.table แƒ“แƒ แƒ›แƒแƒ“แƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ แƒ‘แƒ›แƒฃแƒšแƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ— - แƒแƒ› แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก "แƒฉแƒ˜แƒžแƒ”แƒ‘แƒ˜แƒก" แƒ’แƒแƒ แƒ”แƒจแƒ” แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜. แƒ›แƒแƒ’แƒ˜แƒ“แƒ แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ แƒ—แƒฃแƒšแƒ˜ แƒฌแƒแƒ แƒ›แƒแƒกแƒแƒ“แƒ’แƒ”แƒœแƒ˜แƒ แƒ -แƒจแƒ˜ แƒ แƒแƒ˜แƒ›แƒ” แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ•แƒแƒœแƒ˜ แƒ›แƒแƒชแƒฃแƒšแƒแƒ‘แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ—แƒแƒœ แƒ”แƒคแƒ”แƒฅแƒขแƒฃแƒ แƒแƒ“ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ.

Core i5 แƒšแƒ”แƒžแƒขแƒแƒžแƒ–แƒ” แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒ’แƒแƒ–แƒแƒ›แƒ•แƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒ”แƒ‘แƒ˜ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜แƒ:

แƒ˜แƒขแƒ”แƒ แƒแƒขแƒแƒ แƒ˜แƒก แƒกแƒแƒแƒ แƒ˜แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ แƒœแƒ˜แƒจแƒแƒœแƒ˜

library(Rcpp)
library(keras)
library(ggplot2)

source("utils/rcpp.R")
source("utils/keras_iterator.R")

con <- DBI::dbConnect(drv = MonetDBLite::MonetDBLite(), Sys.getenv("DBDIR"))

ind <- seq_len(DBI::dbGetQuery(con, "SELECT count(*) FROM doodles")[[1L]])
num_classes <- DBI::dbGetQuery(con, "SELECT max(label_int) + 1 FROM doodles")[[1L]]

# ะ˜ะฝะดะตะบัั‹ ะดะปั ะพะฑัƒั‡ะฐัŽั‰ะตะน ะฒั‹ะฑะพั€ะบะธ
train_ind <- sample(ind, floor(length(ind) * 0.995))
# ะ˜ะฝะดะตะบัั‹ ะดะปั ะฟั€ะพะฒะตั€ะพั‡ะฝะพะน ะฒั‹ะฑะพั€ะบะธ
val_ind <- ind[-train_ind]
rm(ind)
# ะšะพัั„ั„ะธั†ะธะตะฝั‚ ะผะฐััˆั‚ะฐะฑะฐ
scale <- 0.5

# ะŸั€ะพะฒะตะดะตะฝะธะต ะทะฐะผะตั€ะฐ
res_bench <- bench::press(
  batch_size = 2^(4:10),
  {
    it1 <- train_generator(
      db_connection = con,
      samples_index = train_ind,
      num_classes = num_classes,
      batch_size = batch_size,
      scale = scale
    )
    bench::mark(
      it1(),
      min_iterations = 50L
    )
  }
)
# ะŸะฐั€ะฐะผะตั‚ั€ั‹ ะฑะตะฝั‡ะผะฐั€ะบะฐ
cols <- c("batch_size", "min", "median", "max", "itr/sec", "total_time", "n_itr")
res_bench[, cols]

#   batch_size      min   median      max `itr/sec` total_time n_itr
#        <dbl> <bch:tm> <bch:tm> <bch:tm>     <dbl>   <bch:tm> <int>
# 1         16     25ms  64.36ms   92.2ms     15.9       3.09s    49
# 2         32   48.4ms 118.13ms 197.24ms     8.17       5.88s    48
# 3         64   69.3ms 117.93ms 181.14ms     8.57       5.83s    50
# 4        128  157.2ms 240.74ms 503.87ms     3.85      12.71s    49
# 5        256  359.3ms 613.52ms 988.73ms     1.54       30.5s    47
# 6        512  884.7ms    1.53s    2.07s     0.674      1.11m    45
# 7       1024     2.7s    3.83s    5.47s     0.261      2.81m    44

ggplot(res_bench, aes(x = factor(batch_size), y = median, group = 1)) +
    geom_point() +
    geom_line() +
    ylab("median time, s") +
    theme_minimal()

DBI::dbDisconnect(con, shutdown = TRUE)

Quick Draw Doodle Recognition: แƒ แƒแƒ’แƒแƒ  แƒ“แƒแƒ•แƒฃแƒ›แƒ”แƒ’แƒแƒ‘แƒ แƒ“แƒ”แƒ— R, C++ แƒ“แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒš แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒก

แƒ—แƒฃ แƒ—แƒฅแƒ•แƒ”แƒœ แƒ’แƒแƒฅแƒ•แƒ— แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜ แƒแƒžแƒ”แƒ แƒแƒขแƒ˜แƒฃแƒšแƒ˜ แƒ›แƒ”แƒฎแƒกแƒ˜แƒ”แƒ แƒ”แƒ‘แƒ, แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒกแƒ”แƒ แƒ˜แƒแƒ–แƒฃแƒšแƒแƒ“ แƒ“แƒแƒแƒฉแƒฅแƒแƒ แƒแƒ— แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ แƒ˜แƒ›แƒแƒ•แƒ” RAM-แƒ–แƒ” แƒ’แƒแƒ“แƒแƒขแƒแƒœแƒ˜แƒ— (แƒฉแƒ•แƒ”แƒœแƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜แƒ 32 แƒ’แƒ‘). Linux-แƒจแƒ˜ แƒ“แƒแƒœแƒแƒงแƒแƒคแƒ˜ แƒ“แƒแƒ›แƒแƒœแƒขแƒแƒŸแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒœแƒแƒ’แƒฃแƒšแƒ˜แƒกแƒฎแƒ›แƒ”แƒ•แƒแƒ“ /dev/shm, แƒ˜แƒ™แƒแƒ•แƒ”แƒ‘แƒก RAM-แƒ˜แƒก แƒขแƒ”แƒ•แƒแƒ“แƒแƒ‘แƒ˜แƒก แƒœแƒแƒฎแƒ”แƒ•แƒแƒ แƒก. แƒ›แƒ”แƒขแƒ˜แƒก แƒ›แƒแƒœแƒ˜แƒจแƒ•แƒœแƒ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ แƒ”แƒ“แƒแƒฅแƒขแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒ— /etc/fstabแƒ แƒแƒ› แƒ›แƒ˜แƒ˜แƒฆแƒแƒ— แƒ›แƒกแƒ’แƒแƒ•แƒกแƒ˜ แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ˜ tmpfs /dev/shm tmpfs defaults,size=25g 0 0. แƒ“แƒแƒ แƒฌแƒ›แƒฃแƒœแƒ“แƒ˜แƒ—, แƒ แƒแƒ› แƒ’แƒแƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ”แƒ— แƒ“แƒ แƒจแƒ”แƒแƒ›แƒแƒฌแƒ›แƒ”แƒ— แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ˜แƒ— df -h.

แƒขแƒ”แƒกแƒขแƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ”แƒแƒ แƒ”แƒ‘แƒ แƒ‘แƒ”แƒ•แƒ แƒแƒ“ แƒฃแƒคแƒ แƒ แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜แƒ, แƒ แƒแƒ“แƒ’แƒแƒœ แƒขแƒ”แƒกแƒขแƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒœแƒแƒ™แƒ แƒ”แƒ‘แƒ˜ แƒ›แƒ—แƒšแƒ˜แƒแƒœแƒแƒ“ แƒฏแƒ“แƒ”แƒ‘แƒ RAM-แƒจแƒ˜:

Iterator แƒขแƒ”แƒกแƒขแƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก

test_generator <- function(dt,
                           batch_size = 32,
                           scale = 1,
                           color = FALSE,
                           imagenet_preproc = FALSE) {

  # ะŸั€ะพะฒะตั€ะบะฐ ะฐั€ะณัƒะผะตะฝั‚ะพะฒ
  checkmate::assert_data_table(dt)
  checkmate::assert_count(batch_size)
  checkmate::assert_number(scale, lower = 0.001, upper = 5)
  checkmate::assert_flag(color)
  checkmate::assert_flag(imagenet_preproc)

  # ะŸั€ะพัั‚ะฐะฒะปัะตะผ ะฝะพะผะตั€ะฐ ะฑะฐั‚ั‡ะตะน
  dt[, batch := (.I - 1L) %/% batch_size + 1L]
  data.table::setkey(dt, batch)
  i <- 1
  max_i <- dt[, max(batch)]

  # ะ—ะฐะผั‹ะบะฐะฝะธะต
  function() {
    batch_x <- cpp_process_json_vector(dt[batch == i, drawing], 
                                       scale = scale, color = color)
    if (imagenet_preproc) {
      # ะจะบะฐะปะธั€ะพะฒะฐะฝะธะต c ะธะฝั‚ะตั€ะฒะฐะปะฐ [0, 1] ะฝะฐ ะธะฝั‚ะตั€ะฒะฐะป [-1, 1]
      batch_x <- (batch_x - 0.5) * 2
    }
    result <- list(batch_x)
    i <<- i + 1
    return(result)
  }
}

4. แƒ›แƒแƒ“แƒ”แƒšแƒ˜แƒก แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ˜แƒก แƒจแƒ”แƒ แƒฉแƒ”แƒ•แƒ

แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ แƒ˜แƒงแƒ mobilenet v1, แƒ แƒแƒ›แƒšแƒ˜แƒก แƒ—แƒแƒ•แƒ˜แƒกแƒ”แƒ‘แƒฃแƒ แƒ”แƒ‘แƒ”แƒ‘แƒ˜ แƒ’แƒแƒœแƒฎแƒ˜แƒšแƒฃแƒšแƒ˜แƒ แƒฅ แƒ”แƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ. แƒจแƒ”แƒ“แƒ˜แƒก แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒฃแƒšแƒแƒ“ แƒ™แƒ”แƒ แƒแƒก แƒ“แƒ, แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“, แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒ R-แƒกแƒ—แƒ•แƒ˜แƒก แƒแƒ›แƒแƒ•แƒ” แƒกแƒแƒฎแƒ”แƒšแƒฌแƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒžแƒแƒ™แƒ”แƒขแƒจแƒ˜. แƒ›แƒแƒ’แƒ แƒแƒ› แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒชแƒ“แƒ˜แƒšแƒแƒ‘แƒ“แƒ˜แƒ— แƒ›แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒแƒก แƒ”แƒ แƒ—แƒแƒ แƒฎแƒ˜แƒแƒœแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒ—, แƒฃแƒชแƒœแƒแƒฃแƒ แƒ˜ แƒ แƒแƒ› แƒแƒฆแƒ›แƒแƒฉแƒœแƒ“แƒ: แƒจแƒ”แƒงแƒ•แƒแƒœแƒ˜แƒก แƒขแƒ”แƒœแƒกแƒแƒ แƒก แƒงแƒแƒ•แƒ”แƒšแƒ—แƒ•แƒ˜แƒก แƒฃแƒœแƒ“แƒ แƒฐแƒฅแƒแƒœแƒ“แƒ”แƒก แƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ. (batch, height, width, 3), แƒแƒœแƒฃ แƒแƒ แƒฎแƒ”แƒ‘แƒ˜แƒก แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ แƒ•แƒ”แƒ  แƒจแƒ”แƒ˜แƒชแƒ•แƒšแƒ”แƒ‘แƒ. Python-แƒจแƒ˜ แƒแƒกแƒ”แƒ—แƒ˜ แƒจแƒ”แƒ–แƒฆแƒฃแƒ“แƒ•แƒ แƒแƒ  แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒฉแƒฅแƒแƒ แƒ”แƒ— แƒ“แƒ แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒ”แƒ— แƒแƒ› แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ˜แƒก แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒ˜ แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ, แƒ—แƒแƒ•แƒ“แƒแƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ (แƒ’แƒแƒ แƒ“แƒแƒชแƒ•แƒšแƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒ แƒ˜แƒก keras แƒ•แƒ”แƒ แƒกแƒ˜แƒแƒจแƒ˜):

Mobilenet v1 แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ

library(keras)

top_3_categorical_accuracy <- custom_metric(
    name = "top_3_categorical_accuracy",
    metric_fn = function(y_true, y_pred) {
         metric_top_k_categorical_accuracy(y_true, y_pred, k = 3)
    }
)

layer_sep_conv_bn <- function(object, 
                              filters,
                              alpha = 1,
                              depth_multiplier = 1,
                              strides = c(2, 2)) {

  # NB! depth_multiplier !=  resolution multiplier
  # https://github.com/keras-team/keras/issues/10349

  layer_depthwise_conv_2d(
    object = object,
    kernel_size = c(3, 3), 
    strides = strides,
    padding = "same",
    depth_multiplier = depth_multiplier
  ) %>%
  layer_batch_normalization() %>% 
  layer_activation_relu() %>%
  layer_conv_2d(
    filters = filters * alpha,
    kernel_size = c(1, 1), 
    strides = c(1, 1)
  ) %>%
  layer_batch_normalization() %>% 
  layer_activation_relu() 
}

get_mobilenet_v1 <- function(input_shape = c(224, 224, 1),
                             num_classes = 340,
                             alpha = 1,
                             depth_multiplier = 1,
                             optimizer = optimizer_adam(lr = 0.002),
                             loss = "categorical_crossentropy",
                             metrics = c("categorical_crossentropy",
                                         top_3_categorical_accuracy)) {

  inputs <- layer_input(shape = input_shape)

  outputs <- inputs %>%
    layer_conv_2d(filters = 32, kernel_size = c(3, 3), strides = c(2, 2), padding = "same") %>%
    layer_batch_normalization() %>% 
    layer_activation_relu() %>%
    layer_sep_conv_bn(filters = 64, strides = c(1, 1)) %>%
    layer_sep_conv_bn(filters = 128, strides = c(2, 2)) %>%
    layer_sep_conv_bn(filters = 128, strides = c(1, 1)) %>%
    layer_sep_conv_bn(filters = 256, strides = c(2, 2)) %>%
    layer_sep_conv_bn(filters = 256, strides = c(1, 1)) %>%
    layer_sep_conv_bn(filters = 512, strides = c(2, 2)) %>%
    layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
    layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
    layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
    layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
    layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
    layer_sep_conv_bn(filters = 1024, strides = c(2, 2)) %>%
    layer_sep_conv_bn(filters = 1024, strides = c(1, 1)) %>%
    layer_global_average_pooling_2d() %>%
    layer_dense(units = num_classes) %>%
    layer_activation_softmax()

    model <- keras_model(
      inputs = inputs,
      outputs = outputs
    )

    model %>% compile(
      optimizer = optimizer,
      loss = loss,
      metrics = metrics
    )

    return(model)
}

แƒแƒ› แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒ˜แƒก แƒฃแƒแƒ แƒงแƒแƒคแƒ˜แƒ—แƒ˜ แƒ›แƒฎแƒแƒ แƒ”แƒ”แƒ‘แƒ˜ แƒแƒจแƒ™แƒแƒ แƒแƒ. แƒ‘แƒ”แƒ•แƒ แƒ˜ แƒ›แƒแƒ“แƒ”แƒšแƒ˜แƒก แƒ’แƒแƒ›แƒแƒชแƒ“แƒ แƒ›แƒ˜แƒœแƒ“แƒ, แƒ›แƒแƒ’แƒ แƒแƒ› แƒžแƒ˜แƒ แƒ˜แƒฅแƒ˜แƒ—, แƒแƒ  แƒ›แƒ˜แƒœแƒ“แƒ แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ˜แƒก แƒฎแƒ”แƒšแƒ˜แƒ— แƒ’แƒแƒ“แƒแƒฌแƒ”แƒ แƒ. แƒฉแƒ•แƒ”แƒœ แƒแƒกแƒ”แƒ•แƒ” แƒฌแƒแƒ’แƒ•แƒแƒ แƒ—แƒ•แƒ”แƒก แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒ, แƒ’แƒแƒ›แƒแƒ’แƒ•แƒ”แƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒœแƒ แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ  แƒ’แƒแƒฌแƒ•แƒ แƒ—แƒœแƒ˜แƒšแƒ˜ แƒ›แƒแƒ“แƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒฌแƒแƒœแƒ. แƒ แƒแƒ’แƒแƒ แƒช แƒงแƒแƒ•แƒ”แƒšแƒ—แƒ•แƒ˜แƒก, แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒกแƒฌแƒแƒ•แƒšแƒ แƒ“แƒแƒ”แƒฎแƒ›แƒแƒ แƒ. แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ get_config() แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ›แƒ˜แƒ˜แƒฆแƒแƒ— แƒ›แƒแƒ“แƒ”แƒšแƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒ แƒ แƒ”แƒ“แƒแƒฅแƒขแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒจแƒ”แƒกแƒแƒคแƒ”แƒ แƒ˜แƒกแƒ˜ แƒคแƒแƒ แƒ›แƒ˜แƒ— (base_model_conf$layers - แƒ แƒ”แƒ’แƒฃแƒšแƒแƒ แƒฃแƒšแƒ˜ R แƒกแƒ˜แƒ) แƒ“แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ from_config() แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒก แƒกแƒแƒžแƒ˜แƒ แƒ˜แƒกแƒžแƒ˜แƒ แƒ แƒ™แƒแƒœแƒ•แƒ”แƒ แƒขแƒแƒชแƒ˜แƒแƒก แƒ›แƒแƒ“แƒ”แƒšแƒ˜แƒก แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒ–แƒ”:

base_model_conf <- get_config(base_model)
base_model_conf$layers[[1]]$config$batch_input_shape[[4]] <- 1L
base_model <- from_config(base_model_conf)

แƒแƒฎแƒšแƒ แƒซแƒœแƒ”แƒšแƒ˜ แƒแƒ  แƒแƒ แƒ˜แƒก แƒฃแƒœแƒ˜แƒ•แƒ”แƒ แƒกแƒแƒšแƒฃแƒ แƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒ“แƒแƒฌแƒ”แƒ แƒ แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒ›แƒ” แƒ›แƒแƒฌแƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜แƒก แƒ›แƒ˜แƒกแƒแƒฆแƒ”แƒ‘แƒแƒ“ แƒ™แƒ”แƒ แƒแƒก imagenet-แƒ–แƒ” แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฌแƒแƒœแƒ”แƒ‘แƒ˜แƒ— แƒแƒœ แƒ›แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ” แƒ›แƒแƒ“แƒ”แƒšแƒ”แƒ‘แƒ˜:

แƒ›แƒ–แƒ แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ”แƒ‘แƒ˜แƒก แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ˜แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ

get_model <- function(name = "mobilenet_v2",
                      input_shape = NULL,
                      weights = "imagenet",
                      pooling = "avg",
                      num_classes = NULL,
                      optimizer = keras::optimizer_adam(lr = 0.002),
                      loss = "categorical_crossentropy",
                      metrics = NULL,
                      color = TRUE,
                      compile = FALSE) {
  # ะŸั€ะพะฒะตั€ะบะฐ ะฐั€ะณัƒะผะตะฝั‚ะพะฒ
  checkmate::assert_string(name)
  checkmate::assert_integerish(input_shape, lower = 1, upper = 256, len = 3)
  checkmate::assert_count(num_classes)
  checkmate::assert_flag(color)
  checkmate::assert_flag(compile)

  # ะŸะพะปัƒั‡ะฐะตะผ ะพะฑัŠะตะบั‚ ะธะท ะฟะฐะบะตั‚ะฐ keras
  model_fun <- get0(paste0("application_", name), envir = asNamespace("keras"))
  # ะŸั€ะพะฒะตั€ะบะฐ ะฝะฐะปะธั‡ะธั ะพะฑัŠะตะบั‚ะฐ ะฒ ะฟะฐะบะตั‚ะต
  if (is.null(model_fun)) {
    stop("Model ", shQuote(name), " not found.", call. = FALSE)
  }

  base_model <- model_fun(
    input_shape = input_shape,
    include_top = FALSE,
    weights = weights,
    pooling = pooling
  )

  # ะ•ัะปะธ ะธะทะพะฑั€ะฐะถะตะฝะธะต ะฝะต ั†ะฒะตั‚ะฝะพะต, ะผะตะฝัะตะผ ั€ะฐะทะผะตั€ะฝะพัั‚ัŒ ะฒั…ะพะดะฐ
  if (!color) {
    base_model_conf <- keras::get_config(base_model)
    base_model_conf$layers[[1]]$config$batch_input_shape[[4]] <- 1L
    base_model <- keras::from_config(base_model_conf)
  }

  predictions <- keras::get_layer(base_model, "global_average_pooling2d_1")$output
  predictions <- keras::layer_dense(predictions, units = num_classes, activation = "softmax")
  model <- keras::keras_model(
    inputs = base_model$input,
    outputs = predictions
  )

  if (compile) {
    keras::compile(
      object = model,
      optimizer = optimizer,
      loss = loss,
      metrics = metrics
    )
  }

  return(model)
}

แƒ”แƒ แƒ—แƒแƒ แƒฎแƒ˜แƒแƒœแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒแƒก แƒแƒ  แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ  แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฌแƒแƒœแƒ. แƒ”แƒก แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒกแƒฌแƒแƒ แƒ“แƒ”แƒก: แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— get_weights() แƒ›แƒ˜แƒ˜แƒฆแƒ”แƒ— แƒ›แƒแƒ“แƒ”แƒšแƒ˜แƒก แƒฌแƒแƒœแƒ R แƒ›แƒแƒกแƒ˜แƒ•แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ˜แƒก แƒกแƒแƒฎแƒ˜แƒ—, แƒจแƒ”แƒชแƒ•แƒแƒšแƒ”แƒ— แƒแƒ› แƒกแƒ˜แƒ˜แƒก แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒ”แƒšแƒ”แƒ›แƒ”แƒœแƒขแƒ˜แƒก แƒ’แƒแƒœแƒ–แƒแƒ›แƒ˜แƒšแƒ”แƒ‘แƒ (แƒ”แƒ แƒ—แƒ˜ แƒคแƒ”แƒ แƒแƒ“แƒ˜ แƒแƒ แƒฎแƒ˜แƒก แƒแƒฆแƒ”แƒ‘แƒ˜แƒ— แƒแƒœ แƒกแƒแƒ›แƒ˜แƒ•แƒ” แƒกแƒแƒจแƒฃแƒแƒšแƒแƒ“) แƒ“แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ”แƒ— แƒฌแƒแƒœแƒ แƒ›แƒแƒ“แƒ”แƒšแƒจแƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒ—. set_weights(). แƒฉแƒ•แƒ”แƒœ แƒแƒ แƒแƒกแƒ“แƒ แƒแƒก แƒ“แƒแƒ•แƒแƒ›แƒแƒขแƒ”แƒ— แƒ”แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒœแƒ˜แƒ แƒ”แƒ‘แƒ, แƒ แƒแƒ“แƒ’แƒแƒœ แƒแƒ› แƒ”แƒขแƒแƒžแƒ–แƒ” แƒฃแƒ™แƒ•แƒ” แƒœแƒแƒ—แƒ”แƒšแƒ˜ แƒ˜แƒงแƒ, แƒ แƒแƒ› แƒฃแƒคแƒ แƒ แƒžแƒ แƒแƒ“แƒฃแƒฅแƒขแƒ˜แƒฃแƒšแƒ˜ แƒ˜แƒงแƒ แƒคแƒ”แƒ แƒแƒ“ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ—แƒแƒœ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ.

แƒฉแƒ•แƒ”แƒœ แƒฉแƒแƒ•แƒแƒขแƒแƒ แƒ”แƒ— แƒ”แƒฅแƒกแƒžแƒ”แƒ แƒ˜แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒฃแƒ›แƒ”แƒขแƒ”แƒกแƒแƒ‘แƒ mobilenet แƒ•แƒ”แƒ แƒกแƒ˜แƒ”แƒ‘แƒ˜แƒก 1 แƒ“แƒ 2, แƒ˜แƒกแƒ”แƒ•แƒ” แƒ แƒแƒ’แƒแƒ แƒช resnet34 แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—. แƒฃแƒคแƒ แƒ แƒ—แƒแƒœแƒแƒ›แƒ”แƒ“แƒ แƒแƒ•แƒ” แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ”แƒ‘แƒ›แƒ, แƒ แƒแƒ’แƒแƒ แƒ˜แƒชแƒแƒ SE-ResNeXt, แƒ™แƒแƒ แƒ’แƒแƒ“ แƒ˜แƒ—แƒแƒ›แƒแƒจแƒ”แƒก แƒแƒ› แƒ™แƒแƒœแƒ™แƒฃแƒ แƒกแƒจแƒ˜. แƒกแƒแƒ›แƒฌแƒฃแƒฎแƒแƒ แƒแƒ“, แƒฉแƒ•แƒ”แƒœ แƒฎแƒ”แƒšแƒ— แƒแƒ  แƒ’แƒ•แƒฅแƒแƒœแƒ“แƒ แƒ›แƒ–แƒ แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ แƒ“แƒ แƒแƒ แƒช แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ“แƒแƒ’แƒ•แƒ˜แƒฌแƒ”แƒ แƒ˜แƒ (แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒšแƒแƒ“ แƒ“แƒแƒ•แƒฌแƒ”แƒ แƒ—).

5. แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ

แƒ›แƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒฃแƒšแƒแƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒขแƒ แƒ”แƒœแƒ˜แƒœแƒ’แƒ˜แƒก แƒ“แƒแƒฌแƒงแƒ”แƒ‘แƒ˜แƒก แƒงแƒ•แƒ”แƒšแƒ แƒ™แƒแƒ“แƒ˜ แƒจแƒ”แƒ˜แƒฅแƒ›แƒœแƒ, แƒ แƒแƒ’แƒแƒ แƒช แƒ”แƒ แƒ—แƒ˜ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜, แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— แƒ“แƒแƒ™แƒแƒžแƒขแƒ˜ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒœแƒแƒ˜แƒ แƒแƒ“:

doc <- '
Usage:
  train_nn.R --help
  train_nn.R --list-models
  train_nn.R [options]

Options:
  -h --help                   Show this message.
  -l --list-models            List available models.
  -m --model=<model>          Neural network model name [default: mobilenet_v2].
  -b --batch-size=<size>      Batch size [default: 32].
  -s --scale-factor=<ratio>   Scale factor [default: 0.5].
  -c --color                  Use color lines [default: FALSE].
  -d --db-dir=<path>          Path to database directory [default: Sys.getenv("db_dir")].
  -r --validate-ratio=<ratio> Validate sample ratio [default: 0.995].
  -n --n-gpu=<number>         Number of GPUs [default: 1].
'
args <- docopt::docopt(doc)

แƒžแƒแƒ™แƒ”แƒขแƒ˜ แƒ“แƒแƒ™แƒแƒžแƒขแƒ˜ แƒฌแƒแƒ แƒ›แƒแƒแƒ“แƒ’แƒ”แƒœแƒก แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒแƒก http://docopt.org/ R.-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ›แƒ˜แƒกแƒ˜ แƒ“แƒแƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ˜แƒ— แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜ แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒ—, แƒ แƒแƒ’แƒแƒ แƒ˜แƒชแƒแƒ Rscript bin/train_nn.R -m resnet50 -c -d /home/andrey/doodle_db แƒแƒœ ./bin/train_nn.R -m resnet50 -c -d /home/andrey/doodle_db, แƒ—แƒฃ แƒคแƒแƒ˜แƒšแƒ˜ train_nn.R แƒแƒ แƒ˜แƒก แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒแƒ“แƒ˜ (แƒ”แƒก แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ แƒ“แƒแƒ˜แƒฌแƒงแƒ”แƒ‘แƒก แƒ›แƒแƒ“แƒ”แƒšแƒ˜แƒก แƒกแƒฌแƒแƒ•แƒšแƒ”แƒ‘แƒแƒก resnet50 128x128 แƒžแƒ˜แƒฅแƒกแƒ”แƒšแƒ˜แƒก แƒ–แƒแƒ›แƒ˜แƒก แƒกแƒแƒ›แƒคแƒ”แƒ แƒแƒ•แƒแƒœ แƒกแƒฃแƒ แƒแƒ—แƒ–แƒ” แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ’แƒแƒœแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒแƒฅแƒแƒฆแƒแƒšแƒ“แƒ”แƒจแƒ˜ /home/andrey/doodle_db). แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ“แƒแƒแƒ›แƒแƒขแƒแƒ— แƒกแƒฌแƒแƒ•แƒšแƒ˜แƒก แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ”, แƒแƒžแƒขแƒ˜แƒ›แƒ˜แƒ–แƒแƒขแƒแƒ แƒ˜แƒก แƒขแƒ˜แƒžแƒ˜ แƒ“แƒ แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ แƒ˜ แƒกแƒฎแƒ•แƒ แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ˜แƒ แƒ”แƒ‘แƒแƒ“แƒ˜ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ˜ แƒกแƒ˜แƒแƒจแƒ˜. แƒžแƒฃแƒ‘แƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒžแƒ แƒแƒชแƒ”แƒกแƒจแƒ˜ แƒแƒฆแƒ›แƒแƒฉแƒœแƒ“แƒ, แƒ แƒแƒ› แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ mobilenet_v2 แƒ›แƒ˜แƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ” แƒ•แƒ”แƒ แƒกแƒ˜แƒ˜แƒ“แƒแƒœ แƒ™แƒ”แƒ แƒแƒก R แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒแƒจแƒ˜ แƒแƒ  แƒฃแƒœแƒ“แƒ R แƒžแƒแƒ™แƒ”แƒขแƒจแƒ˜ แƒ’แƒแƒฃแƒ—แƒ•แƒแƒšแƒ˜แƒกแƒฌแƒ˜แƒœแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒชแƒ•แƒšแƒ˜แƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ, แƒ•แƒ”แƒšแƒแƒ“แƒ”แƒ‘แƒ˜แƒ— แƒ›แƒ˜แƒก แƒ’แƒแƒ›แƒแƒกแƒฌแƒแƒ แƒ”แƒ‘แƒแƒก.

แƒแƒ› แƒ›แƒ˜แƒ“แƒ’แƒแƒ›แƒแƒ› แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ’แƒแƒฎแƒแƒ“แƒ แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ•แƒœแƒแƒ“ แƒ“แƒแƒฉแƒฅแƒแƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒงแƒ แƒ”แƒฅแƒกแƒžแƒ”แƒ แƒ˜แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒ›แƒแƒ“แƒ”แƒšแƒ”แƒ‘แƒ—แƒแƒœ แƒจแƒ”แƒ“แƒแƒ แƒ”แƒ‘แƒ˜แƒ— RStudio-แƒจแƒ˜ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒฃแƒคแƒ แƒ แƒขแƒ แƒแƒ“แƒ˜แƒชแƒ˜แƒฃแƒš แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒแƒกแƒ—แƒแƒœ แƒจแƒ”แƒ“แƒแƒ แƒ”แƒ‘แƒ˜แƒ— (แƒฉแƒ•แƒ”แƒœ แƒแƒฆแƒ•แƒœแƒ˜แƒจแƒœแƒแƒ•แƒ— แƒžแƒแƒ™แƒ”แƒขแƒก, แƒ แƒแƒ’แƒแƒ แƒช แƒจแƒ”แƒกแƒแƒซแƒšแƒ แƒแƒšแƒขแƒ”แƒ แƒœแƒแƒขแƒ˜แƒ•แƒแƒก แƒขแƒคแƒ แƒฃแƒœแƒก). แƒ›แƒแƒ’แƒ แƒแƒ› แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜ แƒฃแƒžแƒ˜แƒ แƒแƒขแƒ”แƒกแƒแƒ‘แƒ แƒแƒ แƒ˜แƒก Docker-แƒจแƒ˜ แƒแƒœ แƒฃแƒ‘แƒ แƒแƒšแƒแƒ“ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ” แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒแƒ“ แƒ›แƒแƒ แƒ—แƒ•แƒ˜แƒก แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒ, แƒแƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก RStudio-แƒก แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”.

6. แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒ™แƒ”แƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ

แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒงแƒ”แƒœแƒ”แƒ— Docker แƒ’แƒแƒ แƒ”แƒ›แƒแƒก แƒžแƒแƒ แƒขแƒแƒ‘แƒ”แƒšแƒฃแƒ แƒแƒ‘แƒ˜แƒก แƒฃแƒ–แƒ แƒฃแƒœแƒ•แƒ”แƒšแƒกแƒแƒงแƒแƒคแƒแƒ“ แƒ’แƒฃแƒœแƒ“แƒ˜แƒก แƒฌแƒ”แƒ•แƒ แƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก แƒขแƒ แƒ”แƒœแƒ˜แƒœแƒ’แƒ˜แƒก แƒ›แƒแƒ“แƒ”แƒšแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ“แƒ แƒฆแƒ แƒฃแƒ‘แƒ”แƒšแƒจแƒ˜ แƒกแƒฌแƒ แƒแƒคแƒ˜ แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ“แƒแƒ˜แƒฌแƒงแƒแƒ— R แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒ˜แƒกแƒขแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒจแƒ”แƒ“แƒแƒ แƒ”แƒ‘แƒ˜แƒ— แƒฃแƒฉแƒ•แƒ”แƒฃแƒšแƒ แƒแƒ› แƒฎแƒ”แƒšแƒกแƒแƒฌแƒงแƒแƒก แƒ’แƒแƒชแƒœแƒแƒ‘แƒ แƒแƒ› แƒžแƒฃแƒ‘แƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒกแƒ”แƒ แƒ˜แƒ แƒแƒœ แƒ•แƒ˜แƒ“แƒ”แƒ แƒ™แƒฃแƒ แƒกแƒ˜.

Docker แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒจแƒ”แƒฅแƒ›แƒœแƒแƒ— แƒ—แƒฅแƒ•แƒ”แƒœแƒ˜ แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜ แƒœแƒฃแƒšแƒ˜แƒ“แƒแƒœ แƒ“แƒ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒ— แƒกแƒฎแƒ•แƒ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜, แƒ แƒแƒ’แƒแƒ แƒช แƒกแƒแƒคแƒฃแƒซแƒ•แƒ”แƒšแƒ˜ แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฅแƒ›แƒœแƒ”แƒšแƒแƒ“. แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜ แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒแƒœแƒแƒšแƒ˜แƒ–แƒ”แƒ‘แƒ˜แƒกแƒแƒก แƒ›แƒ˜แƒ•แƒ”แƒ“แƒ˜แƒ— แƒ“แƒแƒกแƒ™แƒ•แƒœแƒแƒ›แƒ“แƒ”, แƒ แƒแƒ› NVIDIA, CUDA+cuDNN แƒ“แƒ แƒแƒ˜แƒ•แƒ”แƒ แƒ”แƒ‘แƒ˜แƒก แƒ“แƒ Python แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒกแƒฃแƒ แƒแƒ—แƒ˜แƒก แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ›แƒแƒชแƒฃแƒšแƒแƒ‘แƒ˜แƒ—แƒ˜ แƒœแƒแƒฌแƒ˜แƒšแƒ˜แƒ แƒ“แƒ แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ”แƒ— แƒกแƒแƒคแƒฃแƒซแƒ•แƒšแƒแƒ“ แƒแƒ’แƒ•แƒ”แƒฆแƒ แƒแƒคแƒ˜แƒชแƒ˜แƒแƒšแƒฃแƒ แƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ˜. tensorflow/tensorflow:1.12.0-gpu, แƒ˜แƒฅ แƒ“แƒแƒแƒ›แƒแƒขแƒ”แƒ— แƒกแƒแƒญแƒ˜แƒ แƒ R แƒžแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜.

แƒกแƒแƒ‘แƒแƒšแƒแƒ แƒ“แƒแƒ™แƒ”แƒ แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ˜ แƒแƒกแƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒแƒ“แƒ:

dockerfile

FROM tensorflow/tensorflow:1.12.0-gpu

MAINTAINER Artem Klevtsov <[email protected]>

SHELL ["/bin/bash", "-c"]

ARG LOCALE="en_US.UTF-8"
ARG APT_PKG="libopencv-dev r-base r-base-dev littler"
ARG R_BIN_PKG="futile.logger checkmate data.table rcpp rapidjsonr dbi keras jsonlite curl digest remotes"
ARG R_SRC_PKG="xtensor RcppThread docopt MonetDBLite"
ARG PY_PIP_PKG="keras"
ARG DIRS="/db /app /app/data /app/models /app/logs"

RUN source /etc/os-release && 
    echo "deb https://cloud.r-project.org/bin/linux/ubuntu ${UBUNTU_CODENAME}-cran35/" > /etc/apt/sources.list.d/cran35.list && 
    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9 && 
    add-apt-repository -y ppa:marutter/c2d4u3.5 && 
    add-apt-repository -y ppa:timsc/opencv-3.4 && 
    apt-get update && 
    apt-get install -y locales && 
    locale-gen ${LOCALE} && 
    apt-get install -y --no-install-recommends ${APT_PKG} && 
    ln -s /usr/lib/R/site-library/littler/examples/install.r /usr/local/bin/install.r && 
    ln -s /usr/lib/R/site-library/littler/examples/install2.r /usr/local/bin/install2.r && 
    ln -s /usr/lib/R/site-library/littler/examples/installGithub.r /usr/local/bin/installGithub.r && 
    echo 'options(Ncpus = parallel::detectCores())' >> /etc/R/Rprofile.site && 
    echo 'options(repos = c(CRAN = "https://cloud.r-project.org"))' >> /etc/R/Rprofile.site && 
    apt-get install -y $(printf "r-cran-%s " ${R_BIN_PKG}) && 
    install.r ${R_SRC_PKG} && 
    pip install ${PY_PIP_PKG} && 
    mkdir -p ${DIRS} && 
    chmod 777 ${DIRS} && 
    rm -rf /tmp/downloaded_packages/ /tmp/*.rds && 
    rm -rf /var/lib/apt/lists/*

COPY utils /app/utils
COPY src /app/src
COPY tests /app/tests
COPY bin/*.R /app/

ENV DBDIR="/db"
ENV CUDA_HOME="/usr/local/cuda"
ENV PATH="/app:${PATH}"

WORKDIR /app

VOLUME /db
VOLUME /app

CMD bash

แƒ›แƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒฃแƒšแƒแƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒžแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜ แƒ›แƒแƒ—แƒแƒ•แƒกแƒ“แƒ แƒชแƒ•แƒšแƒแƒ“แƒ”แƒ‘แƒจแƒ˜; แƒ“แƒแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒฃแƒ›แƒ”แƒขแƒ”แƒกแƒ˜ แƒœแƒแƒฌแƒ˜แƒšแƒ˜ แƒ™แƒแƒžแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ”แƒ‘แƒจแƒ˜ แƒจแƒ”แƒ™แƒ แƒ”แƒ‘แƒ˜แƒก แƒ“แƒ แƒแƒก. แƒฉแƒ•แƒ”แƒœ แƒแƒกแƒ”แƒ•แƒ” แƒจแƒ”แƒ•แƒชแƒ•แƒแƒšแƒ”แƒ— แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒญแƒฃแƒ แƒ•แƒ˜ /bin/bash แƒจแƒ˜แƒœแƒแƒแƒ แƒกแƒ˜แƒก แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒแƒ“ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก /etc/os-release. แƒแƒ›แƒแƒœ แƒ—แƒแƒ•แƒ˜แƒ“แƒแƒœ แƒแƒ˜แƒชแƒ˜แƒšแƒ OS-แƒ˜แƒก แƒ•แƒ”แƒ แƒกแƒ˜แƒ˜แƒก แƒ™แƒแƒ“แƒจแƒ˜ แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒ˜แƒก แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒ.

แƒ’แƒแƒ แƒ“แƒ แƒแƒ›แƒ˜แƒกแƒ, แƒ“แƒแƒ˜แƒฌแƒ”แƒ แƒ แƒžแƒแƒขแƒแƒ แƒ bash แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒฃแƒจแƒ•แƒแƒ— แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜ แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒ—. แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ”แƒก แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ˜แƒงแƒแƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜ แƒœแƒ”แƒ แƒ•แƒฃแƒšแƒ˜ แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒแƒ“แƒ แƒ” แƒ˜แƒงแƒ แƒ’แƒแƒœแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜แƒก แƒจแƒ˜แƒ’แƒœแƒ˜แƒ—, แƒแƒœ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒกแƒ˜ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜แƒก แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒ—แƒ•แƒ˜แƒกแƒ แƒ“แƒ แƒ›แƒแƒœแƒ˜แƒขแƒแƒ แƒ˜แƒœแƒ’แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก:

แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜แƒก แƒ’แƒแƒกแƒแƒจแƒ•แƒ”แƒ‘แƒแƒ“

#!/bin/sh

DBDIR=${PWD}/db
LOGSDIR=${PWD}/logs
MODELDIR=${PWD}/models
DATADIR=${PWD}/data
ARGS="--runtime=nvidia --rm -v ${DBDIR}:/db -v ${LOGSDIR}:/app/logs -v ${MODELDIR}:/app/models -v ${DATADIR}:/app/data"

if [ -z "$1" ]; then
    CMD="Rscript /app/train_nn.R"
elif [ "$1" = "bash" ]; then
    ARGS="${ARGS} -ti"
else
    CMD="Rscript /app/train_nn.R $@"
fi

docker run ${ARGS} doodles-tf ${CMD}

แƒ—แƒฃ แƒ”แƒก bash แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”, แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒ’แƒแƒ›แƒแƒ˜แƒซแƒแƒฎแƒ”แƒ‘แƒ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜แƒก แƒจแƒ˜แƒ’แƒœแƒ˜แƒ— train_nn.R แƒœแƒแƒ’แƒฃแƒšแƒ˜แƒกแƒฎแƒ›แƒ”แƒ•แƒ˜ แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ”แƒ‘แƒ˜แƒ—; แƒ—แƒฃ แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒžแƒแƒ–แƒ˜แƒชแƒ˜แƒฃแƒ แƒ˜ แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒ˜ แƒแƒ แƒ˜แƒก "bash", แƒ›แƒแƒจแƒ˜แƒœ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜ แƒ“แƒแƒ˜แƒฌแƒงแƒ”แƒ‘แƒ แƒ˜แƒœแƒขแƒ”แƒ แƒแƒฅแƒขแƒ˜แƒฃแƒšแƒแƒ“ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒญแƒฃแƒ แƒ•แƒ˜แƒ—. แƒงแƒ•แƒ”แƒšแƒ แƒกแƒฎแƒ•แƒ แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒžแƒแƒ–แƒ˜แƒชแƒ˜แƒฃแƒ แƒ˜ แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ‘แƒ”แƒ‘แƒ˜ แƒ˜แƒชแƒ•แƒšแƒ”แƒ‘แƒ: CMD="Rscript /app/train_nn.R $@".

แƒแƒฆแƒกแƒแƒœแƒ˜แƒจแƒœแƒแƒ•แƒ˜แƒ, แƒ แƒแƒ› แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ”แƒ‘แƒ˜ แƒฌแƒงแƒแƒ แƒแƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒ— แƒ“แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ”แƒ‘แƒ˜แƒ—, แƒ˜แƒกแƒ”แƒ•แƒ” แƒ แƒแƒ’แƒแƒ แƒช แƒ’แƒแƒฌแƒ•แƒ แƒ—แƒœแƒ˜แƒšแƒ˜ แƒ›แƒแƒ“แƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒก แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ, แƒ“แƒแƒ›แƒแƒœแƒขแƒแƒŸแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒจแƒ˜ แƒ›แƒแƒกแƒžแƒ˜แƒœแƒซแƒ”แƒšแƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒ“แƒแƒœ, แƒ แƒแƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ›แƒ˜แƒ˜แƒฆแƒแƒ— แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒ”แƒ‘แƒ˜ แƒ–แƒ”แƒ“แƒ›แƒ”แƒขแƒ˜ แƒ›แƒแƒœแƒ˜แƒžแƒฃแƒšแƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”.

7. แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” GPU-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ Google Cloud-แƒ–แƒ”

แƒ™แƒแƒœแƒ™แƒฃแƒ แƒกแƒ˜แƒก แƒ”แƒ แƒ—-แƒ”แƒ แƒ—แƒ˜ แƒ›แƒแƒฎแƒแƒกแƒ˜แƒแƒ—แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ˜แƒงแƒ แƒซแƒแƒšแƒ˜แƒแƒœ แƒฎแƒ›แƒแƒฃแƒ แƒ˜แƒแƒœแƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜ (แƒ˜แƒฎแƒ˜แƒšแƒ”แƒ— แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜แƒก แƒกแƒฃแƒ แƒแƒ—แƒ˜, แƒœแƒแƒกแƒ”แƒกแƒฎแƒ”แƒ‘แƒ˜ @Leigh.plt-แƒ“แƒแƒœ ODS slack-แƒ“แƒแƒœ). แƒ“แƒ˜แƒ“แƒ˜ แƒžแƒแƒ แƒขแƒ˜แƒ”แƒ‘แƒ˜ แƒ’แƒ•แƒ”แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ แƒแƒ›แƒ˜แƒก แƒฌแƒ˜แƒœแƒแƒแƒฆแƒ›แƒ“แƒ”แƒ’ แƒ‘แƒ แƒซแƒแƒšแƒแƒจแƒ˜ แƒ“แƒ แƒ™แƒแƒ›แƒžแƒ˜แƒฃแƒขแƒ”แƒ แƒ–แƒ” แƒ”แƒฅแƒกแƒžแƒ”แƒ แƒ˜แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, 1 GPU-แƒ˜แƒ—, แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ”แƒ— แƒ“แƒแƒ”แƒฃแƒคแƒšแƒแƒœ แƒขแƒ แƒ”แƒœแƒ˜แƒœแƒ’แƒ˜แƒก แƒ›แƒแƒ“แƒ”แƒšแƒ”แƒ‘แƒก แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” GPU-แƒ–แƒ” แƒฆแƒ แƒฃแƒ‘แƒ”แƒšแƒจแƒ˜. แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ GoogleCloud (แƒ™แƒแƒ แƒ’แƒ˜ แƒกแƒแƒฎแƒ”แƒšแƒ›แƒซแƒฆแƒ•แƒแƒœแƒ”แƒšแƒ แƒกแƒแƒคแƒฃแƒซแƒ•แƒšแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก) แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜ แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒ“แƒ˜แƒ“แƒ˜ แƒแƒ แƒฉแƒ”แƒ•แƒแƒœแƒ˜แƒก, แƒ’แƒแƒœแƒ˜แƒ•แƒ แƒฃแƒšแƒ˜ แƒคแƒแƒกแƒ”แƒ‘แƒ˜แƒก แƒ“แƒ $300 แƒ‘แƒแƒœแƒฃแƒกแƒ˜แƒก แƒ’แƒแƒ›แƒ. แƒกแƒ˜แƒฎแƒแƒ แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ แƒจแƒ”แƒ•แƒฃแƒ™แƒ•แƒ”แƒ—แƒ” 4xV100 แƒ˜แƒœแƒกแƒขแƒแƒœแƒชแƒ˜แƒ SSD-แƒ˜แƒ— แƒ“แƒ แƒขแƒแƒœแƒ แƒแƒžแƒ”แƒ แƒแƒขแƒ˜แƒฃแƒšแƒ˜ แƒ›แƒ”แƒฎแƒกแƒ˜แƒ”แƒ แƒ”แƒ‘แƒ˜แƒ— แƒ“แƒ แƒ”แƒก แƒ“แƒ˜แƒ“แƒ˜ แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ แƒ˜แƒงแƒ. แƒแƒกแƒ”แƒ—แƒ˜ แƒ›แƒแƒœแƒฅแƒแƒœแƒ แƒกแƒฌแƒ แƒแƒคแƒแƒ“ แƒญแƒแƒ›แƒก แƒคแƒฃแƒšแƒก; แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒแƒ•แƒแƒ แƒ˜แƒฃแƒšแƒ˜ แƒ”แƒฅแƒกแƒžแƒ”แƒ แƒ˜แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒฉแƒแƒขแƒแƒ แƒ”แƒ‘แƒ แƒ“แƒแƒ“แƒแƒกแƒขแƒฃแƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒ˜แƒšแƒกแƒแƒ“แƒ”แƒœแƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”. แƒกแƒแƒ’แƒแƒœแƒ›แƒแƒœแƒแƒ—แƒšแƒ”แƒ‘แƒšแƒ แƒ›แƒ˜แƒ–แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒฃแƒ›แƒฏแƒแƒ‘แƒ”แƒกแƒ˜แƒ K80 แƒแƒ˜แƒฆแƒแƒ—. แƒ›แƒแƒ’แƒ แƒแƒ› แƒ“แƒ˜แƒ“แƒ˜ แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ˜แƒ— แƒแƒžแƒ”แƒ แƒแƒขแƒ˜แƒฃแƒšแƒ˜ แƒ›แƒ”แƒฎแƒกแƒ˜แƒ”แƒ แƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒ’แƒแƒ“แƒ’แƒ”แƒ‘แƒแƒ— - แƒฆแƒ แƒฃแƒ‘แƒšแƒแƒ•แƒแƒœแƒ˜ SSD-แƒ› แƒแƒ  แƒ›แƒแƒแƒฎแƒ“แƒ˜แƒœแƒ แƒจแƒ—แƒแƒ‘แƒ”แƒญแƒ“แƒ˜แƒšแƒ”แƒ‘แƒ แƒ—แƒแƒ•แƒ˜แƒกแƒ˜ แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒ—, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒ แƒ’แƒแƒ“แƒแƒ”แƒชแƒ dev/shm.

แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒแƒ แƒ™แƒแƒ“แƒ˜แƒก แƒคแƒ แƒแƒ’แƒ›แƒ”แƒœแƒขแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒžแƒแƒกแƒฃแƒฎแƒ˜แƒกแƒ›แƒ’แƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ GPU-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒแƒ–แƒ”. แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜, แƒ›แƒแƒ“แƒ”แƒšแƒ˜ แƒ˜แƒฅแƒ›แƒœแƒ”แƒ‘แƒ CPU-แƒ–แƒ” แƒ™แƒแƒœแƒขแƒ”แƒฅแƒกแƒขแƒฃแƒ แƒ˜ แƒ›แƒ”แƒœแƒ”แƒฏแƒ”แƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒ˜แƒกแƒ”แƒ•แƒ” แƒ แƒแƒ’แƒแƒ แƒช แƒžแƒ˜แƒ—แƒแƒœแƒจแƒ˜:

with(tensorflow::tf$device("/cpu:0"), {
  model_cpu <- get_model(
    name = model_name,
    input_shape = input_shape,
    weights = weights,
    metrics =(top_3_categorical_accuracy,
    compile = FALSE
  )
})

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ“แƒแƒฃแƒ™แƒแƒ›แƒžแƒšแƒ”แƒฅแƒขแƒ”แƒ‘แƒ”แƒšแƒ˜ (แƒ”แƒก แƒ›แƒœแƒ˜แƒจแƒ•แƒœแƒ”แƒšแƒแƒ•แƒแƒœแƒ˜แƒ) แƒ›แƒแƒ“แƒ”แƒšแƒ˜ แƒ™แƒแƒžแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜ GPU-แƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒชแƒ”แƒ›แƒฃแƒš แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒแƒ–แƒ” แƒ“แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒฎแƒ“แƒ”แƒ‘แƒ แƒ›แƒ˜แƒกแƒ˜ แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ:

model <- keras::multi_gpu_model(model_cpu, gpus = n_gpu)
keras::compile(
  object = model,
  optimizer = keras::optimizer_adam(lr = 0.0004),
  loss = "categorical_crossentropy",
  metrics = c(top_3_categorical_accuracy)
)

แƒงแƒ•แƒ”แƒšแƒ แƒคแƒ”แƒœแƒ˜แƒก แƒ’แƒแƒงแƒ˜แƒœแƒ•แƒ˜แƒก แƒ™แƒšแƒแƒกแƒ˜แƒ™แƒฃแƒ แƒ˜ แƒขแƒ”แƒฅแƒœแƒ˜แƒ™แƒ, แƒ’แƒแƒ แƒ“แƒ แƒฃแƒ™แƒแƒœแƒแƒกแƒ™แƒœแƒ”แƒšแƒ˜แƒกแƒ, แƒ‘แƒแƒšแƒ แƒคแƒ”แƒœแƒ˜แƒก แƒ•แƒแƒ แƒฏแƒ˜แƒจแƒ˜, แƒ’แƒแƒงแƒ˜แƒœแƒ•แƒ แƒ“แƒ แƒ›แƒ—แƒ”แƒšแƒ˜ แƒ›แƒแƒ“แƒ”แƒšแƒ˜แƒก แƒ’แƒแƒ“แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” GPU-แƒกแƒ—แƒ•แƒ˜แƒก, แƒ•แƒ”แƒ  แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ“แƒ.

แƒขแƒ แƒ”แƒœแƒ˜แƒœแƒ’แƒ˜แƒก แƒ›แƒแƒœแƒ˜แƒขแƒแƒ แƒ˜แƒœแƒ’แƒ˜ แƒฎแƒ“แƒ”แƒ‘แƒแƒ“แƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”. แƒขแƒ”แƒœแƒกแƒแƒ แƒ‘แƒแƒ แƒ“แƒ˜, แƒจแƒ”แƒ›แƒแƒ•แƒ˜แƒคแƒแƒ แƒ’แƒšแƒ”แƒ‘แƒ˜แƒ— แƒŸแƒฃแƒ แƒœแƒแƒšแƒ”แƒ‘แƒ˜แƒก แƒฉแƒแƒฌแƒ”แƒ แƒ˜แƒ— แƒ“แƒ แƒ›แƒแƒ“แƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ˜แƒ— แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒฃแƒšแƒ˜ แƒกแƒแƒฎแƒ”แƒšแƒ”แƒ‘แƒ˜แƒ— แƒงแƒแƒ•แƒ”แƒšแƒ˜ แƒ”แƒžแƒแƒฅแƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’:

แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ”แƒ‘แƒ˜

# ะจะฐะฑะปะพะฝ ะธะผะตะฝะธ ั„ะฐะนะปะฐ ะปะพะณะฐ
log_file_tmpl <- file.path("logs", sprintf(
  "%s_%d_%dch_%s.csv",
  model_name,
  dim_size,
  channels,
  format(Sys.time(), "%Y%m%d%H%M%OS")
))
# ะจะฐะฑะปะพะฝ ะธะผะตะฝะธ ั„ะฐะนะปะฐ ะผะพะดะตะปะธ
model_file_tmpl <- file.path("models", sprintf(
  "%s_%d_%dch_{epoch:02d}_{val_loss:.2f}.h5",
  model_name,
  dim_size,
  channels
))

callbacks_list <- list(
  keras::callback_csv_logger(
    filename = log_file_tmpl
  ),
  keras::callback_early_stopping(
    monitor = "val_loss",
    min_delta = 1e-4,
    patience = 8,
    verbose = 1,
    mode = "min"
  ),
  keras::callback_reduce_lr_on_plateau(
    monitor = "val_loss",
    factor = 0.5, # ัƒะผะตะฝัŒัˆะฐะตะผ lr ะฒ 2 ั€ะฐะทะฐ
    patience = 4,
    verbose = 1,
    min_delta = 1e-4,
    mode = "min"
  ),
  keras::callback_model_checkpoint(
    filepath = model_file_tmpl,
    monitor = "val_loss",
    save_best_only = FALSE,
    save_weights_only = FALSE,
    mode = "min"
  )
)

8. แƒ“แƒแƒกแƒ™แƒ•แƒœแƒ˜แƒก แƒœแƒแƒชแƒ•แƒšแƒแƒ“

แƒ›แƒ—แƒ”แƒšแƒ˜ แƒ แƒ˜แƒ’แƒ˜ แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒจแƒ”แƒ’แƒ•แƒฎแƒ•แƒ“แƒ แƒฏแƒ”แƒ  แƒ™แƒ˜แƒ“แƒ”แƒ• แƒแƒ  แƒแƒ แƒ˜แƒก แƒ“แƒแƒซแƒšแƒ”แƒฃแƒšแƒ˜:

  • ะฒ แƒ™แƒ”แƒ แƒแƒก แƒแƒ  แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒ›แƒ–แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ แƒแƒžแƒขแƒ˜แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒกแƒฌแƒแƒ•แƒšแƒ˜แƒก แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒแƒ•แƒขแƒแƒ›แƒแƒขแƒฃแƒ แƒแƒ“ แƒ›แƒแƒกแƒแƒซแƒ”แƒ‘แƒœแƒแƒ“ (แƒแƒœแƒแƒšแƒแƒ’แƒฃแƒ แƒ˜ lr_finder แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒแƒจแƒ˜ แƒกแƒฌแƒ แƒแƒคแƒแƒ“.แƒแƒ˜); แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒซแƒแƒšแƒ˜แƒกแƒฎแƒ›แƒ”แƒ•แƒ˜แƒ—, แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ›แƒ”แƒกแƒแƒ›แƒ” แƒ›แƒฎแƒแƒ แƒ˜แƒก แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒžแƒแƒ แƒขแƒ˜แƒ แƒ”แƒ‘แƒ R-แƒ–แƒ”, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ”แƒก;
  • แƒฌแƒ˜แƒœแƒ แƒžแƒฃแƒœแƒฅแƒขแƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒแƒ“, แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” GPU-แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒแƒก แƒจแƒ”แƒฃแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ˜แƒงแƒ แƒ•แƒแƒ แƒฏแƒ˜แƒจแƒ˜แƒก แƒกแƒฌแƒแƒ แƒ˜ แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒจแƒ”แƒ แƒฉแƒ”แƒ•แƒ;
  • แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก แƒ—แƒแƒœแƒแƒ›แƒ”แƒ“แƒ แƒแƒ•แƒ” แƒœแƒ”แƒ แƒ•แƒฃแƒšแƒ˜ แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒ˜แƒก แƒœแƒแƒ™แƒšแƒ”แƒ‘แƒแƒ‘แƒ, แƒ’แƒแƒœแƒกแƒแƒ™แƒฃแƒ—แƒ แƒ”แƒ‘แƒ˜แƒ— แƒ˜แƒ›แƒ˜แƒฏแƒœแƒ”แƒขแƒ–แƒ” แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ  แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒฃแƒšแƒ˜;
  • แƒแƒ แƒแƒ•แƒ˜แƒก แƒชแƒ˜แƒ™แƒšแƒ˜แƒก แƒžแƒแƒšแƒ˜แƒขแƒ˜แƒ™แƒ แƒ“แƒ แƒกแƒฌแƒแƒ•แƒšแƒ˜แƒก แƒ“แƒ˜แƒกแƒ™แƒ แƒ˜แƒ›แƒ˜แƒœแƒแƒชแƒ˜แƒฃแƒšแƒ˜ แƒ›แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜ (แƒ™แƒแƒกแƒ˜แƒœแƒฃแƒกแƒฃแƒ แƒ˜ แƒแƒœแƒ˜แƒšแƒ˜แƒ แƒ”แƒ‘แƒ แƒ˜แƒงแƒ แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒ— แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ“แƒ, แƒ›แƒแƒ“แƒšแƒแƒ‘แƒ แƒกแƒ™แƒ”แƒ˜แƒ“แƒแƒœแƒ˜).

แƒ แƒ แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒ แƒแƒ› แƒ•แƒ˜แƒกแƒฌแƒแƒ•แƒšแƒ”แƒ— แƒแƒ› แƒ™แƒแƒœแƒ™แƒฃแƒ แƒกแƒ˜แƒ“แƒแƒœ:

  • แƒจแƒ”แƒ“แƒแƒ แƒ”แƒ‘แƒ˜แƒ— แƒ“แƒแƒ‘แƒแƒšแƒ˜ แƒกแƒ˜แƒ›แƒซแƒšแƒแƒ•แƒ แƒ˜แƒก แƒแƒžแƒแƒ แƒแƒขแƒ–แƒ”, แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ˜แƒ›แƒฃแƒจแƒแƒแƒ— แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒฆแƒ˜แƒ แƒกแƒ”แƒฃแƒšแƒ˜ (แƒ แƒแƒ›แƒ“แƒ”แƒœแƒฏแƒ”แƒ  แƒ›แƒ”แƒขแƒ˜ แƒแƒžแƒ”แƒ แƒแƒขแƒ˜แƒฃแƒšแƒ˜ แƒ›แƒ”แƒฎแƒกแƒ˜แƒ”แƒ แƒ”แƒ‘แƒ˜แƒ—) แƒ›แƒแƒชแƒฃแƒšแƒแƒ‘แƒ˜แƒ—, แƒขแƒ™แƒ˜แƒ•แƒ˜แƒšแƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”. แƒžแƒšแƒแƒกแƒขแƒ˜แƒ™แƒฃแƒ แƒ˜ แƒฉแƒแƒœแƒ—แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜. แƒ›แƒแƒ’แƒ˜แƒ“แƒ แƒ–แƒแƒ’แƒแƒ•แƒก แƒ›แƒ”แƒฎแƒกแƒ˜แƒ”แƒ แƒ”แƒ‘แƒแƒก แƒชแƒฎแƒ แƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒแƒ“แƒ’แƒ˜แƒšแƒ–แƒ” แƒ›แƒแƒ“แƒ˜แƒคแƒ˜แƒชแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ, แƒ แƒแƒช แƒ—แƒแƒ•แƒ˜แƒ“แƒแƒœ แƒแƒ˜แƒชแƒ˜แƒšแƒ”แƒ‘แƒก แƒ›แƒแƒ— แƒ™แƒแƒžแƒ˜แƒ แƒ”แƒ‘แƒแƒก แƒ“แƒ แƒกแƒฌแƒแƒ แƒแƒ“ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒแƒก, แƒ›แƒ˜แƒกแƒ˜ แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒ”แƒ‘แƒ˜ แƒ—แƒ˜แƒ—แƒฅแƒ›แƒ˜แƒก แƒงแƒแƒ•แƒ”แƒšแƒ—แƒ•แƒ˜แƒก แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒก แƒฃแƒ›แƒแƒฆแƒšแƒ”แƒก แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ”แƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ—แƒ•แƒ˜แƒก แƒชแƒœแƒแƒ‘แƒ˜แƒš แƒงแƒ•แƒ”แƒšแƒ แƒฎแƒ”แƒšแƒกแƒแƒฌแƒงแƒแƒก แƒจแƒแƒ แƒ˜แƒก. แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ แƒ‘แƒแƒ–แƒแƒจแƒ˜ แƒจแƒ”แƒœแƒแƒฎแƒ•แƒ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ—, แƒฎแƒจแƒ˜แƒ  แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒกแƒแƒ”แƒ แƒ—แƒแƒ“ แƒแƒ  แƒ˜แƒคแƒ˜แƒฅแƒ แƒแƒ— แƒ›แƒ—แƒ”แƒšแƒ˜ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ—แƒ RAM-แƒจแƒ˜ แƒจแƒ”แƒ™แƒฃแƒ›แƒจแƒ•แƒ˜แƒก แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒแƒ–แƒ”.
  • R-แƒจแƒ˜ แƒœแƒ”แƒšแƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒจแƒ”แƒ˜แƒชแƒ•แƒแƒšแƒแƒก แƒกแƒฌแƒ แƒแƒคแƒ˜ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒ— C++-แƒจแƒ˜ แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— Rcpp. แƒ—แƒฃ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ“แƒ RcppThread แƒแƒœ Rcppแƒžแƒแƒ แƒแƒšแƒ”แƒšแƒฃแƒ แƒ˜, แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒ™แƒ แƒแƒก แƒžแƒšแƒแƒขแƒคแƒแƒ แƒ›แƒ˜แƒก แƒ›แƒ แƒแƒ•แƒแƒš แƒฎแƒ แƒแƒฎแƒœแƒ˜แƒแƒœ แƒ˜แƒ›แƒžแƒšแƒ”แƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒแƒก, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒแƒ  แƒแƒ แƒ˜แƒก แƒกแƒแƒญแƒ˜แƒ แƒ แƒ™แƒแƒ“แƒ˜แƒก แƒžแƒแƒ แƒแƒšแƒ”แƒšแƒ˜แƒ–แƒ”แƒ‘แƒ R แƒ“แƒแƒœแƒ”แƒ–แƒ”.
  • แƒžแƒแƒ™แƒ”แƒขแƒ˜ Rcpp แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒš แƒ˜แƒฅแƒœแƒแƒก C++-แƒ˜แƒก แƒกแƒ”แƒ แƒ˜แƒแƒ–แƒฃแƒšแƒ˜ แƒชแƒแƒ“แƒœแƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”, แƒแƒกแƒแƒฎแƒฃแƒšแƒ˜แƒ แƒกแƒแƒญแƒ˜แƒ แƒ แƒ›แƒ˜แƒœแƒ˜แƒ›แƒฃแƒ›แƒ˜ แƒแƒฅ. แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜ แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ แƒ›แƒแƒ’แƒแƒ แƒ˜ C-แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ’แƒแƒ แƒ˜แƒชแƒแƒ xtensor แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒ CRAN-แƒ–แƒ”, แƒแƒœแƒฃ แƒ˜แƒฅแƒ›แƒœแƒ”แƒ‘แƒ แƒ˜แƒœแƒคแƒ แƒแƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒ แƒžแƒ แƒแƒ”แƒฅแƒขแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒกแƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒšแƒแƒ“, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒแƒ”แƒ แƒ—แƒ˜แƒแƒœแƒ”แƒ‘แƒก แƒ›แƒ–แƒ แƒ›แƒแƒฆแƒแƒšแƒ˜ แƒฎแƒแƒ แƒ˜แƒกแƒฎแƒ˜แƒก C++ แƒ™แƒแƒ“แƒก R-แƒจแƒ˜. แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ˜แƒ—แƒ˜ แƒ›แƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒฃแƒšแƒแƒ‘แƒ แƒแƒ แƒ˜แƒก แƒกแƒ˜แƒœแƒขแƒแƒฅแƒกแƒ˜แƒก แƒฎแƒแƒ–แƒ’แƒแƒกแƒ›แƒ แƒ“แƒ แƒกแƒขแƒแƒขแƒ˜แƒ™แƒฃแƒ แƒ˜ C++ แƒ™แƒแƒ“แƒ˜แƒก แƒแƒœแƒแƒšแƒ˜แƒ–แƒแƒขแƒแƒ แƒ˜ RStudio-แƒจแƒ˜.
  • แƒ“แƒแƒ™แƒแƒžแƒขแƒ˜ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒฃแƒจแƒ•แƒแƒ— แƒ“แƒแƒ›แƒแƒฃแƒ™แƒ˜แƒ“แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜แƒ—. แƒ”แƒก แƒ›แƒแƒกแƒแƒฎแƒ”แƒ แƒฎแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ“แƒ˜แƒกแƒขแƒแƒœแƒชแƒ˜แƒฃแƒ  แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ” แƒ’แƒแƒ›แƒแƒกแƒแƒงแƒ”แƒœแƒ”แƒ‘แƒšแƒแƒ“, แƒ›แƒแƒ— แƒจแƒแƒ แƒ˜แƒก. แƒ“แƒแƒ™แƒ”แƒ แƒ˜แƒก แƒฅแƒ•แƒ”แƒจ. RStudio-แƒจแƒ˜ แƒแƒ แƒแƒกแƒแƒกแƒ˜แƒแƒ›แƒแƒ•แƒœแƒแƒ แƒ›แƒ แƒแƒ•แƒแƒšแƒกแƒแƒแƒ—แƒ˜แƒแƒœแƒ˜ แƒ”แƒฅแƒกแƒžแƒ”แƒ แƒ˜แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒฉแƒแƒขแƒแƒ แƒ”แƒ‘แƒ แƒœแƒ”แƒ แƒ•แƒฃแƒšแƒ˜ แƒฅแƒกแƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒ•แƒแƒ แƒฏแƒ˜แƒจแƒ˜แƒ— แƒ“แƒ แƒ—แƒแƒ•แƒแƒ“ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ” IDE-แƒ˜แƒก แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒงแƒแƒ•แƒ”แƒšแƒ—แƒ•แƒ˜แƒก แƒแƒ  แƒแƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒ—แƒšแƒ”แƒ‘แƒฃแƒšแƒ˜.
  • Docker แƒฃแƒ–แƒ แƒฃแƒœแƒ•แƒ”แƒšแƒงแƒแƒคแƒก แƒ™แƒแƒ“แƒ˜แƒก แƒžแƒแƒ แƒขแƒแƒ‘แƒ”แƒšแƒฃแƒ แƒแƒ‘แƒแƒก แƒ“แƒ แƒจแƒ”แƒ“แƒ”แƒ’แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ”แƒแƒ แƒ”แƒ‘แƒแƒก แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก OS-แƒ˜แƒก แƒ“แƒ แƒ‘แƒ˜แƒ‘แƒšแƒ˜แƒแƒ—แƒ”แƒ™แƒ”แƒ‘แƒ˜แƒก แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒ•แƒ”แƒ แƒกแƒ˜แƒ˜แƒ—, แƒแƒกแƒ”แƒ•แƒ” แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ”แƒ‘แƒ–แƒ” แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒแƒ‘แƒแƒก. แƒ—แƒฅแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ˜แƒซแƒšแƒ˜แƒแƒ— แƒ’แƒแƒฃแƒจแƒ•แƒแƒ— แƒ›แƒ—แƒ”แƒšแƒ˜ แƒกแƒแƒกแƒฌแƒแƒ•แƒšแƒ แƒ›แƒ˜แƒšแƒกแƒแƒ“แƒ”แƒœแƒ˜ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ”แƒ แƒ—แƒ˜ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒ—.
  • Google Cloud แƒแƒ แƒ˜แƒก แƒกแƒแƒ‘แƒ˜แƒฃแƒฏแƒ”แƒขแƒ แƒ’แƒ–แƒ แƒซแƒ•แƒ˜แƒ แƒแƒ“แƒฆแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒแƒžแƒแƒ แƒแƒขแƒฃแƒ แƒ˜แƒก แƒ”แƒฅแƒกแƒžแƒ”แƒ แƒ˜แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ—แƒฅแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒแƒ˜แƒ แƒฉแƒ˜แƒแƒ— แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ แƒคแƒ แƒ—แƒฎแƒ˜แƒšแƒแƒ“.
  • แƒ˜แƒœแƒ“แƒ˜แƒ•แƒ˜แƒ“แƒฃแƒแƒšแƒฃแƒ แƒ˜ แƒ™แƒแƒ“แƒ˜แƒก แƒคแƒ แƒแƒ’แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒฉแƒฅแƒแƒ แƒ˜แƒก แƒ’แƒแƒ–แƒแƒ›แƒ•แƒ แƒซแƒแƒšแƒ˜แƒแƒœ แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒแƒ, แƒ’แƒแƒœแƒกแƒแƒ™แƒฃแƒ—แƒ แƒ”แƒ‘แƒ˜แƒ— R แƒ“แƒ C++-แƒ˜แƒก แƒ™แƒแƒ›แƒ‘แƒ˜แƒœแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒกแƒแƒก แƒ“แƒ แƒžแƒแƒ™แƒ”แƒขแƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“. bench - แƒแƒกแƒ”แƒ•แƒ” แƒซแƒแƒšแƒ˜แƒแƒœ แƒแƒ“แƒ•แƒ˜แƒšแƒ˜แƒ.

แƒกแƒแƒ”แƒ แƒ—แƒ แƒฏแƒแƒ›แƒจแƒ˜, แƒ”แƒก แƒ’แƒแƒ›แƒแƒชแƒ“แƒ˜แƒšแƒ”แƒ‘แƒ แƒซแƒแƒšแƒ˜แƒแƒœ แƒกแƒแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒ˜แƒงแƒ แƒ“แƒ แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒ’แƒ แƒซแƒ”แƒšแƒ”แƒ‘แƒ— แƒ›แƒฃแƒจแƒแƒแƒ‘แƒแƒก แƒฌแƒแƒ›แƒแƒญแƒ แƒ˜แƒšแƒ˜ แƒ–แƒแƒ’แƒ˜แƒ”แƒ แƒ—แƒ˜ แƒกแƒแƒ™แƒ˜แƒ—แƒฎแƒ˜แƒก แƒ›แƒแƒกแƒแƒ’แƒ•แƒแƒ แƒ”แƒ‘แƒšแƒแƒ“.

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ