āĻšā§ āĻšāĻžāĻŦāĻ°!
āĻāĻ¤ āĻĒāĻ¤āĻ¨ā§, āĻāĻžāĻāĻ˛ āĻšāĻžāĻ¤ā§ āĻāĻāĻāĻž āĻāĻŦāĻŋ, āĻā§āĻāĻ āĻĄā§āĻ° āĻĄā§āĻĄāĻ˛ āĻ°āĻŋāĻāĻāĻ¨āĻŋāĻļāĻ¨āĻā§ āĻļā§āĻ°ā§āĻŖā§āĻŦāĻĻā§āĻ§ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻ¯ā§āĻāĻŋāĻ¤āĻžāĻ° āĻāĻ¯āĻŧā§āĻāĻ¨ āĻāĻ°ā§āĻāĻŋāĻ˛, āĻ¯ā§āĻāĻžāĻ¨ā§ āĻ
āĻ¨ā§āĻ¯āĻĻā§āĻ° āĻŽāĻ§ā§āĻ¯ā§, R-āĻŦāĻŋāĻā§āĻāĻžāĻ¨ā§āĻĻā§āĻ° āĻāĻāĻāĻŋ āĻĻāĻ˛ āĻ
āĻāĻļ āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛:
āĻāĻāĻŦāĻžāĻ° āĻāĻāĻŋ āĻŽā§āĻĄā§āĻ˛ āĻĢāĻžāĻ°ā§āĻŽāĻŋāĻāĻ¯āĻŧā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻžāĻ āĻāĻ°ā§āĻ¨āĻŋ, āĻ¤āĻŦā§ āĻ
āĻ¨ā§āĻ āĻŽā§āĻ˛ā§āĻ¯āĻŦāĻžāĻ¨ āĻ
āĻāĻŋāĻā§āĻāĻ¤āĻž āĻ
āĻ°ā§āĻāĻ¨ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§, āĻ¤āĻžāĻ āĻāĻŽāĻŋ āĻ¸āĻŽā§āĻĒā§āĻ°āĻĻāĻžāĻ¯āĻŧāĻā§ āĻāĻžāĻāĻ˛ā§ āĻāĻŦāĻ āĻĻā§āĻ¨āĻ¨ā§āĻĻāĻŋāĻ¨ āĻāĻžāĻā§āĻ° āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻāĻāĻ°ā§āĻˇāĻŖā§āĻ¯āĻŧ āĻāĻŦāĻ āĻĻāĻ°āĻāĻžāĻ°ā§ āĻāĻŋāĻ¨āĻŋāĻ¸ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻŦāĻ˛āĻ¤ā§ āĻāĻžāĻāĨ¤ āĻāĻ˛ā§āĻāĻŋāĻ¤ āĻŦāĻŋāĻˇāĻ¯āĻŧāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§: āĻāĻžāĻĄāĻŧāĻž āĻāĻ āĻŋāĻ¨ āĻā§āĻŦāĻ¨ OpenCV, JSON āĻĒāĻžāĻ°ā§āĻ¸āĻŋāĻ (āĻāĻ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻā§āĻ˛āĻŋ R āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻ āĻŦāĻž āĻĒā§āĻ¯āĻžāĻā§āĻā§ C++ āĻā§āĻĄā§āĻ° āĻāĻā§āĻāĻ°āĻŖ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°ā§ Rcpp), āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻā§āĻ° āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻāĻžāĻ°āĻžāĻāĻā§āĻļāĻ¨ āĻāĻŦāĻ āĻā§āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§āĻ° āĻĄāĻāĻžāĻ°āĻžāĻāĻā§āĻļāĻ¨āĨ¤ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻĒāĻ¯ā§āĻā§āĻ¤ āĻāĻāĻāĻŋ āĻĢāĻ°ā§āĻŽā§āĻ° āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĨā§āĻā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻā§āĻĄ āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻ¯āĻŧ
āĻ¸ā§āĻāĻŋāĻĒāĻ¤ā§āĻ°:
āĻĻāĻā§āĻˇāĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§ CSV āĻĨā§āĻā§ MonetDB-āĻ¤ā§ āĻĄā§āĻāĻž āĻ˛ā§āĻĄ āĻāĻ°ā§āĻ¨ āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤ āĻāĻ°āĻž āĻšāĻā§āĻā§ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻĨā§āĻā§ āĻŦā§āĻ¯āĻžāĻ āĻāĻ¨āĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻāĻžāĻ°ā§ āĻāĻāĻāĻŋ āĻŽāĻĄā§āĻ˛ āĻāĻ°ā§āĻāĻŋāĻā§āĻāĻāĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻāĻ¨ āĻāĻ°āĻž āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻŽāĻŋāĻāĻžāĻ°āĻžāĻāĻā§āĻļāĻ¨ āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻā§āĻ° āĻĄāĻāĻžāĻ°āĻžāĻāĻā§āĻļāĻ¨ Google āĻā§āĻ˛āĻžāĻāĻĄā§ āĻāĻāĻžāĻ§āĻŋāĻ GPU āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤ā§ āĻāĻāĻāĻŋ āĻāĻĒāĻ¸āĻāĻšāĻžāĻ°ā§āĻ°
1. āĻĻāĻā§āĻˇāĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§ CSV āĻĨā§āĻā§ MonetDB āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ā§ āĻĄā§āĻāĻž āĻ˛ā§āĻĄ āĻāĻ°ā§āĻ¨
āĻāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻ¯ā§āĻāĻŋāĻ¤āĻžāĻ° āĻĄā§āĻāĻž āĻ°ā§āĻĄāĻŋāĻŽā§āĻĄ āĻāĻŽā§āĻ āĻāĻāĻžāĻ°ā§ āĻ¨āĻ¯āĻŧ, āĻŦāĻ°āĻ āĻĒāĻ¯āĻŧā§āĻ¨ā§āĻ āĻā§āĻ āĻ°ā§āĻĄāĻŋāĻ¨ā§āĻ āĻ¸āĻš JSON āĻ¸āĻŽāĻ¨ā§āĻŦāĻŋāĻ¤ 340āĻāĻŋ CSV āĻĢāĻžāĻāĻ˛ (āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻā§āĻ˛āĻžāĻ¸ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻĢāĻžāĻāĻ˛) āĻāĻāĻžāĻ°ā§ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻāĻ āĻĒāĻ¯āĻŧā§āĻ¨ā§āĻāĻā§āĻ˛āĻŋāĻā§ āĻ˛āĻžāĻāĻ¨ā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻāĻ¯ā§āĻā§āĻ¤ āĻāĻ°ā§, āĻāĻŽāĻ°āĻž 256x256 āĻĒāĻŋāĻā§āĻ¸ā§āĻ˛ āĻĒāĻ°āĻŋāĻŽāĻžāĻĒā§āĻ° āĻāĻāĻāĻŋ āĻā§āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻāĻŋāĻ¤ā§āĻ° āĻĒāĻžāĻāĨ¤ āĻāĻāĻžāĻĄāĻŧāĻžāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻ°ā§āĻāĻ°ā§āĻĄā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ˛ā§āĻŦā§āĻ˛ āĻ°āĻ¯āĻŧā§āĻā§ āĻ¯āĻž āĻ¨āĻŋāĻ°ā§āĻĻā§āĻļ āĻāĻ°ā§ āĻ¯ā§ āĻĄā§āĻāĻžāĻ¸ā§āĻ āĻ¸āĻāĻā§āĻ°āĻšā§āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻļā§āĻ°ā§āĻŖā§āĻŦāĻŋāĻāĻžāĻāĻāĻžāĻ°ā§āĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻāĻŦāĻŋāĻāĻŋ āĻ¸āĻ āĻŋāĻāĻāĻžāĻŦā§ āĻ¸ā§āĻŦā§āĻā§āĻ¤ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛, āĻāĻŦāĻŋāĻ° āĻ˛ā§āĻāĻā§āĻ° āĻŦāĻ¸āĻŦāĻžāĻ¸ā§āĻ° āĻĻā§āĻļā§āĻ° āĻāĻāĻāĻŋ āĻĻā§āĻ-āĻ āĻā§āĻˇāĻ°ā§āĻ° āĻā§āĻĄ, āĻāĻāĻāĻŋ āĻ āĻ¨āĻ¨ā§āĻ¯ āĻļāĻ¨āĻžāĻā§āĻ¤āĻāĻžāĻ°ā§, āĻāĻāĻāĻŋ āĻāĻžāĻāĻŽāĻ¸ā§āĻā§āĻ¯āĻžāĻŽā§āĻĒ āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻļā§āĻ°ā§āĻŖā§āĻ° āĻ¨āĻžāĻŽ āĻ¯āĻž āĻĢāĻžāĻāĻ˛ā§āĻ° āĻ¨āĻžāĻŽā§āĻ° āĻ¸āĻžāĻĨā§ āĻŽā§āĻ˛ā§āĨ¤ āĻŽā§āĻ˛ āĻĄā§āĻāĻžāĻ° āĻāĻāĻāĻŋ āĻ¸āĻ°āĻ˛ā§āĻā§āĻ¤ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖāĻžāĻāĻžāĻ°ā§ 7.4 āĻāĻŋāĻŦāĻŋ āĻāĻāĻ¨ā§āĻ° āĻāĻŦāĻ āĻāĻ¨āĻĒā§āĻ¯āĻžāĻ āĻāĻ°āĻžāĻ° āĻĒāĻ°ā§ āĻĒā§āĻ°āĻžāĻ¯āĻŧ 20 āĻāĻŋāĻŦāĻŋ, āĻāĻ¨āĻĒā§āĻ¯āĻžāĻ āĻāĻ°āĻžāĻ° āĻĒāĻ°ā§ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻĄā§āĻāĻž 240 āĻāĻŋāĻāĻžāĻŦāĻžāĻāĻ āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻ¨ā§āĻ¯āĻŧāĨ¤ āĻāĻ¯āĻŧā§āĻāĻāĻ°āĻž āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻāĻ°ā§āĻā§āĻ¨ āĻ¯ā§ āĻāĻāĻ¯āĻŧ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖ āĻāĻāĻ āĻ āĻā§āĻāĻ¨ āĻĒā§āĻ¨āĻ°ā§āĻ¤ā§āĻĒāĻžāĻĻāĻ¨ āĻāĻ°ā§āĻā§, āĻ¯āĻžāĻ° āĻ āĻ°ā§āĻĨ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖāĻāĻŋ āĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻāĻŋāĻ˛āĨ¤ āĻ¯āĻžāĻ āĻšā§āĻ āĻ¨āĻž āĻā§āĻ¨, āĻā§āĻ°āĻžāĻĢāĻŋāĻ āĻĢāĻžāĻāĻ˛ā§ āĻŦāĻž āĻ ā§āĻ¯āĻžāĻ°ā§ āĻāĻāĻžāĻ°ā§ 50 āĻŽāĻŋāĻ˛āĻŋāĻ¯āĻŧāĻ¨ āĻāĻŦāĻŋ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻž āĻ āĻŦāĻŋāĻ˛āĻŽā§āĻŦā§ āĻ āĻ˛āĻžāĻāĻāĻ¨āĻ āĻŦāĻ˛ā§ āĻŦāĻŋāĻŦā§āĻāĻŋāĻ¤ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ āĻāĻŦāĻ āĻāĻŽāĻ°āĻž āĻ¸āĻāĻ°āĻā§āĻˇāĻŖāĻžāĻāĻžāĻ° āĻĨā§āĻā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ CSV āĻĢāĻžāĻāĻ˛ āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻāĻ°āĻžāĻ° āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĨ¤ train_simplified.zip āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻŦā§āĻ¯āĻžāĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻāĻāĻžāĻ°ā§āĻ° āĻāĻŦāĻŋāĻā§āĻ˛āĻŋāĻ° āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻĒā§āĻ°āĻāĻ¨ā§āĻŽā§āĻ° āĻ¸āĻžāĻĨā§ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ā§ "āĻāĻĄāĻŧāĻ˛ā§"āĨ¤
āĻāĻāĻāĻŋ āĻāĻžāĻ˛-āĻĒā§āĻ°āĻŽāĻžāĻŖāĻŋāĻ¤ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻĄāĻŋāĻŦāĻŋāĻāĻŽāĻāĻ¸ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻŦā§āĻā§ āĻ¨ā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ MonetDB, āĻ¯ā§āĻŽāĻ¨ āĻāĻāĻāĻŋ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻšāĻŋāĻ¸āĻžāĻŦā§ R āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨
con <- DBI::dbConnect(drv = MonetDBLite::MonetDBLite(), Sys.getenv("DBDIR"))
āĻāĻŽāĻžāĻĻā§āĻ° āĻĻā§āĻāĻŋ āĻā§āĻŦāĻŋāĻ˛ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§: āĻāĻāĻāĻŋ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĄā§āĻāĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻ āĻ¨ā§āĻ¯āĻāĻŋ āĻĄāĻžāĻāĻ¨āĻ˛ā§āĻĄ āĻāĻ°āĻž āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋāĻ° āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻž āĻ¸āĻāĻā§āĻ°āĻžāĻ¨ā§āĻ¤ āĻ¤āĻĨā§āĻ¯ā§āĻ° āĻāĻ¨ā§āĻ¯ (āĻāĻŋāĻā§ āĻā§āĻ˛ āĻšāĻ˛ā§ āĻĻāĻ°āĻāĻžāĻ°ā§ āĻāĻŦāĻ āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻĢāĻžāĻāĻ˛ āĻĄāĻžāĻāĻ¨āĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻĒāĻ°ā§ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§):
āĻā§āĻŦāĻŋāĻ˛ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻā§āĻā§
if (!DBI::dbExistsTable(con, "doodles")) {
DBI::dbCreateTable(
con = con,
name = "doodles",
fields = c(
"countrycode" = "char(2)",
"drawing" = "text",
"key_id" = "bigint",
"recognized" = "bool",
"timestamp" = "timestamp",
"word" = "text"
)
)
}
if (!DBI::dbExistsTable(con, "upload_log")) {
DBI::dbCreateTable(
con = con,
name = "upload_log",
fields = c(
"id" = "serial",
"file_name" = "text UNIQUE",
"uploaded" = "bool DEFAULT false"
)
)
}
āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ā§ āĻĄā§āĻāĻž āĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻĻā§āĻ°ā§āĻ¤āĻ¤āĻŽ āĻāĻĒāĻžāĻ¯āĻŧ āĻāĻŋāĻ˛ āĻāĻ¸āĻāĻŋāĻāĻāĻ˛ - āĻāĻŽāĻžāĻ¨ā§āĻĄ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ CSV āĻĢāĻžāĻāĻ˛ āĻāĻĒāĻŋ āĻāĻ°āĻž 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
āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻĄā§āĻ°āĻžāĻāĻā§āĻ° āĻāĻ¤āĻŋāĻ° āĻŦā§āĻļāĻŋāĻˇā§āĻā§āĻ¯ā§āĻ° āĻāĻĒāĻ° āĻ¨āĻŋāĻ°ā§āĻāĻ° āĻāĻ°ā§ āĻĄā§āĻāĻž āĻ˛ā§āĻĄāĻŋāĻ āĻ¸āĻŽāĻ¯āĻŧ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻŋāĻ¤ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻāĻāĻāĻŋ SSD-āĻāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻŦāĻž āĻāĻāĻāĻŋ āĻĢā§āĻ˛ā§āĻ¯āĻžāĻļ āĻĄā§āĻ°āĻžāĻāĻ (āĻ¸ā§āĻ°ā§āĻ¸ āĻĢāĻžāĻāĻ˛) āĻĨā§āĻā§ SSD (DB) āĻĒāĻĄāĻŧāĻ¤ā§ āĻāĻŦāĻ āĻ˛āĻŋāĻāĻ¤ā§ 10 āĻŽāĻŋāĻ¨āĻŋāĻā§āĻ°āĻ āĻāĻŽ āĻ¸āĻŽāĻ¯āĻŧ āĻ˛āĻžāĻā§ā§ˇ
āĻāĻāĻāĻŋ āĻĒā§āĻ°ā§āĻŖāĻ¸āĻāĻā§āĻ¯āĻž āĻļā§āĻ°ā§āĻŖā§āĻ° āĻ˛ā§āĻŦā§āĻ˛ āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻ¸ā§āĻāĻ āĻāĻ˛āĻžāĻŽ āĻ¸āĻš āĻāĻāĻāĻŋ āĻāĻ˛āĻžāĻŽ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻāĻ°āĻ āĻāĻ¯āĻŧā§āĻ āĻ¸ā§āĻā§āĻ¨ā§āĻĄ āĻ¸āĻŽāĻ¯āĻŧ āĻ˛āĻžāĻā§ (ORDERED INDEX
) āĻ˛āĻžāĻāĻ¨ āĻ¨āĻŽā§āĻŦāĻ° āĻ¸āĻš āĻ¯āĻžāĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦā§āĻ¯āĻžāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻĒāĻ°ā§āĻ¯āĻŦā§āĻā§āĻˇāĻŖāĻā§āĻ˛āĻŋ āĻ¨āĻŽā§āĻ¨āĻž āĻāĻ°āĻž āĻšāĻŦā§:
āĻ āĻ¤āĻŋāĻ°āĻŋāĻā§āĻ¤ āĻāĻ˛āĻžāĻŽ āĻāĻŦāĻ āĻ¸ā§āĻāĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž
message("Generate lables")
invisible(DBI::dbExecute(con, "ALTER TABLE doodles ADD label_int int"))
invisible(DBI::dbExecute(con, "UPDATE doodles SET label_int = dense_rank() OVER (ORDER BY word) - 1"))
message("Generate row numbers")
invisible(DBI::dbExecute(con, "ALTER TABLE doodles ADD id serial"))
invisible(DBI::dbExecute(con, "CREATE ORDERED INDEX doodles_id_ord_idx ON doodles(id)"))
āĻĢā§āĻ˛āĻžāĻāĻ¤ā§ āĻāĻāĻāĻŋ āĻŦā§āĻ¯āĻžāĻ āĻ¤ā§āĻ°āĻŋāĻ° āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯, āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻŦāĻŋāĻ˛ āĻĨā§āĻā§ āĻāĻ˛ā§āĻŽā§āĻ˛ā§ āĻ¸āĻžāĻ°āĻŋ āĻŦā§āĻ° āĻāĻ°āĻžāĻ° āĻ¸āĻ°ā§āĻŦā§āĻā§āĻ āĻāĻ¤āĻŋ āĻ
āĻ°ā§āĻāĻ¨ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§ doodles
. āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻŽāĻ°āĻž 3āĻāĻŋ āĻā§āĻļāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻāĻŋāĨ¤ āĻĒā§āĻ°āĻĨāĻŽāĻāĻŋ āĻāĻŋāĻ˛ āĻĒāĻ°ā§āĻ¯āĻŦā§āĻā§āĻˇāĻŖ āĻāĻāĻĄāĻŋ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°ā§ āĻāĻŽāĻ¨ āĻ§āĻ°āĻ¨ā§āĻ° āĻŽāĻžāĻ¤ā§āĻ°āĻžāĻ° āĻŽāĻžāĻ¤ā§āĻ°āĻž āĻāĻŽāĻžāĻ¨ā§āĨ¤ āĻāĻ¸āĻ˛ āĻĄā§āĻāĻž āĻ¸ā§āĻā§, āĻāĻāĻĄāĻŋ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻĒā§āĻ°āĻāĻžāĻ° bigint
, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻĒāĻ°ā§āĻ¯āĻŦā§āĻā§āĻˇāĻŖā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻ¤āĻžāĻĻā§āĻ° āĻļāĻ¨āĻžāĻā§āĻ¤āĻāĻžāĻ°ā§āĻā§, āĻ
āĻ°ā§āĻĄāĻŋāĻ¨ā§āĻ¯āĻžāĻ˛ āĻ¸āĻāĻā§āĻ¯āĻžāĻ° āĻ¸āĻŽāĻžāĻ¨, āĻĒā§āĻ°āĻāĻžāĻ°ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻŽāĻžāĻĒāĻ¸āĻ āĻāĻ°āĻž āĻ¸āĻŽā§āĻāĻŦ āĻāĻ°ā§ āĻ¤ā§āĻ˛ā§ int
. āĻāĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻ
āĻ¨ā§āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻ
āĻ¨ā§āĻ āĻĻā§āĻ°ā§āĻ¤āĨ¤ āĻĻā§āĻŦāĻŋāĻ¤ā§āĻ¯āĻŧ āĻā§āĻļāĻ˛āĻāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ ORDERED INDEX
â āĻāĻŽāĻ°āĻž āĻāĻ āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ā§ āĻāĻ¸ā§āĻāĻŋ āĻ
āĻāĻŋāĻā§āĻāĻ¤āĻžāĻāĻ¤āĻāĻžāĻŦā§, āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻĒāĻ˛āĻŦā§āĻ§ā§āĻ° āĻŽāĻ§ā§āĻ¯ āĻĻāĻŋāĻ¯āĻŧā§ āĻāĻ˛ā§āĻāĻŋ PREPARE
āĻāĻāĻ āĻ§āĻ°āĻŖā§āĻ° āĻĒā§āĻ°āĻļā§āĻ¨ā§āĻ° āĻāĻāĻāĻŋ āĻā§āĻā§āĻ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤ āĻ
āĻāĻŋāĻŦā§āĻ¯āĻā§āĻ¤āĻŋāĻ° āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦā§ āĻāĻāĻāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¤ā§āĻ˛āĻ¨āĻž āĻāĻ°āĻžāĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻāĻāĻāĻŋ āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻ°āĻ¯āĻŧā§āĻā§ SELECT
āĻĒāĻ°āĻŋāĻ¸āĻāĻā§āĻ¯āĻžāĻ¨āĻāĻ¤ āĻ¤ā§āĻ°ā§āĻāĻŋāĻ° āĻ¸ā§āĻŽāĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĒāĻ°āĻŋāĻŖāĻ¤ āĻšāĻ¯āĻŧā§āĻā§āĨ¤
āĻĄā§āĻāĻž āĻāĻĒāĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻŋ 450 MB āĻāĻ° āĻŦā§āĻļāĻŋ RAM āĻāĻ°āĻ āĻāĻ°ā§ āĻ¨āĻžāĨ¤ āĻ āĻ°ā§āĻĨāĻžā§, āĻŦāĻ°ā§āĻŖāĻŋāĻ¤ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§ āĻāĻĒāĻ¨āĻŋ āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻ¯ā§āĻā§āĻ¨ā§ āĻŦāĻžāĻā§āĻ āĻšāĻžāĻ°ā§āĻĄāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ°ā§ āĻĻāĻļ āĻāĻŋāĻāĻžāĻŦāĻžāĻāĻ āĻāĻāĻ¨ā§āĻ° āĻĄā§āĻāĻžāĻ¸ā§āĻāĻā§āĻ˛āĻŋāĻā§ āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°āĻŦā§āĻ¨, āĻ¯āĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻŋāĻā§ āĻāĻāĻ-āĻŦā§āĻ°ā§āĻĄ āĻĄāĻŋāĻāĻžāĻāĻ¸ āĻ°āĻ¯āĻŧā§āĻā§, āĻ¯āĻž āĻŦā§āĻļ āĻāĻŽā§āĻāĻžāĻ°āĨ¤
āĻ¯āĻž āĻŦāĻžāĻāĻŋ āĻĨāĻžāĻā§ āĻ¤āĻž āĻšāĻ˛ (āĻāĻ˛ā§āĻŽā§āĻ˛ā§) āĻĄā§āĻāĻž āĻĒā§āĻ¨āĻ°ā§āĻĻā§āĻ§āĻžāĻ°ā§āĻ° āĻāĻ¤āĻŋ āĻĒāĻ°āĻŋāĻŽāĻžāĻĒ āĻāĻ°āĻž āĻāĻŦāĻ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻāĻāĻžāĻ°ā§āĻ° āĻŦā§āĻ¯āĻžāĻā§āĻ° āĻ¨āĻŽā§āĻ¨āĻž āĻ¨ā§āĻāĻ¯āĻŧāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¸ā§āĻā§āĻ˛āĻŋāĻ āĻŽā§āĻ˛ā§āĻ¯āĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻž:
āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻŦā§āĻā§āĻāĻŽāĻžāĻ°ā§āĻ
library(ggplot2)
set.seed(0)
# ĐОдĐēĐģŅŅĐĩĐŊиĐĩ Đē йаСĐĩ Đ´Đ°ĐŊĐŊŅŅ
con <- DBI::dbConnect(MonetDBLite::MonetDBLite(), Sys.getenv("DBDIR"))
# ФŅĐŊĐēŅиŅ Đ´ĐģŅ ĐŋОдĐŗĐžŅОвĐēи СаĐŋŅĐžŅĐ° ĐŊĐ° ŅŅĐžŅĐžĐŊĐĩ ŅĐĩŅвĐĩŅĐ°
prep_sql <- function(batch_size) {
sql <- sprintf("PREPARE SELECT id FROM doodles WHERE id IN (%s)",
paste(rep("?", batch_size), collapse = ","))
res <- DBI::dbSendQuery(con, sql)
return(res)
}
# ФŅĐŊĐēŅиŅ Đ´ĐģŅ иСвĐģĐĩŅĐĩĐŊиŅ Đ´Đ°ĐŊĐŊŅŅ
fetch_data <- function(rs, batch_size) {
ids <- sample(seq_len(n), batch_size)
res <- DBI::dbFetch(DBI::dbBind(rs, as.list(ids)))
return(res)
}
# ĐŅОвĐĩĐ´ĐĩĐŊиĐĩ СаĐŧĐĩŅĐ°
res_bench <- bench::press(
batch_size = 2^(4:10),
{
rs <- prep_sql(batch_size)
bench::mark(
fetch_data(rs, batch_size),
min_iterations = 50L
)
}
)
# ĐĐ°ŅĐ°ĐŧĐĩŅŅŅ ĐąĐĩĐŊŅĐŧĐ°ŅĐēĐ°
cols <- c("batch_size", "min", "median", "max", "itr/sec", "total_time", "n_itr")
res_bench[, cols]
# batch_size min median max `itr/sec` total_time n_itr
# <dbl> <bch:tm> <bch:tm> <bch:tm> <dbl> <bch:tm> <int>
# 1 16 23.6ms 54.02ms 93.43ms 18.8 2.6s 49
# 2 32 38ms 84.83ms 151.55ms 11.4 4.29s 49
# 3 64 63.3ms 175.54ms 248.94ms 5.85 8.54s 50
# 4 128 83.2ms 341.52ms 496.24ms 3.00 16.69s 50
# 5 256 232.8ms 653.21ms 847.44ms 1.58 31.66s 50
# 6 512 784.6ms 1.41s 1.98s 0.740 1.1m 49
# 7 1024 681.7ms 2.72s 4.06s 0.377 2.16m 49
ggplot(res_bench, aes(x = factor(batch_size), y = median, group = 1)) +
geom_point() +
geom_line() +
ylab("median time, s") +
theme_minimal()
DBI::dbDisconnect(con, shutdown = TRUE)
2. āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤āĻŋ
āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤āĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ āĻĒāĻĻāĻā§āĻˇā§āĻĒ āĻ¨āĻŋāĻ¯āĻŧā§ āĻāĻ āĻŋāĻ¤:
- āĻŦāĻŋāĻ¨ā§āĻĻā§āĻ° āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻā§āĻ āĻ¸āĻš āĻ¸ā§āĻā§āĻ°āĻŋāĻāĻā§āĻ˛āĻŋāĻ° āĻā§āĻā§āĻāĻ° āĻ§āĻžāĻ°āĻŖāĻāĻžāĻ°ā§ āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ JSON āĻĒāĻžāĻ°ā§āĻ¸ āĻāĻ°āĻž āĻšāĻā§āĻā§āĨ¤
- āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻāĻāĻžāĻ°ā§āĻ° āĻāĻāĻāĻŋ āĻāĻŋāĻ¤ā§āĻ°ā§āĻ° āĻŦāĻŋāĻ¨ā§āĻĻā§āĻā§āĻ˛āĻŋāĻ° āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻā§āĻā§āĻ° āĻāĻĒāĻ° āĻāĻŋāĻ¤ā§āĻ¤āĻŋ āĻāĻ°ā§ āĻ°āĻāĻŋāĻ¨ āĻ˛āĻžāĻāĻ¨ āĻāĻāĻāĻž (āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, 256Ã256 āĻŦāĻž 128Ã128)āĨ¤
- āĻĢāĻ˛āĻ¸ā§āĻŦāĻ°ā§āĻĒ āĻāĻŋāĻ¤ā§āĻ°āĻā§āĻ˛āĻŋāĻā§ āĻāĻāĻāĻŋ āĻā§āĻ¨āĻ¸āĻ°ā§ āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻāĻ°āĻž āĻšāĻā§āĻā§āĨ¤
āĻĒāĻžāĻāĻĨāĻ¨ āĻāĻžāĻ°ā§āĻ¨ā§āĻ˛ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĒā§āĻ°āĻ¤āĻŋāĻ¯ā§āĻāĻŋāĻ¤āĻžāĻ° āĻ āĻāĻļ āĻšāĻŋāĻ¸āĻžāĻŦā§, āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻāĻŋ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻāĻāĻžāĻŦā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ OpenCV. R-āĻāĻ° āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻ¸āĻšāĻ āĻāĻŦāĻ āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻ¸ā§āĻ¸ā§āĻĒāĻˇā§āĻ āĻ ā§āĻ¯āĻžāĻ¨āĻžāĻ˛āĻāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ āĻĻā§āĻāĻ¤ā§ āĻāĻāĻ°āĻāĻŽ āĻšāĻŦā§:
R-āĻ JSON āĻĨā§āĻā§ āĻā§āĻ¨āĻ¸āĻ° āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻž
r_process_json_str <- function(json, line.width = 3,
color = TRUE, scale = 1) {
# ĐĐ°ŅŅиĐŊĐŗ JSON
coords <- jsonlite::fromJSON(json, simplifyMatrix = FALSE)
tmp <- tempfile()
# ĐŖĐ´Đ°ĐģŅĐĩĐŧ вŅĐĩĐŧĐĩĐŊĐŊŅĐš ŅĐ°ĐšĐģ ĐŋĐž СавĐĩŅŅĐĩĐŊиŅ ŅŅĐŊĐēŅии
on.exit(unlink(tmp))
png(filename = tmp, width = 256 * scale, height = 256 * scale, pointsize = 1)
# ĐŅŅŅОК ĐŗŅĐ°ŅиĐē
plot.new()
# РаСĐŧĐĩŅ ĐžĐēĐŊĐ° ĐŗŅĐ°ŅиĐēĐ°
plot.window(xlim = c(256 * scale, 0), ylim = c(256 * scale, 0))
# ĐĻвĐĩŅĐ° ĐģиĐŊиК
cols <- if (color) rainbow(length(coords)) else "#000000"
for (i in seq_along(coords)) {
lines(x = coords[[i]][[1]] * scale, y = coords[[i]][[2]] * scale,
col = cols[i], lwd = line.width)
}
dev.off()
# ĐŅĐĩОйŅаСОваĐŊиĐĩ иСОйŅĐ°ĐļĐĩĐŊиŅ в 3-Ņ
ĐŧĐĩŅĐŊŅĐš ĐŧĐ°ŅŅив
res <- png::readPNG(tmp)
return(res)
}
r_process_json_vector <- function(x, ...) {
res <- lapply(x, r_process_json_str, ...)
# ĐĐąŅĐĩдиĐŊĐĩĐŊиĐĩ 3-Ņ
ĐŧĐĩŅĐŊŅŅ
ĐŧĐ°ŅŅивОв ĐēĐ°ŅŅиĐŊĐžĐē в 4-Ņ
ĐŧĐĩŅĐŊŅĐš в ŅĐĩĐŊСОŅ
res <- do.call(abind::abind, c(res, along = 0))
return(res)
}
āĻĄā§āĻ°āĻ¯āĻŧāĻŋāĻ āĻ¸ā§āĻā§āĻ¯āĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ R āĻā§āĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻ¸āĻā§āĻāĻžāĻ˛āĻŋāĻ¤ āĻšāĻ¯āĻŧ āĻāĻŦāĻ RAM-āĻ¤ā§ āĻ¸āĻāĻ°āĻā§āĻˇāĻŋāĻ¤ āĻāĻāĻāĻŋ āĻ
āĻ¸ā§āĻĨāĻžāĻ¯āĻŧā§ PNG-āĻ¤ā§ āĻ¸āĻāĻ°āĻā§āĻˇāĻŋāĻ¤ āĻšāĻ¯āĻŧ (āĻ˛āĻŋāĻ¨āĻžāĻā§āĻ¸ā§, āĻ
āĻ¸ā§āĻĨāĻžāĻ¯āĻŧā§ R āĻĄāĻŋāĻ°ā§āĻā§āĻāĻ°āĻŋāĻā§āĻ˛āĻŋ āĻĄāĻŋāĻ°ā§āĻā§āĻāĻ°āĻŋāĻ¤ā§ āĻ
āĻŦāĻ¸ā§āĻĨāĻŋāĻ¤āĨ¤ /tmp
, RAM āĻ āĻŽāĻžāĻāĻ¨ā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§)āĨ¤ āĻāĻ āĻĢāĻžāĻāĻ˛āĻāĻŋ āĻ¤āĻžāĻ°āĻĒāĻ° 0 āĻĨā§āĻā§ 1 āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻ¸āĻāĻā§āĻ¯āĻž āĻ¸āĻš āĻāĻāĻāĻŋ āĻ¤ā§āĻ°āĻŋāĻŽāĻžāĻ¤ā§āĻ°āĻŋāĻ āĻ
ā§āĻ¯āĻžāĻ°ā§ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻĒāĻĄāĻŧāĻž āĻšāĻ¯āĻŧā§ˇ āĻāĻāĻŋ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻāĻžāĻ°āĻŖ āĻāĻāĻāĻŋ āĻāĻ°āĻ āĻĒā§āĻ°āĻāĻ˛āĻŋāĻ¤ BMP āĻšā§āĻā§āĻ¸ āĻ°āĻā§āĻ° āĻā§āĻĄ āĻ¸āĻš āĻāĻāĻāĻŋ āĻāĻžāĻāĻāĻž āĻ
ā§āĻ¯āĻžāĻ°ā§āĻ¤ā§ āĻĒāĻĄāĻŧāĻž āĻšāĻŦā§ā§ˇ
āĻāĻ¸ā§āĻ¨ āĻĢāĻ˛āĻžāĻĢāĻ˛ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻž āĻ¯āĻžāĻ:
zip_file <- file.path("data", "train_simplified.zip")
csv_file <- "cat.csv"
unzip(zip_file, files = csv_file, exdir = tempdir(),
junkpaths = TRUE, unzip = getOption("unzip"))
tmp_data <- data.table::fread(file.path(tempdir(), csv_file), sep = ",",
select = "drawing", nrows = 10000)
arr <- r_process_json_str(tmp_data[4, drawing])
dim(arr)
# [1] 256 256 3
plot(magick::image_read(arr))
āĻŦā§āĻ¯āĻžāĻ āĻ¨āĻŋāĻā§āĻ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻāĻ āĻŋāĻ¤ āĻšāĻŦā§:
res <- r_process_json_vector(tmp_data[1:4, drawing], scale = 0.5)
str(res)
# num [1:4, 1:128, 1:128, 1:3] 1 1 1 1 1 1 1 1 1 1 ...
# - attr(*, "dimnames")=List of 4
# ..$ : NULL
# ..$ : NULL
# ..$ : NULL
# ..$ : NULL
āĻāĻ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨āĻāĻŋ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻžāĻā§ āĻ¸āĻ°ā§āĻŦā§āĻ¤ā§āĻ¤āĻŽ āĻŦāĻ˛ā§ āĻŽāĻ¨ā§ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛, āĻ¯ā§āĻšā§āĻ¤ā§ āĻŦāĻĄāĻŧ āĻŦā§āĻ¯āĻžāĻ āĻāĻ āĻ¨ā§ āĻāĻāĻāĻŋ āĻ āĻļāĻžāĻ˛ā§āĻ¨āĻāĻžāĻŦā§ āĻĻā§āĻ°ā§āĻ āĻ¸āĻŽāĻ¯āĻŧ āĻ˛āĻžāĻā§ āĻāĻŦāĻ āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻļāĻā§āĻ¤āĻŋāĻļāĻžāĻ˛ā§ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¸āĻšāĻāĻ°ā§āĻŽā§āĻĻā§āĻ° āĻ āĻāĻŋāĻā§āĻāĻ¤āĻžāĻ° āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻ¨ā§āĻāĻ¯āĻŧāĻžāĻ° āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĨ¤ OpenCV. āĻ¸ā§āĻ āĻ¸āĻŽāĻ¯āĻŧā§ R-āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻā§āĻ¨āĻ āĻ°ā§āĻĄāĻŋāĻŽā§āĻĄ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻāĻŋāĻ˛ āĻ¨āĻž (āĻāĻāĻ¨ āĻ¨ā§āĻ), āĻ¤āĻžāĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻāĻžāĻ°ā§āĻ¯āĻāĻžāĻ°āĻŋāĻ¤āĻžāĻ° āĻāĻāĻāĻŋ āĻ¨ā§āĻ¯ā§āĻ¨āĻ¤āĻŽ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ C++ āĻ āĻ˛ā§āĻāĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ R āĻā§āĻĄ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻā§āĻāĻ°āĻŖā§āĻ° āĻ¸āĻžāĻĨā§ Rcpp.
āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯, āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻāĻŦāĻ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛:
-
OpenCV āĻāĻŽā§āĻ āĻāĻŦāĻ āĻ āĻā§āĻāĻ¨ āĻ˛āĻžāĻāĻ¨ āĻ¸āĻā§āĻā§ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯. āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻĒā§āĻ°āĻŋ-āĻāĻ¨āĻ¸ā§āĻāĻ˛ āĻāĻ°āĻž āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋ āĻāĻŦāĻ āĻšā§āĻĄāĻžāĻ° āĻĢāĻžāĻāĻ˛, āĻ¸ā§āĻāĻ¸āĻžāĻĨā§ āĻĄāĻžāĻāĻ¨āĻžāĻŽāĻŋāĻ āĻ˛āĻŋāĻā§āĻāĻŋāĻāĨ¤
-
āĻāĻā§āĻ¸āĻā§āĻ¨āĻ¸āĻ° āĻŦāĻšā§āĻŽāĻžāĻ¤ā§āĻ°āĻŋāĻ āĻ ā§āĻ¯āĻžāĻ°ā§ āĻāĻŦāĻ āĻā§āĻ¨āĻ¸āĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯āĨ¤ āĻāĻŽāĻ°āĻž āĻāĻāĻ āĻ¨āĻžāĻŽā§āĻ° R āĻĒā§āĻ¯āĻžāĻā§āĻā§ āĻ āĻ¨ā§āĻ¤āĻ°ā§āĻā§āĻā§āĻ¤ āĻšā§āĻĄāĻžāĻ° āĻĢāĻžāĻāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻāĻŋāĨ¤ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋ āĻāĻĒāĻ¨āĻžāĻā§ āĻŦāĻšā§āĻŽāĻžāĻ¤ā§āĻ°āĻŋāĻ āĻ ā§āĻ¯āĻžāĻ°ā§āĻā§āĻ˛āĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻāĻžāĻ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧ, āĻāĻāĻ¯āĻŧ āĻ¸āĻžāĻ°āĻŋ āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻāĻŦāĻ āĻāĻ˛āĻžāĻŽ āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻā§āĻ°āĻŽā§āĨ¤
-
ndjson JSON āĻĒāĻžāĻ°ā§āĻ¸ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯āĨ¤ āĻāĻ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻāĻā§āĻ¸āĻā§āĻ¨āĻ¸āĻ° āĻ¸ā§āĻŦāĻ¯āĻŧāĻāĻā§āĻ°āĻŋāĻ¯āĻŧāĻāĻžāĻŦā§ āĻ¯āĻĻāĻŋ āĻāĻāĻŋ āĻĒā§āĻ°āĻāĻ˛ā§āĻĒā§ āĻāĻĒāĻ¸ā§āĻĨāĻŋāĻ¤ āĻĨāĻžāĻā§āĨ¤
-
RcppThread JSON āĻĨā§āĻā§ āĻāĻāĻāĻŋ āĻā§āĻā§āĻāĻ°ā§āĻ° āĻŽāĻžāĻ˛ā§āĻāĻŋ-āĻĨā§āĻ°ā§āĻĄā§āĻĄ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻ¸āĻāĻāĻ āĻŋāĻ¤ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯āĨ¤ āĻāĻ āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĻā§āĻŦāĻžāĻ°āĻž āĻĒā§āĻ°āĻĻāĻ¤ā§āĻ¤ āĻšā§āĻĄāĻžāĻ° āĻĢāĻžāĻāĻ˛ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§. āĻāĻ°ā§ āĻāĻ¨āĻĒā§āĻ°āĻŋāĻ¯āĻŧ āĻĨā§āĻā§ Rcpp āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻĒā§āĻ¯āĻžāĻā§āĻ, āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻāĻŋāĻ¨āĻŋāĻ¸ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§, āĻāĻāĻāĻŋ āĻ āĻ¨ā§āĻ¤āĻ°ā§āĻ¨āĻŋāĻ°ā§āĻŽāĻŋāĻ¤ āĻ˛ā§āĻĒ āĻŦāĻžāĻ§āĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻā§āĨ¤
āĻāĻāĻŋ āĻ¯ā§ āĻŽā§āĻ˛ā§āĻ¯āĻŦāĻžāĻ¨ āĻāĻā§āĻ¸āĻā§āĻ¨āĻ¸āĻ° āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻāĻĄāĻ¸ā§āĻ¨ā§āĻĄ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻĒāĻ°āĻŋāĻŖāĻ¤ āĻšāĻ¯āĻŧā§āĻā§: āĻāĻāĻŋāĻ° āĻŦā§āĻ¯āĻžāĻĒāĻ āĻāĻžāĻ°ā§āĻ¯āĻāĻžāĻ°āĻŋāĻ¤āĻž āĻāĻŦāĻ āĻāĻā§āĻ āĻāĻžāĻ°ā§āĻ¯āĻāĻžāĻ°āĻŋāĻ¤āĻž āĻāĻžāĻĄāĻŧāĻžāĻ, āĻāĻ° āĻŦāĻŋāĻāĻžāĻļāĻāĻžāĻ°ā§āĻ°āĻž āĻŦā§āĻļ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻļā§āĻ˛ āĻšāĻ¯āĻŧā§ āĻāĻ ā§āĻā§ āĻāĻŦāĻ āĻ āĻŦāĻŋāĻ˛āĻŽā§āĻŦā§ āĻāĻŦāĻ āĻŦāĻŋāĻļāĻĻāĻāĻžāĻŦā§ āĻĒā§āĻ°āĻļā§āĻ¨ā§āĻ° āĻāĻ¤ā§āĻ¤āĻ° āĻĻāĻŋāĻ¯āĻŧā§āĻā§āĨ¤ āĻ¤āĻžāĻĻā§āĻ° āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§, āĻāĻĒā§āĻ¨āĻ¸āĻŋāĻāĻŋ āĻŽā§āĻ¯āĻžāĻā§āĻ°āĻŋāĻā§āĻ¸ā§āĻ° āĻāĻā§āĻ¸āĻā§āĻ¨āĻ¸āĻ° āĻā§āĻ¨āĻ¸āĻ°ā§ āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻž āĻ¸āĻŽā§āĻāĻŦ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛, āĻ¸ā§āĻāĻ¸āĻžāĻĨā§ 3-āĻŽāĻžāĻ¤ā§āĻ°āĻŋāĻ āĻāĻŽā§āĻ āĻā§āĻ¨āĻ¸āĻ°āĻā§āĻ˛āĻŋāĻā§ āĻ¸āĻ āĻŋāĻ āĻŽāĻžāĻ¤ā§āĻ°āĻžāĻ° (āĻŦā§āĻ¯āĻžāĻ āĻ¨āĻŋāĻā§āĻ) 4-āĻŽāĻžāĻ¤ā§āĻ°āĻŋāĻ āĻā§āĻ¨āĻ¸āĻ°ā§ āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻāĻ°āĻžāĻ° āĻāĻĒāĻžāĻ¯āĻŧāĨ¤
Rcpp, xtensor āĻāĻŦāĻ RcppThread āĻļā§āĻāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻĒāĻāĻ°āĻŖ
āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋ āĻāĻŦāĻ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§ āĻāĻ¨āĻ¸ā§āĻāĻ˛ āĻāĻ°āĻž āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻāĻ¤āĻŋāĻļā§āĻ˛ āĻ˛āĻŋāĻā§āĻāĻŋāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻŽāĻ¨ āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋ āĻāĻŽā§āĻĒāĻžāĻāĻ˛ āĻāĻ°āĻ¤ā§, āĻāĻŽāĻ°āĻž āĻĒā§āĻ¯āĻžāĻā§āĻā§ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°āĻž āĻĒā§āĻ˛āĻžāĻāĻāĻ¨ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻāĻŋ Rcpp. āĻ¸ā§āĻŦāĻ¯āĻŧāĻāĻā§āĻ°āĻŋāĻ¯āĻŧāĻāĻžāĻŦā§ āĻĒāĻžāĻĨ āĻāĻŦāĻ āĻĒāĻ¤āĻžāĻāĻž āĻā§āĻāĻā§ āĻĒā§āĻ¤ā§, āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻāĻ¨āĻĒā§āĻ°āĻŋāĻ¯āĻŧ āĻ˛āĻŋāĻ¨āĻžāĻā§āĻ¸ āĻāĻāĻāĻŋāĻ˛āĻŋāĻāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻāĻŋ 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++ āĻ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§āĻ° āĻāĻ¤āĻŋāĻ° āĻ¤ā§āĻ˛āĻ¨āĻž
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++ āĻā§āĻĄā§āĻ° āĻ¸āĻžāĻĨā§ āĻ§āĻ°āĻž āĻ¸āĻŽā§āĻāĻŦ āĻ¨āĻ¯āĻŧāĨ¤
3. āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻĨā§āĻā§ āĻŦā§āĻ¯āĻžāĻ āĻāĻ¨āĻ˛ā§āĻĄ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻāĻžāĻ°ā§
R-āĻāĻ° āĻ°âā§āĻ¯āĻžāĻŽā§āĻ° āĻ¸āĻžāĻĨā§ āĻŽāĻžāĻ¨āĻžāĻ¨āĻ¸āĻ āĻĄā§āĻāĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ¸ā§-āĻ¯ā§āĻā§āĻ¯ āĻā§āĻ¯āĻžāĻ¤āĻŋ āĻ°āĻ¯āĻŧā§āĻā§, āĻ¯āĻāĻ¨ āĻĒāĻžāĻāĻĨāĻ¨āĻāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻŽā§āĻ˛āĻ āĻĄā§āĻāĻž āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻŋāĻ āĻĻā§āĻŦāĻžāĻ°āĻž āĻāĻ°āĻ āĻŦā§āĻļāĻŋāĻˇā§āĻā§āĻ¯āĻ¯ā§āĻā§āĻ¤, āĻ¯āĻž āĻāĻĒāĻ¨āĻžāĻā§ āĻ¸āĻšāĻā§ āĻāĻŦāĻ āĻ¸ā§āĻŦāĻžāĻāĻžāĻŦāĻŋāĻāĻāĻžāĻŦā§ āĻāĻāĻ-āĻ āĻĢ-āĻā§āĻ° āĻāĻŖāĻ¨āĻžāĻā§āĻ˛āĻŋ (āĻŦāĻžāĻšā§āĻ¯āĻŋāĻ āĻŽā§āĻŽāĻ°āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻŖāĻ¨āĻž) āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤ āĻŦāĻ°ā§āĻŖāĻŋāĻ¤ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻĒā§āĻ°ā§āĻā§āĻˇāĻžāĻĒāĻā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻā§āĻ˛āĻžāĻ¸āĻŋāĻ āĻāĻŦāĻ āĻĒā§āĻ°āĻžāĻ¸āĻā§āĻāĻŋāĻ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻšāĻ˛ āĻāĻā§āĻ° āĻ¨āĻŋāĻāĻ°āĻžāĻ˛ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻ āĻ¯āĻž āĻā§āĻ°ā§āĻĄāĻŋāĻ¯āĻŧā§āĻ¨ā§āĻ āĻĄāĻŋāĻ¸ā§āĻ¨ā§āĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ¤ā§ āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŋāĻ¤ āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻ§āĻžāĻĒā§ āĻā§āĻ°ā§āĻĄāĻŋāĻ¯āĻŧā§āĻ¨ā§āĻā§āĻ° āĻāĻ¨ā§āĻŽāĻžāĻ¨āĻŋāĻ āĻāĻāĻāĻŋ āĻā§āĻ āĻ āĻāĻļ āĻĒāĻ°ā§āĻ¯āĻŦā§āĻā§āĻˇāĻŖ āĻŦāĻž āĻŽāĻŋāĻ¨āĻŋ-āĻŦā§āĻ¯āĻžāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĨ¤
āĻĒāĻžāĻāĻĨāĻ¨ā§ āĻ˛ā§āĻāĻž āĻĄāĻŋāĻĒ āĻ˛āĻžāĻ°ā§āĻ¨āĻŋāĻ āĻĢā§āĻ°ā§āĻŽāĻāĻ¯āĻŧāĻžāĻ°ā§āĻāĻā§āĻ˛āĻŋāĻ¤ā§ āĻŦāĻŋāĻļā§āĻˇ āĻā§āĻ˛āĻžāĻ¸ āĻ°āĻ¯āĻŧā§āĻā§ āĻ¯āĻž āĻĄā§āĻāĻžāĻ° āĻāĻĒāĻ° āĻāĻŋāĻ¤ā§āĻ¤āĻŋ āĻāĻ°ā§ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻāĻžāĻ°ā§āĻā§āĻ˛āĻŋāĻā§ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°ā§: āĻā§āĻŦāĻŋāĻ˛, āĻĢā§āĻ˛ā§āĻĄāĻžāĻ°ā§ āĻāĻŦāĻŋ, āĻŦāĻžāĻāĻ¨āĻžāĻ°āĻŋ āĻĢāĻ°ā§āĻŽā§āĻ¯āĻžāĻ āĻāĻ¤ā§āĻ¯āĻžāĻĻāĻŋāĨ¤ āĻāĻĒāĻ¨āĻŋ āĻ¤ā§āĻ°āĻŋ āĻŦāĻŋāĻāĻ˛ā§āĻĒāĻā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻŦāĻž āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻāĻžāĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¨āĻŋāĻā§āĻ° āĻ˛āĻŋāĻāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤ R-āĻ āĻāĻŽāĻ°āĻž āĻĒāĻžāĻāĻĨāĻ¨ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋāĻ° āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŦā§āĻļāĻŋāĻˇā§āĻā§āĻ¯ā§āĻ° āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻ¨āĻŋāĻ¤ā§ āĻĒāĻžāĻ°āĻŋ keras āĻāĻāĻ āĻ¨āĻžāĻŽā§āĻ° āĻĒā§āĻ¯āĻžāĻā§āĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻ° āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻŦā§āĻ¯āĻžāĻāĻāĻ¨ā§āĻĄ āĻ¸āĻš, āĻ¯āĻž āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻāĻĒāĻ°ā§ āĻāĻžāĻ āĻāĻ°ā§ āĻ°ā§āĻāĻŋāĻā§āĻ˛ā§āĻ. āĻĒāĻ°ā§āĻ°āĻāĻŋ āĻāĻāĻāĻŋ āĻĒā§āĻĨāĻ āĻĻā§āĻ°ā§āĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§āĻ° āĻĻāĻžāĻŦāĻŋ āĻ°āĻžāĻā§; āĻāĻāĻŋ āĻāĻĒāĻ¨āĻžāĻā§ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° R āĻĨā§āĻā§ āĻĒāĻžāĻāĻĨāĻ¨ āĻā§āĻĄ āĻāĻžāĻ˛āĻžāĻ¨ā§āĻ° āĻ āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§āĻ¯āĻŧ āĻ¨āĻž, āĻ¤āĻŦā§ āĻāĻĒāĻ¨āĻžāĻā§ R āĻāĻŦāĻ Python āĻ¸ā§āĻļāĻ¨ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻŦāĻ¸ā§āĻ¤ā§ āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻāĻ°āĻžāĻ° āĻ āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§āĻ¯āĻŧ, āĻ¸ā§āĻŦāĻ¯āĻŧāĻāĻā§āĻ°āĻŋāĻ¯āĻŧāĻāĻžāĻŦā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻ§āĻ°āĻ¨ā§āĻ° āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ āĻāĻ°ā§āĨ¤
āĻāĻŽāĻ°āĻž MonetDBLite āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ RAM āĻ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĄā§āĻāĻž āĻ¸āĻā§āĻāĻ¯āĻŧ āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĻ¤āĻž āĻĨā§āĻā§ āĻĒāĻ°āĻŋāĻ¤ā§āĻ°āĻžāĻŖ āĻĒā§āĻ¯āĻŧā§āĻāĻŋ, āĻ¸āĻŽāĻ¸ā§āĻ¤ "āĻ¨āĻŋāĻāĻ°āĻžāĻ˛ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻ" āĻāĻžāĻ āĻĒāĻžāĻāĻĨāĻ¨ā§āĻ° āĻāĻ¸āĻ˛ āĻā§āĻĄ āĻĻā§āĻŦāĻžāĻ°āĻž āĻ¸āĻā§āĻāĻžāĻ˛āĻŋāĻ¤ āĻšāĻŦā§, āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻŦāĻ˛ āĻĄā§āĻāĻžāĻ° āĻāĻĒāĻ°ā§ āĻāĻāĻāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻāĻžāĻ°ā§ āĻ˛āĻŋāĻāĻ¤ā§ āĻšāĻŦā§, āĻ¯ā§āĻšā§āĻ¤ā§ āĻāĻŋāĻā§āĻ āĻĒā§āĻ°āĻ¸ā§āĻ¤ā§āĻ¤ āĻ¨ā§āĻāĨ¤ R āĻŦāĻž Python āĻšāĻ¯āĻŧ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻĒāĻ°āĻŋāĻ¸ā§āĻĨāĻŋāĻ¤āĻŋāĻ° āĻāĻ¨ā§āĻ¯āĨ¤ āĻāĻāĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻŽā§āĻ˛āĻ¤ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻĻā§āĻāĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĻ¤āĻž āĻ°āĻ¯āĻŧā§āĻā§: āĻāĻāĻŋ āĻ āĻŦāĻļā§āĻ¯āĻ āĻāĻāĻāĻŋ āĻ āĻ¨ā§āĻ¤āĻšā§āĻ¨ āĻ˛ā§āĻĒā§ āĻŦā§āĻ¯āĻžāĻāĻā§āĻ˛āĻŋ āĻĢāĻŋāĻ°āĻŋāĻ¯āĻŧā§ āĻāĻ¨āĻ¤ā§ āĻšāĻŦā§ āĻāĻŦāĻ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻŋāĻ° āĻ āĻŦāĻ¸ā§āĻĨāĻž āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§ (āĻāĻ° āĻāĻ° āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§āĻāĻŋ āĻŦāĻ¨ā§āĻ§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻ¸āĻŦāĻā§āĻ¯āĻŧā§ āĻ¸āĻšāĻ āĻāĻĒāĻžāĻ¯āĻŧā§ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§)āĨ¤ āĻĒā§āĻ°ā§āĻŦā§, āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻāĻžāĻ°ā§āĻ° āĻāĻŋāĻ¤āĻ°ā§ 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)
āĻāĻĒāĻ¨āĻžāĻ° āĻ¯āĻĻāĻŋ āĻĒāĻ°ā§āĻ¯āĻžāĻĒā§āĻ¤ āĻĒāĻ°āĻŋāĻŽāĻžāĻŖā§ RAM āĻĨāĻžāĻā§ āĻ¤āĻŦā§ āĻāĻĒāĻ¨āĻŋ āĻāĻ āĻāĻāĻ RAM āĻ āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ° āĻāĻ°ā§ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ā§āĻ° āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ˛āĻžāĻĒāĻā§ āĻā§āĻ°ā§āĻ¤ā§āĻŦ āĻ¸āĻšāĻāĻžāĻ°ā§ āĻĻā§āĻ°ā§āĻ¤ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ (āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻžāĻā§āĻ° āĻāĻ¨ā§āĻ¯ 32 āĻāĻŋāĻŦāĻŋ āĻ¯āĻĨā§āĻˇā§āĻ)āĨ¤ āĻ˛āĻŋāĻ¨āĻžāĻā§āĻ¸ā§, āĻĒāĻžāĻ°ā§āĻāĻŋāĻļāĻ¨āĻāĻŋ āĻĄāĻŋāĻĢāĻ˛ā§āĻāĻ°ā§āĻĒā§ āĻŽāĻžāĻāĻ¨ā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧ /dev/shm
, RAM āĻā§āĻˇāĻŽāĻ¤āĻžāĻ° āĻ
āĻ°ā§āĻ§ā§āĻ āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻĻāĻāĻ˛ āĻāĻ°ā§āĨ¤ āĻāĻĒāĻ¨āĻŋ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨āĻž āĻāĻ°ā§ āĻāĻ°āĻ āĻšāĻžāĻāĻ˛āĻžāĻāĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ /etc/fstab
āĻāĻāĻāĻŋ āĻ°ā§āĻāĻ°ā§āĻĄ āĻĒā§āĻ¤ā§ tmpfs /dev/shm tmpfs defaults,size=25g 0 0
. āĻ°āĻŋāĻŦā§āĻ āĻāĻ°āĻ¤ā§ āĻā§āĻ˛āĻŦā§āĻ¨ āĻ¨āĻž āĻāĻŦāĻ āĻāĻŽāĻžāĻ¨ā§āĻĄāĻāĻŋ āĻāĻžāĻ˛āĻŋāĻ¯āĻŧā§ āĻĢāĻ˛āĻžāĻĢāĻ˛āĻāĻŋ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°ā§āĻ¨ df -h
.
āĻĒāĻ°ā§āĻā§āĻˇāĻžāĻ° āĻĄā§āĻāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻāĻžāĻ°ā§ āĻ āĻ¨ā§āĻ āĻ¸āĻšāĻ āĻĻā§āĻāĻžāĻ¯āĻŧ, āĻ¯ā§āĻšā§āĻ¤ā§ āĻĒāĻ°ā§āĻā§āĻˇāĻžāĻ° āĻĄā§āĻāĻžāĻ¸ā§āĻ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖāĻ°ā§āĻĒā§ RAM-āĻ¤ā§ āĻĢāĻŋāĻ āĻāĻ°ā§:
āĻĒāĻ°ā§āĻā§āĻˇāĻžāĻ° āĻ¤āĻĨā§āĻ¯ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋāĻāĻžāĻ°ā§
test_generator <- function(dt,
batch_size = 32,
scale = 1,
color = FALSE,
imagenet_preproc = FALSE) {
# ĐŅОвĐĩŅĐēĐ° Đ°ŅĐŗŅĐŧĐĩĐŊŅОв
checkmate::assert_data_table(dt)
checkmate::assert_count(batch_size)
checkmate::assert_number(scale, lower = 0.001, upper = 5)
checkmate::assert_flag(color)
checkmate::assert_flag(imagenet_preproc)
# ĐŅĐžŅŅавĐģŅĐĩĐŧ ĐŊĐžĐŧĐĩŅĐ° йаŅŅĐĩĐš
dt[, batch := (.I - 1L) %/% batch_size + 1L]
data.table::setkey(dt, batch)
i <- 1
max_i <- dt[, max(batch)]
# ĐĐ°ĐŧŅĐēĐ°ĐŊиĐĩ
function() {
batch_x <- cpp_process_json_vector(dt[batch == i, drawing],
scale = scale, color = color)
if (imagenet_preproc) {
# ШĐēĐ°ĐģиŅОваĐŊиĐĩ c иĐŊŅĐĩŅваĐģĐ° [0, 1] ĐŊĐ° иĐŊŅĐĩŅваĐģ [-1, 1]
batch_x <- (batch_x - 0.5) * 2
}
result <- list(batch_x)
i <<- i + 1
return(result)
}
}
4. āĻŽāĻĄā§āĻ˛ āĻāĻ°ā§āĻāĻŋāĻā§āĻāĻāĻžāĻ° āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻāĻ¨
āĻĒā§āĻ°āĻĨāĻŽ āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ āĻ¸ā§āĻĨāĻžāĻĒāĻ¤ā§āĻ¯ āĻāĻŋāĻ˛ (batch, height, width, 3)
, āĻ
āĻ°ā§āĻĨāĻžā§ āĻā§āĻ¯āĻžāĻ¨ā§āĻ˛ā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻž āĻ¯āĻžāĻŦā§ āĻ¨āĻžāĨ¤ āĻĒāĻžāĻāĻĨāĻ¨ā§ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻā§āĻ¨ āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§āĻ¤āĻž āĻ¨ā§āĻ, āĻ¤āĻžāĻ āĻāĻŽāĻ°āĻž āĻŽā§āĻ˛ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻāĻŋ āĻ
āĻ¨ā§āĻ¸āĻ°āĻŖ āĻāĻ°ā§ (āĻā§āĻ°āĻžāĻ¸ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖā§ āĻĄā§āĻ°āĻĒāĻāĻāĻ āĻāĻžāĻĄāĻŧāĻž) āĻāĻ āĻāĻ°ā§āĻāĻŋāĻā§āĻāĻāĻžāĻ°āĻāĻŋāĻ° āĻ¨āĻŋāĻāĻ¸ā§āĻŦ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻā§āĻā§ āĻāĻ¸ā§āĻāĻŋ āĻāĻŦāĻ āĻ˛āĻŋāĻā§āĻāĻŋāĻ˛āĻžāĻŽ:
āĻŽā§āĻŦāĻžāĻāĻ˛āĻ¨ā§āĻ v1 āĻāĻ°ā§āĻāĻŋāĻā§āĻāĻāĻžāĻ°
library(keras)
top_3_categorical_accuracy <- custom_metric(
name = "top_3_categorical_accuracy",
metric_fn = function(y_true, y_pred) {
metric_top_k_categorical_accuracy(y_true, y_pred, k = 3)
}
)
layer_sep_conv_bn <- function(object,
filters,
alpha = 1,
depth_multiplier = 1,
strides = c(2, 2)) {
# NB! depth_multiplier != resolution multiplier
# https://github.com/keras-team/keras/issues/10349
layer_depthwise_conv_2d(
object = object,
kernel_size = c(3, 3),
strides = strides,
padding = "same",
depth_multiplier = depth_multiplier
) %>%
layer_batch_normalization() %>%
layer_activation_relu() %>%
layer_conv_2d(
filters = filters * alpha,
kernel_size = c(1, 1),
strides = c(1, 1)
) %>%
layer_batch_normalization() %>%
layer_activation_relu()
}
get_mobilenet_v1 <- function(input_shape = c(224, 224, 1),
num_classes = 340,
alpha = 1,
depth_multiplier = 1,
optimizer = optimizer_adam(lr = 0.002),
loss = "categorical_crossentropy",
metrics = c("categorical_crossentropy",
top_3_categorical_accuracy)) {
inputs <- layer_input(shape = input_shape)
outputs <- inputs %>%
layer_conv_2d(filters = 32, kernel_size = c(3, 3), strides = c(2, 2), padding = "same") %>%
layer_batch_normalization() %>%
layer_activation_relu() %>%
layer_sep_conv_bn(filters = 64, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 128, strides = c(2, 2)) %>%
layer_sep_conv_bn(filters = 128, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 256, strides = c(2, 2)) %>%
layer_sep_conv_bn(filters = 256, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(2, 2)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 1024, strides = c(2, 2)) %>%
layer_sep_conv_bn(filters = 1024, strides = c(1, 1)) %>%
layer_global_average_pooling_2d() %>%
layer_dense(units = num_classes) %>%
layer_activation_softmax()
model <- keras_model(
inputs = inputs,
outputs = outputs
)
model %>% compile(
optimizer = optimizer,
loss = loss,
metrics = metrics
)
return(model)
}
āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻ
āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻā§āĻ˛āĻŋ āĻ¸ā§āĻ¸ā§āĻĒāĻˇā§āĻāĨ¤ āĻāĻŽāĻŋ āĻ
āĻ¨ā§āĻ āĻŽāĻĄā§āĻ˛ āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻ¤ā§ āĻāĻžāĻ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻŦāĻŋāĻĒāĻ°ā§āĻ¤ā§, āĻāĻŽāĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻāĻ°ā§āĻāĻŋāĻā§āĻāĻāĻžāĻ° āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¯āĻŧāĻžāĻ˛āĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻ˛āĻŋāĻāĻ¤ā§ āĻāĻžāĻ āĻ¨āĻžāĨ¤ āĻāĻŽāĻ°āĻž āĻāĻŽā§āĻāĻ¨ā§āĻā§ ââāĻĒā§āĻ°āĻžāĻ-āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŋāĻ¤ āĻŽāĻĄā§āĻ˛ā§āĻ° āĻāĻāĻ¨ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻžāĻ° āĻ¸ā§āĻ¯ā§āĻ āĻĨā§āĻā§āĻ āĻŦāĻā§āĻāĻŋāĻ¤ āĻāĻŋāĻ˛āĻžāĻŽāĨ¤ āĻ¯āĻĨāĻžāĻ°ā§āĻ¤āĻŋ, āĻĄāĻā§āĻŽā§āĻ¨ā§āĻā§āĻļāĻ¨ āĻ
āĻ§ā§āĻ¯āĻ¯āĻŧāĻ¨ āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ āĻāĻ°ā§āĻā§. āĻĢāĻžāĻāĻļāĻ¨ get_config()
āĻāĻĒāĻ¨āĻžāĻā§ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻĒāĻ¯ā§āĻā§āĻ¤ āĻāĻāĻāĻŋ āĻĢāĻ°ā§āĻŽā§ āĻŽāĻĄā§āĻ˛ā§āĻ° āĻāĻāĻāĻŋ āĻŦāĻŋāĻŦāĻ°āĻŖ āĻĒā§āĻ¤ā§ āĻ
āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§āĻ¯āĻŧ (base_model_conf$layers
- āĻāĻāĻāĻŋ āĻ¨āĻŋāĻ¯āĻŧāĻŽāĻŋāĻ¤ R āĻ¤āĻžāĻ˛āĻŋāĻāĻž), āĻāĻŦāĻ āĻĢāĻžāĻāĻļāĻ¨ from_config()
āĻāĻāĻāĻŋ āĻŽāĻĄā§āĻ˛ āĻ
āĻŦāĻā§āĻā§āĻā§ āĻŦāĻŋāĻĒāĻ°ā§āĻ¤ āĻ°ā§āĻĒāĻžāĻ¨ā§āĻ¤āĻ° āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ āĻāĻ°ā§:
base_model_conf <- get_config(base_model)
base_model_conf$layers[[1]]$config$batch_input_shape[[4]] <- 1L
base_model <- from_config(base_model_conf)
āĻāĻāĻ¨ āĻ¸āĻ°āĻŦāĻ°āĻžāĻš āĻāĻ°āĻž āĻ¯ā§āĻā§āĻ¨ā§ āĻāĻāĻāĻŋ āĻĒāĻžāĻāĻ¯āĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ¸āĻžāĻ°ā§āĻŦāĻāĻ¨ā§āĻ¨ āĻĢāĻžāĻāĻļāĻ¨ āĻ˛ā§āĻāĻž āĻāĻ āĻŋāĻ¨ āĻ¨āĻ¯āĻŧ 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)
āĻĒā§āĻ¯āĻžāĻā§āĻ āĻĄāĻāĻĒā§āĻ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻĒā§āĻ°āĻ¤āĻŋāĻ¨āĻŋāĻ§āĻŋāĻ¤ā§āĻŦ āĻāĻ°ā§ 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 āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§
āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻāĻŋ 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
āĻĄāĻŋāĻĢāĻ˛ā§āĻ āĻŽāĻžāĻ¨ āĻ¸āĻš; āĻ¯āĻĻāĻŋ āĻĒā§āĻ°āĻĨāĻŽ āĻ
āĻŦāĻ¸ā§āĻĨāĻžāĻ¨āĻāĻ¤ āĻ¯ā§āĻā§āĻ¤āĻŋ "bash" āĻšāĻ¯āĻŧ, āĻ¤āĻžāĻšāĻ˛ā§ āĻāĻ¨ā§āĻā§āĻāĻ¨āĻžāĻ°āĻāĻŋ āĻāĻāĻāĻŋ āĻāĻŽāĻžāĻ¨ā§āĻĄ āĻļā§āĻ˛ āĻĻāĻŋāĻ¯āĻŧā§ āĻāĻ¨ā§āĻāĻžāĻ°ā§āĻā§āĻāĻŋāĻāĻāĻžāĻŦā§ āĻļā§āĻ°ā§ āĻšāĻŦā§āĨ¤ āĻ
āĻ¨ā§āĻ¯ āĻ¸āĻŦ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻ
āĻŦāĻ¸ā§āĻĨāĻžāĻ¨āĻāĻ¤ āĻāĻ°ā§āĻā§āĻŽā§āĻ¨ā§āĻā§āĻ° āĻŽāĻžāĻ¨ āĻĒā§āĻ°āĻ¤āĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻŋāĻ¤ āĻšāĻ¯āĻŧ: CMD="Rscript /app/train_nn.R $@"
.
āĻāĻāĻŋ āĻ˛āĻā§āĻˇāĻŖā§āĻ¯āĻŧ āĻ¯ā§ āĻāĻ¤ā§āĻ¸ āĻĄā§āĻāĻž āĻāĻŦāĻ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ āĻ¸āĻš āĻĄāĻŋāĻ°ā§āĻā§āĻāĻ°āĻŋāĻā§āĻ˛āĻŋāĻ° āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŋāĻ¤ āĻŽāĻĄā§āĻ˛āĻā§āĻ˛āĻŋ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĄāĻŋāĻ°ā§āĻā§āĻāĻ°āĻŋāĻā§āĻ˛āĻŋ āĻšā§āĻ¸ā§āĻ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽ āĻĨā§āĻā§ āĻāĻ¨ā§āĻā§āĻāĻ¨āĻžāĻ°ā§āĻ° āĻāĻŋāĻ¤āĻ°ā§ āĻŽāĻžāĻāĻ¨ā§āĻ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§, āĻ¯āĻž āĻāĻĒāĻ¨āĻžāĻā§ āĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻŽā§āĻ¯āĻžāĻ¨āĻŋāĻĒā§āĻ˛ā§āĻļāĻ¨ āĻāĻžāĻĄāĻŧāĻžāĻ āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻāĻā§āĻ˛āĻŋāĻ° āĻĢāĻ˛āĻžāĻĢāĻ˛āĻā§āĻ˛āĻŋ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤
7. Google āĻā§āĻ˛āĻžāĻāĻĄā§ āĻāĻāĻžāĻ§āĻŋāĻ GPU āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž
āĻĒā§āĻ°āĻ¤āĻŋāĻ¯ā§āĻāĻŋāĻ¤āĻžāĻ° āĻ
āĻ¨ā§āĻ¯āĻ¤āĻŽ āĻŦā§āĻļāĻŋāĻˇā§āĻā§āĻ¯ āĻāĻŋāĻ˛ āĻā§āĻŦ āĻā§āĻ˛āĻžāĻšāĻ˛āĻĒā§āĻ°ā§āĻŖ āĻĄā§āĻāĻž (āĻļāĻŋāĻ°ā§āĻ¨āĻžāĻŽ āĻāĻŦāĻŋ āĻĻā§āĻā§āĻ¨, ODS āĻ¸ā§āĻ˛ā§āĻ¯āĻžāĻ āĻĨā§āĻā§ @Leigh.plt āĻĨā§āĻā§ āĻ§āĻžāĻ° āĻāĻ°āĻž)āĨ¤ āĻŦāĻĄāĻŧ āĻŦā§āĻ¯āĻžāĻāĻā§āĻ˛āĻŋ āĻāĻāĻŋāĻā§ āĻŽā§āĻāĻžāĻŦā§āĻ˛āĻžāĻ¯āĻŧ āĻ¸āĻšāĻžāĻ¯āĻŧāĻ¤āĻž āĻāĻ°ā§ āĻāĻŦāĻ 1 GPU āĻ¸āĻš āĻāĻāĻāĻŋ āĻĒāĻŋāĻ¸āĻŋāĻ¤ā§ āĻĒāĻ°ā§āĻā§āĻˇāĻž-āĻ¨āĻŋāĻ°ā§āĻā§āĻˇāĻžāĻ° āĻĒāĻ°ā§, āĻāĻŽāĻ°āĻž āĻā§āĻ˛āĻžāĻāĻĄā§ āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ GPU-āĻ¤ā§ āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŖā§āĻ° āĻŽāĻĄā§āĻ˛āĻā§āĻ˛āĻŋ āĻāĻ¯āĻŧāĻ¤ā§āĻ¤ āĻāĻ°āĻžāĻ° āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨āĻŋāĻ¯āĻŧā§āĻāĻŋāĨ¤ āĻŦā§āĻ¯āĻŦāĻšā§āĻ¤ GoogleCloud (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
)
})
āĻ¤āĻžāĻ°āĻĒāĻ°ā§ āĻāĻ¨āĻāĻŽā§āĻĒāĻžāĻāĻ˛ āĻāĻ°āĻž (āĻāĻāĻŋ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ) āĻŽāĻĄā§āĻ˛āĻāĻŋ āĻāĻāĻāĻŋ āĻĒā§āĻ°āĻĻāĻ¤ā§āĻ¤ āĻ¸āĻāĻā§āĻ¯āĻ āĻāĻĒāĻ˛āĻŦā§āĻ§ GPU-āĻ¤ā§ āĻ āĻ¨ā§āĻ˛āĻŋāĻĒāĻŋ āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ¤āĻžāĻ° āĻĒāĻ°ā§ āĻāĻāĻŋ āĻ¸āĻāĻāĻ˛āĻŋāĻ¤ āĻšāĻ¯āĻŧ:
model <- keras::multi_gpu_model(model_cpu, gpus = n_gpu)
keras::compile(
object = model,
optimizer = keras::optimizer_adam(lr = 0.0004),
loss = "categorical_crossentropy",
metrics = c(top_3_categorical_accuracy)
)
āĻļā§āĻˇāĻāĻŋ āĻŦā§āĻ¯āĻ¤ā§āĻ¤ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¸ā§āĻ¤āĻ° āĻšāĻŋāĻŽāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻāĻ°āĻžāĻ° āĻā§āĻ˛āĻžāĻ¸āĻŋāĻ āĻā§āĻļāĻ˛, āĻļā§āĻˇ āĻ¸ā§āĻ¤āĻ°āĻāĻŋāĻā§ āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŖ āĻĻā§āĻāĻ¯āĻŧāĻž, āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ GPU-āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻŽāĻĄā§āĻ˛āĻāĻŋāĻā§ āĻāĻ¨āĻĢā§āĻ°āĻŋāĻ āĻāĻ°āĻž āĻāĻŦāĻ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŖ āĻĻā§āĻāĻ¯āĻŧāĻž āĻ¸āĻŽā§āĻāĻŦ āĻšāĻ¯āĻŧāĻ¨āĻŋā§ˇ
āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŖ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻžāĻĄāĻŧāĻžāĻ āĻĒāĻ°ā§āĻ¯āĻŦā§āĻā§āĻˇāĻŖ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛āĨ¤ āĻā§āĻ¨āĻ¸āĻ°āĻŦā§āĻ°ā§āĻĄ, āĻ˛āĻ āĻ°ā§āĻāĻ°ā§āĻĄāĻŋāĻ āĻāĻŦāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻ¯ā§āĻā§āĻ° āĻĒāĻ°ā§ āĻ¤āĻĨā§āĻ¯āĻĒā§āĻ°ā§āĻŖ āĻ¨āĻžāĻŽ āĻ¸āĻš āĻŽāĻĄā§āĻ˛ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¨āĻŋāĻā§āĻĻā§āĻ°āĻā§ āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§ āĻāĻ°āĻž:
āĻāĻ˛āĻŦā§āĻ¯āĻžāĻ
# ШайĐģĐžĐŊ иĐŧĐĩĐŊи ŅĐ°ĐšĐģĐ° ĐģĐžĐŗĐ°
log_file_tmpl <- file.path("logs", sprintf(
"%s_%d_%dch_%s.csv",
model_name,
dim_size,
channels,
format(Sys.time(), "%Y%m%d%H%M%OS")
))
# ШайĐģĐžĐŊ иĐŧĐĩĐŊи ŅĐ°ĐšĐģĐ° ĐŧОдĐĩĐģи
model_file_tmpl <- file.path("models", sprintf(
"%s_%d_%dch_{epoch:02d}_{val_loss:.2f}.h5",
model_name,
dim_size,
channels
))
callbacks_list <- list(
keras::callback_csv_logger(
filename = log_file_tmpl
),
keras::callback_early_stopping(
monitor = "val_loss",
min_delta = 1e-4,
patience = 8,
verbose = 1,
mode = "min"
),
keras::callback_reduce_lr_on_plateau(
monitor = "val_loss",
factor = 0.5, # ŅĐŧĐĩĐŊŅŅĐ°ĐĩĐŧ lr в 2 ŅаСа
patience = 4,
verbose = 1,
min_delta = 1e-4,
mode = "min"
),
keras::callback_model_checkpoint(
filepath = model_file_tmpl,
monitor = "val_loss",
save_best_only = FALSE,
save_weights_only = FALSE,
mode = "min"
)
)
8. āĻāĻāĻāĻŋ āĻāĻĒāĻ¸āĻāĻšāĻžāĻ°ā§āĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤ā§
āĻāĻŽāĻ°āĻž āĻ¯ā§ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻ¸āĻŽā§āĻŽā§āĻā§āĻ¨ āĻšāĻ¯āĻŧā§āĻāĻŋ āĻ¤āĻžāĻ° āĻāĻāĻāĻŋ āĻ¸āĻāĻā§āĻ¯āĻž āĻāĻāĻ¨āĻ āĻāĻžāĻāĻŋāĻ¯āĻŧā§ āĻāĻ āĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĻ¨āĻŋ:
- в keras āĻ¸āĻ°ā§āĻŦā§āĻ¤ā§āĻ¤āĻŽ āĻļā§āĻāĻžāĻ° āĻšāĻžāĻ° (āĻ
ā§āĻ¯āĻžāĻ¨āĻžāĻ˛āĻ
lr_finder
āĻā§āĻ°āĻ¨ā§āĻĨāĻžāĻāĻžāĻ°ā§ quick.ai); āĻāĻŋāĻā§ āĻĒā§āĻ°āĻā§āĻˇā§āĻāĻžāĻ° āĻ¸āĻžāĻĨā§, āĻ¤ā§āĻ¤ā§āĻ¯āĻŧ āĻĒāĻā§āĻˇā§āĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨āĻā§ R-āĻ āĻĒā§āĻ°ā§āĻ āĻāĻ°āĻž āĻ¸āĻŽā§āĻāĻŦ, āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ,āĻāĻ ; - āĻĒā§āĻ°ā§āĻŦāĻŦāĻ°ā§āĻ¤ā§ āĻĒāĻ¯āĻŧā§āĻ¨ā§āĻā§āĻ° āĻĢāĻ˛āĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ GPU āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¸āĻ āĻŋāĻ āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŖā§āĻ° āĻāĻ¤āĻŋ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻāĻ¨ āĻāĻ°āĻž āĻ¸āĻŽā§āĻāĻŦ āĻāĻŋāĻ˛ āĻ¨āĻž;
- āĻāĻ§ā§āĻ¨āĻŋāĻ āĻ¨āĻŋāĻāĻ°āĻžāĻ˛ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻ āĻāĻ°ā§āĻāĻŋāĻā§āĻāĻāĻžāĻ°ā§āĻ° āĻ āĻāĻžāĻŦ āĻ°āĻ¯āĻŧā§āĻā§, āĻŦāĻŋāĻļā§āĻˇ āĻāĻ°ā§ āĻ¯ā§āĻā§āĻ˛āĻŋ āĻāĻŽā§āĻāĻ¨ā§āĻā§ ââāĻĒā§āĻ°āĻžāĻ-āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŋāĻ¤;
- āĻā§āĻ¨ āĻāĻ āĻāĻā§āĻ° āĻ¨ā§āĻ¤āĻŋ āĻāĻŦāĻ āĻŦā§āĻˇāĻŽā§āĻ¯āĻŽā§āĻ˛āĻ āĻļāĻŋāĻā§āĻˇāĻžāĻ° āĻšāĻžāĻ° (āĻā§āĻ¸āĻžāĻāĻ¨ āĻ
ā§āĻ¯āĻžāĻ¨āĻŋāĻ˛āĻŋāĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻ
āĻ¨ā§āĻ°ā§āĻ§ā§ āĻāĻŋāĻ˛
āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻŋāĻ¤ , āĻ§āĻ¨ā§āĻ¯āĻŦāĻžāĻĻāĻ¸ā§āĻāĻžāĻāĻĄāĻžāĻ¨ ).
āĻāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻ¯ā§āĻāĻŋāĻ¤āĻž āĻĨā§āĻā§ āĻā§ āĻā§ āĻĻāĻ°āĻāĻžāĻ°ā§ āĻāĻŋāĻ¨āĻŋāĻ¸ āĻļāĻŋāĻā§āĻā§:
- āĻ āĻĒā§āĻā§āĻˇāĻžāĻā§āĻ¤ āĻāĻŽ-āĻĒāĻžāĻāĻ¯āĻŧāĻžāĻ° āĻšāĻžāĻ°ā§āĻĄāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ°ā§, āĻāĻĒāĻ¨āĻŋ āĻŦā§āĻ¯āĻĨāĻž āĻāĻžāĻĄāĻŧāĻžāĻ āĻļāĻžāĻ˛ā§āĻ¨ (āĻ°ā§āĻ¯āĻžāĻŽā§āĻ° āĻāĻāĻžāĻ°ā§āĻ° āĻ āĻ¨ā§āĻ āĻā§āĻŖ) āĻāĻ˛āĻŋāĻāĻŽ āĻĄā§āĻāĻž āĻ¨āĻŋāĻ¯āĻŧā§ āĻāĻžāĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤ āĻĒā§āĻ˛āĻžāĻ¸ā§āĻāĻŋāĻ āĻŦā§āĻ¯āĻžāĻ āĻĄā§āĻāĻž.āĻā§āĻ¯āĻžāĻŦāĻ˛ āĻā§āĻŦāĻŋāĻ˛ā§āĻ° āĻāĻ¨-āĻĒā§āĻ˛ā§āĻ¸ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ā§āĻ° āĻāĻžāĻ°āĻŖā§ āĻŽā§āĻŽāĻ°āĻŋ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°ā§, āĻ¯āĻž āĻ¤āĻžāĻĻā§āĻ° āĻ āĻ¨ā§āĻ˛āĻŋāĻĒāĻŋ āĻāĻ°āĻž āĻāĻĄāĻŧāĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻ¯āĻŧ āĻāĻŦāĻ āĻ¸āĻ āĻŋāĻāĻāĻžāĻŦā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ˛ā§, āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻāĻŋāĻ āĻāĻžāĻˇāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻžāĻā§ āĻĒāĻ°āĻŋāĻāĻŋāĻ¤ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¸āĻ°āĻā§āĻāĻžāĻŽāĻā§āĻ˛āĻŋāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻ° āĻā§āĻˇāĻŽāĻ¤āĻžāĻā§āĻ˛āĻŋ āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻ¸āĻŦāĻ¸āĻŽāĻ¯āĻŧāĻ āĻ¸āĻ°ā§āĻŦā§āĻā§āĻ āĻāĻ¤āĻŋ āĻĒā§āĻ°āĻĻāĻ°ā§āĻļāĻ¨ āĻāĻ°ā§āĨ¤ āĻāĻāĻāĻŋ āĻĄāĻžāĻāĻžāĻŦā§āĻ¸ā§ āĻĄā§āĻāĻž āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻž āĻāĻĒāĻ¨āĻžāĻā§ āĻ āĻ¨ā§āĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻĄā§āĻāĻžāĻ¸ā§āĻāĻā§ RAM-āĻ¤ā§ āĻā§āĻĒā§ āĻĻā§āĻāĻ¯āĻŧāĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻŋāĻ¨ā§āĻ¤āĻž āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧ āĻ¨āĻžāĨ¤
- āĻĒā§āĻ¯āĻžāĻā§āĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ R-āĻ āĻ§ā§āĻ° āĻĢāĻžāĻāĻļāĻ¨ C++-āĻ āĻĻā§āĻ°ā§āĻ¤ āĻĢāĻžāĻāĻļāĻ¨ āĻĻāĻŋāĻ¯āĻŧā§ āĻĒā§āĻ°āĻ¤āĻŋāĻ¸ā§āĻĨāĻžāĻĒāĻ¨ āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§ Rcpp. āĻāĻāĻžāĻĄāĻŧāĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ˛ā§ RcppThread āĻŦāĻž Rcpp āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛, āĻāĻŽāĻ°āĻž āĻā§āĻ°āĻ¸-āĻĒā§āĻ˛ā§āĻ¯āĻžāĻāĻĢāĻ°ā§āĻŽ āĻŽāĻžāĻ˛ā§āĻāĻŋ-āĻĨā§āĻ°ā§āĻĄā§āĻĄ āĻāĻŽāĻĒā§āĻ˛āĻŋāĻŽā§āĻ¨ā§āĻā§āĻļāĻ¨ āĻĒāĻžāĻ, āĻ¤āĻžāĻ R āĻ˛ā§āĻā§āĻ˛ā§ āĻā§āĻĄāĻāĻŋāĻā§ āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻāĻ°āĻžāĻ° āĻĻāĻ°āĻāĻžāĻ° āĻ¨ā§āĻāĨ¤
- āĻĒā§āĻ¯āĻžāĻā§āĻ Rcpp C++ āĻāĻ° āĻā§āĻ°ā§āĻ¤āĻ° āĻā§āĻāĻžāĻ¨ āĻāĻžāĻĄāĻŧāĻžāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§, āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻ¨ā§āĻ¯ā§āĻ¨āĻ¤āĻŽ āĻ°ā§āĻĒāĻ°ā§āĻāĻž āĻĻā§āĻāĻ¯āĻŧāĻž āĻāĻā§
āĻāĻāĻžāĻ¨ā§ . āĻŦā§āĻļ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻļā§āĻ¤āĻ˛ āĻ¸āĻŋ-āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻšā§āĻĄāĻžāĻ° āĻĢāĻžāĻāĻ˛ āĻāĻā§āĻ¸āĻā§āĻ¨āĻ¸āĻ° CRAN-āĻ āĻāĻĒāĻ˛āĻŦā§āĻ§, āĻ āĻ°ā§āĻĨāĻžā§, āĻĒā§āĻ°āĻāĻ˛ā§āĻĒāĻā§āĻ˛āĻŋ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻĒāĻ°āĻŋāĻāĻžāĻ āĻžāĻŽā§ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻž āĻšāĻā§āĻā§ āĻ¯āĻž āĻ°ā§āĻĄāĻŋāĻŽā§āĻĄ āĻšāĻžāĻ-āĻĒāĻžāĻ°āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¸ C++ āĻā§āĻĄāĻā§ R-āĻ¤ā§ āĻ¸āĻāĻšāĻ¤ āĻāĻ°ā§āĨ¤ āĻ āĻ¤āĻŋāĻ°āĻŋāĻā§āĻ¤ āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻšāĻ˛ āĻ¸āĻŋāĻ¨āĻā§āĻ¯āĻžāĻā§āĻ¸ āĻšāĻžāĻāĻ˛āĻžāĻāĻāĻŋāĻ āĻāĻŦāĻ RStudio-āĻ¤ā§ āĻāĻāĻāĻŋ āĻ¸ā§āĻā§āĻ¯āĻžāĻāĻŋāĻ C++ āĻā§āĻĄ āĻŦāĻŋāĻļā§āĻ˛ā§āĻˇāĻāĨ¤ - āĻĄāĻāĻĒā§āĻ āĻāĻĒāĻ¨āĻžāĻā§ āĻĒāĻ°āĻžāĻŽāĻŋāĻ¤āĻŋ āĻ¸āĻš āĻ¸ā§āĻŦāĻ¯āĻŧāĻāĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻ¸ā§āĻā§āĻ°āĻŋāĻĒā§āĻ āĻāĻžāĻ˛āĻžāĻ¨ā§āĻ° āĻ āĻ¨ā§āĻŽāĻ¤āĻŋ āĻĻā§āĻ¯āĻŧāĨ¤ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻĻā§āĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°ā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻāĻ¨āĻ, āĻ¸āĻšāĨ¤ āĻĄāĻāĻžāĻ° āĻ āĻ§ā§āĻ¨ā§ RStudio-āĻ¤ā§, āĻ¨āĻŋāĻāĻ°āĻžāĻ˛ āĻ¨ā§āĻāĻāĻ¯āĻŧāĻžāĻ°ā§āĻā§āĻ° āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŖ āĻ¨āĻŋāĻ¯āĻŧā§ āĻ āĻ¨ā§āĻ āĻāĻ¨ā§āĻāĻž āĻĒāĻ°ā§āĻā§āĻˇāĻž-āĻ¨āĻŋāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻž āĻ āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻāĻ¨āĻ, āĻāĻŦāĻ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°ā§ IDE āĻāĻ¨āĻ¸ā§āĻāĻ˛ āĻāĻ°āĻž āĻ¸āĻ°ā§āĻŦāĻĻāĻž āĻ¨ā§āĻ¯āĻžāĻ¯āĻŧāĻ¸āĻā§āĻāĻ¤ āĻ¨āĻ¯āĻŧāĨ¤
- āĻĄāĻāĻžāĻ° OS āĻāĻŦāĻ āĻ˛āĻžāĻāĻŦā§āĻ°ā§āĻ°āĻŋāĻ° āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖ āĻ¸āĻš āĻĄā§āĻā§āĻ˛āĻĒāĻžāĻ°āĻĻā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĢāĻ˛āĻžāĻĢāĻ˛ā§āĻ° āĻā§āĻĄ āĻŦāĻšāĻ¨āĻ¯ā§āĻā§āĻ¯āĻ¤āĻž āĻāĻŦāĻ āĻĒā§āĻ¨āĻ°ā§āĻ¤ā§āĻĒāĻžāĻĻāĻ¨āĻ¯ā§āĻā§āĻ¯āĻ¤āĻž āĻ¨āĻŋāĻļā§āĻāĻŋāĻ¤ āĻāĻ°ā§, āĻ¸ā§āĻāĻ¸āĻžāĻĨā§ āĻ¸āĻžāĻ°ā§āĻāĻžāĻ°āĻā§āĻ˛āĻŋāĻ¤ā§ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨ā§āĻ° āĻ¸āĻšāĻāĻ¤āĻžāĨ¤ āĻāĻĒāĻ¨āĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻāĻāĻāĻŋ āĻāĻŽāĻžāĻ¨ā§āĻĄ āĻĻāĻŋāĻ¯āĻŧā§ āĻ¸āĻŽāĻā§āĻ° āĻĒā§āĻ°āĻļāĻŋāĻā§āĻˇāĻŖ āĻĒāĻžāĻāĻĒāĻ˛āĻžāĻāĻ¨ āĻāĻžāĻ˛ā§ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤
- Google āĻā§āĻ˛āĻžāĻāĻĄ āĻŦā§āĻ¯āĻ¯āĻŧāĻŦāĻšā§āĻ˛ āĻšāĻžāĻ°ā§āĻĄāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻŦāĻžāĻā§āĻ-āĻŦāĻžāĻ¨ā§āĻ§āĻŦ āĻāĻĒāĻžāĻ¯āĻŧ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻĒāĻ¨āĻžāĻā§ āĻ¸āĻžāĻŦāĻ§āĻžāĻ¨ā§ āĻāĻ¨āĻĢāĻŋāĻāĻžāĻ°ā§āĻļāĻ¨ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻāĻ¨ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤
- āĻĒā§āĻĨāĻ āĻā§āĻĄā§āĻ° āĻā§āĻāĻ°ā§āĻā§āĻ˛āĻŋāĻ° āĻāĻ¤āĻŋ āĻĒāĻ°āĻŋāĻŽāĻžāĻĒ āĻāĻ°āĻž āĻā§āĻŦ āĻĻāĻ°āĻāĻžāĻ°ā§, āĻŦāĻŋāĻļā§āĻˇāĻ¤ āĻ¯āĻāĻ¨ R āĻāĻŦāĻ C++ āĻāĻŦāĻ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻ¨ā§āĻ¯āĻžāĻ¯āĻŧāĻžāĻ¸āĻ¨ - āĻāĻāĻžāĻĄāĻŧāĻžāĻ āĻā§āĻŦ āĻ¸āĻšāĻāĨ¤
āĻ¸āĻžāĻŽāĻā§āĻ°āĻŋāĻāĻāĻžāĻŦā§ āĻāĻ āĻ āĻāĻŋāĻā§āĻāĻ¤āĻž āĻā§āĻŦāĻ āĻĢāĻ˛āĻĒā§āĻ°āĻ¸ā§ āĻāĻŋāĻ˛ āĻāĻŦāĻ āĻāĻŽāĻ°āĻž āĻāĻ¤ā§āĻĨāĻžāĻĒāĻŋāĻ¤ āĻāĻŋāĻā§ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻžāĻ āĻāĻžāĻ˛āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻā§āĻāĻŋāĨ¤
āĻāĻ¤ā§āĻ¸: www.habr.com