เดฆเตเดฐเตเดค เดกเตเดฐเต‹ เดกเต‚เดกเดฟเตฝ เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเตฝ: R, C++, เดจเตเดฏเต‚เดฑเตฝ เดจเต†เดฑเตเดฑเตโ€Œเดตเตผเด•เตเด•เตเด•เตพ เดŽเดจเตเดจเดฟเดตเดฏเตเดฎเดพเดฏเดฟ เดŽเด™เตเด™เดจเต† เดšเด™เตเด™เดพเดคเตเดคเด‚ เด•เต‚เดŸเดพเด‚

เดฆเตเดฐเตเดค เดกเตเดฐเต‹ เดกเต‚เดกเดฟเตฝ เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเตฝ: R, C++, เดจเตเดฏเต‚เดฑเตฝ เดจเต†เดฑเตเดฑเตโ€Œเดตเตผเด•เตเด•เตเด•เตพ เดŽเดจเตเดจเดฟเดตเดฏเตเดฎเดพเดฏเดฟ เดŽเด™เตเด™เดจเต† เดšเด™เตเด™เดพเดคเตเดคเด‚ เด•เต‚เดŸเดพเด‚

เดนเต‡ เดนเดฌเตผ!

เด•เดดเดฟเดžเตเดž เดถเดฐเดคเตเด•เดพเดฒเดคเตเดคเดฟเตฝ, เด•เตˆเด•เตŠเดฃเตเดŸเต เดตเดฐเดšเตเดš เดšเดฟเดคเตเดฐเด™เตเด™เตพ, เด•เตเดตเดฟเด•เตเด•เต เดกเตเดฐเต‹ เดกเต‚เดกเดฟเตฝ เดฑเต†เด•เตเด•เด—เตเดจเดฟเดทเตป เดคเดฐเด‚เดคเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด’เดฐเต เดฎเดคเตเดธเดฐเด‚ Kaggle เดธเด‚เด˜เดŸเดฟเดชเตเดชเดฟเดšเตเดšเต, เด…เดคเดฟเตฝ, เดฎเดฑเตเดฑเตเดณเตเดณเดตเดฏเดฟเตฝ, R-เดถเดพเดธเตเดคเตเดฐเดœเตเดžเดฐเตเดŸเต† เด’เดฐเต เดธเด‚เด˜เด‚ เดชเด™เตเด•เต†เดŸเตเดคเตเดคเต: เด†เตผเดŸเต†เด‚ เด•เตเดฒเต†เดตเตเดคเตเดธเต‹เดต, เดซเดฟเดฒเดฟเดชเตเดชเต เดฎเดพเดจเต‡เดœเตผ ะธ เด†เตปเดกเตเดฐเดฟ เด’เด—เตเตผเดŸเตเดŸเตเดธเต‹เดตเต. เดžเด™เตเด™เตพ เดฎเดคเตเดธเดฐเดคเตเดคเต† เดตเดฟเดถเดฆเดฎเดพเดฏเดฟ เดตเดฟเดตเดฐเดฟเด•เตเด•เตเดจเตเดจเดฟเดฒเตเดฒ; เด…เดคเต เด‡เดคเดฟเดจเด•เด‚ เดšเต†เดฏเตเดคเตเด•เดดเดฟเดžเตเดžเต เดธเดฎเต€เดชเด•เดพเดฒ เดชเตเดฐเดธเดฟเดฆเตเดงเต€เด•เดฐเดฃเด‚.

เด‡เดคเตเดคเดตเดฃ เดฎเต†เดกเตฝ เดซเดพเดฎเดฟเด‚เด—เดฟเตฝ เด‡เดคเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดšเตเดšเดฟเดฒเตเดฒ, เดชเด•เตเดทเต‡ เดตเดฟเดฒเดชเตเดชเต†เดŸเตเดŸ เดงเดพเดฐเดพเดณเด‚ เด…เดจเตเดญเดตเด™เตเด™เตพ เดฒเดญเดฟเดšเตเดšเต, เด…เดคเดฟเดจเดพเตฝ เด•เด—เตเดฒเต†เดฏเดฟเดฒเตเด‚ เดฆเตˆเดจเด‚เดฆเดฟเดจ เดœเต‹เดฒเดฟเดฏเดฟเดฒเตเด‚ เดเดฑเตเดฑเดตเตเด‚ เดฐเดธเด•เดฐเดตเตเด‚ เด‰เดชเดฏเต‹เด—เดชเตเดฐเดฆเดตเตเดฎเดพเดฏ เดจเดฟเดฐเดตเดงเดฟ เด•เดพเดฐเตเดฏเด™เตเด™เดณเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเต เดธเดฎเต‚เดนเดคเตเดคเต‹เดŸเต เดชเดฑเดฏเดพเตป เดžเดพเตป เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจเต. เดšเตผเดšเตเดš เดšเต†เดฏเตเดค เดตเดฟเดทเดฏเด™เตเด™เดณเดฟเตฝ: เดฌเตเดฆเตเดงเดฟเดฎเตเดŸเตเดŸเตเดณเตเดณ เดœเต€เดตเดฟเดคเด‚ เด“เดชเตเดชเตบโ€Œเดธเดฟโ€Œเดตเดฟ, JSON เดชเดพเดดเตโ€Œเดธเดฟเด‚เด—เต (เดˆ เด‰เดฆเดพเดนเดฐเดฃเด™เตเด™เตพ R เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดธเตโ€Œเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเดฟเดฒเต‡เด•เตเด•เต‹ เดชเดพเด•เตเด•เต‡เดœเตเด•เดณเดฟเดฒเต‡เด•เตเด•เต‹ C++ เด•เต‹เดกเดฟเดจเตเดฑเต† เดธเด‚เดฏเต‹เดœเดจเด‚ เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เตเดจเตเดจเต Rcpp), เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเตเดŸเต† เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเดฑเตˆเดธเต‡เดทเดจเตเด‚ เด…เดจเตเดคเดฟเดฎ เดชเดฐเดฟเดนเดพเดฐเดคเตเดคเดฟเดจเตเดฑเต† เดกเต‹เด•เตเด•เดฑเตˆเดธเต‡เดทเดจเตเด‚. เดจเดฟเตผเดตเตเดตเดนเดฃเดคเตเดคเดฟเดจเต เด…เดจเตเดฏเต‹เดœเตเดฏเดฎเดพเดฏ เด’เดฐเต เดซเต‹เดฎเดฟเตฝ เดธเดจเตเดฆเต‡เดถเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เดŽเดฒเตเดฒเดพ เด•เต‹เดกเตเด‚ เดฒเดญเตเดฏเดฎเดพเดฃเต เดถเต‡เด–เดฐเด™เตเด™เตพ.

เด‰เดณเตเดณเดŸเด•เตเด•เด‚:

  1. CSV-เดฏเดฟเตฝ เดจเดฟเดจเตเดจเต MonetDB-เดฏเดฟเดฒเต‡เด•เตเด•เต เดกเดพเดฑเตเดฑ เด•เดพเดฐเตเดฏเด•เตเดทเดฎเดฎเดพเดฏเดฟ เดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเด•
  2. เดฌเดพเดšเตเดšเตเด•เตพ เดคเดฏเตเดฏเดพเดฑเดพเด•เตเด•เตเดจเตเดจเต
  3. เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเตฝ เดจเดฟเดจเตเดจเต เดฌเดพเดšเตเดšเตเด•เตพ เด…เตบเดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเดฑเตเด•เตพ
  4. เด’เดฐเต เดฎเต‹เดกเตฝ เด†เตผเด•เตเด•เดฟเดŸเต†เด•เตเดšเตผ เดคเดฟเดฐเดžเตเดžเต†เดŸเตเด•เตเด•เตเดจเตเดจเต
  5. เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเต เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเดฑเตˆเดธเต‡เดทเตป
  6. เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเตเดŸเต† เดกเต‹เด•เตเด•เดฑเตˆเดธเต‡เดทเตป
  7. Google เด•เตเดฒเต—เดกเดฟเตฝ เด’เดจเตเดจเดฟเดฒเดงเดฟเด•เด‚ GPU-เด•เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต
  8. เดชเด•เดฐเด‚ เด’เดฐเต เดจเดฟเด—เดฎเดจเดคเตเดคเดฟเตฝ เดŽเดจเตเดจ

1. MonetDB เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดฒเต‡เด•เตเด•เต CSV-เดฏเดฟเตฝ เดจเดฟเดจเตเดจเต เดกเดพเดฑเตเดฑ เด•เดพเดฐเตเดฏเด•เตเดทเดฎเดฎเดพเดฏเดฟ เดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเด•

เดˆ เดฎเดคเตเดธเดฐเดคเตเดคเดฟเดฒเต† เดกเดพเดฑเตเดฑ เดจเตฝเด•เดฟเดฏเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเดคเต เดฑเต†เดกเดฟเดฎเต†เดฏเตเดกเต เด‡เดฎเต‡เดœเตเด•เดณเตเดŸเต† เดฐเต‚เดชเดคเตเดคเดฟเดฒเดฒเตเดฒ, เดฎเดฑเดฟเดšเตเดšเต เดชเต‹เดฏเดฟเดจเตเดฑเต เด•เต‹เตผเดกเดฟเดจเต‡เดฑเตเดฑเตเด•เดณเตเดณเตเดณ JSON-เด•เตพ เด…เดŸเด™เตเด™เดฟเดฏ 340 CSV เดซเดฏเดฒเตเด•เดณเตเดŸเต† (เด“เดฐเต‹ เด•เตเดฒเดพเดธเดฟเดจเตเด‚ เด’เดฐเต เดซเดฏเตฝ) เดฐเต‚เดชเดคเตเดคเดฟเดฒเดพเดฃเต. เดˆ เดชเต‹เดฏเดฟเดจเตเดฑเตเด•เตพ เดฒเตˆเดจเตเด•เดณเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดฒเต‚เดŸเต†, 256x256 เดชเดฟเด•เตเดธเดฒเตเด•เตพ เด…เดณเด•เตเด•เตเดจเตเดจ เด’เดฐเต เด…เดจเตเดคเดฟเดฎ เดšเดฟเดคเตเดฐเด‚ เดจเดฎเตเด•เตเด•เต เดฒเดญเดฟเด•เตเด•เตเด‚. เด“เดฐเต‹ เดฑเต†เด•เตเด•เต‹เตผเดกเดฟเดจเตเด‚ เดกเดพเดฑเตเดฑเดพเดธเต†เดฑเตเดฑเต เดถเต‡เด–เดฐเดฟเด•เตเด•เตเดจเตเดจ เดธเดฎเดฏเดคเตเดคเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดš เด•เตเดฒเดพเดธเดฟเดซเดฏเตผ เดšเดฟเดคเตเดฐเด‚ เดถเดฐเดฟเดฏเดพเดฏเดฟ เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดžเตเดžเต‹ เดŽเดจเตเดจเต เดธเต‚เดšเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจ เด’เดฐเต เดฒเต‡เดฌเตฝ เด‰เดฃเตเดŸเต, เดšเดฟเดคเตเดฐเดคเตเดคเดฟเดจเตเดฑเต† เดฐเดšเดฏเดฟเดคเดพเดตเต เดคเดพเดฎเดธเดฟเด•เตเด•เตเดจเตเดจ เดฐเดพเดœเตเดฏเดคเตเดคเดฟเดจเตเดฑเต† เดฐเดฃเตเดŸเด•เตเดทเดฐ เด•เต‹เดกเต, เด’เดฐเต เด…เดฆเตเดตเดฟเดคเต€เดฏ เดเดกเดจเตเดฑเดฟเดซเดฏเตผ, เด’เดฐเต เดŸเตˆเด‚เดธเตเดฑเตเดฑเดพเดฎเตเดชเต เดซเดฏเดฒเดฟเดจเตเดฑเต† เดชเต‡เดฐเตเดฎเดพเดฏเดฟ เดชเตŠเดฐเตเดคเตเดคเดชเตเดชเต†เดŸเตเดจเตเดจ เด’เดฐเต เด•เตเดฒเดพเดธเต เดจเดพเดฎเดตเตเด‚. เดฏเดฅเดพเตผเดคเตเดฅ เดกเดพเดฑเตเดฑเดฏเตเดŸเต† เดฒเดณเดฟเดคเดฎเดพเดฏ เดชเดคเดฟเดชเตเดชเต เด†เตผเด•เตเด•เตˆเดตเดฟเตฝ 7.4 GB เดญเดพเดฐเดตเตเด‚ เด…เตบเดชเดพเด•เตเด•เต เดšเต†เดฏเตเดคเดคเดฟเดจเต เดถเต‡เดทเด‚ เดเด•เดฆเต‡เดถเด‚ 20 GB เด†เดฃเต, เด…เตบเดชเดพเด•เตเด•เต เดšเต†เดฏเตเดคเดคเดฟเดจเต เดถเต‡เดทเดฎเตเดณเตเดณ เดฎเตเดดเตเดตเตป เดกเดพเดฑเตเดฑเดฏเตเด‚ 240 GB เดŽเดŸเตเด•เตเด•เตเด‚. เดฐเดฃเตเดŸเต เดชเดคเดฟเดชเตเดชเตเด•เดณเตเด‚ เด’เดฐเต‡ เดกเตเดฐเต‹เดฏเดฟเด‚เด—เตเด•เตพ เดชเตเดจเตผเดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเตเดตเต†เดจเตเดจเต เดธเด‚เด˜เดพเดŸเด•เตผ เด‰เดฑเดชเตเดชเดพเด•เตเด•เดฟ, เด…เดคเดพเดฏเดคเต เดชเต‚เตผเดฃเตเดฃ เดชเดคเดฟเดชเตเดชเต เด…เดจเดพเดตเดถเตเดฏเดฎเดพเดฃเต. เดเดคเดพเดฏเดพเดฒเตเด‚, เด—เตเดฐเดพเดซเดฟเด•เต เดซเดฏเดฒเตเด•เดณเดฟเดฒเต‹ เด…เดฑเต‡เด•เดณเตเดŸเต† เดฐเต‚เดชเดคเตเดคเดฟเดฒเต‹ 50 เดฆเดถเดฒเด•เตเดทเด‚ เดšเดฟเดคเตเดฐเด™เตเด™เตพ เดธเด‚เดญเดฐเดฟเด•เตเด•เตเดจเตเดจเดคเต เดฒเดพเดญเด•เดฐเดฎเดฒเตเดฒเต†เดจเตเดจเต เด‰เดŸเดจเดŸเดฟ เดชเดฐเดฟเด—เดฃเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดŸเต, เด•เต‚เดŸเดพเดคเต† เดŽเดฒเตเดฒเดพ CSV เดซเดฏเดฒเตเด•เดณเตเด‚ เด†เตผเด•เตเด•เตˆเดตเดฟเตฝ เดจเดฟเดจเตเดจเต เดฒเดฏเดฟเดชเตเดชเดฟเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เดคเต€เดฐเตเดฎเดพเดจเดฟเดšเตเดšเต. train_simplified.zip เด“เดฐเต‹ เดฌเดพเดšเตเดšเดฟเดจเตเด‚ เด†เดตเดถเตเดฏเดฎเดพเดฏ เดตเดฒเตเดชเตเดชเดคเตเดคเดฟเดฒเตเดณเตเดณ "เด“เตบ เดฆเดฟ เดซเตเดฒเตˆ" เด‡เดฎเต‡เดœเตเด•เดณเตเดŸเต† เดคเตเดŸเตผเดจเตเดจเตเดณเตเดณ เดคเดฒเดฎเตเดฑเด•เดณเตเดณเตเดณ เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดฒเต‡เด•เตเด•เต.

เดจเดจเตเดจเดพเดฏเดฟ เดคเต†เดณเดฟเดฏเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดŸ เด’เดฐเต เดธเด‚เดตเดฟเดงเดพเดจเด‚ เดกเดฟเดฌเดฟเดŽเด‚เดŽเดธเดพเดฏเดฟ เดคเดฟเดฐเดžเตเดžเต†เดŸเตเดคเตเดคเต เดฎเต‹เดจเต†เดฑเตเดฑเตเดกเดฟเดฌเดฟ, เด…เดคเดพเดฏเดคเต R เด’เดฐเต เดชเดพเด•เตเด•เต‡เดœเดพเดฏเดฟ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตฝ MonetDBLite. เดชเดพเด•เตเด•เต‡เดœเดฟเตฝ เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเต เดธเต†เตผเดตเดฑเดฟเดจเตเดฑเต† เด’เดฐเต เด‰เตพเดšเตเดšเต‡เตผเดคเตเดค เดชเดคเดฟเดชเตเดชเต เด‰เตพเดชเตเดชเต†เดŸเตเดจเตเดจเต เด•เต‚เดŸเดพเดคเต† เด’เดฐเต R เดธเต†เดทเดจเดฟเตฝ เดจเดฟเดจเตเดจเต เดจเต‡เดฐเดฟเดŸเตเดŸเต เดธเต†เตผเดตเตผ เดŽเดŸเตเดคเตเดคเต เด…เดตเดฟเดŸเต† เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต. เด’เดฐเต เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเต เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจเดคเตเด‚ เด…เดคเดฟเดฒเต‡เด•เตเด•เต เด•เดฃเด•เตเดฑเตเดฑเตเดšเต†เดฏเตเดฏเตเดจเตเดจเดคเตเด‚ เด’เดฐเต เด•เดฎเดพเตปเดกเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดจเดŸเดคเตเดคเตเดจเตเดจเต:

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

เดžเด™เตเด™เตพเด•เตเด•เต เดฐเดฃเตเดŸเต เดชเดŸเตเดŸเดฟเด•เด•เตพ เดธเตƒเดทเตโ€ŒเดŸเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต: เด’เดจเตเดจเต เดŽเดฒเตเดฒเดพ เดกเดพเดฑเตเดฑเดฏเตโ€Œเด•เตเด•เตเด‚, เดฎเดฑเตเดฑเตŠเดจเตเดจเต เดกเต—เตบเดฒเต‹เดกเต เดšเต†เดฏเตโ€Œเดค เดซเดฏเดฒเตเด•เดณเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดธเต‡เดตเดจ เดตเดฟเดตเดฐเด™เตเด™เตพเด•เตเด•เตเด‚ (เดŽเดจเตเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เดคเต†เดฑเตเดฑเต เดธเด‚เดญเดตเดฟเดšเตเดšเดพเตฝ เด‰เดชเดฏเต‹เด—เดชเตเดฐเดฆเดฎเดพเดฃเต เด•เต‚เดŸเดพเดคเต† เดจเดฟเดฐเดตเดงเดฟ เดซเดฏเดฒเตเด•เตพ เดกเต—เตบเดฒเต‹เดกเต เดšเต†เดฏเตโ€Œเดคเดคเดฟเดจเต เดถเต‡เดทเด‚ เดชเตเดฐเด•เตเดฐเดฟเดฏ เดชเตเดจเดฐเดพเดฐเด‚เดญเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต):

เดชเดŸเตเดŸเดฟเด•เด•เตพ เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจเต

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

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

SQL - เด•เดฎเดพเตปเดกเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต CSV เดซเดฏเดฒเตเด•เตพ เดจเต‡เดฐเดฟเดŸเตเดŸเต เดชเด•เตผเดคเตเดคเตเด• เดŽเดจเตเดจเดคเดพเดฃเต เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดฒเต‡เด•เตเด•เต เดกเดพเดฑเตเดฑ เดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดเดฑเตเดฑเดตเตเด‚ เดตเต‡เด—เดคเดฏเต‡เดฑเดฟเดฏ เดฎเดพเตผเด—เด‚. COPY OFFSET 2 INTO tablename FROM path USING DELIMITERS ',','n','"' NULL AS '' BEST EFFORTเดŽเดตเดฟเดŸเต† tablename - เดชเดŸเตเดŸเดฟเด•เดฏเตเดŸเต† เดชเต‡เดฐเต เด’เดชเตเดชเด‚ path - เดซเดฏเดฒเดฟเดฒเต‡เด•เตเด•เตเดณเตเดณ เดชเดพเดค. เด†เตผเด•เตเด•เตˆเดตเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เดฌเดฟเตฝเดฑเตเดฑเต-เด‡เตป เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตฝ เด•เดฃเตเดŸเต†เดคเตเดคเดฟ unzip เด†เตผเด•เตเด•เตˆเดตเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เดจเดฟเดฐเดตเดงเดฟ เดซเดฏเดฒเตเด•เดณเดฟเตฝ R เดถเดฐเดฟเดฏเดพเดฏเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเดฟเดฒเตเดฒ, เด…เดคเดฟเดจเดพเตฝ เดžเด™เตเด™เตพ เดธเดฟเดธเตเดฑเตเดฑเด‚ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต unzip (เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเตผ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต getOption("unzip")).

เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดฒเต‡เด•เตเด•เต เดŽเดดเตเดคเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดชเตเดฐเดตเตผเดคเตเดคเดจเด‚

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

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

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

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

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

  return(invisible(TRUE))
}

เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดฒเต‡เด•เตเด•เต เดŽเดดเตเดคเตเดจเตเดจเดคเดฟเดจเตเดฎเตเดฎเตเดชเต เดชเดŸเตเดŸเดฟเด• เดฐเต‚เดชเดพเดจเตเดคเดฐเดชเตเดชเต†เดŸเตเดคเตเดคเดฃเดฎเต†เด™เตเด•เดฟเตฝ, เด†เตผเด—เตเดฏเตเดฎเต†เดจเตเดฑเดฟเตฝ เดชเดพเดธเตเดธเดพเด•เตเด•เดฟเดฏเดพเตฝ เดฎเดคเดฟ preprocess เดกเดพเดฑเตเดฑ เดฐเต‚เดชเดพเดจเตเดคเดฐเดชเตเดชเต†เดŸเตเดคเตเดคเตเดจเตเดจ เดชเตเดฐเดตเตผเดคเตเดคเดจเด‚.

เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดฒเต‡เด•เตเด•เต เดคเตเดŸเตผเดšเตเดšเดฏเดพเดฏเดฟ เดกเดพเดฑเตเดฑ เดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด•เต‹เดกเต:

เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดฒเต‡เด•เตเด•เต เดกเดพเดฑเตเดฑ เดŽเดดเตเดคเตเดจเตเดจเต

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

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

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

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

เด‰เดชเดฏเต‹เด—เดฟเดšเตเดš เดกเตเดฐเตˆเดตเดฟเดจเตเดฑเต† เดธเตเดชเต€เดกเต เดธเดตเดฟเดถเต‡เดทเดคเด•เดณเต† เด†เดถเตเดฐเดฏเดฟเดšเตเดšเต เดกเดพเดฑเตเดฑ เดฒเต‹เดกเดฟเด‚เด—เต เดธเดฎเดฏเด‚ เดตเตเดฏเดคเตเดฏเดพเดธเดชเตเดชเต†เดŸเดพเด‚. เดžเด™เตเด™เดณเตเดŸเต† เด•เดพเดฐเตเดฏเดคเตเดคเดฟเตฝ, เด’เดฐเต เดŽเดธเตเดŽเดธเตเดกเดฟเดฏเดฟเตฝ เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เด’เดฐเต เดซเตเดฒเดพเดทเต เดกเตเดฐเตˆเดตเดฟเตฝ (เดธเต‹เดดเตเดธเต เดซเดฏเตฝ) เดจเดฟเดจเตเดจเต เด’เดฐเต เดŽเดธเตเดŽเดธเตเดกเดฟเดฏเดฟเดฒเต‡เด•เตเด•เต (เดกเดฟเดฌเดฟ) เดตเดพเดฏเดฟเด•เตเด•เดพเดจเตเด‚ เดŽเดดเตเดคเดพเดจเตเด‚ 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 เดคเดจเตเดคเตเดฐเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต. เดจเดฟเดฐเต€เด•เตเดทเดฃ เดเดกเดฟ เดธเด‚เดญเดฐเดฟเด•เตเด•เตเดจเตเดจ เดคเดฐเดคเตเดคเดฟเดจเตเดฑเต† เด…เดณเดตเต เด•เตเดฑเดฏเตเด•เตเด•เตเด• เดŽเดจเตเดจเดคเดพเดฏเดฟเดฐเตเดจเตเดจเต เด†เดฆเตเดฏเดคเตเดคเต‡เดคเต. เดฏเดฅเดพเตผเดคเตเดฅ เดกเดพเดฑเตเดฑเดพ เดธเต†เดฑเตเดฑเดฟเตฝ, เดเดกเดฟ เดธเด‚เดญเดฐเดฟเด•เตเด•เดพเตป เด†เดตเดถเตเดฏเดฎเดพเดฏ เดคเดฐเด‚ bigint, เดŽเดจเตเดจเดพเตฝ เดจเดฟเดฐเต€เด•เตเดทเดฃเด™เตเด™เดณเตเดŸเต† เดŽเดฃเตเดฃเด‚ เด…เดตเดฏเตเดŸเต† เดเดกเดจเตเดฑเดฟเดซเดฏเดฑเตเด•เตพ, เด“เตผเดกเดฟเดจเตฝ เดจเดฎเตเดชเดฑเดฟเดจเต เดคเตเดฒเตเดฏเดฎเดพเดฏ เดคเดฐเดคเตเดคเดฟเดฒเต‡เด•เตเด•เต เด˜เดŸเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเต เดธเดพเดงเตเดฏเดฎเดพเด•เตเด•เตเดจเตเดจเต. int. เดˆ เดธเดพเดนเดšเดฐเตเดฏเดคเตเดคเดฟเตฝ เดคเดฟเดฐเดšเตเดšเดฟเตฝ เดตเดณเดฐเต† เดตเต‡เด—เดคเตเดคเดฟเดฒเดพเดฃเต. เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต† เดคเดจเตเดคเตเดฐเด‚ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด•เดฏเดพเดฏเดฟเดฐเตเดจเตเดจเต ORDERED INDEX - เดฒเดญเตเดฏเดฎเดพเดฏ เดŽเดฒเตเดฒเดพ เด•เดพเดฐเตเดฏเด™เตเด™เดณเดฟเดฒเต‚เดŸเต†เดฏเตเด‚ เดžเด™เตเด™เตพ เด…เดจเตเดญเดตเดชเดฐเดฎเดพเดฏเดฟ เดˆ เดคเต€เดฐเตเดฎเดพเดจเดคเตเดคเดฟเดฒเต†เดคเตเดคเดฟ ะฒะฐั€ะธะฐะฝั‚ั‹. เดฎเต‚เดจเตเดจเดพเดฎเดคเตเดคเต‡เดคเต เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเตผ เดšเต†เดฏเตเดค เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเดคเดพเดฏเดฟเดฐเตเดจเตเดจเต. เด•เดฎเดพเตปเดกเต เด’เดฐเดฟเด•เตเด•เตฝ เดŽเด•เตเดธเดฟเด•เตเดฏเต‚เดŸเตเดŸเต เดšเต†เดฏเตเดฏเตเด• เดŽเดจเตเดจเดคเดพเดฃเต เดฐเต€เดคเดฟเดฏเตเดŸเต† เดธเดพเดฐเด‚ PREPARE เด’เดฐเต‡ เดคเดฐเดคเตเดคเดฟเดฒเตเดณเตเดณ เด’เดฐเต เด•เต‚เดŸเตเดŸเด‚ เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพ เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ เดคเดฏเตเดฏเดพเดฑเดพเด•เตเด•เดฟเดฏ เด’เดฐเต เดชเดฆเดชเตเดฐเดฏเต‹เด—เดคเตเดคเดฟเดจเตเดฑเต† เดคเตเดŸเตผเดจเตเดจเตเดณเตเดณ เด‰เดชเดฏเต‹เด—เดคเตเดคเดฟเดฒเต‚เดŸเต†, เดŽเดจเตเดจเดพเตฝ เดตเดพเดธเตเดคเดตเดคเตเดคเดฟเตฝ เดฒเดณเดฟเดคเดฎเดพเดฏ เด’เดจเตเดจเตเดฎเดพเดฏเดฟ เดคเดพเดฐเดคเดฎเตเดฏเดชเตเดชเต†เดŸเตเดคเตเดคเตเดฎเตเดชเต‹เตพ เด’เดฐเต เดจเต‡เดŸเตเดŸเดฎเตเดฃเตเดŸเต SELECT เดธเตเดฅเดฟเดคเดฟเดตเดฟเดตเดฐเด•เตเด•เดฃเด•เตเด•เต เดชเดฟเดถเด•เดฟเดจเตเดฑเต† เดชเดฐเดฟเดงเดฟเด•เตเด•เตเดณเตเดณเดฟเดฒเดพเดฃเต†เดจเตเดจเต เดคเต†เดณเดฟเดžเตเดžเต.

เดกเดพเดฑเตเดฑ เด…เดชเตโ€Œเดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเดจเตเดจ เดชเตเดฐเด•เตเดฐเดฟเดฏเดฏเตเด•เตเด•เต 450 MB เดฑเดพเดฎเดฟเตฝ เด•เต‚เดŸเตเดคเตฝ เด†เดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ. เด…เดคเดพเดฏเดคเต, เดตเดฟเดตเดฐเดฟเดšเตเดš เดธเดฎเต€เดชเดจเด‚, เดšเดฟเดฒ เดธเดฟเด‚เด—เดฟเตพ เดฌเต‹เตผเดกเต เด‰เดชเด•เดฐเดฃเด™เตเด™เตพ เด‰เตพเดชเตเดชเต†เดŸเต†, เดเดคเดพเดฃเตเดŸเต เดเดคเต เดฌเดœเดฑเตเดฑเต เดนเดพเตผเดกเตโ€Œเดตเต†เดฏเดฑเดฟเดฒเตเด‚ เดชเดคเดฟเดจเดพเดฏเดฟเดฐเด•เตเด•เดฃเด•เตเด•เดฟเดจเต เดœเดฟเด—เดพเดฌเตˆเดฑเตเดฑเต เดญเดพเดฐเดฎเตเดณเตเดณ เดกเดพเดฑเตเดฑเดพเดธเต†เดฑเตเดฑเตเด•เตพ เดจเต€เด•เตเด•เดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต, เด…เดคเต เดตเดณเดฐเต† เดฐเดธเด•เดฐเดฎเดพเดฃเต.

เดตเตเดฏเดคเตเดฏเดธเตโ€Œเดค เดตเดฒเตเดชเตเดชเดคเตเดคเดฟเดฒเตเดณเตเดณ เดฌเดพเดšเตเดšเตเด•เตพ เดธเดพเดฎเตเดชเดฟเตพ เดšเต†เดฏเตเดฏเตเดฎเตเดชเต‹เตพ (เดฑเดพเตปเดกเด‚) เดกเดพเดฑเตเดฑ เดตเต€เดฃเตเดŸเต†เดŸเตเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดฑเต† เดตเต‡เด—เดค เด…เดณเด•เตเด•เตเด•เดฏเตเด‚ เดธเตเด•เต†เดฏเดฟเดฒเดฟเด‚เด—เต เดตเดฟเดฒเดฏเดฟเดฐเตเดคเตเดคเตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเด• เดฎเดพเดคเตเดฐเดฎเดพเดฃเต เด…เดตเดถเต‡เดทเดฟเด•เตเด•เตเดจเตเดจเดคเต:

เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเต เดฌเต†เดžเตเดšเตเดฎเดพเตผเด•เตเด•เต

library(ggplot2)

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

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

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

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

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

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

DBI::dbDisconnect(con, shutdown = TRUE)

เดฆเตเดฐเตเดค เดกเตเดฐเต‹ เดกเต‚เดกเดฟเตฝ เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเตฝ: 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 เดŸเต‚เดณเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดกเตเดฐเต‹เดฏเดฟเด‚เด—เต เดจเดŸเดคเตเดคเตเด•เดฏเตเด‚ เดฑเดพเดฎเดฟเตฝ เดธเด‚เดญเดฐเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจ เด’เดฐเต เดคเดพเตฝเด•เตเด•เดพเดฒเดฟเด• PNG-เดฒเต‡เด•เตเด•เต เดธเด‚เดฐเด•เตเดทเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต (เดฒเดฟเดจเด•เตเดธเดฟเตฝ, เดคเดพเตฝเด•เตเด•เดพเดฒเดฟเด• R เดกเดฏเดฑเด•เตเดŸเดฑเดฟเด•เตพ เดกเดฏเดฑเด•เตเดŸเดฑเดฟเดฏเดฟเตฝ เดธเตเดฅเดฟเดคเดฟเดšเต†เดฏเตเดฏเตเดจเตเดจเต. /tmp, เดฑเดพเดฎเดฟเตฝ เด˜เดŸเดฟเดชเตเดชเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต). เดˆ เดซเดฏเตฝ เดชเดฟเดจเตเดจเต€เดŸเต 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 เด•เต‹เดกเดฟเดฒเต‡เด•เตเด•เต เดธเด‚เดฏเต‹เดœเดฟเดชเตเดชเดฟเดšเตเดšเต Rcpp.

เดชเตเดฐเดถเตเดจเด‚ เดชเดฐเดฟเดนเดฐเดฟเด•เตเด•เดพเตป, เด‡เดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เดชเดพเด•เตเด•เต‡เดœเตเด•เดณเตเด‚ เดฒเตˆเดฌเตเดฐเดฑเดฟเด•เดณเตเด‚ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต:

  1. เด“เดชเตเดชเตบโ€Œเดธเดฟโ€Œเดตเดฟ เดšเดฟเดคเตเดฐเด™เตเด™เดณเตเด‚ เดตเดฐเด•เดณเตเด‚ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เดพเตป. เดฎเตเตปเด•เต‚เดŸเตเดŸเดฟ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดค เดธเดฟเดธเตเดฑเตเดฑเด‚ เดฒเตˆเดฌเตเดฐเดฑเดฟเด•เดณเตเด‚ เดนเต†เดกเตผ เดซเดฏเดฒเตเด•เดณเตเด‚ เดกเตˆเดจเดพเดฎเดฟเด•เต เดฒเดฟเด™เตเด•เดฟเด‚เด—เตเด‚ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต.

  2. เดŽเด•เตเดธเตเดฑเตเดฑเตปเดธเตผ เดฎเตพเดŸเตเดŸเดฟเดกเตˆเดฎเตปเดทเดฃเตฝ เด…เดฑเต‡เด•เดณเตเด‚ เดŸเต†เตปเดธเดฑเตเด•เดณเตเด‚ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต. เด…เดคเต‡ เดชเต‡เดฐเดฟเดฒเตเดณเตเดณ R เดชเดพเด•เตเด•เต‡เดœเดฟเตฝ เด‰เตพเดชเตเดชเต†เดŸเตเดคเตเดคเดฟเดฏเดฟเดŸเตเดŸเตเดณเตเดณ เดนเต†เดกเตผ เดซเดฏเดฒเตเด•เตพ เดžเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต. เดตเดฐเดฟ เดฎเต‡เดœเตผ, เด•เต‹เดณเด‚ เดฎเต‡เดœเตผ เด•เตเดฐเดฎเดคเตเดคเดฟเตฝ เดฎเตพเดŸเตเดŸเดฟเดกเตˆเดฎเตปเดทเดฃเตฝ เด…เดฑเต‡เด•เตพเด•เตเด•เตŠเดชเตเดชเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เดพเตป เดฒเตˆเดฌเตเดฐเดฑเดฟ เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต.

  3. ndjson JSON เดชเดพเดดเตโ€Œเดธเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต. เดˆ เดฒเตˆเดฌเตเดฐเดฑเดฟ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต เดŽเด•เตเดธเตเดฑเตเดฑเตปเดธเตผ เด…เดคเต เดชเตเดฐเต‹เดœเด•เตเดฑเตเดฑเดฟเตฝ เด‰เดฃเตเดŸเต†เด™เตเด•เดฟเตฝ เดธเตเดตเดฏเดฎเต‡เดต.

  4. RcppThread JSON-เตฝ เดจเดฟเดจเตเดจเต เดตเต†เด•เตโ€ŒเดŸเดฑเดฟเดจเตเดฑเต† เดฎเตพเดŸเตเดŸเดฟ-เดคเตเดฐเต†เดกเต เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เต เดธเด‚เด˜เดŸเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต. เดˆ เดชเดพเด•เตเด•เต‡เดœเต เดจเตฝเด•เตเดจเตเดจ เดนเต†เดกเตผ เดซเดฏเดฒเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต. เด•เต‚เดŸเตเดคเตฝ เดœเดจเดชเตเดฐเดฟเดฏเดฎเดพเดฏเดคเดฟเตฝ เดจเดฟเดจเตเดจเต RcppParallel เดชเดพเด•เตเด•เต‡เดœเดฟเดจเต, เดฎเดฑเตเดฑเต เด•เดพเดฐเตเดฏเด™เตเด™เตพเด•เตเด•เตŠเดชเตเดชเด‚, เด’เดฐเต เดฌเดฟเตฝเดฑเตเดฑเต-เด‡เตป เดฒเต‚เดชเตเดชเต เด‡เดจเตเดฑเดฑเดชเตเดฑเตเดฑเต เดฎเต†เด•เตเด•เดพเดจเดฟเดธเดฎเตเดฃเตเดŸเต.

เด…เดคเต เดถเตเดฐเดฆเตเดงเต‡เดฏเดฎเดพเดฃเต เดŽเด•เตเดธเตเดฑเตเดฑเตปเดธเตผ เด’เดฐเต เดฆเตˆเดตเดพเดจเตเด—เตเดฐเดนเดฎเดพเดฏเดฟ เดฎเดพเดฑเดฟ: เด‡เดคเดฟเดจเต เดตเดฟเดชเตเดฒเดฎเดพเดฏ เดชเตเดฐเดตเตผเดคเตเดคเดจเด•เตเดทเดฎเดคเดฏเตเด‚ เด‰เดฏเตผเดจเตเดจ เดชเตเดฐเด•เดŸเดจเดตเตเดฎเตเดฃเตเดŸเต เดŽเดจเตเดจเดคเดฟเดจเต เดชเตเดฑเดฎเต‡, เด…เดคเดฟเดจเตเดฑเต† เดกเดตเดฒเดชเตเดชเตผเดฎเดพเตผ เดคเดฟเด•เดšเตเดšเตเด‚ เดชเตเดฐเดคเดฟเด•เดฐเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต‹เดฆเตเดฏเด™เตเด™เตพเด•เตเด•เต เด‰เดŸเดจเดŸเดฟ เดตเดฟเดถเดฆเดฎเดพเดฏเตเด‚ เด‰เดคเตเดคเดฐเด‚ เดจเตฝเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดคเต. เด…เดตเดฐเตเดŸเต† เดธเดนเดพเดฏเดคเตเดคเต‹เดŸเต†, เด“เดชเตเดชเตบเดธเดฟเดตเดฟ เดฎเต†เดŸเตเดฐเดฟเด•เตเดธเตเด•เดณเต† เดŽเด•เตโ€Œเดธเตโ€ŒเดŸเต†เตปเดธเตผ เดŸเต†เตปเดธเดฑเตเด•เดณเดพเดฏเดฟ เดชเดฐเดฟเดตเตผเดคเตเดคเดจเด‚ เดšเต†เดฏเตเดฏเดพเดจเตเด‚ 3-เดกเตˆเดฎเตปเดทเดฃเตฝ เด‡เดฎเต‡เดœเต เดŸเต†เตปเดธเดฑเตเด•เดณเต† เดถเดฐเดฟเดฏเดพเดฏ เด…เดณเดตเดฟเดจเตเดฑเต† (เดฌเดพเดšเตเดšเต เดคเดจเตเดจเต†) 4-เดกเตˆเดฎเตปเดทเดฃเตฝ เดŸเต†เตปเดธเดฑเดฟเดฒเต‡เด•เตเด•เต เดธเด‚เดฏเต‹เดœเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด’เดฐเต เดฎเดพเตผเด—เดตเตเด‚ เดธเดพเดงเตเดฏเดฎเดพเดฏเดฟ.

Rcpp, xtensor, RcppThread เดŽเดจเตเดจเดฟเดต เดชเด เดฟเด•เตเด•เดพเดจเตเดณเตเดณ เดธเดพเดฎเด—เตเดฐเดฟเด•เตพ

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

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

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

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

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

เดธเดฟเดธเตเดฑเตเดฑเด‚ เดซเดฏเดฒเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจ เดซเดฏเดฒเตเด•เตพ เด•เด‚เดชเตˆเตฝ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเด‚ เดธเดฟเดธเตเดฑเตเดฑเดคเตเดคเดฟเตฝ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดคเดฟเดŸเตเดŸเตเดณเตเดณ เดฒเตˆเดฌเตเดฐเดฑเดฟเด•เดณเตเดฎเดพเดฏเตเดณเตเดณ เดกเตˆเดจเดพเดฎเดฟเด•เต เดฒเดฟเด™เตเด•เดฟเด‚เด—เดฟเดจเตเด‚ เดžเด™เตเด™เตพ เดชเดพเด•เตเด•เต‡เดœเดฟเตฝ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เดฟเดฏ เดชเตเดฒเด—เดฟเตป เดฎเต†เด•เตเด•เดพเดจเดฟเดธเด‚ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต. Rcpp. เดชเดพเดคเด•เดณเตเด‚ เดซเตเดฒเดพเด—เตเด•เดณเตเด‚ เดธเตเดตเดฏเดฎเต‡เดต เด•เดฃเตเดŸเต†เดคเตเดคเตเดจเตเดจเดคเดฟเดจเต, เดžเด™เตเด™เตพ เด’เดฐเต เดœเดจเดชเตเดฐเดฟเดฏ Linux เดฏเต‚เดŸเตเดŸเดฟเดฒเดฟเดฑเตเดฑเดฟ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต pkg-config.

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 เดจเดฟเดจเตเดจเต เดฑเดฟเดชเตเดชเต‹เดธเดฟเดฑเตเดฑเต‹เดฑเดฟเดฏ. เด•เต‹เดกเต เดจเดฟเดฐเดตเดงเดฟ เดซเด‚เด—เตเดทเดจเตเด•เดณเดพเดฏเดฟ เดคเดฟเดฐเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต:

  • 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. เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเตฝ เดจเดฟเดจเตเดจเต เดฌเดพเดšเตเดšเตเด•เตพ เด…เตบเดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเดฑเตเด•เตพ

RAM-เตฝ เดฏเต‹เดœเดฟเดšเตเดš เดกเดพเดฑเตเดฑ เดชเตเดฐเต‹เดธเดธเตเดธเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเตฝ R-เดจเต เด…เตผเดนเดฎเดพเดฏ เดชเตเดฐเดถเดธเตเดคเดฟ เด‰เดฃเตเดŸเต, เด…เดคเต‡เดธเดฎเดฏเด‚ เดชเตˆเดคเตเดคเดฃเดฟเดจเต เด†เดตเตผเดคเตเดคเดจ เดกเดพเดฑเตเดฑเดพ เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เดพเดฃเต เด•เต‚เดŸเตเดคเตฝ เดธเดตเดฟเดถเต‡เดทเดค, เด‡เดคเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด”เดŸเตเดŸเต-เด“เดซเต-เด•เต‹เตผ เด•เดฃเด•เตเด•เตเด•เต‚เดŸเตเดŸเดฒเตเด•เตพ (เดฌเดพเดนเตเดฏ เดฎเต†เดฎเตเดฎเดฑเดฟ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเตเดณเตเดณ เด•เดฃเด•เตเด•เตเด•เต‚เดŸเตเดŸเดฒเตเด•เตพ) เดŽเดณเตเดชเตเดชเดคเตเดคเดฟเดฒเตเด‚ เดธเตเดตเดพเดญเดพเดตเดฟเด•เดฎเดพเดฏเตเด‚ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เดพเตป เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต. เดตเดฟเดตเดฐเดฟเดšเตเดš เดชเตเดฐเดถเตเดจเดคเตเดคเดฟเดจเตเดฑเต† เดชเดถเตเดšเดพเดคเตเดคเดฒเดคเตเดคเดฟเตฝ เดžเด™เตเด™เตพเด•เตเด•เต เด’เดฐเต เดฎเดฟเด•เดšเตเดšเดคเตเด‚ เดชเตเดฐเดธเด•เตเดคเดตเตเดฎเดพเดฏ เด‰เดฆเดพเดนเดฐเดฃเด‚ เด—เตเดฐเต‡เดกเดฟเดฏเดจเตเดฑเต เดกเดฟเดธเต†เดจเตเดฑเต เดฐเต€เดคเดฟ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดชเดฐเดฟเดถเต€เดฒเดฟเดชเตเดชเดฟเดšเตเดš เด†เดดเดคเตเดคเดฟเดฒเตเดณเตเดณ เดจเตเดฏเต‚เดฑเตฝ เดจเต†เดฑเตเดฑเตโ€Œเดตเตผเด•เตเด•เตเด•เดณเดพเดฃเต, เด“เดฐเต‹ เด˜เดŸเตเดŸเดคเตเดคเดฟเดฒเตเด‚ เด—เตเดฐเต‡เดกเดฟเดฏเดจเตเดฑเดฟเดจเตเดฑเต† เดเด•เดฆเต‡เดถ เด•เดฃเด•เตเด•เต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดจเดฟเดฐเต€เด•เตเดทเดฃเด™เตเด™เดณเตเดŸเต† เด’เดฐเต เดšเต†เดฑเดฟเดฏ เดญเดพเด—เด‚ เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เดฎเดฟเดจเดฟ-เดฌเดพเดšเตเดšเต.

เดชเตˆเดคเตเดคเดฃเดฟเตฝ เดŽเดดเตเดคเดฟเดฏ เด†เดดเดคเตเดคเดฟเดฒเตเดณเตเดณ เดชเด เดจ เดšเดŸเตเดŸเด•เตเด•เต‚เดŸเตเด•เตพเด•เตเด•เต เดกเดพเดฑเตเดฑเดฏเต† เด…เดŸเดฟเดธเตเดฅเดพเดจเดฎเดพเด•เตเด•เดฟเดฏเตเดณเตเดณ เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเดฑเตเด•เตพ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตเดจเตเดจ เดชเตเดฐเดคเตเดฏเต‡เด• เด•เตเดฒเดพเดธเตเด•เตพ เด‰เดฃเตเดŸเต: เดชเดŸเตเดŸเดฟเด•เด•เตพ, เดซเต‹เตพเดกเดฑเตเด•เดณเดฟเดฒเต† เดšเดฟเดคเตเดฐเด™เตเด™เตพ, เดฌเตˆเดจเดฑเดฟ เดซเต‹เตผเดฎเดพเดฑเตเดฑเตเด•เตพ เดฎเตเดคเดฒเดพเดฏเดต. เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดฑเต†เดกเดฟเดฎเต†เดฏเตเดกเต เด“เดชเตเดทเดจเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเด‚ เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เดจเดฟเตผเดฆเตเดฆเดฟเดทเตเดŸ เดœเต‹เดฒเดฟเด•เตพเด•เตเด•เดพเดฏเดฟ เดธเตเดตเดจเตเดคเดฎเดพเดฏเดฟ เดŽเดดเตเดคเดพเด‚. R-เตฝ เดจเดฎเตเด•เตเด•เต เดชเตˆเดคเตเดคเตบ เดฒเตˆเดฌเตเดฐเดฑเดฟเดฏเตเดŸเต† เดŽเดฒเตเดฒเดพ เดธเดตเดฟเดถเต‡เดทเดคเด•เดณเตเด‚ เดชเตเดฐเดฏเต‹เดœเดจเดชเตเดชเต†เดŸเตเดคเตเดคเดพเด‚ keras เด…เดคเต‡ เดชเต‡เดฐเดฟเดฒเตเดณเตเดณ เดชเดพเด•เตเด•เต‡เดœเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด…เดคเดฟเดจเตเดฑเต† เดตเดฟเดตเดฟเดง เดฌเดพเด•เตเด•เต†เตปเดกเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต, เด…เดคเต เดชเดพเด•เตเด•เต‡เดœเดฟเดจเตเดฑเต† เดฎเตเด•เดณเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต เดœเดพเดฒเดฟเด•. เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต‡เดคเต เด’เดฐเต เดชเตเดฐเดคเตเดฏเต‡เด• เดจเต€เดฃเตเดŸ เดฒเต‡เด–เดจเด‚ เด…เตผเดนเดฟเด•เตเด•เตเดจเตเดจเต; R-เตฝ เดจเดฟเดจเตเดจเต เดชเตˆเดคเตเดคเตบ เด•เต‹เดกเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เดพเตป เด‡เดคเต เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเด• เดฎเดพเดคเตเดฐเดฎเดฒเตเดฒ, R, Python เดธเต†เดทเดจเตเด•เตพเด•เตเด•เดฟเดŸเดฏเดฟเตฝ เด’เดฌเตเดœเด•เตเดฑเตเดฑเตเด•เตพ เด•เตˆเดฎเดพเดฑเดพเดจเตเด‚ เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต, เด†เดตเดถเตเดฏเดฎเดพเดฏ เดŽเดฒเตเดฒเดพ เดคเดฐเด‚ เดชเดฐเดฟเดตเตผเดคเตเดคเดจเด™เตเด™เดณเตเด‚ เดธเตเดตเดฏเดฎเต‡เดต เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตเดจเตเดจเต.

MonetDBLite เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดŽเดฒเตเดฒเดพ เดกเดพเดฑเตเดฑเดฏเตเด‚ เดฑเดพเดฎเดฟเตฝ เดธเด‚เดญเดฐเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเดฟเดจเตเดฑเต† เด†เดตเดถเตเดฏเด•เดค เดžเด™เตเด™เตพ เด’เดดเดฟเดตเดพเด•เตเด•เดฟ, เดŽเดฒเตเดฒเดพ "เดจเตเดฏเต‚เดฑเตฝ เดจเต†เดฑเตเดฑเตโ€Œเดตเตผเด•เตเด•เต" เดœเต‹เดฒเดฟเด•เดณเตเด‚ เดชเตˆเดคเตเดคเดฃเดฟเดฒเต† เด’เดฑเดฟเดœเดฟเดจเตฝ เด•เต‹เดกเต เดฎเตเด–เต‡เดจ เดจเดฟเตผเดตเตเดตเดนเดฟเด•เตเด•เตเด‚, เด’เดจเตเดจเตเด‚ เดคเดฏเตเดฏเดพเดฑเดฒเตเดฒเดพเดคเตเดคเดคเดฟเดจเดพเตฝ เดžเด™เตเด™เตพ เดกเดพเดฑเตเดฑเดฏเตเด•เตเด•เต เดฎเตเด•เดณเดฟเตฝ เด’เดฐเต เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเตผ เดŽเดดเตเดคเต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต. R เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เดชเตˆเดคเตเดคเดฃเดฟเตฝ เด…เดคเตเดคเดฐเด‚ เด’เดฐเต เดธเดพเดนเดšเดฐเตเดฏเดคเตเดคเดฟเดจเต. เด‡เดคเดฟเดจเต เดชเตเดฐเดงเดพเดจเดฎเดพเดฏเตเด‚ เดฐเดฃเตเดŸเต เด†เดตเดถเตเดฏเด•เดคเด•เตพ เดฎเดพเดคเตเดฐเดฎเต‡เดฏเตเดณเตเดณเต‚: เด‡เดคเต เด…เดจเดจเตเดคเดฎเดพเดฏ เดฒเต‚เดชเตเดชเดฟเตฝ เดฌเดพเดšเตเดšเตเด•เตพ เดคเดฟเดฐเดฟเด•เต† เดจเตฝเด•เตเด•เดฏเตเด‚ เด†เดตเตผเดคเตเดคเดจเด™เตเด™เตพเด•เตเด•เดฟเดŸเดฏเดฟเตฝ เด…เดคเดฟเดจเตเดฑเต† เด…เดตเดธเตเดฅ เดธเด‚เดฐเด•เตเดทเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดตเต‡เดฃเด‚ (เด†เตผ-เตฝ เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต‡เดคเต เด…เดŸเดšเตเดšเตเดชเต‚เดŸเตเดŸเดฒเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดฒเดณเดฟเดคเดฎเดพเดฏ เดฐเต€เดคเดฟเดฏเดฟเตฝ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตเดจเตเดจเต). เดฎเตเดฎเตเดชเต, เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเดฑเดฟเดจเตเดณเตเดณเดฟเดฒเต† เดจเดฎเตเดชเดฟ เด…เดฑเต‡เด•เดณเดพเด•เตเด•เดฟ เด†เตผ เด…เดฑเต‡เด•เดณเต† เดตเตเดฏเด•เตเดคเดฎเดพเดฏเดฟ เดชเดฐเดฟเดตเตผเดคเตเดคเดจเด‚ เดšเต†เดฏเตเดฏเต‡เดฃเตเดŸเดคเต เด†เดตเดถเตเดฏเดฎเดพเดฏเดฟเดฐเตเดจเตเดจเต, เดŽเดจเตเดจเดพเตฝ เดชเดพเด•เตเด•เต‡เดœเดฟเดจเตเดฑเต† เดจเดฟเดฒเดตเดฟเดฒเต† เดชเดคเดฟเดชเตเดชเต keras เด…เดคเต เดธเตเดตเดฏเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจเต.

เดชเดฐเดฟเดถเต€เดฒเดจเดคเตเดคเดฟเดจเตเด‚ เดฎเต‚เดฒเตเดฏเดจเดฟเตผเดฃเตเดฃเดฏ เดกเดพเดฑเตเดฑเดฏเตเด•เตเด•เตเดฎเตเดณเตเดณ เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเตผ เด‡เดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจเดคเดพเดฏเดฟ เดฎเดพเดฑเดฟ:

เดชเดฐเดฟเดถเต€เดฒเดจเดคเตเดคเดฟเดจเตเด‚ เดฎเต‚เดฒเตเดฏเดจเดฟเตผเดฃเตเดฃเดฏ เดกเดพเดฑเตเดฑเดฏเตเด•เตเด•เตเดฎเตเดณเตเดณ เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเตผ

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] เดตเดฐเต† เดธเตเด•เต†เดฏเดฟเตฝ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต‡เดคเต เด†เดตเดถเตเดฏเดฎเดพเดฃเต, เด‡เดคเต เดตเดฟเดคเดฐเดฃเด‚ เดšเต†เดฏเตเดคเดตเดฐเต† เดชเดฐเดฟเดถเต€เดฒเดฟเดชเตเดชเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต. keras เดฎเต‹เดกเดฒเตเด•เตพ.

เดฌเดพเดนเตเดฏ เดซเด‚เด—เตโ€Œเดทเดจเดฟเตฝ เด†เตผเด—เตเดฏเตเดฎเต†เดจเตเดฑเต เดคเดฐเด‚ เดชเดฐเดฟเดถเต‹เดงเดจ, เด’เดฐเต เดชเดŸเตเดŸเดฟเด• เด…เดŸเด™เตเด™เดฟเดฏเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต 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-เดฒเต† เดเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เดชเตเดฐเดงเดพเดจเดชเตเดชเต†เดŸเตเดŸ เดกเดพเดฑเตเดฑ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดซเดฒเดชเตเดฐเดฆเดฎเดพเดฏเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเดคเต เดธเด™เตเด•เตฝเดชเตเดชเดฟเด•เตเด•เดพเตป เดชเตเดฐเดฏเดพเดธเดฎเดพเดฃเต.

เด’เดฐเต Core i5 เดฒเดพเดชเตโ€ŒเดŸเต‹เดชเตเดชเดฟเดฒเต† เดตเต‡เด—เดค เด…เดณเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดฑเต† เดซเดฒเด™เตเด™เตพ เด‡เดชเตเดฐเด•เดพเดฐเดฎเดพเดฃเต:

เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเตผ เดฌเต†เดžเตเดšเตเดฎเดพเตผเด•เตเด•เต

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

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

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

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

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

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

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

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

DBI::dbDisconnect(con, shutdown = TRUE)

เดฆเตเดฐเตเดค เดกเตเดฐเต‹ เดกเต‚เดกเดฟเตฝ เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเตฝ: R, C++, เดจเตเดฏเต‚เดฑเตฝ เดจเต†เดฑเตเดฑเตโ€Œเดตเตผเด•เตเด•เตเด•เตพ เดŽเดจเตเดจเดฟเดตเดฏเตเดฎเดพเดฏเดฟ เดŽเด™เตเด™เดจเต† เดšเด™เตเด™เดพเดคเตเดคเด‚ เด•เต‚เดŸเดพเด‚

เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดฎเดคเดฟเดฏเดพเดฏ เดฑเดพเด‚ เด‰เดฃเตเดŸเต†เด™เตเด•เดฟเตฝ, เด…เดคเต‡ เดฑเดพเดฎเดฟเดฒเต‡เด•เตเด•เต เดฎเดพเดฑเตเดฑเตเดจเตเดจเดคเดฟเดฒเต‚เดŸเต† เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดจเตเดฑเต† เดชเตเดฐเดตเตผเดคเตเดคเดจเด‚ เดตเต‡เด—เดคเตเดคเดฟเดฒเดพเด•เตเด•เดพเตป เด•เดดเดฟเดฏเตเด‚ (เดžเด™เตเด™เดณเตเดŸเต† เดšเตเดฎเดคเดฒเดฏเตเด•เตเด•เต 32 เดœเดฟเดฌเดฟ เดฎเดคเดฟ). เดฒเดฟเดจเด•เตเดธเดฟเตฝ, เดชเดพเตผเดŸเตเดŸเต€เดทเตป เดกเดฟเดซเต‹เตพเดŸเตเดŸเดพเดฏเดฟ เดฎเตŒเดฃเตเดŸเต เดšเต†เดฏเตเดคเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต /dev/shm, เดฑเดพเด‚ เดถเต‡เดทเดฟเดฏเตเดŸเต† เดชเด•เตเดคเดฟ เดตเดฐเต† เด‰เตพเด•เตเด•เตŠเดณเตเดณเตเดจเตเดจเต. เดŽเดกเดฟเดฑเตเดฑเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดฒเต‚เดŸเต† เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด•เต‚เดŸเตเดคเตฝ เดนเตˆเดฒเตˆเดฑเตเดฑเต เดšเต†เดฏเตเดฏเดพเด‚ /etc/fstabเดชเต‹เดฒเตเดณเตเดณ เด’เดฐเต เดฑเต†เด•เตเด•เต‹เตผเดกเต เดฒเดญเดฟเด•เตเด•เดพเตป tmpfs /dev/shm tmpfs defaults,size=25g 0 0. เด•เดฎเดพเตปเดกเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเดšเตเดšเต เดฑเต€เดฌเต‚เดŸเตเดŸเต เดšเต†เดฏเตเดคเต เดซเดฒเด‚ เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เตเดจเตเดจเดคเต เด‰เดฑเดชเตเดชเดพเด•เตเด•เตเด• df -h.

เดŸเต†เดธเตเดฑเตเดฑเต เดกเดพเดฑเตเดฑเดฏเตเด•เตเด•เตเดณเตเดณ เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเตผ เดตเดณเดฐเต† เดฒเดณเดฟเดคเดฎเดพเดฏเดฟ เด•เดพเดฃเดชเตเดชเต†เดŸเตเดจเตเดจเต, เด•เดพเดฐเดฃเด‚ เดŸเต†เดธเตเดฑเตเดฑเต เดกเดพเดฑเตเดฑเดพเดธเต†เดฑเตเดฑเต เดชเต‚เตผเดฃเตเดฃเดฎเดพเดฏเตเด‚ เดฑเดพเดฎเดฟเดฒเต‡เด•เตเด•เต เดฏเต‹เดœเดฟเด•เตเด•เตเดจเตเดจเต:

เดŸเต†เดธเตเดฑเตเดฑเต เดกเดพเดฑเตเดฑเดฏเตเด•เตเด•เตเดณเตเดณ เด‡เดฑเตเดฑเดฑเต‡เดฑเตเดฑเตผ

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, เด…เดคเดฟเดจเตเดฑเต† เดธเดตเดฟเดถเต‡เดทเดคเด•เตพ เดšเตผเดšเตเดšเดšเต†เดฏเตเดฏเตเดจเตเดจเต เด‡เดคเต เดธเดจเตเดฆเต‡เดถเด‚. เด‡เดคเต เดธเตเดฑเตเดฑเดพเตปเดกเต‡เตผเดกเดพเดฏเดฟ เด‰เตพเดชเตเดชเต†เดŸเตเดคเตเดคเดฟเดฏเดฟเดŸเตเดŸเตเดฃเตเดŸเต keras เด•เต‚เดŸเดพเดคเต†, เด…เดคเดจเตเดธเดฐเดฟเดšเตเดšเต, R-เดจเตเดณเตเดณ เด…เดคเต‡ เดชเต‡เดฐเดฟเดฒเตเดณเตเดณ เดชเดพเด•เตเด•เต‡เดœเดฟเตฝ เดฒเดญเตเดฏเดฎเดพเดฃเต. เดŽเดจเตเดจเดพเตฝ เดธเดฟเด‚เด—เดฟเตพ-เดšเดพเดจเตฝ เด‡เดฎเต‡เดœเตเด•เตพเด•เตเด•เตŠเดชเตเดชเด‚ เด‡เดคเต เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเตป เดถเตเดฐเดฎเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เด’เดฐเต เดตเดฟเดšเดฟเดคเตเดฐเดฎเดพเดฏ เด•เดพเดฐเตเดฏเด‚ เดคเต†เดณเดฟเดžเตเดžเต: เด‡เตปเดชเตเดŸเตเดŸเต เดŸเต†เตปเดธเดฑเดฟเดจเต เดŽเดฒเตเดฒเดพเดฏเตเดชเตเดชเต‹เดดเตเด‚ เด…เดณเดตเตเด•เตพ เด‰เดฃเตเดŸเดพเดฏเดฟเดฐเดฟเด•เตเด•เดฃเด‚. (batch, height, width, 3), เด…เดคเดพเดฏเดคเต, เดšเดพเดจเดฒเตเด•เดณเตเดŸเต† เดŽเดฃเตเดฃเด‚ เดฎเดพเดฑเตเดฑเดพเตป เด•เดดเดฟเดฏเดฟเดฒเตเดฒ. เดชเตˆเดคเตเดคเดฃเดฟเตฝ เด…เดคเตเดคเดฐเด‚ เดชเดฐเดฟเดฎเดฟเดคเดฟเด•เดณเตŠเดจเตเดจเตเดฎเดฟเดฒเตเดฒ, เด…เดคเดฟเดจเดพเตฝ เดฏเดฅเดพเตผเดคเตเดฅ เดฒเต‡เด–เดจเด‚ (เด•เต‡เดฐเดพเดธเต เดชเดคเดฟเดชเตเดชเดฟเดฒเต† เดกเตเดฐเต‹เดชเตเดชเตเด”เดŸเตเดŸเต เด‡เดฒเตเดฒเดพเดคเต†) เดชเดฟเดจเตเดคเตเดŸเตผเดจเตเดจเต เดžเด™เตเด™เตพ เดคเดฟเดฐเด•เตเด•เดฟเดŸเตเดŸเต เดˆ เดตเดพเดธเตเดคเตเดตเดฟเดฆเตเดฏเดฏเตเดŸเต† เดธเตเดตเดจเตเดคเด‚ เดจเดŸเดชเตเดชเดพเด•เตเด•เตฝ เดŽเดดเตเดคเดฟ.

Mobilenet v1 เด†เตผเด•เตเด•เดฟเดŸเต†เด•เตเดšเตผ

library(keras)

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

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

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

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

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

  inputs <- layer_input(shape = input_shape)

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

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

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

    return(model)
}

เดˆ เดธเดฎเต€เดชเดจเดคเตเดคเดฟเดจเตเดฑเต† เดชเต‹เดฐเดพเดฏเตเดฎเด•เตพ เดตเตเดฏเด•เตเดคเดฎเดพเดฃเต. เดŽเดจเดฟเด•เตเด•เต เด’เดฐเตเดชเดพเดŸเต เดฎเต‹เดกเดฒเตเด•เตพ เดชเดฐเต€เด•เตเดทเดฟเด•เตเด•เดพเตป เด†เด—เตเดฐเดนเดฎเตเดฃเตเดŸเต, เดŽเดจเตเดจเดพเตฝ เดจเต‡เดฐเต†เดฎเดฑเดฟเดšเตเดšเต, เด“เดฐเต‹ เด†เตผเด•เตเด•เดฟเดŸเต†เด•เตเดšเดฑเตเด‚ เดธเตเดตเดฎเต‡เดงเดฏเดพ เดตเต€เดฃเตเดŸเตเด‚ เดŽเดดเตเดคเดพเตป เดžเดพเตป เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจเดฟเดฒเตเดฒ. เด‡เดฎเต‡เดœเตเดจเต†เดฑเตเดฑเดฟเตฝ เดฎเตเตปเด•เต‚เดŸเตเดŸเดฟ เดชเดฐเดฟเดถเต€เดฒเดฟเดชเตเดชเดฟเดšเตเดš เดฎเต‹เดกเดฒเตเด•เดณเตเดŸเต† เดญเดพเดฐเด‚ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเดจเตเดณเตเดณ เด…เดตเดธเดฐเดตเตเด‚ เดžเด™เตเด™เตพเด•เตเด•เต เดจเดทเตเดŸเดฎเดพเดฏเดฟ. เดชเดคเดฟเดตเตเดชเต‹เดฒเต†, เดกเต‹เด•เตเดฏเตเดฎเต†เดจเตเดฑเต‡เดทเตป เดชเด เดฟเด•เตเด•เตเดจเตเดจเดคเต เดธเดนเดพเดฏเดฟเดšเตเดšเต. เดซเด‚เด—เตเดทเตป get_config() เดŽเดกเดฟเดฑเตเดฑเดฟเด‚เด—เดฟเดจเต เด…เดจเตเดฏเต‹เดœเตเดฏเดฎเดพเดฏ เดฐเต‚เดชเดคเตเดคเดฟเตฝ เดฎเต‹เดกเดฒเดฟเดจเตเดฑเต† เด’เดฐเต เดตเดฟเดตเดฐเดฃเด‚ เดฒเดญเดฟเด•เตเด•เดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต (base_model_conf$layers - เด’เดฐเต เดธเดพเดงเดพเดฐเดฃ R เดฒเดฟเดธเตเดฑเตเดฑเต), เด’เดชเตเดชเด‚ เดซเด‚เด—เตโ€Œเดทเดจเตเด‚ from_config() เด’เดฐเต เดฎเต‹เดกเตฝ เด’เดฌเตเดœเด•เตเดฑเตเดฑเดฟเดฒเต‡เด•เตเด•เต เดตเดฟเดชเดฐเต€เดค เดชเดฐเดฟเดตเตผเดคเตเดคเดจเด‚ เดจเดŸเดคเตเดคเตเดจเตเดจเต:

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

เด‡เดชเตเดชเต‹เตพ เดตเดฟเดคเดฐเดฃเด‚ เดšเต†เดฏเตเดค เดเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เด’เดฐเต เดธเดพเตผเดตเดคเตเดฐเดฟเด• เดซเด‚เด—เตเดทเตป เดŽเดดเตเดคเตเดจเตเดจเดคเต เดฌเตเดฆเตเดงเดฟเดฎเตเดŸเตเดŸเตเดณเตเดณ เด•เดพเดฐเตเดฏเดฎเดฒเตเดฒ keras เด‡เดฎเต‡เดœเตเดจเต†เดฑเตเดฑเดฟเตฝ เดชเดฐเดฟเดถเต€เดฒเดฟเดชเตเดชเดฟเดšเตเดš เดญเดพเดฐเดฎเตเดณเตเดณเดคเต‹ เด‡เดฒเตเดฒเดพเดคเตเดคเดคเต‹ เด†เดฏ เดฎเต‹เดกเดฒเตเด•เตพ:

เดฑเต†เดกเดฟเดฎเต†เดฏเตเดกเต เด†เตผเด•เตเด•เดฟเดŸเต†เด•เตเดšเดฑเตเด•เตพ เดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดชเตเดฐเดตเตผเดคเตเดคเดจเด‚

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. เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเตเดŸเต† เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเดฑเตˆเดธเต‡เดทเตป

เดธเต—เด•เดฐเตเดฏเดพเตผเดคเตเดฅเด‚, เดชเดฐเดฟเดถเต€เดฒเดจเด‚ เด†เดฐเด‚เดญเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดŽเดฒเตเดฒเดพ เด•เต‹เดกเตเด•เดณเตเด‚ เด’เดฐเตŠเดฑเตเดฑ เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเดพเดฏเดฟ เดฐเต‚เดชเด•เตฝเดชเตเดชเดจ เดšเต†เดฏเตโ€Œเดคเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต, เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเตผ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดกเต‹เด•เต‹เดชเตเดฑเตเดฑเต เด‡เดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เดชเตเดฐเด•เดพเดฐเด‚:

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

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

เดชเดพเด•เตเด•เต‡เดœเต เดกเต‹เด•เต‹เดชเตเดฑเตเดฑเต เดจเดŸเดชเตเดชเดพเด•เตเด•เดฒเดฟเดจเต† เดชเตเดฐเดคเดฟเดจเดฟเดงเต€เด•เดฐเดฟเด•เตเด•เตเดจเตเดจเต http://docopt.org/ เด†เตผเด•เตเด•เต เดตเต‡เดฃเตเดŸเดฟ. เด…เดคเดฟเดจเตเดฑเต† เดธเดนเดพเดฏเดคเตเดคเต‹เดŸเต†, เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เตพ เดคเตเดŸเด™เตเด™เดฟเดฏ เดฒเดณเดฟเดคเดฎเดพเดฏ เด•เดฎเดพเตปเดกเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เตเดจเตเดจเต 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 เดจเดฟเดฒเดตเดฟเดฒเต† เดชเดคเดฟเดชเตเดชเดฟเตฝ เดจเดฟเดจเตเดจเต keras R เด‰เดชเดฏเต‹เด—เดคเตเดคเดฟเตฝ เด•เดดเดฟเดฏเดฟเดฒเตเดฒ R เดชเดพเด•เตเด•เต‡เดœเดฟเดฒเต† เดฎเดพเดฑเตเดฑเด™เตเด™เตพ เด•เดฃเด•เตเด•เดฟเดฒเต†เดŸเตเด•เตเด•เดพเดคเตเดคเดคเดฟเดจเดพเตฝ, เด…เดตเตผ เด…เดคเต เดชเดฐเดฟเดนเดฐเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเดพเดฏเดฟ เดžเด™เตเด™เตพ เด•เดพเดคเตเดคเดฟเดฐเดฟเด•เตเด•เตเด•เดฏเดพเดฃเต.

RStudio-เดฏเดฟเดฒเต† เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเตเดŸเต† เดชเดฐเดฎเตเดชเดฐเดพเด—เดค เดฒเต‹เดžเตเดšเตเดฎเดพเดฏเดฟ เดคเดพเดฐเดคเดฎเตเดฏเดชเตเดชเต†เดŸเตเดคเตเดคเตเดฎเตเดชเต‹เตพ เดตเตเดฏเดคเตเดฏเดธเตเดค เดฎเต‹เดกเดฒเตเด•เดณเตเดฎเดพเดฏเตเดณเตเดณ เดชเดฐเต€เด•เตเดทเดฃเด™เตเด™เตพ เด—เดฃเตเดฏเดฎเดพเดฏเดฟ เดตเต‡เด—เดคเตเดคเดฟเดฒเดพเด•เตเด•เดพเตป เดˆ เดธเดฎเต€เดชเดจเด‚ เดธเดพเดงเตเดฏเดฎเดพเด•เตเด•เดฟ (เดธเดพเดงเตเดฏเดฎเดพเดฏ เด’เดฐเต เดฌเดฆเดฒเดพเดฏเดฟ เดžเด™เตเด™เตพ เดชเดพเด•เตเด•เต‡เดœเต เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เตเดจเตเดจเต. tfruns). เด‡เดคเดฟเดจเดพเดฏเดฟ RStudio เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเดพเดคเต† เดคเดจเตเดจเต† เดกเต‹เด•เตเด•เดฑเดฟเดฒเต‹ เดธเต†เตผเดตเดฑเดฟเดฒเต‹ เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเตเดŸเต† เดฒเต‹เดžเตเดšเต เดŽเดณเตเดชเตเดชเดคเตเดคเดฟเตฝ เด•เตˆเด•เดพเดฐเตเดฏเด‚ เดšเต†เดฏเตเดฏเดพเดจเตเดณเตเดณ เด•เดดเดฟเดตเดพเดฃเต เดชเตเดฐเดงเดพเดจ เดจเต‡เดŸเตเดŸเด‚.

6. เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเตเดŸเต† เดกเต‹เด•เตเด•เดฑเตˆเดธเต‡เดทเตป

เดŸเต€เด‚ เด…เด‚เด—เด™เตเด™เตพ เดคเดฎเตเดฎเดฟเดฒเตเดณเตเดณ เดชเดฐเดฟเดถเต€เดฒเดจ เดฎเต‹เดกเดฒเตเด•เตพเด•เตเด•เตเด‚ เด•เตเดฒเต—เดกเดฟเตฝ เดฆเตเดฐเตเดคเด—เดคเดฟเดฏเดฟเดฒเตเดณเตเดณ เดตเดฟเดจเตเดฏเดพเดธเดคเตเดคเดฟเดจเตเด‚ เดชเดฐเดฟเดธเตเดฅเดฟเดคเดฟเดฏเตเดŸเต† เดชเต‹เตผเดŸเตเดŸเดฌเดฟเดฒเดฟเดฑเตเดฑเดฟ เด‰เดฑเดชเตเดชเดพเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เดกเต‹เด•เตเด•เตผ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต. เด†เตผ เดชเตเดฐเต‹เด—เตเดฐเดพเดฎเตผเด•เตเด•เต เดคเดพเดฐเดคเดฎเตเดฏเต‡เดจ เด…เดธเดพเดงเดพเดฐเดฃเดฎเดพเดฏ เดˆ เดŸเต‚เดณเตเดฎเดพเดฏเดฟ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดชเดฐเดฟเดšเดฏเดชเตเดชเต†เดŸเดพเตป เดคเตเดŸเด™เตเด™เดพเด‚ เด‡เดคเต เดชเตเดฐเดธเดฟเดฆเตเดงเต€เด•เดฐเดฃเด™เตเด™เดณเตเดŸเต† เดชเดฐเดฎเตเดชเดฐ เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เดตเต€เดกเดฟเดฏเต‹ เด•เต‹เดดเตเดธเต.

เด†เดฆเตเดฏเด‚ เดฎเตเดคเตฝ เดจเดฟเด™เตเด™เดณเตเดŸเต† เดธเตเดตเดจเตเดคเด‚ เดšเดฟเดคเตเดฐเด™เตเด™เตพ เดธเตƒเดทเตโ€ŒเดŸเดฟเด•เตเด•เดพเดจเตเด‚ เดจเดฟเด™เตเด™เดณเตเดŸเต‡เดคเต เดธเตƒเดทเตโ€ŒเดŸเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เด…เดŸเดฟเดธเตเดฅเดพเดจเดฎเดพเดฏเดฟ เดฎเดฑเตเดฑเต เดšเดฟเดคเตเดฐเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเดจเตเด‚ เดกเต‹เด•เตเด•เตผ เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต. เดฒเดญเตเดฏเดฎเดพเดฏ เด“เดชเตโ€Œเดทเดจเตเด•เตพ เดตเดฟเดถเด•เดฒเดจเด‚ เดšเต†เดฏเตเดฏเตเดฎเตเดชเต‹เตพ, NVIDIA, CUDA+cuDNN เดกเตเดฐเตˆเดตเดฑเตเด•เตพ, เดชเตˆเดคเตเดคเตบ เดฒเตˆเดฌเตเดฐเดฑเดฟเด•เตพ เดŽเดจเตเดจเดฟเดต เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเต เดšเดฟเดคเตเดฐเดคเตเดคเดฟเดจเตเดฑเต† เดตเดฒเดฟเดฏเตŠเดฐเต เดญเดพเด—เดฎเดพเดฃเต†เดจเตเดจ เดจเดฟเด—เดฎเดจเดคเตเดคเดฟเดฒเต†เดคเตเดคเดฟ, เด”เดฆเตเดฏเต‹เด—เดฟเด• เดšเดฟเดคเตเดฐเด‚ เด’เดฐเต เด…เดŸเดฟเดธเตเดฅเดพเดจเดฎเดพเดฏเดฟ เดŽเดŸเตเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เดคเต€เดฐเตเดฎเดพเดจเดฟเดšเตเดšเต. tensorflow/tensorflow:1.12.0-gpu, เด†เดตเดถเตเดฏเดฎเดพเดฏ R เดชเดพเด•เตเด•เต‡เดœเตเด•เตพ เด…เดตเดฟเดŸเต† เดšเต‡เตผเด•เตเด•เตเดจเตเดจเต.

เด…เดตเดธเดพเดจ เดกเต‹เด•เตเด•เตผ เดซเดฏเตฝ เด‡เดคเตเดชเต‹เดฒเต† เด•เดพเดฃเดชเตเดชเต†เดŸเตเดŸเต:

Dockerfile

FROM tensorflow/tensorflow:1.12.0-gpu

MAINTAINER Artem Klevtsov <[email protected]>

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

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

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

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

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

WORKDIR /app

VOLUME /db
VOLUME /app

CMD bash

เดธเต—เด•เดฐเตเดฏเดพเตผเดคเตเดฅเด‚, เด‰เดชเดฏเต‹เด—เดฟเดšเตเดš เดชเดพเด•เตเด•เต‡เดœเตเด•เตพ เดตเต‡เดฐเดฟเดฏเดฌเดฟเดณเตเด•เดณเดฟเตฝ เด‰เตพเดชเตเดชเต†เดŸเตเดคเตเดคเดฟเดฏเดฟเดŸเตเดŸเตเดฃเตเดŸเต; เดŽเดดเตเดคเดชเตเดชเต†เดŸเตเดŸ เดธเตโ€Œเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเตเดŸเต† เดญเต‚เดฐเดฟเดญเดพเด—เดตเตเด‚ เด…เดธเด‚เดฌเตเดฒเดฟ เดธเดฎเดฏเดคเตเดคเต เด•เดฃเตเดŸเต†เดฏเตโ€Œเดจเดฑเดฟเดจเตเดณเตเดณเดฟเตฝ เดชเด•เตผเดคเตเดคเตเดจเตเดจเต. เดžเด™เตเด™เตพ เด•เดฎเดพเตปเดกเต เดทเต†เดฒเตเดฒเตเด‚ เดฎเดพเดฑเตเดฑเดฟ /bin/bash เด‰เดณเตเดณเดŸเด•เตเด•เดคเตเดคเดฟเดจเตเดฑเต† เดŽเดณเตเดชเตเดชเดคเตเดคเดฟเดจเดพเดฏเดฟ /etc/os-release. เด‡เดคเต เด•เต‹เดกเดฟเดฒเต† OS เดชเดคเดฟเดชเตเดชเต เดตเตเดฏเด•เตเดคเดฎเดพเด•เตเด•เต‡เดฃเตเดŸเดคเดฟเดจเตเดฑเต† เด†เดตเดถเตเดฏเด•เดค เด’เดดเดฟเดตเดพเด•เตเด•เดฟ.

เด•เต‚เดŸเดพเดคเต†, เดตเดฟเดตเดฟเดง เด•เดฎเดพเตปเดกเตเด•เดณเตเดณเตเดณ เด’เดฐเต เด•เดฃเตเดŸเต†เดฏเตเดจเตผ เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจ เด’เดฐเต เดšเต†เดฑเดฟเดฏ เดฌเดพเดทเต เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเต เดŽเดดเตเดคเดฟเดฏเดฟเดŸเตเดŸเตเดฃเตเดŸเต. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เด‡เดต เดฎเตเดฎเตเดชเต เด•เดฃเตเดŸเต†เดฏเตโ€Œเดจเดฑเดฟเดจเตเดณเตเดณเดฟเตฝ เดธเตเดฅเดพเดชเดฟเดšเตเดšเดฟเดฐเตเดจเตเดจ เดจเตเดฏเต‚เดฑเตฝ เดจเต†เดฑเตเดฑเตโ€Œเดตเตผเด•เตเด•เตเด•เดณเต† เดชเดฐเดฟเดถเต€เดฒเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดธเตโ€Œเด•เตเดฐเดฟเดชเตโ€Œเดฑเตเดฑเตเด•เดณเดพเด•เดพเด‚ เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เด•เดฃเตเดŸเต†เดฏเตโ€Œเดจเดฑเดฟเดจเตเดฑเต† เดชเตเดฐเดตเตผเดคเตเดคเดจเด‚ เดกเต€เดฌเด—เตเด—เต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเด‚ เดจเดฟเดฐเต€เด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดฎเตเดณเตเดณ เด’เดฐเต เด•เดฎเดพเตปเดกเต เดทเต†เดฒเตเดฒเดพเดฏเดฟเดฐเดฟเด•เตเด•เดพเด‚:

เด•เดฃเตเดŸเต†เดฏเตเดจเตผ เดฒเต‹เดžเตเดšเต เดšเต†เดฏเตเดฏเดพเดจเตเดณเตเดณ เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเต

#!/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 เดธเตเดฅเดฟเดฐ เดฎเต‚เดฒเตเดฏเด™เตเด™เตพเด•เตเด•เตŠเดชเตเดชเด‚; เด†เดฆเตเดฏเดคเตเดคเต† เดชเตŠเดธเดฟเดทเดฃเตฝ เด†เตผเด—เตเดฏเตเดฎเต†เดจเตเดฑเต "เดฌเดพเดทเต" เด†เดฃเต†เด™เตเด•เดฟเตฝ, เด•เดฃเตเดŸเต†เดฏเตเดจเตผ เด’เดฐเต เด•เดฎเดพเตปเดกเต เดทเต†เดฒเตเดฒเตเดฎเดพเดฏเดฟ เดธเด‚เดตเต‡เดฆเดจเดพเดคเตเดฎเด•เดฎเดพเดฏเดฟ เด†เดฐเด‚เดญเดฟเด•เตเด•เตเด‚. เดฎเดฑเตเดฑเต†เดฒเตเดฒเดพ เดธเดพเดนเดšเดฐเตเดฏเด™เตเด™เดณเดฟเดฒเตเด‚, เดชเตŠเดธเดฟเดทเดฃเตฝ เด†เตผเด—เตเดฏเตเดฎเต†เดจเตเดฑเตเด•เดณเตเดŸเต† เดฎเต‚เดฒเตเดฏเด™เตเด™เตพ เดฎเดพเดฑเตเดฑเดฟเดธเตเดฅเดพเดชเดฟเด•เตเด•เตเดจเตเดจเต: CMD="Rscript /app/train_nn.R $@".

เด‰เดฑเดตเดฟเดŸ เดกเดพเดฑเตเดฑเดฏเตเด‚ เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเตเด‚ เด‰เดณเตเดณ เดกเดฏเดฑเด•เตเดŸเดฑเดฟเด•เดณเตเด‚ เดชเดฐเดฟเดถเต€เดฒเดจเด‚ เดฒเดญเดฟเดšเตเดš เดฎเต‹เดกเดฒเตเด•เตพ เดธเด‚เดฐเด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดกเดฏเดฑเด•เตเดŸเดฑเดฟเดฏเตเด‚ เดนเต‹เดธเตเดฑเตเดฑเต เดธเดฟเดธเตเดฑเตเดฑเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเต เด•เดฃเตเดŸเต†เดฏเตเดจเดฑเดฟเดจเตเดณเตเดณเดฟเตฝ เด˜เดŸเดฟเดชเตเดชเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต เดŽเดจเตเดจเดคเต เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเดพเดฃเต, เด‡เดคเต เด…เดจเดพเดตเดถเตเดฏ เด•เตƒเดคเตเดฐเดฟเดฎเดคเตเดตเด™เตเด™เดณเดฟเดฒเตเดฒเดพเดคเต† เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เดณเตเดŸเต† เดซเดฒเด™เตเด™เตพ เด†เด•เตเดธเดธเต เดšเต†เดฏเตเดฏเดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต.

7. Google เด•เตเดฒเต—เดกเดฟเตฝ เด’เดจเตเดจเดฟเดฒเดงเดฟเด•เด‚ GPU-เด•เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต

เดฎเดคเตเดธเดฐเดคเตเดคเดฟเดจเตเดฑเต† เดธเดตเดฟเดถเต‡เดทเดคเด•เดณเดฟเดฒเตŠเดจเตเดจเต เดตเดณเดฐเต† เดถเดฌเตเดฆเดฎเดฏเดฎเดพเดฏ เดกเดพเดฑเตเดฑเดฏเดพเดฏเดฟเดฐเตเดจเตเดจเต (เดถเต€เตผเดทเด• เดšเดฟเดคเตเดฐเด‚ เด•เดพเดฃเตเด•, ODS เดธเตเดฒเดพเด•เตเด•เดฟเตฝ เดจเดฟเดจเตเดจเต @Leigh.plt-เตฝ เดจเดฟเดจเตเดจเต เด•เดŸเดฎเต†เดŸเตเดคเตเดคเดคเต). เดตเดฒเดฟเดฏ เดฌเดพเดšเตเดšเตเด•เตพ เด‡เดคเดฟเดจเต† เดšเต†เดฑเตเด•เตเด•เดพเตป เดธเดนเดพเดฏเดฟเด•เตเด•เตเดจเตเดจเต, 1 เดœเดฟเดชเดฟเดฏเต เด‰เดณเตเดณ เด’เดฐเต เดชเดฟเดธเดฟเดฏเดฟเดฒเต† เดชเดฐเต€เด•เตเดทเดฃเด™เตเด™เตพเด•เตเด•เต เดถเต‡เดทเด‚, เด•เตเดฒเต—เดกเดฟเดฒเต† เดจเดฟเดฐเดตเดงเดฟ เดœเดฟเดชเดฟเดฏเตเด•เดณเดฟเตฝ เดชเดฐเดฟเดถเต€เดฒเดจ เดฎเต‹เดกเดฒเตเด•เตพ เดฎเดพเดธเตเดฑเตเดฑเตผ เดšเต†เดฏเตเดฏเดพเตป เดžเด™เตเด™เตพ เดคเต€เดฐเตเดฎเดพเดจเดฟเดšเตเดšเต. เด‰เดชเดฏเต‹เด—เดฟเดšเตเดš GoogleCloud (เด…เดŸเดฟเดธเตเดฅเดพเดจเด•เดพเดฐเตเดฏเด™เตเด™เดณเดฟเดฒเต‡เด•เตเด•เตเดณเตเดณ เดจเดฒเตเดฒ เดตเดดเดฟเด•เดพเดŸเตเดŸเดฟ) เดฒเดญเตเดฏเดฎเดพเดฏ เด•เต‹เตบเดซเดฟเด—เดฑเต‡เดทเดจเตเด•เดณเตเดŸเต† เดตเดฒเดฟเดฏ เดคเดฟเดฐเดžเตเดžเต†เดŸเตเดชเตเดชเต, เดจเตเดฏเดพเดฏเดฎเดพเดฏ เดตเดฟเดฒเด•เตพ, $300 เดฌเต‹เดฃเดธเต เดŽเดจเตเดจเดฟเดต เด•เดพเดฐเดฃเด‚. เด…เดคเตเดฏเดพเด—เตเดฐเดนเด‚ เด•เดพเดฐเดฃเด‚, เดžเดพเตป เด’เดฐเต เดŽเดธเตเดŽเดธเตเดกเดฟเดฏเตเด‚ เด’เดฐเต เดŸเตบ เดฑเดพเดฎเตเด‚ เด‰เดณเตเดณ เด’เดฐเต 4xV100 เด‡เตปเดธเตโ€Œเดฑเตเดฑเตปเดธเต เด“เตผเดกเตผ เดšเต†เดฏเตเดคเต, เด…เดคเตŠเดฐเต เดตเดฒเดฟเดฏ เดคเต†เดฑเตเดฑเดพเดฏเดฟเดฐเตเดจเตเดจเต. เด…เดคเตเดคเดฐเดฎเตŠเดฐเต เดฏเดจเตเดคเตเดฐเด‚ เดตเต‡เด—เดคเตเดคเดฟเตฝ เดชเดฃเด‚ เดคเดฟเดจเตเดจเตเดจเตเดจเต; เดคเต†เดณเดฟเดฏเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดŸ เดชเตˆเดชเตเดชเตเดฒเตˆเตป เด‡เดฒเตเดฒเดพเดคเต† เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดชเดฐเต€เด•เตเดทเดฃเด‚ เดจเดŸเดคเตเดคเดพเตป เด•เดดเดฟเดฏเตเด‚. เดตเดฟเดฆเตเดฏเดพเดญเตเดฏเดพเดธ เด†เดตเดถเตเดฏเด™เตเด™เตพเด•เตเด•เดพเดฏเดฟ, K80 เดŽเดŸเตเด•เตเด•เตเดจเตเดจเดคเดพเดฃเต เดจเดฒเตเดฒเดคเต. เดŽเดจเตเดจเดพเตฝ เดตเดฒเดฟเดฏ เด…เดณเดตเดฟเดฒเตเดณเตเดณ เดฑเดพเด‚ เด‰เดชเดฏเต‹เด—เดชเตเดฐเดฆเดฎเดพเดฏเดฟ - เด•เตเดฒเต—เดกเต เดŽเดธเตเดŽเดธเตเดกเดฟ เด…เดคเดฟเดจเตเดฑเต† เดชเตเดฐเด•เดŸเดจเดคเตเดคเดฟเตฝ เดฎเดคเดฟเดชเตเดชเตเดณเดตเดพเด•เตเด•เตเดจเตเดจเดฟเดฒเตเดฒ, เด…เดคเดฟเดจเดพเตฝ เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเต เด‡เดคเดฟเดฒเต‡เด•เตเด•เต เดฎเดพเดฑเตเดฑเดฟ dev/shm.

เด’เดจเตเดจเดฟเดฒเดงเดฟเด•เด‚ GPU-เด•เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เด‰เดคเตเดคเดฐเดตเดพเดฆเดฟเดฏเดพเดฏ เด•เต‹เดกเต เดถเด•เดฒเดฎเดพเดฃเต เดเดฑเตเดฑเดตเตเด‚ เดคเดพเตฝเดชเตเดชเดฐเตเดฏเดฎเตเดณเตเดณเดคเต. เด†เดฆเตเดฏเด‚, เดชเตˆเดคเตเดคเดฃเดฟเดฒเต† เดชเต‹เดฒเต† เด’เดฐเต เด•เต‹เตบเดŸเต†เด•เตเดธเตเดฑเตเดฑเต เดฎเดพเดจเต‡เดœเตผ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเดพเดฃเต เดฎเต‹เดกเตฝ เดธเดฟเดชเดฟเดฏเตเดตเดฟเตฝ เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจเดคเต:

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

เด•เด‚เดชเตˆเตฝ เดšเต†เดฏเตเดฏเดพเดคเตเดค (เด‡เดคเต เดชเตเดฐเดงเดพเดจเดฎเดพเดฃเต) เดฎเต‹เดกเตฝ เดฒเดญเตเดฏเดฎเดพเดฏ เดฒเดญเตเดฏเดฎเดพเดฏ เดœเดฟเดชเดฟเดฏเตเดตเตเด•เดณเดฟเดฒเต‡เด•เตเด•เต เดชเด•เตผเดคเตเดคเดฟ, เด…เดคเดฟเดจเตเดถเต‡เดทเด‚ เดฎเดพเดคเตเดฐเดฎเต‡ เด…เดคเต เด•เด‚เดชเตˆเตฝ เดšเต†เดฏเตเดฏเตเด•เดฏเตเดณเตเดณเต‚:

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

เด…เดตเดธเดพเดจเดคเตเดคเต‡เดคเต เด’เดดเดฟเด•เต†เดฏเตเดณเตเดณ เดŽเดฒเตเดฒเดพ เดฒเต†เดฏเดฑเตเด•เดณเตเด‚ เดซเตเดฐเต€เดธเตเดšเต†เดฏเตเดฏเตเด•, เด…เดตเดธเดพเดจเดคเตเดคเต† เดฒเต†เดฏเตผ เดชเดฐเดฟเดถเต€เดฒเดฟเดชเตเดชเดฟเด•เตเด•เตเด•, เดจเดฟเดฐเดตเดงเดฟ เดœเดฟเดชเดฟเดฏเตเดตเตเด•เตพเด•เตเด•เดพเดฏเดฟ เดฎเตเดดเตเดตเตป เดฎเต‹เดกเดฒเตเด‚ เด…เตบเดซเตเดฐเต€เดธเต เดšเต†เดฏเตเดฏเตเด•เดฏเตเด‚ เดตเต€เดฃเตเดŸเตเด‚ เดชเดฐเดฟเดถเต€เดฒเดฟเดชเตเดชเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจ เด•เตเดฒเดพเดธเดฟเด•เต เดธเดพเด™เตเด•เต‡เดคเดฟเด•เดค เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เดพเตป เด•เดดเดฟเดžเตเดžเดฟเดฒเตเดฒ.

เดชเดฐเดฟเดถเต€เดฒเดจเด‚ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเดคเต† เดจเดฟเดฐเต€เด•เตเดทเดฟเดšเตเดšเต. เดŸเต†เตปเดธเตผเดฌเต‹เตผเดกเต, เด“เดฐเต‹ เดฏเตเด—เดคเตเดคเดฟเดจเตเดถเต‡เดทเดตเตเด‚ เดฒเต‹เด—เตเด•เตพ เดฑเต†เด•เตเด•เต‹เตผเดกเตเดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเด‚ เดตเดฟเดตเดฐเดฆเดพเดฏเด•เดฎเดพเดฏ เดชเต‡เดฐเตเด•เดณเตเดณเตเดณ เดฎเต‹เดกเดฒเตเด•เตพ เดธเด‚เดฐเด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเด‚ เดธเตเดตเดฏเด‚ เดชเดฐเดฟเดฎเดฟเดคเดชเตเดชเต†เดŸเตเดคเตเดคเตเดจเตเดจเต:

เด•เต‹เตพเดฌเดพเด•เตเด•เตเด•เตพ

# ะจะฐะฑะปะพะฝ ะธะผะตะฝะธ ั„ะฐะนะปะฐ ะปะพะณะฐ
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. เด’เดฐเต เดจเดฟเด—เดฎเดจเดคเตเดคเดฟเดจเต เดชเด•เดฐเด‚

เดžเด™เตเด™เตพ เดจเต‡เดฐเดฟเดŸเตเดŸ เดจเดฟเดฐเดตเดงเดฟ เดชเตเดฐเดถเตเดจเด™เตเด™เตพ เด‡เดคเตเดตเดฐเต† เดคเดฐเดฃเด‚ เดšเต†เดฏเตเดคเดฟเดŸเตเดŸเดฟเดฒเตเดฒ:

  • ะฒ keras เด’เดชเตเดฑเตเดฑเดฟเดฎเตฝ เดชเด เดจ เดจเดฟเดฐเด•เตเด•เต (เด…เดจเดฒเต‹เด—เต) เดธเตเดตเดฏเดฎเต‡เดต เดคเดฟเดฐเดฏเตเดจเตเดจเดคเดฟเดจเต เดฑเต†เดกเดฟเดฎเต†เดฏเตเดกเต เดซเด‚เด—เตโ€Œเดทเตป เด’เดจเตเดจเตเดฎเดฟเดฒเตเดฒ lr_finder เดฒเตˆเดฌเตเดฐเดฑเดฟเดฏเดฟเตฝ เดซเดพเดธเตเดฑเตเดฑเต.เด); เด•เตเดฑเดšเตเดšเต เดชเดฐเดฟเดถเตเดฐเดฎเดคเตเดคเดฟเดฒเต‚เดŸเต†, เดฎเต‚เดจเตเดจเดพเด‚ เด•เด•เตเดทเดฟ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เดฒเตเด•เตพ R-เดฒเต‡เด•เตเด•เต เดชเต‹เตผเดŸเตเดŸเต เดšเต†เดฏเตเดฏเดพเตป เด•เดดเดฟเดฏเตเด‚, เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เด‡เดคเต;
  • เดฎเตเดฎเตเดชเดคเตเดคเต† เดชเต‹เดฏเดฟเดจเตเดฑเดฟเดจเตเดฑเต† เด…เดจเดจเตเดคเดฐเดซเดฒเดฎเดพเดฏเดฟ, เดจเดฟเดฐเดตเดงเดฟ เดœเดฟเดชเดฟเดฏเต เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ เดถเดฐเดฟเดฏเดพเดฏ เดชเดฐเดฟเดถเต€เดฒเดจ เดตเต‡เด—เดค เดคเดฟเดฐเดžเตเดžเต†เดŸเตเด•เตเด•เดพเตป เด•เดดเดฟเดžเตเดžเดฟเดฒเตเดฒ;
  • เด†เดงเตเดจเดฟเด• เดจเตเดฏเต‚เดฑเตฝ เดจเต†เดฑเตเดฑเตโ€Œเดตเตผเด•เตเด•เต เด†เตผเด•เตเด•เดฟเดŸเต†เด•เตเดšเดฑเตเด•เดณเตเดŸเต† เด…เดญเดพเดตเดฎเตเดฃเตเดŸเต, เดชเตเดฐเดคเตเดฏเต‡เด•เดฟเดšเตเดšเต เด‡เดฎเต‡เดœเตเดจเต†เดฑเตเดฑเดฟเตฝ เดฎเตเตปเด•เต‚เดŸเตเดŸเดฟ เดชเดฐเดฟเดถเต€เดฒเดจเด‚ เดฒเดญเดฟเดšเตเดšเดต;
  • เด’เดฐเต เดธเตˆเด•เตเด•เดฟเตพ เดจเดฏเดตเตเด‚ เดตเดฟเดตเต‡เดšเดจเดชเดฐเดฎเดพเดฏ เดชเด เดจ เดจเดฟเดฐเด•เตเด•เตเด•เดณเตเด‚ เด‡เดฒเตเดฒ (เด•เต‹เดธเตˆเตป เด…เดจเต€เดฒเดฟเด‚เด—เต เดžเด™เตเด™เดณเตเดŸเต† เด…เดญเตเดฏเตผเดคเตเดฅเดจเดชเตเดฐเด•เดพเดฐเดฎเดพเดฏเดฟเดฐเตเดจเตเดจเต เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เดฟ, เดจเดจเตเดฆเดฟ เดธเตเด•เต†เดฏเตเดกเดพเตป).

เดˆ เดฎเดคเตเดธเดฐเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเต เดŽเดจเตเดคเต เดชเตเดฐเดฏเต‹เดœเดจเด•เดฐเดฎเดพเดฏ เด•เดพเดฐเตเดฏเด™เตเด™เตพ เดชเด เดฟเดšเตเดšเต:

  • เดคเดพเดฐเดคเดฎเตเดฏเต‡เดจ เด•เตเดฑเดžเตเดž เดชเดตเตผ เดนเดพเตผเดกเตโ€Œเดตเต†เดฏเดฑเดฟเตฝ, เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดตเต‡เดฆเดจเดฏเดฟเดฒเตเดฒเดพเดคเต† เดฎเดพเดจเตเดฏเดฎเดพเดฏ (เดฑเดพเดฎเดฟเดจเตเดฑเต† เดชเดฒ เดฎเดŸเด™เตเด™เต เดตเดฒเตเดชเตเดชเดฎเตเดณเตเดณ) เดกเดพเดฑเตเดฑเดฏเตเดŸเต† เด…เดณเดตเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เดพเตป เด•เดดเดฟเดฏเตเด‚. เดชเตเดฒเดพเดธเตเดฑเตเดฑเดฟเด•เต เดธเดžเตเดšเดฟ เดกเดพเดฑเตเดฑ. เดชเดŸเตเดŸเดฟเด• เดŸเต‡เดฌเดฟเดณเตเด•เดณเตเดŸเต† เด‡เตป-เดชเตเดฒเต‡เดธเต เดชเดฐเดฟเดทเตโ€Œเด•เตเด•เดฐเดฃเด‚ เด•เดพเดฐเดฃเด‚ เดฎเต†เดฎเตเดฎเดฑเดฟ เดธเด‚เดฐเด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเต, เด…เดคเต เด…เดต เดชเด•เตผเดคเตเดคเตเดจเตเดจเดคเต เด’เดดเดฟเดตเดพเด•เตเด•เตเดจเตเดจเต, เดถเดฐเดฟเดฏเดพเดฏเดฟ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เด…เดคเดฟเดจเตเดฑเต† เด•เดดเดฟเดตเตเด•เตพ เดŽเดฒเตเดฒเดพเดฏเตเดชเตเดชเต‹เดดเตเด‚ เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเดฟเด‚เด—เต เดญเดพเดทเด•เตพเด•เตเด•เดพเดฏเดฟ เดจเดฎเตเด•เตเด•เต เด…เดฑเดฟเดฏเดพเดตเตเดจเตเดจ เดŽเดฒเตเดฒเดพ เด‰เดชเด•เดฐเดฃเด™เตเด™เดณเดฟเดฒเตเด‚ เดเดฑเตเดฑเดตเตเด‚ เด‰เดฏเตผเดจเตเดจ เดตเต‡เด—เดค เดชเตเดฐเด•เดŸเดฎเดพเด•เตเด•เตเดจเตเดจเต. เด’เดฐเต เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเตฝ เดกเดพเดฑเตเดฑ เดธเด‚เดฐเด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเดคเต, เดฎเดฟเด•เตเด• เด•เต‡เดธเตเด•เดณเดฟเดฒเตเด‚, เดฎเตเดดเตเดตเตป เดกเดพเดฑเตเดฑเดพเดธเต†เดฑเตเดฑเตเด‚ เดฑเดพเดฎเดฟเดฒเต‡เด•เตเด•เต เดšเต‚เดทเดฃเด‚ เดšเต†เดฏเตเดฏเต‡เดฃเตเดŸเดคเดฟเดจเตเดฑเต† เด†เดตเดถเตเดฏเด•เดคเดฏเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเต เดšเดฟเดจเตเดคเดฟเด•เตเด•เดพเดคเดฟเดฐเดฟเด•เตเด•เดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต.
  • เดชเดพเด•เตเด•เต‡เดœเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต R เดฒเต† เดธเตเดฒเต‹ เดซเด‚เด—เตโ€Œเดทเดจเตเด•เตพ C++ เดฒเต† เดซเดพเดธเตเดฑเตเดฑเต เด†เดฏเดต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดฎเดพเดฑเตเดฑเดฟเดธเตเดฅเดพเดชเดฟเด•เตเด•เดพเดจเดพเด•เตเด‚ Rcpp. เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต เดชเตเดฑเดฎเต‡ เด†เดฃเต†เด™เตเด•เดฟเตฝ RcppThread เด…เดฅเดตเดพ RcppParallel, เดจเดฎเตเด•เตเด•เต เด•เตเดฐเต‹เดธเต-เดชเตเดฒเดพเดฑเตเดฑเตเดซเต‹เด‚ เดฎเตพเดŸเตเดŸเดฟ-เดคเตเดฐเต†เดกเต เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เดฒเตเด•เตพ เดฒเดญเดฟเด•เตเด•เตเดจเตเดจเต, เด…เดคเดฟเดจเดพเตฝ R เดฒเต†เดตเดฒเดฟเตฝ เด•เต‹เดกเต เดธเดฎเดพเดจเตเดคเดฐเดฎเดพเด•เตเด•เต‡เดฃเตเดŸ เด†เดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ.
  • เดชเดพเด•เตเด•เต‡เดœเต Rcpp C++ เดฏเต† เด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เด—เต—เดฐเดตเดฎเดพเดฏ เด…เดฑเดฟเดตเดฟเดฒเตเดฒเดพเดคเต† เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเตป เด•เดดเดฟเดฏเตเด‚, เด†เดตเดถเตเดฏเดฎเดพเดฏ เดฎเดฟเดจเดฟเดฎเด‚ เดตเดฟเดตเดฐเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต เด‡เดตเดฟเดŸเต†. เดชเต‹เดฒเตเดณเตเดณ เดฐเดธเด•เดฐเดฎเดพเดฏ เดจเดฟเดฐเดตเดงเดฟ เดธเดฟ-เดฒเตˆเดฌเตเดฐเดฑเดฟเด•เตพเด•เตเด•เตเดณเตเดณ เดนเต†เดกเตเดกเตผ เดซเดฏเดฒเตเด•เตพ เดŽเด•เตเดธเตเดฑเตเดฑเตปเดธเตผ CRAN-เตฝ เดฒเดญเตเดฏเดฎเดพเดฃเต, เด…เดคเดพเดฏเดคเต, เดฑเต†เดกเดฟเดฎเต†เดฏเตเดกเต เด‰เดฏเตผเดจเตเดจ เดชเตเดฐเด•เดŸเดจเดฎเตเดณเตเดณ C++ เด•เต‹เดกเต R-เดฒเต‡เด•เตเด•เต เดธเดฎเดจเตเดตเดฏเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจ เดชเตเดฐเต‹เดœเด•เตเดŸเตเด•เตพ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตเดจเตเดจเดคเดฟเดจเดพเดฏเดฟ เด’เดฐเต เด…เดŸเดฟเดธเตเดฅเดพเดจ เดธเต—เด•เดฐเตเดฏเด‚ เดฐเต‚เดชเต€เด•เดฐเดฟเด•เตเด•เตเดจเตเดจเต. เด…เดงเดฟเด• เดธเต—เด•เดฐเตเดฏเด‚ เดธเดฟเดจเตเดฑเดพเด•เตเดธเต เดนเตˆเดฒเตˆเดฑเตเดฑเดฟเด‚เด—เตเด‚ RStudio-เดฏเดฟเดฒเต† เด’เดฐเต เดธเตเดฑเตเดฑเดพเดฑเตเดฑเดฟเด•เต C++ เด•เต‹เดกเต เด…เดจเดฒเตˆเดธเดฑเตเดฎเดพเดฃเต.
  • เดกเต‹เด•เต‹เดชเตเดฑเตเดฑเต เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเดฑเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดธเตเดตเดฏเด‚ เด‰เตพเด•เตเด•เตŠเดณเตเดณเตเดจเตเดจ เดธเตเด•เตเดฐเดฟเดชเตเดฑเตเดฑเตเด•เตพ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต. เดตเดฟเดฆเต‚เดฐ เดธเต†เตผเดตเดฑเดฟเตฝ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เดพเตป เด‡เดคเต เดธเต—เด•เดฐเตเดฏเดชเตเดฐเดฆเดฎเดพเดฃเต, เด‰เตพเดชเตเดชเต†เดŸเต†. เดกเต‹เด•เตเด•เดฑเดฟเดจเต เด•เต€เดดเดฟเตฝ. RStudio-เดฏเดฟเตฝ, เดชเดฐเดฟเดถเต€เดฒเดจ เดจเตเดฏเต‚เดฑเตฝ เดจเต†เดฑเตเดฑเตโ€Œเดตเตผเด•เตเด•เตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดฎเดฃเดฟเด•เตเด•เต‚เดฑเตเด•เดณเต‹เดณเด‚ เดชเดฐเต€เด•เตเดทเดฃเด™เตเด™เตพ เดจเดŸเดคเตเดคเตเดจเตเดจเดคเต เด…เดธเต—เด•เดฐเตเดฏเดฎเดพเดฃเต, เด•เต‚เดŸเดพเดคเต† เดธเต†เตผเดตเดฑเดฟเตฝ เดคเดจเตเดจเต† IDE เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเต เดŽเดฒเตเดฒเดพเดฏเตเดชเตเดชเต‹เดดเตเด‚ เดจเตเดฏเดพเดฏเต€เด•เดฐเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดจเตเดจเดฟเดฒเตเดฒ.
  • OS-เดจเตเดฑเต†เดฏเตเด‚ เดฒเตˆเดฌเตเดฐเดฑเดฟเด•เดณเตเดŸเต†เดฏเตเด‚ เดตเตเดฏเดคเตเดฏเดธเตโ€Œเดค เดชเดคเดฟเดชเตเดชเตเด•เดณเตเดณเตเดณ เดกเต†เดตเดฒเดชเตเดชเตผเดฎเดพเตผเด•เตเด•เดฟเดŸเดฏเดฟเตฝ เด•เต‹เดกเต เดชเต‹เตผเดŸเตเดŸเดฌเดฟเดฒเดฟเดฑเตเดฑเดฟเดฏเตเด‚ เดซเดฒเด™เตเด™เดณเตเดŸเต† เดชเตเดจเตผเดจเดฟเตผเดฎเตเดฎเดพเดฃเดตเตเด‚ เดกเต‹เด•เตเด•เตผ เด‰เดฑเดชเตเดชเดพเด•เตเด•เตเดจเตเดจเต, เด•เต‚เดŸเดพเดคเต† เดธเต†เตผเดตเดฑเตเด•เดณเดฟเดฒเต† เดŽเด•เตโ€Œเดธเดฟเด•เตเดฏเต‚เดทเตป เดŽเดณเตเดชเตเดชเดตเตเด‚. เด’เดฐเต เด•เดฎเดพเตปเดกเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดฎเตเดดเตเดตเตป เดชเดฐเดฟเดถเต€เดฒเดจ เดชเตˆเดชเตเดชเตเดฒเตˆเดจเตเด‚ เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เดพเด‚.
  • เดตเดฟเดฒเด•เต‚เดŸเดฟเดฏ เดนเดพเตผเดกเตโ€Œเดตเต†เดฏเดฑเดฟเตฝ เดชเดฐเต€เด•เตเดทเดฃเด‚ เดจเดŸเดคเตเดคเดพเดจเตเดณเตเดณ เดฌเดœเดฑเตเดฑเต เดธเต—เดนเตƒเดฆ เดฎเดพเตผเด—เดฎเดพเดฃเต Google เด•เตเดฒเต—เดกเต, เดŽเดจเตเดจเดพเตฝ เดจเดฟเด™เตเด™เตพ เด•เต‹เตบเดซเดฟเด—เดฑเต‡เดทเดจเตเด•เตพ เดถเตเดฐเดฆเตเดงเดพเดชเต‚เตผเดตเตเดตเด‚ เดคเดฟเดฐเดžเตเดžเต†เดŸเตเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต.
  • เดตเตเดฏเด•เตเดคเดฟเด—เดค เด•เต‹เดกเต เดถเด•เดฒเด™เตเด™เดณเตเดŸเต† เดตเต‡เด—เดค เด…เดณเด•เตเด•เตเดจเตเดจเดคเต เดตเดณเดฐเต† เด‰เดชเดฏเต‹เด—เดชเตเดฐเดฆเดฎเดพเดฃเต, เดชเตเดฐเดคเตเดฏเต‡เด•เดฟเดšเตเดšเตเด‚ R, C++ เดŽเดจเตเดจเดฟเดต เดธเด‚เดฏเต‹เดœเดฟเดชเตเดชเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เดชเดพเด•เตเด•เต‡เดœเดฟเดจเตŠเดชเตเดชเด‚ เดฌเต†เดžเตเดšเต - เดตเดณเดฐเต† เดŽเดณเตเดชเตเดชเดฎเดพเดฃเต.

เดฎเตŠเดคเตเดคเดคเตเดคเดฟเตฝ เดˆ เด…เดจเตเดญเดตเด‚ เดตเดณเดฐเต† เดชเตเดฐเดคเดฟเดซเดฒเดฆเดพเดฏเด•เดฎเดพเดฏเดฟเดฐเตเดจเตเดจเต, เด‰เดจเตเดจเดฏเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดŸ เดšเดฟเดฒ เดชเตเดฐเดถเตเดจเด™เตเด™เตพ เดชเดฐเดฟเดนเดฐเดฟเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เดคเตเดŸเตผเดจเตเดจเตเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต.

เด…เดตเดฒเด‚เดฌเด‚: www.habr.com

เด’เดฐเต เด…เดญเดฟเดชเตเดฐเดพเดฏเด‚ เดšเต‡เตผเด•เตเด•เตเด•