เจคเจคเจ•เจพเจฒ เจกเจฐเจพเจ… เจกเฉ‚เจกเจฒ เจชเจ›เจพเจฃ: R, C++ เจ…เจคเฉ‡ เจจเจฟเจŠเจฐเจฒ เจจเฉˆเฉฑเจŸเจตเจฐเจ•เจพเจ‚ เจจเจพเจฒ เจฆเฉ‹เจธเจคเฉ€ เจ•เจฟเจตเฉ‡เจ‚ เจ•เจฐเฉ€เจ

เจคเจคเจ•เจพเจฒ เจกเจฐเจพเจ… เจกเฉ‚เจกเจฒ เจชเจ›เจพเจฃ: R, C++ เจ…เจคเฉ‡ เจจเจฟเจŠเจฐเจฒ เจจเฉˆเฉฑเจŸเจตเจฐเจ•เจพเจ‚ เจจเจพเจฒ เจฆเฉ‹เจธเจคเฉ€ เจ•เจฟเจตเฉ‡เจ‚ เจ•เจฐเฉ€เจ

เจนเฉ‡ เจนเจฌเจฐ!

เจชเจฟเจ›เจฒเฉ€ เจ—เจฟเจฐเจพเจตเจŸ เจตเจฟเฉฑเจš, เจ•เจพเจ—เจฒ เจจเฉ‡ เจนเฉฑเจฅเจพเจ‚ เจจเจพเจฒ เจ–เจฟเฉฑเจšเฉ€เจ†เจ‚ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจจเฉ‚เฉฐ เจตเจฐเจ—เฉ€เจ•เฉเจฐเจฟเจค เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจฆเฉ€ เจฎเฉ‡เจœเจผเจฌเจพเจจเฉ€ เจ•เฉ€เจคเฉ€, เจคเฉ‡เจœเจผ เจกเจฐเจพเจ… เจกเฉ‚เจกเจฒ เจชเจ›เจพเจฃ, เจœเจฟเจธ เจตเจฟเฉฑเจš, เจนเฉ‹เจฐเจพเจ‚ เจตเจฟเฉฑเจš, เจ†เจฐ-เจตเจฟเจ—เจฟเจ†เจจเฉ€เจ†เจ‚ เจฆเฉ€ เจ‡เฉฑเจ• เจŸเฉ€เจฎ เจจเฉ‡ เจนเจฟเฉฑเจธเจพ เจฒเจฟเจ†: เจ†เจฐเจŸเฉ‡เจฎ เจ•เจฒเฉ‡เจตเจคเจธเฉ‹เจตเจพ, เจซเจฟเจฒเจฟเจชเจพ เจฎเฉˆเจจเฉ‡เจœเจฐ ะธ เจ†เจ‚เจฆเจฐเฉ‡ เจ“เจ—เฉเจฐเจคเจธเฉ‹เจต. เจ…เจธเฉ€เจ‚ เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจฆเจพ เจตเจฟเจธเจคเจพเจฐ เจตเจฟเฉฑเจš เจตเจฐเจฃเจจ เจจเจนเฉ€เจ‚ เจ•เจฐเจพเจ‚เจ—เฉ‡; เจœเฉ‹ เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจ•เฉ€เจคเจพ เจœเจพ เจšเฉเฉฑเจ•เจพ เจนเฉˆ เจนเจพเจฒเฉ€เจ† เจชเฉเจฐเจ•เจพเจธเจผเจจ.

เจ‡เจธ เจตเจพเจฐ เจฎเฉˆเจกเจฒ เจซเจพเจฐเจฎเจฟเฉฐเจ— เจจเจพเจฒ เจ•เฉฐเจฎ เจจเจนเฉ€เจ‚ เจนเฉ‹เจ‡เจ†, เจชเจฐ เจฌเจนเฉเจค เจธเจพเจฐเจพ เจ•เฉ€เจฎเจคเฉ€ เจคเจœเจฐเจฌเจพ เจนเจพเจธเจฒ เจนเฉ‹เจ‡เจ†, เจ‡เจธ เจฒเจˆ เจฎเฉˆเจ‚ เจ•เจฎเจฟเจŠเจจเจฟเจŸเฉ€ เจจเฉ‚เฉฐ เจ•เจพเจ—เจฒเฉ‡ เจ…เจคเฉ‡ เจฐเฉ‹เจœเจผเจพเจจเจพ เจฆเฉ‡ เจ•เฉฐเจฎ เจตเจฟเฉฑเจš เจฌเจนเฉเจค เจธเจพเจฐเฉ€เจ†เจ‚ เจฆเจฟเจฒเจšเจธเจช เจ…เจคเฉ‡ เจ‰เจชเจฏเฉ‹เจ—เฉ€ เจšเฉ€เจœเจผเจพเจ‚ เจฌเจพเจฐเฉ‡ เจฆเฉฑเจธเจฃเจพ เจšเจพเจนเจพเจ‚เจ—เจพเฅค เจšเจฐเจšเจพ เจ•เฉ€เจคเฉ‡ เจ—เจ เจตเจฟเจธเจผเจฟเจ†เจ‚ เจตเจฟเฉฑเจšเฉ‹เจ‚: เจฌเจฟเจจเจพเจ‚ เจฎเฉเจธเจผเจ•เจฒ เจœเฉ€เจตเจจ เจ“เจชเจจเจธเฉ€เจตเฉ€, JSON เจชเจพเจฐเจธเจฟเฉฐเจ— (เจ‡เจน เจ‰เจฆเจพเจนเจฐเจจเจพเจ‚ R เจตเจฟเฉฑเจš เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจœเจพเจ‚ เจชเฉˆเจ•เฉ‡เจœเจพเจ‚ เจตเจฟเฉฑเจš C++ เจ•เฉ‹เจก เจฆเฉ‡ เจเจ•เฉ€เจ•เจฐเจจ เจฆเฉ€ เจœเจพเจ‚เจš เจ•เจฐเจฆเฉ€เจ†เจ‚ เจนเจจเฅค เจ†เจฐ.เจธเฉ€.เจชเฉ€.เจชเฉ€), เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจฆเจพ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจˆเจœเจผเฉ‡เจธเจผเจจ เจ…เจคเฉ‡ เจ…เฉฐเจคเจฎ เจนเฉฑเจฒ เจฆเจพ เจกเฉŒเจ•เจฐเจพเจˆเจœเจผเฉ‡เจธเจผเจจเฅค เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจฒเจˆ เจขเฉเจ•เจตเฉ‡เจ‚ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจธเฉฐเจฆเฉ‡เจธเจผ เจฆเฉ‡ เจธเจพเจฐเฉ‡ เจ•เฉ‹เจก เจตเจฟเฉฑเจš เจ‰เจชเจฒเจฌเจง เจนเจจ เจฐเจฟเจชเฉ‹เจœเจผเจŸเจฐเฉ€เจ†เจ‚.

เจธเจฎเฉฑเจ—เจฐเฉ€:

  1. CSV เจคเฉ‹เจ‚ MonetDB เจตเจฟเฉฑเจš เจ•เฉเจธเจผเจฒเจคเจพ เจจเจพเจฒ เจกเจพเจŸเจพ เจฒเฉ‹เจก เจ•เจฐเฉ‹
  2. เจฌเฉˆเจšเจพเจ‚ เจฆเฉ€ เจคเจฟเจ†เจฐเฉ€
  3. เจกเจพเจŸเจพเจฌเฉ‡เจธ เจคเฉ‹เจ‚ เจฌเฉˆเจšเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเจฒเฉ‹เจก เจ•เจฐเจจ เจฒเจˆ เจ‡เจŸเจฐเฉ‡เจŸเจฐ
  4. เจ‡เฉฑเจ• เจฎเจพเจกเจฒ เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจฆเฉ€ เจšเฉ‹เจฃ
  5. เจธเจ•เฉเจฐเจฟเจชเจŸ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจˆเจœเจผเฉ‡เจธเจผเจจ
  6. เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจฆเจพ เจกเฉŒเจ•เจฐเจพเจˆเจœเจผเฉ‡เจธเจผเจจ
  7. เจ—เฉ‚เจ—เจฒ เจ•เจฒเจพเจ‰เจก 'เจคเฉ‡ เจ•เจˆ GPUs เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจเจพ
  8. เจธเฉฐเจชเฉ‚เจฐเจจ เจนเฉ‹เจฃ เจฆเฉ‡ เจฌเจœเจพเจ

1. CSV เจคเฉ‹เจ‚ เจฎเฉ‹เจจเฉ‡เจŸเจกเฉ€เจฌเฉ€ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจ•เฉเจธเจผเจฒเจคเจพ เจจเจพเจฒ เจกเจพเจŸเจพ เจฒเฉ‹เจก เจ•เจฐเฉ‹

เจ‡เจธ เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจฆเจพ เจกเฉ‡เจŸเจพ เจคเจฟเจ†เจฐ-เจ•เฉ€เจคเฉ€ เจšเจฟเฉฑเจคเจฐเจพเจ‚ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจจเจนเฉ€เจ‚, เจธเจ—เฉ‹เจ‚ 340 CSV เจซเจพเจˆเจฒเจพเจ‚ (เจนเจฐเฉ‡เจ• เจ•เจฒเจพเจธ เจฒเจˆ เจ‡เฉฑเจ• เจซเจพเจˆเจฒ) เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจชเฉเจฐเจฆเจพเจจ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆ เจœเจฟเจธ เจตเจฟเฉฑเจš เจชเฉเจ†เจ‡เฉฐเจŸ เจ•เฉ‹เจ†เจฐเจกเฉ€เจจเฉ‡เจŸเจธ เจตเจพเจฒเฉ‡ JSON เจนเจจเฅค เจ‡เจนเจจเจพเจ‚ เจฌเจฟเฉฐเจฆเฉ‚เจ†เจ‚ เจจเฉ‚เฉฐ เจฒเจพเจˆเจจเจพเจ‚ เจจเจพเจฒ เจœเฉ‹เฉœ เจ•เฉ‡, เจ…เจธเฉ€เจ‚ 256x256 เจชเจฟเจ•เจธเจฒ เจฎเจพเจชเจฃ เจตเจพเจฒเฉ€ เจ‡เฉฑเจ• เจ…เฉฐเจคเจฎ เจšเจฟเฉฑเจคเจฐ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจจเจพเจฒ เจนเฉ€ เจนเจฐเฉ‡เจ• เจฐเจฟเจ•เจพเจฐเจก เจฒเจˆ เจ‡เฉฑเจ• เจฒเฉ‡เจฌเจฒ เจนเฉเฉฐเจฆเจพ เจนเฉˆ เจœเฉ‹ เจ‡เจน เจฆเจฐเจธเจพเจ‰เจ‚เจฆเจพ เจนเฉˆ เจ•เจฟ เจ•เฉ€ เจกเฉ‡เจŸเจพเจธเฉˆเจŸ เจ‡เจ•เฉฑเจคเจฐ เจ•เฉ€เจคเฉ‡ เจœเจพเจฃ เจตเฉ‡เจฒเฉ‡ เจตเจฐเจคเฉ‡ เจ—เจ เจตเจฐเจ—เฉ€เจ•เจฐเจฃ เจฆเฉเจ†เจฐเจพ เจคเจธเจตเฉ€เจฐ เจจเฉ‚เฉฐ เจธเจนเฉ€ เจขเฉฐเจ— เจจเจพเจฒ เจชเจ›เจพเจฃเจฟเจ† เจ—เจฟเจ† เจธเฉ€, เจคเจธเจตเฉ€เจฐ เจฆเฉ‡ เจฒเฉ‡เจ–เจ• เจฆเฉ‡ เจจเจฟเจตเจพเจธ เจฆเฉ‡ เจฆเฉ‡เจธเจผ เจฆเจพ เจ‡เฉฑเจ• เจฆเฉ‹-เจ…เฉฑเจ–เจฐเจพเจ‚ เจฆเจพ เจ•เฉ‹เจก, เจ‡เฉฑเจ• เจตเจฟเจฒเฉฑเจ–เจฃ เจชเจ›เจพเจฃเจ•เจฐเจคเจพ, เจ‡เฉฑเจ• เจŸเจพเจˆเจฎเจธเจŸเฉˆเจ‚เจชเฅค เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจ•เจฒเจพเจธ เจจเจพเจฎ เจœเฉ‹ เจซเจพเจˆเจฒ เจจเจพเจฎ เจจเจพเจฒ เจฎเฉ‡เจฒ เจ–เจพเจ‚เจฆเจพ เจนเฉˆเฅค เจ†เจฐเจ•เจพเจˆเจต เจตเจฟเฉฑเจš เจฎเฉ‚เจฒ เจกเฉ‡เจŸเจพ เจฆเฉ‡ เจ‡เฉฑเจ• เจธเจฐเจฒ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจตเจœเจผเจจ 7.4 GB เจ…เจคเฉ‡ เจ…เจจเจชเฉˆเจ• เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจฒเจ—เจญเจ— 20 GB เจนเฉเฉฐเจฆเจพ เจนเฉˆ, เจ…เจจเจชเฉˆเจ• เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจชเฉ‚เจฐเจพ เจกเฉ‡เจŸเจพ 240 GB เจคเฉฑเจ• เจฒเฉˆ เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค เจ†เจฏเฉ‹เจœเจ•เจพเจ‚ เจจเฉ‡ เจ‡เจน เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพเจ‡เจ† เจ•เจฟ เจฆเฉ‹เจตเฉ‡เจ‚ เจธเฉฐเจธเจ•เจฐเจฃ เจ‡เฉฑเจ•เฉ‹ เจกเจฐเจพเจ‡เฉฐเจ— เจจเฉ‚เฉฐ เจฆเฉเจฌเจพเจฐเจพ เจคเจฟเจ†เจฐ เจ•เจฐเจฆเฉ‡ เจนเจจ, เจญเจพเจต เจชเฉ‚เจฐเจพ เจธเฉฐเจธเจ•เจฐเจฃ เจฌเฉ‡เจฒเฉ‹เฉœเจพ เจธเฉ€เฅค เจ•เจฟเจธเฉ‡ เจตเฉ€ เจธเจฅเจฟเจคเฉ€ เจตเจฟเฉฑเจš, เจ—เฉเจฐเจพเจซเจฟเจ• เจซเจพเจˆเจฒเจพเจ‚ เจตเจฟเฉฑเจš เจœเจพเจ‚ เจเจฐเฉ‡ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš 50 เจฎเจฟเจฒเฉ€เจ…เจจ เจšเจฟเฉฑเจคเจฐเจพเจ‚ เจจเฉ‚เฉฐ เจธเจŸเฉ‹เจฐ เจ•เจฐเจจเจพ เจคเฉเจฐเฉฐเจค เจ—เฉˆเจฐ-เจฒเจพเจญเจ•เจพเจฐเฉ€ เจฎเฉฐเจจเจฟเจ† เจ—เจฟเจ† เจธเฉ€, เจ…เจคเฉ‡ เจ…เจธเฉ€เจ‚ เจ†เจฐเจ•เจพเจˆเจต เจคเฉ‹เจ‚ เจธเจพเจฐเฉ€เจ†เจ‚ CSV เจซเจพเจˆเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจฎเจฟเจฒเจพเจ‰เจฃ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เฉ€เจคเจพ เจนเฉˆ train_simplified.zip เจนเจฐเฉ‡เจ• เจฌเฉˆเจš เจฒเจˆ "เจ‰เฉฑเจกเจฃ 'เจคเฉ‡" เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ‡ เจ†เจ•เจพเจฐ เจฆเฉ€เจ†เจ‚ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจฆเฉ€ เจ…เจ—เจฒเฉ€ เจชเฉ€เฉœเฉเจนเฉ€ เจฆเฉ‡ เจจเจพเจฒ เจกเจพเจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจšเฅค

เจ‡เฉฑเจ• เจšเฉฐเจ—เฉ€ เจคเจฐเฉเจนเจพเจ‚ เจธเจพเจฌเจค เจชเฉเจฐเจฃเจพเจฒเฉ€ เจจเฉ‚เฉฐ DBMS เจตเจœเฉ‹เจ‚ เจšเฉเจฃเจฟเจ† เจ—เจฟเจ† เจธเฉ€ เจฎเฉ‹เจจเฉ‡เจŸเจกเฉ€เจฌเฉ€, เจ…เจฐเจฅเจพเจค เจ‡เฉฑเจ• เจชเฉˆเจ•เฉ‡เจœ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš R เจฒเจˆ เจ‡เฉฑเจ• เจฒเจพเจ—เฉ‚เจ•เจฐเจจ MonetDBLite. เจชเฉˆเจ•เฉ‡เจœ เจตเจฟเฉฑเจš เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจธเจฐเจตเจฐ เจฆเจพ เจ‡เฉฑเจ• เจเจฎเจฌเฉˆเจกเจก เจธเฉฐเจธเจ•เจฐเจฃ เจธเจผเจพเจฎเจฒ เจนเฉเฉฐเจฆเจพ เจนเฉˆ เจ…เจคเฉ‡ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจ†เจฐ เจธเฉˆเจธเจผเจจ เจคเฉ‹เจ‚ เจธเจฐเจตเจฐ เจจเฉ‚เฉฐ เจธเจฟเฉฑเจงเจพ เจšเฉเฉฑเจ•เจฃ เจ…เจคเฉ‡ เจ‰เฉฑเจฅเฉ‡ เจ‡เจธเจฆเฉ‡ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฆเฉ€ เจ†เจ—เจฟเจ† เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค เจ‡เฉฑเจ• เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจฌเจฃเจพเจ‰เจฃเจพ เจ…เจคเฉ‡ เจ‡เจธ เจจเจพเจฒ เจœเฉเฉœเจจเจพ เจ‡เฉฑเจ• เจ•เจฎเจพเจ‚เจก เจจเจพเจฒ เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ:

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 เจซเจพเจˆเจฒเจพเจ‚ เจฆเฉ€ เจธเจฟเฉฑเจงเฉ€ เจจเจ•เจฒ เจ•เจฐเจจเจพ เจธเฉ€ COPY OFFSET 2 INTO tablename FROM path USING DELIMITERS ',','n','"' NULL AS '' BEST EFFORTเจ•เจฟเฉฑเจฅเฉ‡ tablename - เจŸเฉ‡เจฌเจฒ เจฆเจพ เจจเจพเจฎ เจ…เจคเฉ‡ path - เจซเจพเจˆเจฒ เจฆเจพ เจฎเจพเจฐเจ—เฅค เจ†เจฐเจ•เจพเจˆเจต เจฆเฉ‡ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจฆเฉ‡ เจธเจฎเฉ‡เจ‚, เจ‡เจน เจชเจคเจพ เจฒเจ—เจพเจ‡เจ† เจ—เจฟเจ† เจ•เจฟ เจฌเจฟเจฒเจŸ-เจ‡เจจ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ unzip เจ†เจฐ เจตเจฟเฉฑเจš เจ†เจฐเจ•เจพเจˆเจต เจฆเฉ€เจ†เจ‚ เจ•เจˆ เจซเจพเจˆเจฒเจพเจ‚ เจจเจพเจฒ เจธเจนเฉ€ เจขเฉฐเจ— เจจเจพเจฒ เจ•เฉฐเจฎ เจจเจนเฉ€เจ‚ เจ•เจฐเจฆเจพ, เจ‡เจธเจฒเจˆ เจ…เจธเฉ€เจ‚ เจธเจฟเจธเจŸเจฎ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ 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 เจคเฉ‹เจ‚ เจตเฉฑเจง RAM เจฆเฉ€ เจ–เจชเจค เจจเจนเฉ€เจ‚ เจ•เจฐเจฆเฉ€ เจนเฉˆเฅค เจญเจพเจต, เจตเจฐเจฃเจฟเจค เจชเจนเฉเฉฐเจš เจคเฉเจนเจพเจจเฉ‚เฉฐ เจฒเจ—เจญเจ— เจ•เจฟเจธเฉ‡ เจตเฉ€ เจฌเจœเจŸ เจนเจพเจฐเจกเจตเฉ‡เจ…เจฐ 'เจคเฉ‡ เจฆเจธเจพเจ‚ เจ—เฉ€เจ—เจพเจฌเจพเจˆเจŸ เจตเจœเจผเจจ เจตเจพเจฒเฉ‡ เจกเฉ‡เจŸเจพเจธเฉˆเจŸเจพเจ‚ เจจเฉ‚เฉฐ เจฎเฉ‚เจต เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเฉ€ เจนเฉˆ, เจœเจฟเจธ เจตเจฟเฉฑเจš เจ•เฉเจ เจธเจฟเฉฐเจ—เจฒ-เจฌเฉ‹เจฐเจก เจกเจฟเจตเจพเจˆเจธเจพเจ‚ เจตเฉ€ เจธเจผเจพเจฎเจฒ เจนเจจ, เจœเฉ‹ เจ•เจฟ เจฌเจนเฉเจค เจตเจงเฉ€เจ† เจนเฉˆเฅค

เจœเฉ‹ เจ•เฉเจ เจฌเจšเจฟเจ† เจนเฉˆ เจ‰เจน เจนเฉˆ (เจฌเฉ‡เจคเจฐเจคเฉ€เจฌ) เจกเฉ‡เจŸเจพ เจจเฉ‚เฉฐ เจฎเฉเฉœ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฆเฉ€ เจ—เจคเฉ€ เจจเฉ‚เฉฐ เจฎเจพเจชเจฃเจพ เจ…เจคเฉ‡ เจตเฉฑเจ–-เจตเฉฑเจ– เจ†เจ•เจพเจฐเจพเจ‚ เจฆเฉ‡ เจฌเฉˆเจšเจพเจ‚ เจฆเจพ เจจเจฎเฉ‚เจจเจพ เจฒเฉˆเจ‚เจฆเฉ‡ เจธเจฎเฉ‡เจ‚ เจธเจ•เฉ‡เจฒเจฟเฉฐเจ— เจฆเจพ เจฎเฉเจฒเจพเจ‚เจ•เจฃ เจ•เจฐเจจเจพ:

เจกเจพเจŸเจพเจฌเฉ‡เจธ เจฌเฉˆเจ‚เจšเจฎเจพเจฐเจ•

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)

เจคเจคเจ•เจพเจฒ เจกเจฐเจพเจ… เจกเฉ‚เจกเจฒ เจชเจ›เจพเจฃ: R, C++ เจ…เจคเฉ‡ เจจเจฟเจŠเจฐเจฒ เจจเฉˆเฉฑเจŸเจตเจฐเจ•เจพเจ‚ เจจเจพเจฒ เจฆเฉ‹เจธเจคเฉ€ เจ•เจฟเจตเฉ‡เจ‚ เจ•เจฐเฉ€เจ

2. เจฌเฉˆเจšเจพเจ‚ เจฆเฉ€ เจคเจฟเจ†เจฐเฉ€

เจชเฉ‚เจฐเฉ‡ เจฌเฉˆเจš เจฆเฉ€ เจคเจฟเจ†เจฐเฉ€ เจฆเฉ€ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจตเจฟเฉฑเจš เจนเฉ‡เจ  เจฒเจฟเจ–เฉ‡ เจ•เจฆเจฎ เจนเจจ:

  1. เจฌเจฟเฉฐเจฆเฉ‚เจ†เจ‚ เจฆเฉ‡ เจ•เฉ‹เจ†เจฐเจกเฉ€เจจเฉ‡เจŸเจธ เจจเจพเจฒ เจธเจคเจฐ เจฆเฉ‡ เจตเฉˆเจ•เจŸเจฐ เจตเจพเจฒเฉ‡ เจ•เจˆ JSON เจจเฉ‚เฉฐ เจชเจพเจฐเจธ เจ•เจฐเจจเจพเฅค
  2. เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ‡ เจ†เจ•เจพเจฐ เจฆเฉ‡ เจšเจฟเฉฑเจคเจฐ (เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, 256ร—256 เจœเจพเจ‚ 128ร—128) 'เจคเฉ‡ เจฌเจฟเฉฐเจฆเฉ‚เจ†เจ‚ เจฆเฉ‡ เจงเฉเจฐเฉ‡ เจฆเฉ‡ เจ†เจงเจพเจฐ 'เจคเฉ‡ เจฐเฉฐเจ—เจฆเจพเจฐ เจฒเจพเจˆเจจเจพเจ‚ เจฌเจฃเจพเจ‰เจฃเจพเฅค
  3. เจจเจคเฉ€เจœเฉ‡ เจตเจพเจฒเฉ€เจ†เจ‚ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจจเฉ‚เฉฐ เจŸเฉˆเจ‚เจธเจฐ เจตเจฟเฉฑเจš เจฌเจฆเจฒเจฃเจพเฅค

เจชเจพเจˆเจฅเจจ เจ•เจฐเจจเจฒ เจตเจฟเจšเจ•เจพเจฐ เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจฆเฉ‡ เจนเจฟเฉฑเจธเฉ‡ เจตเจœเฉ‹เจ‚, เจธเจฎเฉฑเจธเจฟเจ† เจจเฉ‚เฉฐ เจฎเฉเฉฑเจ– เจคเฉŒเจฐ 'เจคเฉ‡ เจตเจฐเจค เจ•เฉ‡ เจนเฉฑเจฒ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€ เจ“เจชเจจเจธเฉ€เจตเฉ€. R เจตเจฟเฉฑเจš เจธเจญ เจคเฉ‹เจ‚ เจธเจฐเจฒ เจ…เจคเฉ‡ เจธเจญ เจคเฉ‹เจ‚ เจธเจชเฉฑเจธเจผเจŸ เจเจจเจพเจฒเจพเจ—เจธ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจ‡เฉฑเจ• เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ เจฆเจฟเจ–เจพเจˆ เจฆเฉ‡เจตเฉ‡เจ—เจพ:

R เจตเจฟเฉฑเจš JSON เจคเฉ‹เจ‚ เจŸเฉˆเจ‚เจธเจฐ เจชเจฐเจฟเจตเจฐเจคเจจ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ

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 เจŸเฉ‚เจฒเจธ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ เจ…เจคเฉ‡ RAM เจตเจฟเฉฑเจš เจธเจŸเฉ‹เจฐ เจ•เฉ€เจคเฉ€ เจ‡เฉฑเจ• เจ…เจธเจฅเจพเจˆ PNG เจตเจฟเฉฑเจš เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ (เจฒเฉ€เจจเจ•เจธ เจ‰เฉฑเจคเฉ‡, เจ†เจฐเจœเจผเฉ€ เจ†เจฐ เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€เจ†เจ‚ เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€ เจตเจฟเฉฑเจš เจธเจฅเจฟเจค เจนเฉเฉฐเจฆเฉ€เจ†เจ‚ เจนเจจเฅค /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))

เจคเจคเจ•เจพเจฒ เจกเจฐเจพเจ… เจกเฉ‚เจกเจฒ เจชเจ›เจพเจฃ: 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

เจ‡เจน เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ เจธเจพเจกเฉ‡ เจฒเจˆ เจธเจญ เจคเฉ‹เจ‚ เจ…เจจเฉเจ•เฉ‚เจฒ เจœเจพเจชเจฆเจพ เจนเฉˆ, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจตเฉฑเจกเฉ‡ เจฌเฉˆเจšเจพเจ‚ เจฆเฉ‡ เจ—เจ เจจ เจตเจฟเฉฑเจš เจฌเจนเฉเจค เจœเจผเจฟเจ†เจฆเจพ เจธเจฎเจพเจ‚ เจฒเฉฑเจ—เจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจธเจผเจ•เจคเฉ€เจธเจผเจพเจฒเฉ€ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ†เจชเจฃเฉ‡ เจธเจนเจฟเจฏเฉ‹เจ—เฉ€เจ†เจ‚ เจฆเฉ‡ เจคเจœเจผเจฐเจฌเฉ‡ เจฆเจพ เจฒเจพเจญ เจฒเฉˆเจฃ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เฉ€เจคเจพ เจนเฉˆเฅค เจ“เจชเจจเจธเฉ€เจตเฉ€. เจ‰เจธ เจธเจฎเฉ‡เจ‚ R เจฒเจˆ เจ•เฉ‹เจˆ เจคเจฟเจ†เจฐ เจชเฉˆเจ•เฉ‡เจœ เจจเจนเฉ€เจ‚ เจธเฉ€ (เจนเฉเจฃ เจ•เฉ‹เจˆ เจจเจนเฉ€เจ‚ เจนเฉˆ), เจ‡เจธเจฒเจˆ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ€ เจ•เจพเจฐเจœเจธเจผเฉ€เจฒเจคเจพ เจฆเจพ เจ‡เฉฑเจ• เจ˜เฉฑเจŸเฉ‹-เจ˜เฉฑเจŸ เจฒเจพเจ—เฉ‚เจ•เจฐเจจ C++ เจตเจฟเฉฑเจš R เจ•เฉ‹เจก เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจเจ•เฉ€เจ•เจฐเจฃ เจฆเฉ‡ เจจเจพเจฒ เจฒเจฟเจ–เจฟเจ† เจ—เจฟเจ† เจธเฉ€เฅค เจ†เจฐ.เจธเฉ€.เจชเฉ€.เจชเฉ€.

เจธเจฎเฉฑเจธเจฟเจ† เจจเฉ‚เฉฐ เจนเฉฑเจฒ เจ•เจฐเจจ เจฒเจˆ, เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ‡ เจชเฉˆเจ•เฉ‡เจœ เจ…เจคเฉ‡ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€เจ†เจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจธเฉ€:

  1. เจ“เจชเจจเจธเฉ€เจตเฉ€ เจšเจฟเฉฑเจคเจฐเจพเจ‚ เจ…เจคเฉ‡ เจกเจฐเจพเจ‡เฉฐเจ— เจฒเจพเจˆเจจเจพเจ‚ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฒเจˆเฅค เจชเฉ‚เจฐเจต-เจธเจฅเจพเจชเจค เจธเจฟเจธเจŸเจฎ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€เจ†เจ‚ เจ…เจคเฉ‡ เจธเจฟเจฐเจฒเฉ‡เจ– เจซเจพเจˆเจฒเจพเจ‚, เจจเจพเจฒ เจนเฉ€ เจกเจพเจ‡เจจเจพเจฎเจฟเจ• เจฒเจฟเฉฐเจ•เจฟเฉฐเจ— เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจ—เจˆเฅค

  2. xtensor เจฌเจนเฉ-เจ†เจฏเจพเจฎเฉ€ เจเจฐเฉ‡ เจ…เจคเฉ‡ เจŸเฉˆเจ‚เจธเจฐเจพเจ‚ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฒเจˆเฅค เจ…เจธเฉ€เจ‚ เจ‰เจธเฉ‡ เจจเจพเจฎ เจฆเฉ‡ R เจชเฉˆเจ•เฉ‡เจœ เจตเจฟเฉฑเจš เจธเจผเจพเจฎเจฒ เจนเฉˆเจกเจฐ เจซเจพเจˆเจฒเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจนเฉˆเฅค เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจฌเจนเฉ-เจ†เจฏเจพเจฎเฉ€ เจเจฐเฉ‡ เจฆเฉ‡ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเฉ€ เจนเฉˆ, เจฆเฉ‹เจตเฉ‡เจ‚ เจ•เจคเจพเจฐ เจฎเฉ‡เจœเจฐ เจ…เจคเฉ‡ เจ•เจพเจฒเจฎ เจฎเฉเฉฑเจ– เจ•เฉเจฐเจฎ เจตเจฟเฉฑเจšเฅค

  3. ndjson JSON เจจเฉ‚เฉฐ เจชเจพเจฐเจธ เจ•เจฐเจจ เจฒเจˆเฅค เจตเจฟเฉฑเจš เจ‡เจธ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ xtensor เจ†เจŸเฉ‹เจฎเฉˆเจŸเจฟเจ•เจฒเฉ€ เจœเฉ‡ เจ‡เจน เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ เจตเจฟเฉฑเจš เจฎเฉŒเจœเฉ‚เจฆ เจนเฉˆเฅค

  4. RcppThread JSON เจคเฉ‹เจ‚ เจตเฉˆเจ•เจŸเจฐ เจฆเฉ€ เจฎเจฒเจŸเฉ€-เจฅเฉเจฐเฉˆเจกเจก เจชเฉเจฐเฉ‹เจธเฉˆเจธเจฟเฉฐเจ— เจจเฉ‚เฉฐ เจธเฉฐเจ—เจ เจฟเจค เจ•เจฐเจจ เจฒเจˆเฅค เจ‡เจธ เจชเฉˆเจ•เฉ‡เจœ เจฆเฉเจ†เจฐเจพ เจชเฉเจฐเจฆเจพเจจ เจ•เฉ€เจคเฉ€เจ†เจ‚ เจธเจฟเจฐเจฒเฉ‡เจ– เจซเจพเจˆเจฒเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจนเฉˆเฅค เจนเฉ‹เจฐ เจชเฉเจฐเจธเจฟเฉฑเจง เจคเฉฑเจ• เจ†เจฐเจธเฉ€เจชเฉ€เจชเฉ€เจชเฉˆเจฐเจฒเจฒ เจชเฉˆเจ•เฉ‡เจœ, เจนเฉ‹เจฐ เจšเฉ€เจœเจผเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ, เจ‡เฉฑเจ• เจฌเจฟเจฒเจŸ-เจ‡เจจ เจฒเฉ‚เจช เจ‡เฉฐเจŸเจฐเฉฑเจชเจŸ เจตเจฟเจงเฉ€ เจนเฉˆเฅค

เจ‡เจน เจ‡เจธ เจตเฉฑเจฒ เจงเจฟเจ†เจจ เจฆเฉ‡เจฃ เจฏเฉ‹เจ— เจนเฉˆ 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

เจ‰เจนเจจเจพเจ‚ เจซเจพเจˆเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ•เฉฐเจชเจพเจ‡เจฒ เจ•เจฐเจจ เจฒเจˆ เจœเฉ‹ เจธเจฟเจธเจŸเจฎ เจซเจพเจˆเจฒเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจจ เจ…เจคเฉ‡ เจธเจฟเจธเจŸเจฎ เจคเฉ‡ เจธเจฅเจพเจชเจฟเจค เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€เจ†เจ‚ เจจเจพเจฒ เจ—เจคเฉ€เจธเจผเฉ€เจฒ เจฒเจฟเฉฐเจ•เจฟเฉฐเจ— เจ•เจฐเจฆเฉ‡ เจนเจจ, เจ…เจธเฉ€เจ‚ เจชเฉˆเจ•เฉ‡เจœ เจตเจฟเฉฑเจš เจฒเจพเจ—เฉ‚ เจชเจฒเฉฑเจ—เจ‡เจจ เจตเจฟเจงเฉ€ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจนเฉˆ เจ†เจฐ.เจธเฉ€.เจชเฉ€.เจชเฉ€. เจ†เจชเจฃเฉ‡ เจ†เจช เจฎเจพเจฐเจ— เจ…เจคเฉ‡ เจซเจฒเฉˆเจ— เจฒเฉฑเจญเจฃ เจฒเจˆ, เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจชเฉเจฐเจธเจฟเฉฑเจง Linux เจ‰เจชเจฏเฉ‹เจ—เจคเจพ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจนเฉˆ pkg-config.

OpenCV เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฒเจˆ Rcpp เจชเจฒเฉฑเจ—เจ‡เจจ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ

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"))))

C++ เจตเจฟเฉฑเจš เจŸเฉˆเจ‚เจธเจฐ เจชเจฐเจฟเจตเจฐเจคเจจ เจฒเจˆ JSON เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ

// [[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 เจคเฉฑเจ• REPOZITORIA. เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจ•เจˆ เจซเฉฐเจ•เจธเจผเจจเจพเจ‚ เจตเจฟเฉฑเจš เจตเฉฐเจกเจฟเจ† เจ—เจฟเจ† เจนเฉˆ:

  • 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))

เจคเจคเจ•เจพเจฒ เจกเจฐเจพเจ… เจกเฉ‚เจกเจฒ เจชเจ›เจพเจฃ: 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") 

เจคเจคเจ•เจพเจฒ เจกเจฐเจพเจ… เจกเฉ‚เจกเจฒ เจชเจ›เจพเจฃ: R, C++ เจ…เจคเฉ‡ เจจเจฟเจŠเจฐเจฒ เจจเฉˆเฉฑเจŸเจตเจฐเจ•เจพเจ‚ เจจเจพเจฒ เจฆเฉ‹เจธเจคเฉ€ เจ•เจฟเจตเฉ‡เจ‚ เจ•เจฐเฉ€เจ

เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจคเฉเจธเฉ€เจ‚ เจตเฉ‡เจ– เจธเจ•เจฆเฉ‡ เจนเฉ‹, เจ—เจคเฉ€ เจตเจฟเฉฑเจš เจตเจพเจงเจพ เจฌเจนเฉเจค เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจธเจพเจฌเจค เจนเฉ‹เจ‡เจ† เจนเฉˆ, เจ…เจคเฉ‡ R เจ•เฉ‹เจก เจฆเฉ‡ เจธเจฎเจพเจจเจพเจ‚เจคเจฐ เจ•เจฐเจ•เฉ‡ C++ เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจซเฉœเจจเจพ เจธเฉฐเจญเจต เจจเจนเฉ€เจ‚ เจนเฉˆเฅค

3. เจกเจพเจŸเจพเจฌเฉ‡เจธ เจคเฉ‹เจ‚ เจฌเฉˆเจšเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเจฒเฉ‹เจก เจ•เจฐเจจ เจฒเจˆ เจ‡เจŸเจฐเฉ‡เจŸเจฐ

R เจ•เฉ‹เจฒ RAM เจตเจฟเฉฑเจš เจซเจฟเฉฑเจŸ เจนเฉ‹เจฃ เจตเจพเจฒเฉ‡ เจกเฉ‡เจŸเจพ เจจเฉ‚เฉฐ เจชเฉเจฐเฉ‹เจธเฉˆเจธ เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจšเฉฐเจ—เฉ€-เจฒเจพเจ‡เจ• เจชเฉเจฐเจคเจฟเจธเจผเจ เจพ เจนเฉˆ, เจœเจฆเฉ‹เจ‚ เจ•เจฟ เจชเจพเจˆเจฅเจจ เจจเฉ‚เฉฐ เจฆเฉเจนเจฐเจพเจ‰เจฃ เจตเจพเจฒเฉ‡ เจกเฉ‡เจŸเจพ เจชเฉเจฐเฉ‹เจธเฉˆเจธเจฟเฉฐเจ— เจฆเฉเจ†เจฐเจพ เจตเจงเฉ‡เจฐเฉ‡ เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพ เจฆเจฟเฉฑเจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ, เจœเจฟเจธ เจจเจพเจฒ เจคเฉเจธเฉ€เจ‚ เจ†เจธเจพเจจเฉ€ เจจเจพเจฒ เจ…เจคเฉ‡ เจ•เฉเจฆเจฐเจคเฉ€ เจคเฉŒเจฐ 'เจคเฉ‡ เจ†เจŠเจŸ-เจ†เจซ-เจ•เฉ‹เจฐ เจ—เจฃเจจเจพเจตเจพเจ‚ (เจฌเจพเจนเจฐเฉ€ เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจ—เจฃเจจเจพ) เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค เจตเจฐเจฃเจฟเจค เจธเจฎเฉฑเจธเจฟเจ† เจฆเฉ‡ เจธเฉฐเจฆเจฐเจญ เจตเจฟเฉฑเจš เจธเจพเจกเฉ‡ เจฒเจˆ เจ‡เฉฑเจ• เจŸเจ•เจธเจพเจฒเฉ€ เจ…เจคเฉ‡ เจขเฉเจ•เจตเฉ€เจ‚ เจ‰เจฆเจพเจนเจฐเจจ เจนเฉˆ เจกเฉ‚เฉฐเจ˜เฉ‡ เจจเจฟเจŠเจฐเจฒ เจจเฉˆเฉฑเจŸเจตเจฐเจ• เจนเจจ เจœเฉ‹ เจ—เจฐเฉ‡เจกเฉ€เจเจ‚เจŸ เจกเจฟเจธเฉˆเจ‚เจŸ เจตเจฟเจงเฉ€ เจฆเฉเจ†เจฐเจพ เจธเจฟเจ–เจฒเจพเจˆ เจชเฉเจฐเจพเจชเจค เจ•เฉ€เจคเฉ‡ เจ—เจ เจนเจจ, เจœเฉ‹ เจ•เจฟ เจจเจฟเจฐเฉ€เจ–เจฃเจพเจ‚ เจฆเฉ‡ เจ‡เฉฑเจ• เจ›เฉ‹เจŸเฉ‡ เจœเจฟเจนเฉ‡ เจนเจฟเฉฑเจธเฉ‡, เจœเจพเจ‚ เจฎเจฟเฉฐเจจเฉ€-เจฌเฉˆเจš เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจนเจฐเฉ‡เจ• เจชเฉœเจพเจ… 'เจคเฉ‡ เจ—เจฐเฉ‡เจกเฉ€เจเจ‚เจŸ เจฆเฉ‡ เจ…เจจเฉเจฎเจพเจจ เจฆเฉ‡ เจจเจพเจฒ เจนเจจเฅค

เจชเจพเจˆเจฅเจจ เจตเจฟเฉฑเจš เจฒเจฟเจ–เฉ‡ เจกเฉ‚เฉฐเจ˜เฉ‡ เจธเจฟเฉฑเจ–เจฃ เจฆเฉ‡ เจซเจฐเฉ‡เจฎเจตเจฐเจ• เจตเจฟเฉฑเจš เจตเจฟเจธเจผเฉ‡เจธเจผ เจ•เจฒเจพเจธเจพเจ‚ เจนเฉเฉฐเจฆเฉ€เจ†เจ‚ เจนเจจ เจœเฉ‹ เจกเฉ‡เจŸเจพ เจฆเฉ‡ เจ…เจงเจพเจฐ 'เจคเฉ‡ เจฆเฉเจนเจฐเจพเจ“ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจฆเฉ€เจ†เจ‚ เจนเจจ: เจŸเฉ‡เจฌเจฒ, เจซเฉ‹เจฒเจกเจฐเจพเจ‚ เจตเจฟเฉฑเจš เจคเจธเจตเฉ€เจฐเจพเจ‚, เจฌเจพเจˆเจจเจฐเฉ€ เจซเจพเจฐเจฎเฉˆเจŸ, เจ†เจฆเจฟเฅค เจคเฉเจธเฉ€เจ‚ เจคเจฟเจ†เจฐ เจตเจฟเจ•เจฒเจชเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹ เจœเจพเจ‚ เจ–เจพเจธ เจ•เฉฐเจฎเจพเจ‚ เจฒเจˆ เจ†เจชเจฃเฉ‡ เจ–เฉเจฆ เจฆเฉ‡ เจฒเจฟเจ– เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค เจ†เจฐ เจตเจฟเฉฑเจš เจ…เจธเฉ€เจ‚ เจชเจพเจˆเจฅเจจ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€ เจฆเฉ€เจ†เจ‚ เจธเจพเจฐเฉ€เจ†เจ‚ เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพเจตเจพเจ‚ เจฆเจพ เจฒเจพเจญ เจฒเฉˆ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚ เจ•เฉ‡เจฐเจธ เจ‡เจธเจฆเฉ‡ เจตเฉฑเจ–-เจตเฉฑเจ– เจฌเฉˆเจ•เจเจ‚เจกเจพเจ‚ เจจเจพเจฒ เจ‡เฉฑเจ•เฉ‹ เจจเจพเจฎ เจฆเฉ‡ เจชเฉˆเจ•เฉ‡เจœ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ, เจœเฉ‹ เจฌเจฆเจฒเฉ‡ เจตเจฟเฉฑเจš เจชเฉˆเจ•เฉ‡เจœ เจฆเฉ‡ เจธเจฟเจ–เจฐ 'เจคเฉ‡ เจ•เฉฐเจฎ เจ•เจฐเจฆเจพ เจนเฉˆ เจœเจพเจฒเฉ€เจฆเจพเจฐ. เจฌเจพเจ…เจฆ เจตเจพเจฒเจพ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเฉ‡ เจฒเฉฐเจฌเฉ‡ เจฒเฉ‡เจ– เจฆเจพ เจนเฉฑเจ•เจฆเจพเจฐ เจนเฉˆ; เจ‡เจน เจคเฉเจนเจพเจจเฉ‚เฉฐ เจจเจพ เจธเจฟเจฐเจซเจผ R เจคเฉ‹เจ‚ Python เจ•เฉ‹เจก เจšเจฒเจพเจ‰เจฃ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ, เจธเจ—เฉ‹เจ‚ เจคเฉเจนเจพเจจเฉ‚เฉฐ R เจ…เจคเฉ‡ Python เจธเฉˆเจธเจผเจจเจพเจ‚ เจตเจฟเจšเจ•เจพเจฐ เจ†เจฌเจœเฉˆเจ•เจŸ เจŸเฉเจฐเจพเจ‚เจธเจซเจฐ เจ•เจฐเจจ เจฆเฉ€ เจตเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ, เจ†เจŸเฉ‹เจฎเฉˆเจŸเจฟเจ• เจนเฉ€ เจธเจพเจฐเฉ‡ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ‡ เจชเฉเจฐเจ•เจพเจฐ เจฆเฉ‡ เจชเจฐเจฟเจตเจฐเจคเจจ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจเฅค

เจ…เจธเฉ€เจ‚ MonetDBLite เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจธเจพเจฐเฉ‡ เจกเฉ‡เจŸเจพ เจจเฉ‚เฉฐ RAM เจตเจฟเฉฑเจš เจธเจŸเฉ‹เจฐ เจ•เจฐเจจ เจฆเฉ€ เจœเจผเจฐเฉ‚เจฐเจค เจคเฉ‹เจ‚ เจ›เฉเจŸเจ•เจพเจฐเจพ เจชเจพ เจฒเจฟเจ† เจนเฉˆ, เจธเจพเจฐเฉ‡ "เจจเจฟเจŠเจฐเจฒ เจจเฉˆเจŸเจตเจฐเจ•" เจ•เฉฐเจฎ เจชเจพเจˆเจฅเจจ เจตเจฟเฉฑเจš เจ…เจธเจฒ เจ•เฉ‹เจก เจฆเฉเจ†เจฐเจพ เจ•เฉ€เจคเฉ‡ เจœเจพเจฃเจ—เฉ‡, เจธเจพเจจเฉ‚เฉฐ เจกเฉ‡เจŸเจพ เจ‰เฉฑเจคเฉ‡ เจ‡เฉฑเจ• เจ‡เจŸเจฐเฉ‡เจŸเจฐ เจฒเจฟเจ–เจฃเจพ เจชเจตเฉ‡เจ—เจพ, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‡เฉฑเจฅเฉ‡ เจ•เฉเจ เจตเฉ€ เจคเจฟเจ†เจฐ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค R เจœเจพเจ‚ Python เจตเจฟเฉฑเจš เจ…เจœเจฟเจนเฉ€ เจธเจฅเจฟเจคเฉ€ เจฒเจˆเฅค เจ‡เจธเจฆเฉ‡ เจฒเจˆ เจฒเจพเจœเจผเจฎเฉ€ เจคเฉŒเจฐ 'เจคเฉ‡ เจธเจฟเจฐเจซ เจฆเฉ‹ เจฒเฉ‹เฉœเจพเจ‚ เจนเจจ: เจ‡เจธเจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจฌเฉ‡เจ…เฉฐเจค เจฒเฉ‚เจช เจตเจฟเฉฑเจš เจฌเฉˆเจšเจพเจ‚ เจจเฉ‚เฉฐ เจตเจพเจชเจธ เจ•เจฐเจจเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ เจ…เจคเฉ‡ เจ‡เจธเจฆเฉ€ เจธเจฅเจฟเจคเฉ€ เจจเฉ‚เฉฐ เจฆเฉเจนเจฐเจพเจ“ เจฆเฉ‡ เจตเจฟเจšเจ•เจพเจฐ เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เจฐเจจเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ (เจ†เจฐ เจตเจฟเฉฑเจš เจฌเจพเจ…เจฆ เจตเจพเจฒเฉ‡ เจจเฉ‚เฉฐ เจฌเฉฐเจฆ เจ•เจฐเจจ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจธเจญ เจคเฉ‹เจ‚ เจธเจฐเจฒ เจคเจฐเฉ€เจ•เฉ‡ เจจเจพเจฒ เจฒเจพเจ—เฉ‚ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆ)เฅค เจชเจนเจฟเจฒเจพเจ‚, เจ‡เจธ เจจเฉ‚เฉฐ เจธเจชเจธเจผเจŸ เจคเฉŒเจฐ 'เจคเฉ‡ เจ†เจฐ เจเจฐเฉ‡ เจจเฉ‚เฉฐ เจ‡เจŸเจฐเฉ‡เจŸเจฐ เจฆเฉ‡ เจ…เฉฐเจฆเจฐ เจจเฉฐเจชเฉ€ เจเจฐเฉ‡ เจตเจฟเฉฑเจš เจฌเจฆเจฒเจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจธเฉ€, เจชเจฐ เจชเฉˆเจ•เฉ‡เจœ เจฆเจพ เจฎเฉŒเจœเฉ‚เจฆเจพ เจธเฉฐเจธเจ•เจฐเจฃ เจ•เฉ‡เจฐเจธ เจ‡เจน เจ†เจชเจฃเฉ‡ เจ†เจช เจ•เจฐเจฆเจพ เจนเฉˆเฅค

เจธเจฟเจ–เจฒเจพเจˆ เจ…เจคเฉ‡ เจชเฉเจฐเจฎเจพเจฃเจฟเจ•เจคเจพ เจกเฉ‡เจŸเจพ เจฒเจˆ เจฆเฉเจนเจฐเจพเจ“ เจนเฉ‡เจ  เจฒเจฟเจ–เฉ‡ เจ…เจจเฉเจธเจพเจฐ เจจเจฟเจ•เจฒเจฟเจ†:

เจธเจฟเจ–เจฒเจพเจˆ เจ…เจคเฉ‡ เจชเฉเจฐเจฎเจพเจฃเจฟเจ•เจคเจพ เจกเฉ‡เจŸเจพ เจฒเจˆ เจ‡เจŸเจฐเฉ‡เจŸเจฐ

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 เจนเจฐเฉ‡เจ• เจธเจŸเฉเจฐเฉ‹เจ• เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจจเจตเฉ‡เจ‚ เจฐเฉฐเจ— เจตเจฟเฉฑเจš เจ–เจฟเฉฑเจšเจฟเจ† เจ—เจฟเจ† เจนเฉˆ) เจ…เจคเฉ‡ เจ‡เจฎเฉ‡เจœเจจเฉˆเฉฑเจŸ 'เจคเฉ‡ เจชเจนเจฟเจฒเจพเจ‚ เจคเฉ‹เจ‚ เจธเจฟเจ–เจฒเจพเจˆ เจชเฉเจฐเจพเจชเจค เจจเฉˆเจŸเจตเจฐเจ•เจพเจ‚ เจฒเจˆ เจ‡เฉฑเจ• เจชเฉเจฐเฉ€-เจชเฉเจฐเฉ‹เจธเฉˆเจธเจฟเฉฐเจ— เจธเฉ‚เจšเจ•เฅค เจ…เฉฐเจคเจฐเจพเจฒ [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 เจ…เจคเฉ‡ เจฒเจฟเฉฐเจ• เจฆเฉเจ†เจฐเจพ เจธเฉ‹เจง - เจ‡เจนเจจเจพเจ‚ เจชเฉˆเจ•เฉ‡เจœ "เจšเจฟเฉฑเจชเจพเจ‚" เจคเฉ‹เจ‚ เจฌเจฟเจจเจพเจ‚ เจกเฉ‡เจŸเจพ.เจŸเฉˆเจฌเจฒ R เจตเจฟเฉฑเจš เจ•เจฟเจธเฉ‡ เจตเฉ€ เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจฎเจพเจคเจฐเจพ เจตเจฟเฉฑเจš เจกเฉ‡เจŸเจพ เจฆเฉ‡ เจจเจพเจฒ เจชเฉเจฐเจญเจพเจตเจธเจผเจพเจฒเฉ€ เจขเฉฐเจ— เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฆเฉ€ เจ•เจฒเจชเจจเจพ เจ•เจฐเจจเจพ เจฌเจนเฉเจค เจฎเฉเจธเจผเจ•เจฒ เจนเฉˆเฅค

เจ•เฉ‹เจฐ 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)

เจคเจคเจ•เจพเจฒ เจกเจฐเจพเจ… เจกเฉ‚เจกเจฒ เจชเจ›เจพเจฃ: R, C++ เจ…เจคเฉ‡ เจจเจฟเจŠเจฐเจฒ เจจเฉˆเฉฑเจŸเจตเจฐเจ•เจพเจ‚ เจจเจพเจฒ เจฆเฉ‹เจธเจคเฉ€ เจ•เจฟเจตเฉ‡เจ‚ เจ•เจฐเฉ€เจ

เจœเฉ‡ เจคเฉเจนเจพเจกเฉ‡ เจ•เฉ‹เจฒ เจ•เจพเจซเจผเฉ€ เจฎเจพเจคเจฐเจพ เจตเจฟเฉฑเจš RAM เจนเฉˆ, เจคเจพเจ‚ เจคเฉเจธเฉ€เจ‚ เจ‡เจธ เจจเฉ‚เฉฐ เจ‰เจธเฉ‡ เจฐเฉˆเจฎ เจตเจฟเฉฑเจš เจŸเฉเจฐเจพเจ‚เจธเจซเจฐ เจ•เจฐเจ•เฉ‡ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจฆเฉ‡ เจธเฉฐเจšเจพเจฒเจจ เจจเฉ‚เฉฐ เจ—เฉฐเจญเฉ€เจฐเจคเจพ เจจเจพเจฒ เจคเฉ‡เจœเจผ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹ (เจธเจพเจกเฉ‡ เจ•เฉฐเจฎ เจฒเจˆ 32 GB เจ•เจพเจซเจผเฉ€ เจนเฉˆ)เฅค เจฒเฉ€เจจเจ•เจธ เจตเจฟเฉฑเจš, เจญเจพเจ— เจฎเฉ‚เจฒ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจฎเจพเจŠเจ‚เจŸ เจนเฉเฉฐเจฆเจพ เจนเฉˆ /dev/shm, เจ…เฉฑเจงเฉ€ RAM เจธเจฎเจฐเฉฑเจฅเจพ เจคเฉฑเจ• เจฆเจพ เจ•เจฌเจœเจผเจพ เจนเฉˆเฅค เจคเฉเจธเฉ€เจ‚ เจธเฉฐเจชเจพเจฆเจจ เจ•เจฐเจ•เฉ‡ เจนเฉ‹เจฐ เจ‰เจœเจพเจ—เจฐ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹ /etc/fstabเจตเจฐเจ—เจพ เจฐเจฟเจ•เจพเจฐเจก เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ tmpfs /dev/shm tmpfs defaults,size=25g 0 0. เจฐเฉ€เจฌเฉ‚เจŸ เจ•เจฐเจจเจพ เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพเจ“ เจ…เจคเฉ‡ เจ•เจฎเจพเจ‚เจก เจšเจฒเจพ เจ•เฉ‡ เจจเจคเฉ€เจœเจพ เจšเฉˆเฉฑเจ• เจ•เจฐเฉ‹ df -h.

เจŸเฉˆเจธเจŸ เจกเฉ‡เจŸเจพ เจฒเจˆ เจ‡เจŸเจฐเฉ‡เจŸเจฐ เจฌเจนเฉเจค เจธเจฐเจฒ เจฆเจฟเจ–เจพเจˆ เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจŸเฉˆเจธเจŸ เจกเฉ‡เจŸเจพเจธเฉˆเจŸ เจชเฉ‚เจฐเฉ€ เจคเจฐเฉเจนเจพเจ‚ RAM เจตเจฟเฉฑเจš เจซเจฟเฉฑเจŸ เจนเฉเฉฐเจฆเจพ เจนเฉˆ:

เจŸเฉˆเจธเจŸ เจกเฉ‡เจŸเจพ เจฒเจˆ เจ‡เจŸเจฐเฉ‡เจŸเจฐ

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. เจฎเจพเจกเจฒ เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจฆเฉ€ เจšเฉ‹เจฃ

เจธเจญ เจคเฉ‹เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจตเจฐเจคเจฟเจ† เจ—เจฟเจ† เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจธเฉ€ เจฎเฉ‹เจฌเจพเจˆเจฒเจจเฉˆเฉฑเจŸ v1, เจœเจฟเจธ เจฆเฉ€เจ†เจ‚ เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพเจตเจพเจ‚ เจตเจฟเฉฑเจš เจšเจฐเจšเจพ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจนเฉˆ เจ‡เจน เจธเฉเจจเฉ‡เจนเจพเฅค เจ‡เจน เจฎเจฟเจ†เจฐเฉ€ เจฆเฉ‡ เจคเฉŒเจฐ 'เจคเฉ‡ เจธเจผเจพเจฎเจฟเจฒ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆ เจ•เฉ‡เจฐเจธ เจ…เจคเฉ‡, เจ‡เจธเจฆเฉ‡ เจ…เจจเฉเจธเจพเจฐ, R เจฒเจˆ เจ‰เจธเฉ‡ เจจเจพเจฎ เจฆเฉ‡ เจชเฉˆเจ•เฉ‡เจœ เจตเจฟเฉฑเจš เจ‰เจชเจฒเจฌเจง เจนเฉˆเฅค เจชเจฐ เจœเจฆเฉ‹เจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจธเจฟเฉฐเจ—เจฒ-เจšเฉˆเจจเจฒ เจšเจฟเฉฑเจคเจฐเจพเจ‚ เจจเจพเจฒ เจตเจฐเจคเจฃ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เฉ€เจคเฉ€ เจ—เจˆ, เจคเจพเจ‚ เจ‡เฉฑเจ• เจ…เจœเฉ€เจฌ เจ—เฉฑเจฒ เจธเจพเจนเจฎเจฃเฉ‡ เจ†เจˆ: เจ‡เจจเจชเฉเจŸ เจŸเฉˆเจ‚เจธเจฐ เจตเจฟเฉฑเจš เจนเจฎเฉ‡เจธเจผเจพเจ‚ เจฎเจพเจช เจนเฉ‹เจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ (batch, height, width, 3), เจญเจพเจต, เจšเฉˆเจจเจฒเจพเจ‚ เจฆเฉ€ เจ—เจฟเจฃเจคเฉ€ เจจเฉ‚เฉฐ เจฌเจฆเจฒเจฟเจ† เจจเจนเฉ€เจ‚ เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆเฅค เจชเจพเจˆเจฅเจจ เจตเจฟเฉฑเจš เจ…เจœเจฟเจนเฉ€ เจ•เฉ‹เจˆ เจธเฉ€เจฎเจพ เจจเจนเฉ€เจ‚ เจนเฉˆ, เจ‡เจธเจฒเจˆ เจ…เจธเฉ€เจ‚ เจ•เจพเจนเจฒเฉ€ เจ•เฉ€เจคเฉ€ เจ…เจคเฉ‡ เจ‡เจธ เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจฆเฉ‡ เจ†เจชเจฃเฉ‡ เจ–เฉเจฆ เจฆเฉ‡ เจฒเจพเจ—เฉ‚เจ•เจฐเจจ เจจเฉ‚เฉฐ เจฎเฉ‚เจฒ เจฒเฉ‡เจ– (เจ•เฉ‡เจฐเจธ เจธเฉฐเจธเจ•เจฐเจฃ เจตเจฟเฉฑเจš เจ›เฉฑเจกเจฃ เจคเฉ‹เจ‚ เจฌเจฟเจจเจพเจ‚) เจฆเฉ€ เจชเจพเจฒเจฃเจพ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจฒเจฟเจ–เจฟเจ†:

เจฎเฉ‹เจฌเจพเจˆเจฒเจจเฉˆเฉฑเจŸ 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)

เจนเฉเจฃ เจธเจชเจฒเจพเจˆ เจ•เฉ€เจคเฉ‡ เจ•เจฟเจธเฉ‡ เจตเฉ€ เจจเฉ‚เฉฐ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจฏเฉ‚เจจเฉ€เจตเจฐเจธเจฒ เจซเฉฐเจ•เจธเจผเจจ เจฒเจฟเจ–เจฃเจพ เจฎเฉเจธเจผเจ•เจฒ เจจเจนเฉ€เจ‚ เจนเฉˆ เจ•เฉ‡เจฐเจธ เจ‡เจฎเฉ‡เจœเจจเฉˆเฉฑเจŸ 'เจคเฉ‡ เจธเจฟเจ–เจฒเจพเจˆ เจชเฉเจฐเจพเจชเจค เจตเจœเจผเจจ เจฆเฉ‡ เจจเจพเจฒ เจœเจพเจ‚ เจฌเจฟเจจเจพเจ‚ เจฎเจพเจกเจฒ:

เจฐเฉˆเจกเฉ€เจฎเฉ‡เจก เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจฒเฉ‹เจก เจ•เจฐเจจ เจฒเจˆ เจซเฉฐเจ•เจธเจผเจจ

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(). เจ…เจธเฉ€เจ‚ เจ•เจฆเฉ‡ เจตเฉ€ เจ‡เจธ เจ•เจพเจฐเจœเจ•เฉเจธเจผเจฒเจคเจพ เจจเฉ‚เฉฐ เจธเจผเจพเจฎเจฒ เจจเจนเฉ€เจ‚ เจ•เฉ€เจคเจพ, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‡เจธ เจชเฉœเจพเจ… 'เจคเฉ‡ เจ‡เจน เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจธเจชเฉฑเจธเจผเจŸ เจธเฉ€ เจ•เจฟ เจฐเฉฐเจ—เฉ€เจจ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจเจพ เจตเจงเฉ‡เจฐเฉ‡ เจฒเจพเจญเจ•เจพเจฐเฉ€ เจธเฉ€.

เจ…เจธเฉ€เจ‚ เจฎเฉ‹เจฌเจพเจˆเจฒเจจเฉˆเฉฑเจŸ เจธเฉฐเจธเจ•เจฐเจฃ 1 เจ…เจคเฉ‡ 2, เจ…เจคเฉ‡ เจจเจพเจฒ เจนเฉ€ resnet34 เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจœเจผเจฟเจ†เจฆเจพเจคเจฐ เจชเฉเจฐเจฏเฉ‹เจ— เจ•เฉ€เจคเฉ‡เฅค เจนเฉ‹เจฐ เจ†เจงเฉเจจเจฟเจ• เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ SE-ResNeXt เจจเฉ‡ เจ‡เจธ เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจตเจฟเฉฑเจš เจตเจงเฉ€เจ† เจชเฉเจฐเจฆเจฐเจธเจผเจจ เจ•เฉ€เจคเจพเฅค เจฌเจฆเจ•เจฟเจธเจฎเจคเฉ€ เจจเจพเจฒ, เจธเจพเจกเฉ‡ เจ•เฉ‹เจฒ เจธเจพเจกเฉ‡ เจจเจฟเจชเจŸเจพเจฐเฉ‡ 'เจคเฉ‡ เจคเจฟเจ†เจฐ-เจ•เฉ€เจคเฉ‡ เจ…เจฎเจฒ เจจเจนเฉ€เจ‚ เจธเจจ, เจ…เจคเฉ‡ เจ…เจธเฉ€เจ‚ เจ†เจชเจฃเจพ เจจเจนเฉ€เจ‚ เจฒเจฟเจ–เจฟเจ† (เจชเจฐ เจ…เจธเฉ€เจ‚ เจœเจผเจฐเฉ‚เจฐ เจฒเจฟเจ–เจพเจ‚เจ—เฉ‡)เฅค

5. เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจฆเจพ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจˆเจœเจผเฉ‡เจธเจผเจจ

เจธเจนเฉ‚เจฒเจค เจฒเจˆ, เจธเจฟเจ–เจฒเจพเจˆ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจจ เจฒเจˆ เจธเจพเจฐเฉ‡ เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจธเจฟเฉฐเจ—เจฒ เจธเจ•เฉเจฐเจฟเจชเจŸ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจกเจฟเจœเจผเจพเจ‡เจจ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€, เจœเจฟเจธเจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจˆเจœเจผ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€ docopt เจนเฉ‡เจ  เจฒเจฟเจ–เฉ‡ เจ…เจจเฉเจธเจพเจฐ:

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)

เจชเฉˆเจ•เฉ‡เจœ docopt เจฒเจพเจ—เฉ‚ เจ•เจฐเจจ เจจเฉ‚เฉฐ เจฆเจฐเจธเจพเจ‰เจ‚เจฆเจพ เจนเฉˆ http://docopt.org/ เจ‡เจธเจฆเฉ€ เจฎเจฆเจฆ เจจเจพเจฒ, เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจจเฉ‚เฉฐ เจธเจงเจพเจฐเจจ เจ•เจฎเจพเจ‚เจกเจพเจ‚ เจจเจพเจฒ เจฒเจพเจ‚เจš เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ 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 เจชเฉˆเจ•เฉ‡เจœ เจตเจฟเฉฑเจš เจคเจฌเจฆเฉ€เจฒเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจงเจฟเจ†เจจ เจตเจฟเฉฑเจš เจจเจนเฉ€เจ‚ เจฐเฉฑเจ–เจฃ เจฆเฉ‡ เจ•เจพเจฐเจจ, เจ…เจธเฉ€เจ‚ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ เฉ€เจ• เจ•เจฐเจจ เจฆเฉ€ เจ‰เจกเฉ€เจ• เจ•เจฐ เจฐเจนเฉ‡ เจนเจพเจ‚เฅค

เจ‡เจธ เจชเจนเฉเฉฐเจš เจจเฉ‡ RStudio เจตเจฟเฉฑเจš เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจฆเฉ‡ เจตเจงเฉ‡เจฐเฉ‡ เจฐเจตเจพเจ‡เจคเฉ€ เจฒเจพเจ‚เจš เจฆเฉ‡ เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจตเฉฑเจ–-เจตเฉฑเจ– เจฎเจพเจกเจฒเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ เจชเฉเจฐเจฏเฉ‹เจ—เจพเจ‚ เจจเฉ‚เฉฐ เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจคเฉŒเจฐ 'เจคเฉ‡ เจคเฉ‡เจœเจผ เจ•เจฐเจจเจพ เจธเฉฐเจญเจต เจฌเจฃเจพเจ‡เจ† (เจ…เจธเฉ€เจ‚ เจชเฉˆเจ•เฉ‡เจœ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจธเฉฐเจญเจพเจตเฉ€ เจตเจฟเจ•เจฒเจช เจตเจœเฉ‹เจ‚ เจจเฉ‹เจŸ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค tfruns). เจชเจฐ เจฎเฉเฉฑเจ– เจซเจพเจ‡เจฆเจพ เจ‡เจธ เจฒเจˆ RStudio เจจเฉ‚เฉฐ เจธเจฅเจพเจชเจฟเจค เจ•เฉ€เจคเฉ‡ เจฌเจฟเจจเจพเจ‚, เจกเฉŒเจ•เจฐ เจตเจฟเฉฑเจš เจœเจพเจ‚ เจธเจฟเจฐเจซเจผ เจธเจฐเจตเจฐ 'เจคเฉ‡ เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจฆเฉ€ เจธเจผเฉเจฐเฉ‚เจ†เจค เจจเฉ‚เฉฐ เจ†เจธเจพเจจเฉ€ เจจเจพเจฒ เจชเฉเจฐเจฌเฉฐเจงเจฟเจค เจ•เจฐเจจ เจฆเฉ€ เจธเจฎเจฐเฉฑเจฅเจพ เจนเฉˆเฅค

6. เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจฆเจพ เจกเฉŒเจ•เจฐเจพเจˆเจœเจผเฉ‡เจธเจผเจจ

เจ…เจธเฉ€เจ‚ เจŸเฉ€เจฎ เจฆเฉ‡ เจฎเฉˆเจ‚เจฌเจฐเจพเจ‚ เจตเจฟเจšเจ•เจพเจฐ เจธเจฟเจ–เจฒเจพเจˆ เจฎเจพเจกเจฒเจพเจ‚ เจ…เจคเฉ‡ เจ•เจฒเจพเจ‰เจก เจตเจฟเฉฑเจš เจคเฉ‡เจœเจผเฉ€ เจจเจพเจฒ เจคเจพเจ‡เจจเจพเจคเฉ€ เจฒเจˆ เจตเจพเจคเจพเจตเจฐเจฃ เจฆเฉ€ เจชเฉ‹เจฐเจŸเฉ‡เจฌเจฟเจฒเจŸเฉ€ เจจเฉ‚เฉฐ เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจกเฉŒเจ•เจฐ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€เฅค เจคเฉเจธเฉ€เจ‚ เจ‡เจธ เจŸเฉ‚เจฒ เจจเจพเจฒ เจœเจพเจฃเฉ‚ เจนเฉ‹เจฃเจพ เจธเจผเฉเจฐเฉ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹, เจœเฉ‹ เจ•เจฟ เจ‡เฉฑเจ• เจ†เจฐ เจชเฉเจฐเฉ‹เจ—เจฐเจพเจฎเจฐ เจฒเจˆ เจฎเฉเจ•เจพเจฌเจฒเจคเจจ เจ…เจธเจพเจงเจพเจฐเจจ เจนเฉˆ, เจจเจพเจฒ เจ‡เจน เจชเฉเจฐเจ•เจพเจธเจผเจจเจพเจ‚ เจฆเฉ€ เจฒเฉœเฉ€ เจœเจพเจ‚ เจตเฉ€เจกเฉ€เจ“ เจ•เฉ‹เจฐเจธ.

เจกเฉŒเจ•เจฐ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจ•เฉเจฐเฉˆเจš เจคเฉ‹เจ‚ เจ†เจชเจฃเฉ€เจ†เจ‚ เจ–เฉเจฆ เจฆเฉ€เจ†เจ‚ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจฌเจฃเจพเจ‰เจฃ เจ…เจคเฉ‡ เจคเฉเจนเจพเจกเฉ€เจ†เจ‚ เจ–เฉเจฆ เจฆเฉ€เจ†เจ‚ เจคเจธเจตเฉ€เจฐเจพเจ‚ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ‡ เจ…เจงเจพเจฐ เจตเจœเฉ‹เจ‚ เจนเฉ‹เจฐ เจšเจฟเฉฑเจคเจฐเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค เจ‰เจชเจฒเจฌเจง เจตเจฟเจ•เจฒเจชเจพเจ‚ เจฆเจพ เจตเจฟเจธเจผเจฒเฉ‡เจธเจผเจฃ เจ•เจฐเจฆเฉ‡ เจธเจฎเฉ‡เจ‚, เจ…เจธเฉ€เจ‚ เจ‡เจธ เจธเจฟเฉฑเจŸเฉ‡ 'เจคเฉ‡ เจชเจนเฉเฉฐเจšเฉ‡ เจ•เจฟ NVIDIA, CUDA + cuDNN เจกเจฐเจพเจˆเจตเจฐเจพเจ‚ เจ…เจคเฉ‡ เจชเจพเจˆเจฅเจจ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจธเจฅเจพเจชเจฟเจค เจ•เจฐเจจเจพ เจšเจฟเฉฑเจคเจฐ เจฆเจพ เจ•เจพเจซเจผเฉ€ เจตเฉฑเจกเจพ เจนเจฟเฉฑเจธเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจ…เจธเฉ€เจ‚ เจ…เจงเจฟเจ•เจพเจฐเจค เจšเจฟเฉฑเจคเจฐ เจจเฉ‚เฉฐ เจ…เจงเจพเจฐ เจตเจœเฉ‹เจ‚ เจฒเฉˆเจฃ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เฉ€เจคเจพ เจนเฉˆเฅค tensorflow/tensorflow:1.12.0-gpu, เจ‰เฉฑเจฅเฉ‡ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ‡ R เจชเฉˆเจ•เฉ‡เจœ เจธเจผเจพเจฎเจฒ เจ•เจฐเจจเจพเฅค

เจซเจพเจˆเจจเจฒ เจกเฉŒเจ•เจฐ เจซเจพเจˆเจฒ เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ เจฆเจฟเจ–เจพเจˆ เจฆเจฟเฉฐเจฆเฉ€ เจธเฉ€:

เจกเฉŒเจ•เจฐเจซเจพเจˆเจฒ

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 เจธเฉฐเจธเจ•เจฐเจฃ เจจเฉ‚เฉฐ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เจฐเจจ เจฆเฉ€ เจœเจผเจฐเฉ‚เจฐเจค เจคเฉ‹เจ‚ เจฌเจšเจฟเจ† เจนเฉˆเฅค

เจ‡เจธ เจคเฉ‹เจ‚ เจ‡เจฒเจพเจตเจพ, เจ‡เฉฑเจ• เจ›เฉ‹เจŸเฉ€ เจฌเฉˆเจธเจผ เจธเจ•เฉเจฐเจฟเจชเจŸ เจฒเจฟเจ–เฉ€ เจ—เจˆ เจธเฉ€ เจœเฉ‹ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ•เจˆ เจ•เจฎเจพเจ‚เจกเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ เจ‡เฉฑเจ• เจ•เฉฐเจŸเฉ‡เจจเจฐ เจฒเจพเจ‚เจš เจ•เจฐเจจ เจฆเฉ€ เจ†เจ—เจฟเจ† เจฆเจฟเฉฐเจฆเฉ€ เจนเฉˆเฅค เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจ‡เจน เจคเฉฐเจคเฉ‚ เจจเฉˆเฉฑเจŸเจตเจฐเจ•เจพเจ‚ เจฆเฉ€ เจธเจฟเจ–เจฒเจพเจˆ เจฒเจˆ เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจนเฉ‹ เจธเจ•เจฆเฉ€เจ†เจ‚ เจนเจจ เจœเฉ‹ เจชเจนเจฟเจฒเจพเจ‚ เจ•เฉฐเจŸเฉ‡เจจเจฐ เจฆเฉ‡ เจ…เฉฐเจฆเจฐ เจฐเฉฑเจ–เฉ‡ เจ—เจ เจธเจจ, เจœเจพเจ‚ เจ•เฉฐเจŸเฉ‡เจจเจฐ เจฆเฉ‡ เจธเฉฐเจšเจพเจฒเจจ เจจเฉ‚เฉฐ เจกเฉ€เจฌเฉฑเจ— เจ•เจฐเจจ เจ…เจคเฉ‡ เจจเจฟเจ—เจฐเจพเจจเฉ€ เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจ•เจฎเจพเจ‚เจก เจธเจผเฉˆเฉฑเจฒ:

เจ•เฉฐเจŸเฉ‡เจจเจฐ เจจเฉ‚เฉฐ เจฒเจพเจ‚เจš เจ•เจฐเจจ เจฒเจˆ เจธเจ•เฉเจฐเจฟเจชเจŸ

#!/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}

เจœเฉ‡เจ•เจฐ เจ‡เจน เจฌเฉˆเจธเจผ เจธเจ•เฉเจฐเจฟเจชเจŸ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจ‚ เจคเฉ‹เจ‚ เจฌเจฟเจจเจพเจ‚ เจšเจฒเจพเจˆ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ, เจคเจพเจ‚ เจธเจ•เฉเจฐเจฟเจชเจŸ เจจเฉ‚เฉฐ เจ•เฉฐเจŸเฉ‡เจจเจฐ เจฆเฉ‡ เจ…เฉฐเจฆเจฐ เจฌเฉเจฒเจพเจ‡เจ† เจœเจพเจตเฉ‡เจ—เจพ train_nn.R เจกเจฟเจซเฉŒเจฒเจŸ เจฎเฉเฉฑเจฒเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ; เจœเฉ‡เจ•เจฐ เจชเจนเจฟเจฒเฉ€ เจธเจฅเจฟเจคเฉ€ เจธเฉฐเจฌเฉฐเจงเฉ€ เจ†เจฐเจ—เฉ‚เจฎเฉˆเจ‚เจŸ "bash" เจนเฉˆ, เจคเจพเจ‚ เจ•เฉฐเจŸเฉ‡เจจเจฐ เจ•เจฎเจพเจ‚เจก เจธเจผเฉˆเฉฑเจฒ เจจเจพเจฒ เจ‡เฉฐเจŸเจฐเจเจ•เจŸเจฟเจต เจคเฉŒเจฐ 'เจคเฉ‡ เจธเจผเฉเจฐเฉ‚ เจนเฉ‹เจตเฉ‡เจ—เจพเฅค เจนเฉ‹เจฐ เจธเจพเจฐเฉ‡ เจฎเจพเจฎเจฒเจฟเจ†เจ‚ เจตเจฟเฉฑเจš, เจธเจฅเจฟเจคเฉ€ เจธเฉฐเจฌเฉฐเจงเฉ€ เจ†เจฐเจ—เฉ‚เจฎเฉˆเจ‚เจŸเจพเจ‚ เจฆเฉ‡ เจฎเฉเฉฑเจฒ เจฌเจฆเจฒเฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ: CMD="Rscript /app/train_nn.R $@".

เจ‡เจน เจงเจฟเจ†เจจ เจฆเฉ‡เจฃ เจฏเฉ‹เจ— เจนเฉˆ เจ•เจฟ เจธเจฐเฉ‹เจค เจกเฉ‡เจŸเจพ เจ…เจคเฉ‡ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจตเจพเจฒเฉ€เจ†เจ‚ เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€เจ†เจ‚, เจ…เจคเฉ‡ เจจเจพเจฒ เจนเฉ€ เจธเจฟเจ–เจฒเจพเจˆ เจชเฉเจฐเจพเจชเจค เจฎเจพเจกเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เจฐเจจ เจฒเจˆ เจกเจพเจ‡เจฐเฉˆเจ•เจŸเจฐเฉ€, เจนเฉ‹เจธเจŸ เจธเจฟเจธเจŸเจฎ เจคเฉ‹เจ‚ เจ•เฉฐเจŸเฉ‡เจจเจฐ เจฆเฉ‡ เจ…เฉฐเจฆเจฐ เจฎเจพเจŠเจ‚เจŸ เจ•เฉ€เจคเฉ€เจ†เจ‚ เจ—เจˆเจ†เจ‚ เจนเจจ, เจœเฉ‹ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจฆเฉ‡ เจจเจคเฉ€เจœเจฟเจ†เจ‚ เจจเฉ‚เฉฐ เจฌเฉ‡เจฒเฉ‹เฉœเฉ€ เจนเฉ‡เจฐเจพเจซเฉ‡เจฐเฉ€ เจคเฉ‹เจ‚ เจฌเจฟเจจเจพเจ‚ เจเจ•เจธเฉˆเจธ เจ•เจฐเจจ เจฆเฉ€ เจ†เจ—เจฟเจ† เจฆเจฟเฉฐเจฆเฉ€เจ†เจ‚ เจนเจจ.

7. เจ—เฉ‚เจ—เจฒ เจ•เจฒเจพเจ‰เจก 'เจคเฉ‡ เจ•เจˆ GPUs เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจเจพ

เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจฆเฉ€เจ†เจ‚ เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพเจตเจพเจ‚ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจ‡เฉฑเจ• เจฌเจนเฉเจค เจฐเฉŒเจฒเจพ-เจฐเฉฑเจชเจพ เจตเจพเจฒเจพ เจกเฉ‡เจŸเจพ เจธเฉ€ (เจธเจฟเจฐเจฒเฉ‡เจ– เจคเจธเจตเฉ€เจฐ เจฆเฉ‡เจ–เฉ‹, ODS เจธเจฒเฉˆเจ• เจคเฉ‹เจ‚ @Leigh.plt เจคเฉ‹เจ‚ เจ‰เจงเจพเจฐ เจฒเจฟเจ† เจ—เจฟเจ†)เฅค เจตเฉฑเจกเฉ‡ เจฌเฉˆเจš เจ‡เจธ เจจเจพเจฒ เจฒเฉœเจจ เจตเจฟเฉฑเจš เจฎเจฆเจฆ เจ•เจฐเจฆเฉ‡ เจนเจจ, เจ…เจคเฉ‡ 1 GPU เจตเจพเจฒเฉ‡ เจ‡เฉฑเจ• PC 'เจคเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ—เจพเจ‚ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ, เจ…เจธเฉ€เจ‚ เจ•เจฒเจพเจ‰เจก เจตเจฟเฉฑเจš เจ•เจˆ GPUs 'เจคเฉ‡ เจธเจฟเจ–เจฒเจพเจˆ เจฎเจพเจกเจฒเจพเจ‚ เจตเจฟเฉฑเจš เจฎเฉเจนเจพเจฐเจค เจนเจพเจธเจฒ เจ•เจฐเจจ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เฉ€เจคเจพ เจนเฉˆเฅค เจตเจฐเจคเจฟเจ† GoogleCloud (เจฌเฉเจจเจฟเจ†เจฆเฉ€ เจฒเจˆ เจšเฉฐเจ—เฉ€ เจ—เจพเจˆเจก) เจ‰เจชเจฒเจฌเจง เจธเฉฐเจฐเจšเจจเจพเจตเจพเจ‚, เจตเจพเจœเจฌ เจ•เฉ€เจฎเจคเจพเจ‚ เจ…เจคเฉ‡ $300 เจฌเฉ‹เจจเจธ เจฆเฉ€ เจตเฉฑเจกเฉ€ เจšเฉ‹เจฃ เจฆเฉ‡ เจ•เจพเจฐเจจเฅค เจฒเจพเจฒเจš เจฆเฉ‡ เจ•เจพเจฐเจจ, เจฎเฉˆเจ‚ เจ‡เฉฑเจ• SSD เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจŸเจจ RAM เจฆเฉ‡ เจจเจพเจฒ เจ‡เฉฑเจ• 4xV100 เจ‰เจฆเจพเจนเจฐเจฃ เจฆเจพ เจ†เจฐเจกเจฐ เจ•เฉ€เจคเจพ, เจ…เจคเฉ‡ เจ‡เจน เจ‡เฉฑเจ• เจตเฉฑเจกเฉ€ เจ—เจฒเจคเฉ€ เจธเฉ€เฅค เจ…เจœเจฟเจนเฉ€ เจฎเจธเจผเฉ€เจจ เจคเฉ‡เจœเจผเฉ€ เจจเจพเจฒ เจชเฉˆเจธเจพ เจ–เจพ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ; เจคเฉเจธเฉ€เจ‚ เจฌเจฟเจจเจพเจ‚ เจธเจพเจฌเจค เจชเจพเจˆเจชเจฒเจพเจˆเจจ เจฆเฉ‡ เจŸเฉเฉฑเจŸเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ— เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค เจตเจฟเจฆเจฟเจ…เจ• เจ‰เจฆเฉ‡เจธเจผเจพเจ‚ เจฒเจˆ, K80 เจฒเฉˆเจฃเจพ เจฌเจฟเจนเจคเจฐ เจนเฉˆ. เจชเจฐ เจฐเฉˆเจฎ เจฆเฉ€ เจตเฉฑเจกเฉ€ เจฎเจพเจคเจฐเจพ เจ•เฉฐเจฎ เจตเจฟเฉฑเจš เจ†เจˆ - เจ•เจฒเจพเจ‰เจก SSD เจจเฉ‡ เจ‡เจธเจฆเฉ‡ เจชเฉเจฐเจฆเจฐเจธเจผเจจ เจจเจพเจฒ เจชเฉเจฐเจญเจพเจตเจค เจจเจนเฉ€เจ‚ เจ•เฉ€เจคเจพ, เจ‡เจธเจฒเจˆ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจจเฉ‚เฉฐ เจŸเฉเจฐเจพเจ‚เจธเจซเจฐ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€ dev/shm.

เจธเจญ เจคเฉ‹เจ‚ เจตเฉฑเจง เจฆเจฟเจฒเจšเจธเจชเฉ€ เจฆเจพ เจ•เฉ‹เจก เจซเจฐเฉˆเจ—เจฎเฉˆเจ‚เจŸ เจนเฉˆ เจœเฉ‹ เจฎเจฒเจŸเฉ€เจชเจฒ GPUs เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฒเจˆ เจœเจผเจฟเฉฐเจฎเฉ‡เจตเจพเจฐ เจนเฉˆเฅค เจชเจนเจฟเจฒเจพเจ‚, เจฎเจพเจกเจฒ เจจเฉ‚เฉฐ 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
  )
})

เจซเจฟเจฐ เจ…เจฃเจ•เฉฐเจชเจพเจˆเจฒเจก (เจ‡เจน เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจนเฉˆ) เจฎเจพเจกเจฒ เจจเฉ‚เฉฐ เจ‰เจชเจฒเจฌเจง GPUs เจฆเฉ€ เจ‡เฉฑเจ• เจฆเจฟเฉฑเจคเฉ€ เจ—เจˆ เจธเฉฐเจ–เจฟเจ† เจตเจฟเฉฑเจš เจ•เจพเจชเฉ€ เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจ‡เจธเจฆเฉ‡ เจฌเจพเจ…เจฆ เจนเฉ€ เจ‡เจธเจจเฉ‚เฉฐ เจ•เฉฐเจชเจพเจ‡เจฒ เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ:

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)
)

เจ†เจ–เจฐเฉ€ เจจเฉ‚เฉฐ เจ›เฉฑเจก เจ•เฉ‡ เจธเจพเจฐเฉ€เจ†เจ‚ เจฒเฉ‡เจ…เจฐเจพเจ‚ เจจเฉ‚เฉฐ เจซเฉเจฐเฉ€เจœเจผ เจ•เจฐเจจ, เจ†เจ–เจฐเฉ€ เจฒเฉ‡เจ…เจฐ เจจเฉ‚เฉฐ เจŸเจฐเฉ‡เจจเจฟเฉฐเจ— เจฆเฉ‡เจฃ, เจ•เจˆ GPUs เจฒเจˆ เจชเฉ‚เจฐเฉ‡ เจฎเจพเจกเจฒ เจจเฉ‚เฉฐ เจ…เจจเจซเฉเจฐเฉ€เจœเจผ เจ•เจฐเจจ เจ…เจคเฉ‡ เจฆเฉเจฌเจพเจฐเจพ เจธเจฟเจ–เจฒเจพเจˆ เจฆเฉ‡เจฃ เจฆเฉ€ เจ•เจฒเจพเจธเจฟเจ• เจคเจ•เจจเฉ€เจ• เจฒเจพเจ—เฉ‚ เจจเจนเฉ€เจ‚ เจ•เฉ€เจคเฉ€ เจœเจพ เจธเจ•เฉ€เฅค

เจธเจฟเจ–เจฒเจพเจˆ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจคเฉ‹เจ‚ เจฌเจฟเจจเจพเจ‚ เจจเจฟเจ—เจฐเจพเจจเฉ€ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจธเฉ€. เจŸเฉˆเจ‚เจธเจฐเจฌเฉ‹เจฐเจก, เจ†เจชเจฃเฉ‡ เจ†เจช เจจเฉ‚เฉฐ เจฒเฉŒเจ— เจฐเจฟเจ•เจพเจฐเจก เจ•เจฐเจจ เจ…เจคเฉ‡ เจนเจฐเฉ‡เจ• เจฏเฉเฉฑเจ— เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจœเจพเจฃเจ•เจพเจฐเฉ€ เจตเจพเจฒเฉ‡ เจจเจพเจตเจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ เจฎเจพเจกเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เจฐเจจ เจคเฉฑเจ• เจธเฉ€เจฎเจค เจ•เจฐเจจเจพ:

เจ•เจพเจฒเจฌเฉˆเจ•เจธ

# ะจะฐะฑะปะพะฝ ะธะผะตะฝะธ ั„ะฐะนะปะฐ ะปะพะณะฐ
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 เจจเฉ‚เฉฐ เจชเฉ‹เจฐเจŸ เจ•เจฐเจจเจพ เจธเฉฐเจญเจต เจนเฉˆ, เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจ‡เจน;
  • เจชเจฟเจ›เจฒเฉ‡ เจฌเจฟเฉฐเจฆเฉ‚ เจฆเฉ‡ เจจเจคเฉ€เจœเฉ‡ เจตเจœเฉ‹เจ‚, เจ•เจˆ GPUs เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจธเจฎเฉ‡เจ‚ เจธเจนเฉ€ เจธเจฟเจ–เจฒเจพเจˆ เจฆเฉ€ เจ—เจคเฉ€ เจฆเฉ€ เจšเฉ‹เจฃ เจ•เจฐเจจเจพ เจธเฉฐเจญเจต เจจเจนเฉ€เจ‚ เจธเฉ€;
  • เจ†เจงเฉเจจเจฟเจ• เจจเจฟเจŠเจฐเจฒ เจจเฉˆเฉฑเจŸเจตเจฐเจ• เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจฆเฉ€ เจ˜เจพเจŸ เจนเฉˆ, เจ–เจพเจธ เจคเฉŒเจฐ 'เจคเฉ‡ เจ‰เจน เจœเฉ‹ เจ‡เจฎเฉ‡เจœเจจเฉˆเฉฑเจŸ 'เจคเฉ‡ เจชเจนเจฟเจฒเจพเจ‚ เจคเฉ‹เจ‚ เจธเจฟเจ–เจฒเจพเจˆ เจชเฉเจฐเจพเจชเจค เจนเจจ;
  • เจ•เฉ‹เจˆ เจ‡เฉฑเจ• เจšเฉฑเจ•เจฐ เจจเฉ€เจคเฉ€ เจ…เจคเฉ‡ เจชเฉฑเจ–เจชเจพเจคเฉ€ เจธเจฟเฉฑเจ–เจฃ เจฆเฉ€เจ†เจ‚ เจฆเจฐเจพเจ‚ เจจเจนเฉ€เจ‚ (เจ•เฉ‹เจธเจพเจˆเจจ เจเจจเฉ€เจฒเจฟเฉฐเจ— เจธเจพเจกเฉ€ เจฌเฉ‡เจจเจคเฉ€ 'เจคเฉ‡ เจธเฉ€ เจฒเจพเจ—เฉ‚ เจ•เฉ€เจคเจพ, เจคเฉเจนเจพเจกเจพ เจงเฉฐเจจเจตเจพเจฆ เจธเจ•เจพเจˆเจกเจจ).

เจ‡เจธ เจฎเฉเจ•เจพเจฌเจฒเฉ‡ เจคเฉ‹เจ‚ เจ•เจฟเจนเฉœเฉ€เจ†เจ‚ เจฒเจพเจญเจฆเจพเจ‡เจ• เจ—เฉฑเจฒเจพเจ‚ เจธเจฟเฉฑเจ–เฉ€เจ†เจ‚ เจ—เจˆเจ†เจ‚:

  • เจฎเฉเจ•เจพเจฌเจฒเจคเจจ เจ˜เฉฑเจŸ-เจชเจพเจตเจฐ เจนเจพเจฐเจกเจตเฉ‡เจ…เจฐ 'เจคเฉ‡, เจคเฉเจธเฉ€เจ‚ เจฌเจฟเจจเจพเจ‚ เจฆเจฐเจฆ เจฆเฉ‡ เจกเจพเจŸเจพ เจฆเฉ‡ เจตเจฟเจจเฉ€เจค (เจ•เจˆ เจตเจพเจฐ RAM เจฆเฉ‡ เจ†เจ•เจพเจฐ) เจตเจพเจฒเฉ€เจ…เจฎ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค เจชเจฒเจพเจธเจŸเจฟเจ• เจฌเฉˆเจ— เจกเฉ‡เจŸเจพ.เจŸเฉˆเจฌเจฒ เจŸเฉ‡เจฌเจฒเจพเจ‚ เจฆเฉ€ เจฅเจพเจ‚-เจฅเจพเจ‚ เจธเฉฐเจธเจผเฉ‹เจงเจจ เจ•เจฐเจ•เฉ‡ เจฎเฉˆเจฎเฉ‹เจฐเฉ€ เจจเฉ‚เฉฐ เจฌเจšเจพเจ‰เจ‚เจฆเจพ เจนเฉˆ, เจœเฉ‹ เจ‰เจนเจจเจพเจ‚ เจฆเฉ€ เจจเจ•เจฒ เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจšเจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจœเจฆเฉ‹เจ‚ เจธเจนเฉ€ เจขเฉฐเจ— เจจเจพเจฒ เจตเจฐเจคเจฟเจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆ, เจคเจพเจ‚ เจ‡เจธเจฆเฉ€เจ†เจ‚ เจธเจฎเจฐเฉฑเจฅเจพเจตเจพเจ‚ เจฒเจ—เจญเจ— เจนเจฎเฉ‡เจธเจผเจพเจ‚ เจธเจญ เจคเฉ‹เจ‚ เจ‰เฉฑเจšเฉ€ เจ—เจคเฉ€ เจฆเจฐเจธเจพเจ‰เจ‚เจฆเฉ€เจ†เจ‚ เจนเจจ เจœเฉ‹ เจธเจพเจจเฉ‚เฉฐ เจธเจ•เฉเจฐเจฟเจชเจŸเจฟเฉฐเจ— เจญเจพเจธเจผเจพเจตเจพเจ‚ เจฒเจˆ เจœเจพเจฃเฉ€เจ†เจ‚ เจœเจพเจ‚เจฆเฉ€เจ†เจ‚ เจนเจจเฅค เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจตเจฟเฉฑเจš เจกเฉ‡เจŸเจพ เจจเฉ‚เฉฐ เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เจฐเจจเจพ เจคเฉเจนเจพเจจเฉ‚เฉฐ, เจฌเจนเฉเจค เจธเจพเจฐเฉ‡ เจฎเจพเจฎเจฒเจฟเจ†เจ‚ เจตเจฟเฉฑเจš, เจชเฉ‚เจฐเฉ‡ เจกเฉ‡เจŸเจพเจธเฉˆเจŸ เจจเฉ‚เฉฐ RAM เจตเจฟเฉฑเจš เจจเจฟเจšเฉ‹เฉœเจจ เจฆเฉ€ เจœเจผเจฐเฉ‚เจฐเจค เจฌเจพเจฐเฉ‡ เจฌเจฟเจฒเจ•เฉเจฒ เจตเฉ€ เจจเจนเฉ€เจ‚ เจธเฉ‹เจšเจฃ เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค
  • R เจตเจฟเฉฑเจš เจนเฉŒเจฒเฉ€ เจซเฉฐเจ•เจธเจผเจจเจพเจ‚ เจจเฉ‚เฉฐ เจชเฉˆเจ•เฉ‡เจœ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ C++ เจตเจฟเฉฑเจš เจคเฉ‡เจœเจผ เจซเฉฐเจ•เจธเจผเจจเจพเจ‚ เจจเจพเจฒ เจฌเจฆเจฒเจฟเจ† เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆ เจ†เจฐ.เจธเฉ€.เจชเฉ€.เจชเฉ€. เจœเฉ‡เจ•เจฐ เจ‡เจธ เจคเฉ‹เจ‚ เจ‡เจฒเจพเจตเจพ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจœเจพเจตเฉ‡ RcppThread เจœ เจ†เจฐเจธเฉ€เจชเฉ€เจชเฉ€เจชเฉˆเจฐเจฒเจฒ, เจธเจพเจจเฉ‚เฉฐ เจ•เฉเจฐเจพเจธ-เจชเจฒเฉ‡เจŸเจซเจพเจฐเจฎ เจฎเจฒเจŸเฉ€-เจฅเฉเจฐเฉˆเจกเจก เจฒเจพเจ—เฉ‚เจ•เจฐเจจ เจฎเจฟเจฒเจฆเจพ เจนเฉˆ, เจ‡เจธเจฒเจˆ R เจชเฉฑเจงเจฐ 'เจคเฉ‡ เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจธเจฎเจพเจจเจพเจ‚เจคเจฐ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจ•เฉ‹เจˆ เจฒเฉ‹เฉœ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค
  • เจชเฉˆเจ•เฉ‡เจœ เจ†เจฐ.เจธเฉ€.เจชเฉ€.เจชเฉ€ C++ เจฆเฉ‡ เจ—เฉฐเจญเฉ€เจฐ เจ—เจฟเจ†เจจ เจคเฉ‹เจ‚ เจฌเจฟเจจเจพเจ‚ เจตเจฐเจคเจฟเจ† เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆ, เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ€ เจ˜เฉฑเจŸเฉ‹-เจ˜เฉฑเจŸ เจฐเฉ‚เจชเจฐเฉ‡เจ–เจพ เจฆเจฟเฉฑเจคเฉ€ เจ—เจˆ เจนเฉˆ เจ‡เฉฑเจฅเฉ‡. เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจฌเจนเฉเจค เจธเจพเจฐเฉ€เจ†เจ‚ เจ เฉฐเจกเฉ€เจ†เจ‚ เจธเฉ€-เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€เจ†เจ‚ เจฒเจˆ เจนเฉˆเจกเจฐ เจซเจพเจˆเจฒเจพเจ‚ xtensor CRAN 'เจคเฉ‡ เจ‰เจชเจฒเจฌเจง เจนเฉˆ, เจฏเจพเจจเฉ€ เจ•เจฟ, เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸเจพเจ‚ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจฌเฉเจจเจฟเจ†เจฆเฉ€ เจขเจพเจ‚เจšเจพ เจฌเจฃเจพเจ‡เจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ เจœเฉ‹ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ‡ เจ‰เฉฑเจš-เจชเฉเจฐเจฆเจฐเจธเจผเจจ เจตเจพเจฒเฉ‡ C++ เจ•เฉ‹เจก เจจเฉ‚เฉฐ R เจตเจฟเฉฑเจš เจœเฉ‹เฉœเจฆเฉ‡ เจนเจจเฅค เจตเจพเจงเฉ‚ เจธเจนเฉ‚เจฒเจค RStudio เจตเจฟเฉฑเจš เจธเจฟเฉฐเจŸเฉˆเจ•เจธ เจนเจพเจˆเจฒเจพเจˆเจŸเจฟเฉฐเจ— เจ…เจคเฉ‡ เจ‡เฉฑเจ• เจธเจฅเจฟเจฐ C++ เจ•เฉ‹เจก เจเจจเจพเจฒเจพเจˆเจœเจผเจฐ เจนเฉˆเฅค
  • docopt เจคเฉเจนเจพเจจเฉ‚เฉฐ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจ‚ เจจเจพเจฒ เจธเจตเฉˆ-เจจเจฟเจฐเจญเจฐ เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจšเจฒเจพเจ‰เจฃ เจฆเฉ€ เจ†เจ—เจฟเจ† เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค เจ‡เจน เจฐเจฟเจฎเฉ‹เจŸ เจธเจฐเจตเจฐ 'เจคเฉ‡ เจตเจฐเจคเจฃ เจฒเจˆ เจธเฉเจตเจฟเจงเจพเจœเจจเจ• เจนเฉˆ, เจธเจฎเฉ‡เจคเฅค เจกเฉŒเจ•เจฐ เจฆเฉ‡ เจ…เจงเฉ€เจจ. RStudio เจตเจฟเฉฑเจš, เจธเจฟเจ–เจฒเจพเจˆ เจจเจฟเจŠเจฐเจฒ เจจเฉˆเฉฑเจŸเจตเจฐเจ•เจพเจ‚ เจฆเฉ‡ เจจเจพเจฒ เจ•เจˆ เจ˜เฉฐเจŸเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ— เจ•เจฐเจจเจพ เจ…เจธเฉเจตเจฟเจงเจพเจœเจจเจ• เจนเฉˆ, เจ…เจคเฉ‡ เจธเจฐเจตเจฐ 'เจคเฉ‡ IDE เจจเฉ‚เฉฐ เจธเจฅเจพเจชเจฟเจค เจ•เจฐเจจเจพ เจนเจฎเฉ‡เจธเจผเจพ เจœเจพเจ‡เจœเจผ เจจเจนเฉ€เจ‚ เจนเฉเฉฐเจฆเจพ เจนเฉˆเฅค
  • เจกเฉŒเจ•เจฐ เจ•เฉ‹เจก เจชเฉ‹เจฐเจŸเฉ‡เจฌเจฟเจฒเจŸเฉ€ เจ…เจคเฉ‡ OS เจ…เจคเฉ‡ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€เจ†เจ‚ เจฆเฉ‡ เจตเฉฑเจ–-เจตเฉฑเจ– เจธเฉฐเจธเจ•เจฐเจฃเจพเจ‚ เจตเจพเจฒเฉ‡ เจกเจฟเจตเฉˆเจฒเจชเจฐเจพเจ‚ เจตเจฟเจšเจ•เจพเจฐ เจจเจคเฉ€เจœเจฟเจ†เจ‚ เจฆเฉ€ เจชเฉเจจเจฐ-เจ‰เจคเจชเจพเจฆเจจเจฏเฉ‹เจ—เจคเจพ เจฆเฉ‡ เจจเจพเจฒ เจจเจพเจฒ เจธเจฐเจตเจฐเจพเจ‚ 'เจคเฉ‡ เจเจ—เจœเจผเฉ€เจ•เจฟเจŠเจธเจผเจจ เจฆเฉ€ เจธเฉŒเจ– เจจเฉ‚เฉฐ เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพเจ‰เจ‚เจฆเจพ เจนเฉˆเฅค เจคเฉเจธเฉ€เจ‚ เจธเจฟเจฐเจซเจผ เจ‡เฉฑเจ• เจ•เจฎเจพเจ‚เจก เจจเจพเจฒ เจชเฉ‚เจฐเฉ€ เจธเจฟเจ–เจฒเจพเจˆ เจชเจพเจˆเจชเจฒเจพเจˆเจจ เจฒเจพเจ‚เจš เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค
  • เจ—เฉ‚เจ—เจฒ เจ•เจฒเจพเจ‰เจก เจฎเจนเจฟเฉฐเจ—เฉ‡ เจนเจพเจฐเจกเจตเฉ‡เจ…เจฐ 'เจคเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ— เจ•เจฐเจจ เจฆเจพ เจ‡เฉฑเจ• เจฌเจœเจŸ-เจ…เจจเฉเจ•เฉ‚เจฒ เจคเจฐเฉ€เจ•เจพ เจนเฉˆ, เจชเจฐ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเฉฐเจฐเจšเจจเจพเจตเจพเจ‚ เจจเฉ‚เฉฐ เจงเจฟเจ†เจจ เจจเจพเจฒ เจšเฉเจฃเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค
  • เจตเจฟเจ…เจ•เจคเฉ€เจ—เจค เจ•เฉ‹เจก เจฆเฉ‡ เจŸเฉเจ•เฉœเจฟเจ†เจ‚ เจฆเฉ€ เจ—เจคเฉ€ เจจเฉ‚เฉฐ เจฎเจพเจชเจฃเจพ เจฌเจนเฉเจค เจฒเจพเจญเจฆเจพเจ‡เจ• เจนเฉˆ, เจ–เจพเจธ เจ•เจฐเจ•เฉ‡ เจœเจฆเฉ‹เจ‚ R เจ…เจคเฉ‡ C++ เจจเฉ‚เฉฐ เจœเฉ‹เฉœเจฆเฉ‡ เจนเฉ‹เจ, เจ…เจคเฉ‡ เจชเฉˆเจ•เฉ‡เจœ เจฆเฉ‡ เจจเจพเจฒ เจฌเฉˆเจ‚เจš - เจ‡เจน เจตเฉ€ เจฌเจนเฉเจค เจ†เจธเจพเจจ.

เจ•เฉเฉฑเจฒ เจฎเจฟเจฒเจพ เจ•เฉ‡ เจ‡เจน เจคเจœเจฐเจฌเจพ เจฌเจนเฉเจค เจฒเจพเจญเจฆเจพเจ‡เจ• เจธเฉ€ เจ…เจคเฉ‡ เจ…เจธเฉ€เจ‚ เจ‰เจ เจพเจ เจ—เจ เจ•เฉเจ เจฎเฉเฉฑเจฆเจฟเจ†เจ‚ เจจเฉ‚เฉฐ เจนเฉฑเจฒ เจ•เจฐเจจ เจฒเจˆ เจ•เฉฐเจฎ เจ•เจฐเจจเจพ เจœเจพเจฐเฉ€ เจฐเฉฑเจ–เจฆเฉ‡ เจนเจพเจ‚เฅค

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹