แฐแแ แฐแแแ !
แแแกแฃแ แจแแแแแแแแแแ แแแแแแ แฃแแแกแแแแซแแ แแแแแฃแ แกแก แฎแแแแ แแแฎแแขแฃแแ แกแฃแ แแแแแแก แแแแกแแคแแแแชแแแกแแแแก, Quick Draw Doodle Recognition, แ แแแแแจแแช, แกแฎแแแแ แจแแ แแก, R-แแแชแแแแ แแ แฏแแฃแคแแ แแแแฆแ แแแแแฌแแแแแแ:
แแแฏแแ แแ แแแแแแแแก แแแฃแ แแแแแแ แแ แแแแแแ แแแ, แแแแ แแ แแแแ แฆแแ แแแฃแแ แแแแแชแแแแแแ แแแแ แแแแ, แแแแขแแ แแกแฃแ แก แกแแแแแแแแแแแก แแฃแแฎแ แ แ แแแแแแแแ แงแแแแแแ แกแแแแขแแ แแกแ แแ แกแแกแแ แแแแแ แ แแ แแแแแแแ แแ แงแแแแแแฆแแฃแ แกแแฅแแแแแแแแจแ. แแแแฎแแแฃแ แแแแแแก แจแแ แแก: แ แแฃแแ แชแฎแแแ แแแ แแแ แแจแ OpenCV, JSON แแแ แกแแแแ (แแก แแแแแแแแแแ แแแแแฎแแแแแก C++ แแแแแก แแแขแแแ แแชแแแก แกแแ แแแขแแแจแ แแ R-แจแ แแแแแขแแแจแ, แแแแแงแแแแแแ Rcpp), แกแแ แแแขแแแแก แแแ แแแแขแ แแแแชแแ แแ แกแแแแแแ แแแแฎแกแแแก แแแแแ แแแแชแแ. แจแแขแงแแแแแแแแแแแแ แงแแแแ แแแแ แจแแกแแกแ แฃแแแแแแ แจแแกแแคแแ แแกแ แคแแ แแแ แฎแแแแแกแแฌแแแแแแ
แจแแแแแ แกแ:
แแคแแฅแขแฃแ แแ แฉแแขแแแ แแแ แแแแแชแแแแแ CSV-แแแ MonetDB-แจแ แแแ แขแแแแแก แแแแแแแแแ แแขแแ แแขแแ แแแ แแแ แขแแแแแก แแแแแชแแแแ แแแแแแแ แแแแแแขแแแ แแแแกแแแแก แแแแแแแก แแ แฅแแขแแฅแขแฃแ แแก แจแแ แฉแแแ แกแแ แแแขแแก แแแ แแแแขแ แแแแชแแ แกแแ แแแขแแแแก แแแแแ แแแแชแแ Google Cloud-แแ แแ แแแแแ GPU-แก แแแแแงแแแแแ แแแแก แแแชแแแแ, แ แแ แแแกแแแแ
1. แแคแแฅแขแฃแ แแ แฉแแขแแแ แแแ แแแแแชแแแแแ CSV-แแแ MonetDB แแแแแชแแแแ แแแแแจแ
แแ แแแแแฃแ แกแแก แแแแแชแแแแแ แแแฌแแแแแฃแแแ แแ แ แแแ แกแฃแ แแแแแแก แกแแฎแแ, แแ แแแแ 340 CSV แคแแแแแก แกแแฎแแ (แแแแ แคแแแแ แแแแแแฃแ แแแแกแแ), แ แแแแแแช แจแแแชแแแก JSON-แแแก แฌแแ แขแแแแแแแ แแแแ แแแแแขแแแแ. แแ แฌแแ แขแแแแแแก แฎแแแแแแแ แจแแแ แแแแแ แแแแแฆแแแ แกแแแแแแ แกแฃแ แแแก 256x256 แแแฅแกแแแแก แแแแแก. แแกแแแ แแแแแแฃแแ แฉแแแแฌแแ แแกแแแแก แแ แแก แแขแแแแขแ, แ แแแแแแช แแแฃแแแแแแก, แกแฌแแ แแ แแฅแแ แแฃ แแ แ แกแฃแ แแแแก แแแแชแแแแ แแแแกแแคแแแแขแแ แแก แแแแ , แ แแแแแแช แแแแแแงแแแแแ แแแแแชแแแแ แแแแ แแแแก แจแแแ แแแแแแก แแ แแก, แกแฃแ แแแแก แแแขแแ แแก แกแแชแฎแแแ แแแแแ แฅแแแงแแแก แแ แแกแแแแแ แแแแ, แฃแแแแแแฃแ แ แแแแแขแแคแแแแขแแ แ, แแ แแแก แจแขแแแแ. แแ แแแแกแแก แกแแฎแแแ, แ แแแแแแช แจแแแกแแแแแแแ แคแแแแแก แกแแฎแแแก. แแ แแแแแแแฃแ แ แแแแแชแแแแแแก แแแแแ แขแแแแแฃแแ แแแ แกแแ แแฌแแแแก 7.4 GB แแ แฅแแแจแ แแ แแแแฎแแแแแแ 20 GB แจแแคแฃแแแแก แจแแแแแ, แกแ แฃแแ แแแแแชแแแแแ 240 GB-แก แจแแแแแแแก. แแ แแแแแแแขแแ แแแแ แแแ แฌแแฃแแแแแ, แ แแ แแ แแแ แแแ แกแแแจแ แแ แแ แแ แแแแแ แแแฎแแขแแแแก แ แแแ แแแฃแชแแ แแแ แแแฎแแ, แ แแช แแแแก แแแจแแแแก, แ แแ แกแ แฃแแ แแแ แกแแ แแแแแแขแ แแงแ. แแแแแกแแแแ แจแแแแฎแแแแแจแ, 50 แแแแแแแ แกแฃแ แแแแก แแ แแคแแแฃแ แคแแแแแแจแ แแ แแแกแแแแแแก แกแแฎแแ แจแแแแฎแแ แแแจแแแแ แฌแแแแแแแ แฉแแแแแแแ แแ แฉแแแ แแแแแแฌแงแแแขแแ แจแแแแแแ แแแแแแ แงแแแแ CSV แคแแแแ แแ แฅแแแแแแ. train_simplified.zip แแแแแชแแแแ แแแแแจแ แกแแญแแ แ แแแแแก แกแฃแ แแแแแแก แจแแแแแแแ แแแแแ แแ แแแแ แแแแแแฃแแ แแแ แขแแแกแแแแก.
แแแ แแแ แแแแแกแขแฃแ แแแฃแแ แกแแกแขแแแ แแแ แฉแแแก DBMS-แแ 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 แคแแแแแแแก แแแ แแแแแ แแแแแ แแแ SQL - แแ แซแแแแแแก แแแแแงแแแแแแ COPY OFFSET 2 INTO tablename FROM path USING DELIMITERS ',','n','"' NULL AS '' BEST EFFORT
แกแแ tablename
- แแแแแแแก แกแแฎแแแ แแ path
- แคแแแแแก แแแ. แแ แฅแแแแแ แแฃแจแแแแแกแแก แแแแ แแแ, แ แแ แฉแแจแแแแแฃแแ แแแแฎแแ แชแแแแแแ unzip
in R แแ แแฃแจแแแแก แกแฌแแ แแ แแ แฅแแแแแแ แ แแแแแแแแ แคแแแแแแ, แแแแขแแ แฉแแแ แแแแแแแงแแแแ แกแแกแขแแแ unzip
(แแแ แแแแขแ แแก แแแแแงแแแแแแ getOption("unzip")
).
แแแแแชแแแแ แแแแแจแ แฉแแฌแแ แแก แคแฃแแฅแชแแ
#' @title ะะทะฒะปะตัะตะฝะธะต ะธ ะทะฐะณััะทะบะฐ ัะฐะนะปะพะฒ
#'
#' @description
#' ะะทะฒะปะตัะตะฝะธะต CSV-ัะฐะนะปะพะฒ ะธะท ZIP-ะฐัั
ะธะฒะฐ ะธ ะทะฐะณััะทะบะฐ ะธั
ะฒ ะฑะฐะทั ะดะฐะฝะฝัั
#'
#' @param con ะะฑัะตะบั ะฟะพะดะบะปััะตะฝะธั ะบ ะฑะฐะทะต ะดะฐะฝะฝัั
(ะบะปะฐัั `MonetDBEmbeddedConnection`).
#' @param tablename ะะฐะทะฒะฐะฝะธะต ัะฐะฑะปะธัั ะฒ ะฑะฐะทะต ะดะฐะฝะฝัั
.
#' @oaram zipfile ะััั ะบ ZIP-ะฐัั
ะธะฒั.
#' @oaram filename ะะผั ัะฐะนะปะฐ ะฒะฝััะธ ZIP-ะฐัั
ะธะฒะฐ.
#' @param preprocess ะคัะฝะบัะธั ะฟัะตะดะพะฑัะฐะฑะพัะบะธ, ะบะพัะพัะฐั ะฑัะดะตั ะฟัะธะผะตะฝะตะฝะฐ ะธะทะฒะปะตััะฝะฝะพะผั ัะฐะนะปั.
#' ะะพะปะถะฝะฐ ะฟัะธะฝะธะผะฐัั ะพะดะธะฝ ะฐัะณัะผะตะฝั `data` (ะพะฑัะตะบั `data.table`).
#'
#' @return `TRUE`.
#'
upload_file <- function(con, tablename, zipfile, filename, preprocess = NULL) {
# ะัะพะฒะตัะบะฐ ะฐัะณัะผะตะฝัะพะฒ
checkmate::assert_class(con, "MonetDBEmbeddedConnection")
checkmate::assert_string(tablename)
checkmate::assert_string(filename)
checkmate::assert_true(DBI::dbExistsTable(con, tablename))
checkmate::assert_file_exists(zipfile, access = "r", extension = "zip")
checkmate::assert_function(preprocess, args = c("data"), null.ok = TRUE)
# ะะทะฒะปะตัะตะฝะธะต ัะฐะนะปะฐ
path <- file.path(tempdir(), filename)
unzip(zipfile, files = filename, exdir = tempdir(),
junkpaths = TRUE, unzip = getOption("unzip"))
on.exit(unlink(file.path(path)))
# ะัะธะผะตะฝัะตะผ ััะฝะบัะธั ะฟัะตะดะพะฑัะฐะฑะพัะบะธ
if (!is.null(preprocess)) {
.data <- data.table::fread(file = path)
.data <- preprocess(data = .data)
data.table::fwrite(x = .data, file = path, append = FALSE)
rm(.data)
}
# ะะฐะฟัะพั ะบ ะะ ะฝะฐ ะธะผะฟะพัั CSV
sql <- sprintf(
"COPY OFFSET 2 INTO %s FROM '%s' USING DELIMITERS ',','n','"' NULL AS '' BEST EFFORT",
tablename, path
)
# ะัะฟะพะปะฝะตะฝะธะต ะทะฐะฟัะพัะฐ ะบ ะะ
DBI::dbExecute(con, sql)
# ะะพะฑะฐะฒะปะตะฝะธะต ะทะฐะฟะธัะธ ะพะฑ ััะฟะตัะฝะพะน ะทะฐะณััะทะบะต ะฒ ัะปัะถะตะฑะฝัั ัะฐะฑะปะธัั
DBI::dbExecute(con, sprintf("INSERT INTO upload_log(file_name, uploaded) VALUES('%s', true)",
filename))
return(invisible(TRUE))
}
แแฃ แแฅแแแ แแญแแ แแแแแ แชแฎแ แแแแก แขแ แแแกแคแแ แแแชแแ แแแแแชแแแแ แแแแแจแ แฉแแฌแแ แแแแ, แกแแแแแ แแกแแ แแ แแฃแแแแขแจแ แฉแแแแ แแแ preprocess
แคแฃแแฅแชแแ, แ แแแแแแช แแแ แแแฅแแแแก แแแแแชแแแแแก.
แแแแแชแแแแ แแแแแจแ แแแแแชแแแแแแก แแแแแแแแแแ แฃแแ แฉแแขแแแ แแแแก แแแแ:
แแแแแชแแแแ แแแแแจแ แฉแแฌแแ แ
# ะกะฟะธัะพะบ ัะฐะนะปะพะฒ ะดะปั ะทะฐะฟะธัะธ
files <- unzip(zipfile, list = TRUE)$Name
# ะกะฟะธัะพะบ ะธัะบะปััะตะฝะธะน, ะตัะปะธ ัะฐััั ัะฐะนะปะพะฒ ัะถะต ะฑัะปะฐ ะทะฐะณััะถะตะฝะฐ
to_skip <- DBI::dbGetQuery(con, "SELECT file_name FROM upload_log")[[1L]]
files <- setdiff(files, to_skip)
if (length(files) > 0L) {
# ะะฐะฟััะบะฐะตะผ ัะฐะนะผะตั
tictoc::tic()
# ะัะพะณัะตัั ะฑะฐั
pb <- txtProgressBar(min = 0L, max = length(files), style = 3)
for (i in seq_along(files)) {
upload_file(con = con, tablename = "doodles",
zipfile = zipfile, filename = files[i])
setTxtProgressBar(pb, i)
}
close(pb)
# ะััะฐะฝะฐะฒะปะธะฒะฐะตะผ ัะฐะนะผะตั
tictoc::toc()
}
# 526.141 sec elapsed - ะบะพะฟะธัะพะฒะฐะฝะธะต SSD->SSD
# 558.879 sec elapsed - ะบะพะฟะธัะพะฒะฐะฝะธะต USB->SSD
แแแแแชแแแแ แฉแแขแแแ แแแแก แแ แ แจแแแซแแแแ แแแแกแฎแแแแแแแแแแก แแแแแงแแแแแฃแแ แแแกแแแก แกแแฉแฅแแ แแก แแแฎแแกแแแแแแแแแแก แแแฎแแแแแ. แฉแแแแก แจแแแแฎแแแแแจแ, แแ แแ SSD-แจแ แแ แคแแแจ แแ แแแแแแแ (แฌแงแแ แ แคแแแแ) SSD-แแแ (DB) แแแแฎแแแกแ แแ แฉแแฌแแ แแก 10 แฌแฃแแแ แแแแแแ แแ แ แกแญแแ แแแแ.
แแแแแ แ แแแแแแแแ แฌแแแ แกแญแแ แแแแ แกแแแขแแก แจแแฅแแแแก แแแแแ แแแแกแแก แแแแแแแ แแ แแแแแฅแกแแก แกแแแขแแ (ORDERED INDEX
) แกแขแ แแฅแแแแแแก แแแแ แแแแ, แ แแแแแแแแแช แแฅแแแแ แแแแแแ แแแแแก แแแแฃแจแแก แแฆแแแ แแแ แขแแแแแก แจแแฅแแแแกแแก:
แแแแแขแแแแแ แกแแแขแแแแก แแ แแแแแฅแกแแก แจแแฅแแแ
message("Generate lables")
invisible(DBI::dbExecute(con, "ALTER TABLE doodles ADD label_int int"))
invisible(DBI::dbExecute(con, "UPDATE doodles SET label_int = dense_rank() OVER (ORDER BY word) - 1"))
message("Generate row numbers")
invisible(DBI::dbExecute(con, "ALTER TABLE doodles ADD id serial"))
invisible(DBI::dbExecute(con, "CREATE ORDERED INDEX doodles_id_ord_idx ON doodles(id)"))
แคแ แแแแก แแ แแก แฏแแฃแคแแก แจแแฅแแแแก แแ แแแแแแแก แแแแแกแแญแ แแแแ, แฉแแแ แแแญแแ แแแแแแ แแแแแแแแแ แจแแแแฎแแแแแแ แ แแแแแแก แแแแฆแแแแก แแแฅแกแแแแแฃแ แ แกแแฉแฅแแ แแก แแแฆแฌแแแ. doodles
. แแแแกแแแแก แแแแแแแงแแแแ 3 แฎแ แแแ. แแแ แแแแ แแงแ แแ แขแแแแก แแแแแแแแแแแแก แจแแแชแแ แแแ, แ แแแแแแช แแแแฎแแแก แแแแแแ แแแแแก ID-แก. แแ แแแแแแแฃแ แแแแแชแแแแ แแแแ แแแจแ ID-แแก แจแแกแแแแฎแแ แกแแญแแ แ แขแแแ แแ แแก bigint
, แแแแ แแ แแแแแแ แแแแแแแก แ แแแแแแแแ แจแแกแแซแแแแแแก แฎแแแก แแแแ แแแแแขแแคแแแแขแแ แแแแก, แ แแแแแ แ แแชแฎแแแก แขแแแ, แขแแแจแ แแแ แแแแแก int
. แแ แจแแแแฎแแแแแจแ แซแแแแ แแแแ แแ แฃแคแ แ แกแฌแ แแคแแ. แแแแ แ แฎแ แแแ แแงแ แแแแแงแแแแแ ORDERED INDEX
- แแ แแแแแฌแงแแแขแแแแแแแแ แแแแแแแ แแแแแ แแฃแแแ, แงแแแแ แแ แกแแแฃแแแก แแแแแแก แจแแแแแ PREPARE
แแแแแแแแแฃแแ แแแแแแแแฅแแแแแก แจแแแแแแแ แแแแแงแแแแแแ แแแแแ แขแแแแก แแแแฎแแแแแแแก แแแแแฃแแแก แจแแฅแแแแกแแก, แแแแ แแ แกแแแแแแแแแแจแ แแ แกแแแแแก แฃแแแ แแขแแกแแแ แแแ แขแแแแแ แจแแแแ แแแแ SELECT
แแฆแแแฉแแแ แกแขแแขแแกแขแแแฃแ แ แชแแแแแแแแแก แคแแ แแแแแจแ.
แแแแแชแแแแ แแขแแแ แแแแก แแ แแชแแกแ แแแแฎแแแ แก แแ แแฃแแแขแแก 450 MB แแแแ แแขแแฃแแ แแแฎแกแแแ แแแ. แแแฃ, แแฆแฌแแ แแแ แแแแแแแ แกแแจแฃแแแแแแก แแแซแแแแ แแแแแแขแแแแ แแแแแชแแแแ แแแแ แแแ, แ แแแแแแช แแฌแแแแก แแแแแแ แแแแแแแแขแก, แแแแฅแแแก แแแแแกแแแแ แกแแแแฃแฏแแขแ แแแแ แแขแฃแ แแแ, แแแ แจแแ แแก แแแแแแ แ แแ แแแแ แข แแแฌแงแแแแแแแแแ, แ แแช แกแแแแแแ แแแแแ แแ.
แ แฉแแแ แแฎแแแแ (แจแแแแฎแแแแแแ) แแแแแชแแแแแแก แแแแแแแแแก แกแแฉแฅแแ แแก แแแแแแแ แแ แกแแแแแ แแแแก แจแแคแแกแแแ แกแฎแแแแแกแฎแแ แแแแแก แแแ แขแแแแแก แจแแ แฉแแแแกแแก:
แแแแแชแแแแ แแแแแก แกแแแ แแแแขแแชแแ แแแจแแแ
library(ggplot2)
set.seed(0)
# ะะพะดะบะปััะตะฝะธะต ะบ ะฑะฐะทะต ะดะฐะฝะฝัั
con <- DBI::dbConnect(MonetDBLite::MonetDBLite(), Sys.getenv("DBDIR"))
# ะคัะฝะบัะธั ะดะปั ะฟะพะดะณะพัะพะฒะบะธ ะทะฐะฟัะพัะฐ ะฝะฐ ััะพัะพะฝะต ัะตัะฒะตัะฐ
prep_sql <- function(batch_size) {
sql <- sprintf("PREPARE SELECT id FROM doodles WHERE id IN (%s)",
paste(rep("?", batch_size), collapse = ","))
res <- DBI::dbSendQuery(con, sql)
return(res)
}
# ะคัะฝะบัะธั ะดะปั ะธะทะฒะปะตัะตะฝะธั ะดะฐะฝะฝัั
fetch_data <- function(rs, batch_size) {
ids <- sample(seq_len(n), batch_size)
res <- DBI::dbFetch(DBI::dbBind(rs, as.list(ids)))
return(res)
}
# ะัะพะฒะตะดะตะฝะธะต ะทะฐะผะตัะฐ
res_bench <- bench::press(
batch_size = 2^(4:10),
{
rs <- prep_sql(batch_size)
bench::mark(
fetch_data(rs, batch_size),
min_iterations = 50L
)
}
)
# ะะฐัะฐะผะตััั ะฑะตะฝัะผะฐัะบะฐ
cols <- c("batch_size", "min", "median", "max", "itr/sec", "total_time", "n_itr")
res_bench[, cols]
# batch_size min median max `itr/sec` total_time n_itr
# <dbl> <bch:tm> <bch:tm> <bch:tm> <dbl> <bch:tm> <int>
# 1 16 23.6ms 54.02ms 93.43ms 18.8 2.6s 49
# 2 32 38ms 84.83ms 151.55ms 11.4 4.29s 49
# 3 64 63.3ms 175.54ms 248.94ms 5.85 8.54s 50
# 4 128 83.2ms 341.52ms 496.24ms 3.00 16.69s 50
# 5 256 232.8ms 653.21ms 847.44ms 1.58 31.66s 50
# 6 512 784.6ms 1.41s 1.98s 0.740 1.1m 49
# 7 1024 681.7ms 2.72s 4.06s 0.377 2.16m 49
ggplot(res_bench, aes(x = factor(batch_size), y = median, group = 1)) +
geom_point() +
geom_line() +
ylab("median time, s") +
theme_minimal()
DBI::dbDisconnect(con, shutdown = TRUE)
2. แแแ แขแแแแแก แแแแแแแแแ
แแแแแ แฏแแฃแคแแก แแแแแแแแแแก แแ แแชแแกแ แจแแแแแแ แจแแแแแแ แแแแแฏแแแแกแแแ:
- แ แแแแแแแแ JSON-แแก แแแ แฉแแแ, แ แแแแแแแช แจแแแชแแแก แกแขแ แแฅแแแแแแก แแแฅแขแแ แแแก แฌแแ แขแแแแแแก แแแแ แแแแแขแแแแ.
- แกแแญแแ แ แแแแแก แกแฃแ แแแแ (แแแแแแแแแ, 256ร256 แแ 128ร128) แฌแแ แขแแแแแแก แแแแ แแแแแขแแแแ แแแงแ แแแแแแ แคแแ แแแ แฎแแแแแแก แแแฎแแขแแ.
- แแแฆแแแฃแแ แกแฃแ แแแแแแก แขแแแแแ แแ แแแแแฅแชแแแ.
แแแแแแแก แแแ แแแแแก แจแแ แแก แแแแแฃแ แกแแก แคแแ แแแแแจแ, แแ แแแแแแ แแแแแแ แแ แซแแ แแแแแแ แแแแแงแแแแแแ OpenCV. แแ แ-แแ แแ แงแแแแแแ แแแ แขแแแ แแ แแจแแแ แ แแแแแแแ R-แจแ แแกแ แแแแแแงแฃแ แแแ:
JSON-แแก แขแแแกแแ แจแ แแแแแแ แขแแชแแแก แแแแฎแแ แชแแแแแแ R-แจแ
r_process_json_str <- function(json, line.width = 3,
color = TRUE, scale = 1) {
# ะะฐััะธะฝะณ JSON
coords <- jsonlite::fromJSON(json, simplifyMatrix = FALSE)
tmp <- tempfile()
# ะฃะดะฐะปัะตะผ ะฒัะตะผะตะฝะฝัะน ัะฐะนะป ะฟะพ ะทะฐะฒะตััะตะฝะธั ััะฝะบัะธะธ
on.exit(unlink(tmp))
png(filename = tmp, width = 256 * scale, height = 256 * scale, pointsize = 1)
# ะัััะพะน ะณัะฐัะธะบ
plot.new()
# ะ ะฐะทะผะตั ะพะบะฝะฐ ะณัะฐัะธะบะฐ
plot.window(xlim = c(256 * scale, 0), ylim = c(256 * scale, 0))
# ะฆะฒะตัะฐ ะปะธะฝะธะน
cols <- if (color) rainbow(length(coords)) else "#000000"
for (i in seq_along(coords)) {
lines(x = coords[[i]][[1]] * scale, y = coords[[i]][[2]] * scale,
col = cols[i], lwd = line.width)
}
dev.off()
# ะัะตะพะฑัะฐะทะพะฒะฐะฝะธะต ะธะทะพะฑัะฐะถะตะฝะธั ะฒ 3-ั
ะผะตัะฝัะน ะผะฐััะธะฒ
res <- png::readPNG(tmp)
return(res)
}
r_process_json_vector <- function(x, ...) {
res <- lapply(x, r_process_json_str, ...)
# ะะฑัะตะดะธะฝะตะฝะธะต 3-ั
ะผะตัะฝัั
ะผะฐััะธะฒะพะฒ ะบะฐััะธะฝะพะบ ะฒ 4-ั
ะผะตัะฝัะน ะฒ ัะตะฝะทะพั
res <- do.call(abind::abind, c(res, along = 0))
return(res)
}
แแแฎแแแ แจแแกแ แฃแแแแฃแแแ แกแขแแแแแ แขแฃแแ R แแแกแขแ แฃแแแแขแแแแก แแแแแงแแแแแแ แแ แแแแฎแแแ แแ แแแแแ PNG-แจแ, แ แแแแแแช แแแแฎแแแ RAM-แจแ (Linux-แแ แแ แแแแแแ R แแแ แแฅแขแแ แแแแ แแแแแแแกแแแฃแแแ แแแ แแฅแขแแ แแแจแ /tmp
, แแแแแแขแแแแแฃแแ RAM-แจแ). แแก แคแแแแ แจแแแแแ แแแแแฎแแแ แกแแแแแแแแแแแแแแแแ แแแกแแแแก แกแแฎแแ 0-แแแ 1-แแแ แ แแชแฎแแแแแ. แแก แแแแจแแแแแแแแแแ, แ แแแแแ แฃแคแ แ แฉแแแฃแแแแ แแแ BMP แฌแแแแแแฎแแแ แแแแแแฃแ แแแกแแแจแ แแแฅแแกแแแขแแแแแ แคแแ แแก แแแแแแแ.
แแแแแ แจแแแแแแฌแแแ แจแแแแแ:
zip_file <- file.path("data", "train_simplified.zip")
csv_file <- "cat.csv"
unzip(zip_file, files = csv_file, exdir = tempdir(),
junkpaths = TRUE, unzip = getOption("unzip"))
tmp_data <- data.table::fread(file.path(tempdir(), csv_file), sep = ",",
select = "drawing", nrows = 10000)
arr <- r_process_json_str(tmp_data[4, drawing])
dim(arr)
# [1] 256 256 3
plot(magick::image_read(arr))
แแแแแ แแแ แขแแ แฉแแแแงแแแแแแแแ แจแแแแแแแแแ แแ:
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 แกแฃแ แแแแแแแ แแฃแจแแแแแกแ แแ แฎแแแแแแก แแแฎแแขแแแกแแแแก. แแแแแงแแแแแฃแแแ แฌแแแแกแฌแแ แแแแแกแขแแแแ แแแฃแแ แกแแกแขแแแแก แแแแแแแแแแแแ แแ แกแแแแฃแ แแก แคแแแแแแ, แแกแแแ แแแแแแแฃแ แ แแแแแแแ.
-
xtensor แแ แแแแแแแแแแแแแแแแแ แแแกแแแแแแแ แแ แขแแแกแแ แแแแแ แแฃแจแแแแแกแแแแก. แฉแแแ แแแแแแแงแแแแ แกแแแแฃแ แแก แคแแแแแแ, แ แแแแแแแช แจแแแแก แแแแแ แกแแฎแแแฌแแแแแแก R แแแแแขแจแ. แแแแแแแแแแ แกแแจแฃแแแแแแก แแแซแแแแ แแแฃแจแแแ แแ แแแแแแแแแแแแแแแแแ แแแกแแแแแแแ, แ แแแแ แช แแฌแแ แแแแก แซแแ แแแแแ, แแกแแแ แกแแแขแแก แซแแ แแแแแ แแแแแแแแแแ แแแแ.
-
แแฏแกแแแ JSON แแแกแแแแแแแแแแแแ. แแก แแแแแแแแแแ แแแแแแงแแแแแ xtensor แแแขแแแแขแฃแ แแ, แแฃ แแก แแ แแก แแ แแแฅแขแจแ.
-
RcppThread JSON-แแแ แแแฅแขแแ แแก แแ แแแแแกแแ แแฃแแแแแ แแแแฃแจแแแแแแก แแ แแแแแแแแแกแแแแก. แแแแแแงแแแ แแ แแแแแขแแ แแแฌแแแแแฃแแ แกแแแแฃแ แแก แคแแแแแแ. แฃแคแ แ แแแแฃแแแ แฃแแแแแ Rcppแแแ แแแแแฃแ แ แแแแแขแก, แกแฎแแ แกแแแแแฎแแแแแ แแ แแแ, แแฅแแก แฉแแจแแแแแฃแแ แแแ แงแฃแแแก แจแแฌแงแแแขแแก แแแฅแแแแแแ.
แแฆแกแแแแจแแแแแ, แ แแ xtensor แฆแแแแฃแ แ แแแญแ แแฆแแแฉแแแ: แแแ แแ แแแแกแ, แ แแ แแแก แแฅแแก แคแแ แแ แคแฃแแฅแชแแแแแ แแแ แแ แแแฆแแแ แจแแกแ แฃแแแแ, แแแกแ แแแแแแแแแ แแแ แกแแแแแแ แกแแแแกแฃแฎแ แแฆแแแฉแแแแแ แแ แกแฌแ แแคแแ แแ แแแขแแแฃแ แแ แฃแแแกแฃแฎแแก แแแแฎแแแแก. แแแแ แแแฎแแแ แแแแ แจแแกแแซแแแแแแ แแแฎแแ OpenCV แแแขแ แแชแแแแก แขแ แแแกแคแแ แแแชแแแแ xtensor แขแแแแแ แแแแ, แแกแแแ แ แแแแ แช 3-แแแแแแแแแแแแแแ แแแแแกแแฎแฃแแแแแก แขแแแกแแ แแแแก แแแแ แแแแแแแแก แแแ แกแฌแแ แ แแแแแแแแแแแแก 4-แแแแแแแแแแแแแ แขแแแแแ แจแ (แแแแแ แแแ แขแแ).
แแแกแแแแแ Rcpp, xtensor แแ RcppThread-แแก แจแแกแแกแฌแแแแแ
แคแแแแแแแก แจแแแแแแแกแแแแก, แ แแแแแแแช แแงแแแแแแ แกแแกแขแแแฃแ แคแแแแแแก แแ แแแแแแแฃแ แแแแจแแ แก แกแแกแขแแแแจแ แแแงแแแแแฃแ แแแแแแแแแแแแแแ, แฉแแแ แแแแแแแงแแแแ แแแแแขแจแ แแแแแ แแแแ แแแแแแแขแแก แแแฅแแแแแแ. Rcpp. แแแแแแแแแกแ แแ แแ แแจแแแแก แแแขแแแแขแฃแ แแ แแแกแแซแแแแแ, แฉแแแ แแแแแแแงแแแแ แแแแฃแแแ แฃแแ Linux แแ แแแ แแแ pkg-config.
Rcpp แแแแฃแแแก แแแแแ แแแ OpenCV แแแแแแแแแแแก แแแแแกแแงแแแแแแแ
Rcpp::registerPlugin("opencv", function() {
# ะะพะทะผะพะถะฝัะต ะฝะฐะทะฒะฐะฝะธั ะฟะฐะบะตัะฐ
pkg_config_name <- c("opencv", "opencv4")
# ะะธะฝะฐัะฝัะน ัะฐะนะป ััะธะปะธัั pkg-config
pkg_config_bin <- Sys.which("pkg-config")
# ะัะพะฒัะตะบะฐ ะฝะฐะปะธัะธั ััะธะปะธัั ะฒ ัะธััะตะผะต
checkmate::assert_file_exists(pkg_config_bin, access = "x")
# ะัะพะฒะตัะบะฐ ะฝะฐะปะธัะธั ัะฐะนะปะฐ ะฝะฐัััะพะตะบ OpenCV ะดะปั pkg-config
check <- sapply(pkg_config_name,
function(pkg) system(paste(pkg_config_bin, pkg)))
if (all(check != 0)) {
stop("OpenCV config for the pkg-config not found", call. = FALSE)
}
pkg_config_name <- pkg_config_name[check == 0]
list(env = list(
PKG_CXXFLAGS = system(paste(pkg_config_bin, "--cflags", pkg_config_name),
intern = TRUE),
PKG_LIBS = system(paste(pkg_config_bin, "--libs", pkg_config_name),
intern = TRUE)
))
})
แแแแฃแแแก แแฃแจแแแแแก แจแแแแแแ, แจแแแแแแแก แแ แแชแแกแจแ แจแแแชแแแแแ แจแแแแแแ แแแแจแแแแแแแแแ:
Rcpp:::.plugins$opencv()$env
# $PKG_CXXFLAGS
# [1] "-I/usr/include/opencv"
#
# $PKG_LIBS
# [1] "-lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_datasets -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_line_descriptor -lopencv_optflow -lopencv_video -lopencv_plot -lopencv_reg -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_rgbd -lopencv_viz -lopencv_surface_matching -lopencv_text -lopencv_ximgproc -lopencv_calib3d -lopencv_features2d -lopencv_flann -lopencv_xobjdetect -lopencv_objdetect -lopencv_ml -lopencv_xphoto -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_photo -lopencv_imgproc -lopencv_core"
แแแแแแแแแขแแชแแแก แแแแ JSON-แแก แแแ แฉแแแแกแ แแ แแแแแแแ แแแแแชแแแแก แกแแ แแแก แแแแแ แแ แแแแกแแแแก แแแชแแแฃแแแ แกแแแแแแ แแก แฅแแแจ. แแแ แแแ แ แแแจแ, แแแแแแขแแ แแแแแแแแ แแแ แแ แแแฅแขแแก แแแ แแฅแขแแ แแ แกแแแแฃแ แแก แคแแแแแแแก แแแกแแซแแแแแ (แกแแญแแ แแ ndjson-แแกแแแแก):
Sys.setenv("PKG_CXXFLAGS" = paste0("-I", normalizePath(file.path("src"))))
JSON-แแก แขแแแกแแ แแ แแแแแฅแชแแแแก แแแแฎแแ แชแแแแแแ C++-แจแ
// [[Rcpp::plugins(cpp14)]]
// [[Rcpp::plugins(opencv)]]
// [[Rcpp::depends(xtensor)]]
// [[Rcpp::depends(RcppThread)]]
#include <xtensor/xjson.hpp>
#include <xtensor/xadapt.hpp>
#include <xtensor/xview.hpp>
#include <xtensor-r/rtensor.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <Rcpp.h>
#include <RcppThread.h>
// ะกะธะฝะพะฝะธะผั ะดะปั ัะธะฟะพะฒ
using RcppThread::parallelFor;
using json = nlohmann::json;
using points = xt::xtensor<double,2>; // ะะทะฒะปะตััะฝะฝัะต ะธะท JSON ะบะพะพัะดะธะฝะฐัั ัะพัะตะบ
using strokes = std::vector<points>; // ะะทะฒะปะตััะฝะฝัะต ะธะท JSON ะบะพะพัะดะธะฝะฐัั ัะพัะตะบ
using xtensor3d = xt::xtensor<double, 3>; // ะขะตะฝะทะพั ะดะปั ั
ัะฐะฝะตะฝะธั ะผะฐััะธัั ะธะทะพะพะฑัะฐะถะตะฝะธั
using xtensor4d = xt::xtensor<double, 4>; // ะขะตะฝะทะพั ะดะปั ั
ัะฐะฝะตะฝะธั ะผะฝะพะถะตััะฒะฐ ะธะทะพะฑัะฐะถะตะฝะธะน
using rtensor3d = xt::rtensor<double, 3>; // ะะฑัััะบะฐ ะดะปั ัะบัะฟะพััะฐ ะฒ R
using rtensor4d = xt::rtensor<double, 4>; // ะะฑัััะบะฐ ะดะปั ัะบัะฟะพััะฐ ะฒ R
// ะกัะฐัะธัะตัะบะธะต ะบะพะฝััะฐะฝัั
// ะ ะฐะทะผะตั ะธะทะพะฑัะฐะถะตะฝะธั ะฒ ะฟะธะบัะตะปัั
const static int SIZE = 256;
// ะขะธะฟ ะปะธะฝะธะธ
// ะกะผ. https://en.wikipedia.org/wiki/Pixel_connectivity#2-dimensional
const static int LINE_TYPE = cv::LINE_4;
// ะขะพะปัะธะฝะฐ ะปะธะฝะธะธ ะฒ ะฟะธะบัะตะปัั
const static int LINE_WIDTH = 3;
// ะะปะณะพัะธัะผ ัะตัะฐะนะทะฐ
// https://docs.opencv.org/3.1.0/da/d54/group__imgproc__transform.html#ga5bb5a1fea74ea38e1a5445ca803ff121
const static int RESIZE_TYPE = cv::INTER_LINEAR;
// ะจะฐะฑะปะพะฝ ะดะปั ะบะพะฝะฒะตััะธัะพะฒะฐะฝะธั OpenCV-ะผะฐััะธัั ะฒ ัะตะฝะทะพั
template <typename T, int NCH, typename XT=xt::xtensor<T,3,xt::layout_type::column_major>>
XT to_xt(const cv::Mat_<cv::Vec<T, NCH>>& src) {
// ะ ะฐะทะผะตัะฝะพััั ัะตะปะตะฒะพะณะพ ัะตะฝะทะพัะฐ
std::vector<int> shape = {src.rows, src.cols, NCH};
// ะะฑัะตะต ะบะพะปะธัะตััะฒะพ ัะปะตะผะตะฝัะพะฒ ะฒ ะผะฐััะธะฒะต
size_t size = src.total() * NCH;
// ะัะตะพะฑัะฐะทะพะฒะฐะฝะธะต cv::Mat ะฒ xt::xtensor
XT res = xt::adapt((T*) src.data, size, xt::no_ownership(), shape);
return res;
}
// ะัะตะพะฑัะฐะทะพะฒะฐะฝะธะต JSON ะฒ ัะฟะธัะพะบ ะบะพะพัะดะธะฝะฐั ัะพัะตะบ
strokes parse_json(const std::string& x) {
auto j = json::parse(x);
// ะ ะตะทัะปััะฐั ะฟะฐััะธะฝะณะฐ ะดะพะปะถะตะฝ ะฑััั ะผะฐััะธะฒะพะผ
if (!j.is_array()) {
throw std::runtime_error("'x' must be JSON array.");
}
strokes res;
res.reserve(j.size());
for (const auto& a: j) {
// ะะฐะถะดัะน ัะปะตะผะตะฝั ะผะฐััะธะฒะฐ ะดะพะปะถะตะฝ ะฑััั 2-ะผะตัะฝัะผ ะผะฐััะธะฒะพะผ
if (!a.is_array() || a.size() != 2) {
throw std::runtime_error("'x' must include only 2d arrays.");
}
// ะะทะฒะปะตัะตะฝะธะต ะฒะตะบัะพัะฐ ัะพัะตะบ
auto p = a.get<points>();
res.push_back(p);
}
return res;
}
// ะััะธัะพะฒะบะฐ ะปะธะฝะธะน
// ะฆะฒะตัะฐ HSV
cv::Mat ocv_draw_lines(const strokes& x, bool color = true) {
// ะัั
ะพะดะฝัะน ัะธะฟ ะผะฐััะธัั
auto stype = color ? CV_8UC3 : CV_8UC1;
// ะัะพะณะพะฒัะน ัะธะฟ ะผะฐััะธัั
auto dtype = color ? CV_32FC3 : CV_32FC1;
auto bg = color ? cv::Scalar(0, 0, 255) : cv::Scalar(255);
auto col = color ? cv::Scalar(0, 255, 220) : cv::Scalar(0);
cv::Mat img = cv::Mat(SIZE, SIZE, stype, bg);
// ะะพะปะธัะตััะฒะพ ะปะธะฝะธะน
size_t n = x.size();
for (const auto& s: x) {
// ะะพะปะธัะตััะฒะพ ัะพัะตะบ ะฒ ะปะธะฝะธะธ
size_t n_points = s.shape()[1];
for (size_t i = 0; i < n_points - 1; ++i) {
// ะขะพัะบะฐ ะฝะฐัะฐะปะฐ ัััะธั
ะฐ
cv::Point from(s(0, i), s(1, i));
// ะขะพัะบะฐ ะพะบะพะฝัะฐะฝะธั ัััะธั
ะฐ
cv::Point to(s(0, i + 1), s(1, i + 1));
// ะััะธัะพะฒะบะฐ ะปะธะฝะธะธ
cv::line(img, from, to, col, LINE_WIDTH, LINE_TYPE);
}
if (color) {
// ะะตะฝัะตะผ ัะฒะตั ะปะธะฝะธะธ
col[0] += 180 / n;
}
}
if (color) {
// ะะตะฝัะตะผ ัะฒะตัะพะฒะพะต ะฟัะตะดััะฐะฒะปะตะฝะธะต ะฝะฐ RGB
cv::cvtColor(img, img, cv::COLOR_HSV2RGB);
}
// ะะตะฝัะตะผ ัะพัะผะฐั ะฟัะตะดััะฐะฒะปะตะฝะธั ะฝะฐ float32 ั ะดะธะฐะฟะฐะทะพะฝะพะผ [0, 1]
img.convertTo(img, dtype, 1 / 255.0);
return img;
}
// ะะฑัะฐะฑะพัะบะฐ JSON ะธ ะฟะพะปััะตะฝะธะต ัะตะฝะทะพัะฐ ั ะดะฐะฝะฝัะผะธ ะธะทะพะฑัะฐะถะตะฝะธั
xtensor3d process(const std::string& x, double scale = 1.0, bool color = true) {
auto p = parse_json(x);
auto img = ocv_draw_lines(p, color);
if (scale != 1) {
cv::Mat out;
cv::resize(img, out, cv::Size(), scale, scale, RESIZE_TYPE);
cv::swap(img, out);
out.release();
}
xtensor3d arr = color ? to_xt<double,3>(img) : to_xt<double,1>(img);
return arr;
}
// [[Rcpp::export]]
rtensor3d cpp_process_json_str(const std::string& x,
double scale = 1.0,
bool color = true) {
xtensor3d res = process(x, scale, color);
return res;
}
// [[Rcpp::export]]
rtensor4d cpp_process_json_vector(const std::vector<std::string>& x,
double scale = 1.0,
bool color = false) {
size_t n = x.size();
size_t dim = floor(SIZE * scale);
size_t channels = color ? 3 : 1;
xtensor4d res({n, dim, dim, channels});
parallelFor(0, n, [&x, &res, scale, color](int i) {
xtensor3d tmp = process(x[i], scale, color);
auto view = xt::view(res, i, xt::all(), xt::all(), xt::all());
view = tmp;
});
return res;
}
แแก แแแแ แฃแแแ แแแแแแแกแแแก แคแแแแจแ src/cv_xt.cpp
แแ แแแแแแแแชแแ แแ แซแแแแแแ Rcpp::sourceCpp(file = "src/cv_xt.cpp", env = .GlobalEnv)
; แแกแแแ แกแแญแแ แแ แกแแแฃแจแแแกแแแแก nlohmann/json.hpp
แกแแฅแแ แแแแแแก
-
to_xt
- แจแแแแแแฃแ แ แคแฃแแฅแชแแ แแแแแกแแฎแฃแแแแแก แแแขแ แแชแแก แแแ แแแฅแแแแกแแแแก (cv::Mat
) แขแแแแแ แแxt::xtensor
; -
parse_json
โ แคแฃแแฅแชแแ แแแแแแแแแแก JSON แกแขแ แแฅแแแก, แแแแแฆแแแก แฌแแ แขแแแแแแก แแแแ แแแแแขแแแก แแ แแแแแกแแแก แแแ แแแฅแขแแ แจแ; -
ocv_draw_lines
โ แฌแแ แแแฅแแแแแ แฌแแ แขแแแแแแก แแแฅแขแแ แแแแ แฎแแแแแก แแ แแแแแคแแ แแแแ แฎแแแแแก; -
process
โ แแแ แแแแแแแก แแแแแฎแกแแแแแฃแ แคแฃแแฅแชแแแแก แแ แแกแแแ แแแแขแแแก แแแฆแแแฃแแ แแแแแกแแฎแฃแแแแแก แแแกแจแขแแแแ แแแแก แจแแกแแซแแแแแแแแก; -
cpp_process_json_str
- แจแแคแฃแแแ แคแฃแแฅแชแแแแprocess
, แ แแแแแแช แแฎแแแแก แจแแแแแแก แแฅแกแแแ แขแก R-แแแแแฅแขแจแ (แแ แแแแแแแแแแแแแแแแแแ แแแกแแแ); -
cpp_process_json_vector
- แจแแคแฃแแแ แคแฃแแฅแชแแแแcpp_process_json_str
, แ แแแแแแช แกแแจแฃแแแแแแก แแแซแแแแ แแแแแฃแจแแแแ แกแขแ แแฅแแแ แแแฅแขแแ แ แแ แแแแแซแแคแแก แ แแแแแจแ.
แแ แแแแแคแแ แแแ แฎแแแแแแก แแแกแแฎแแขแแ แแแแแงแแแแแฃแแ แแฅแแ HSV แคแแ แแก แแแแแแ, แ แแกแแช แแแฐแงแแ แแแแแแ แขแแชแแ RGB-แแ. แแแแแ แจแแแแแแฌแแแ แจแแแแแ:
arr <- cpp_process_json_str(tmp_data[4, drawing])
dim(arr)
# [1] 256 256 3
plot(magick::image_read(arr))
แแแแฎแแ แชแแแแแแแแแก แกแแฉแฅแแ แแก แจแแแแ แแแ 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-แก แแฅแแก แแแแกแแฎแฃแ แแแฃแแ แ แแแฃแขแแชแแ แแแแแชแแแแ แแแแฃแจแแแแแแกแแแแก, แ แแแแแแช แฏแแแแ RAM-แจแ, แฎแแแ Python-แก แฃแคแ แ แแแขแแ แแฎแแกแแแแแแก แแแแแชแแแแ แแแแแแแ แแแแแ แแแแฃแจแแแแแ, แ แแช แกแแจแฃแแแแแแก แแแซแแแแ แแแ แขแแแแ แแ แแฃแแแแ แแแแ แแแแแฎแแ แชแแแแแ แแแ แ แแแแแแแแแแ (แแแแแแแแแแ แแแ แ แแแฎแกแแแ แแแแก แแแแแงแแแแแแ). แฉแแแแแแแก แแแแกแแแฃแ แ แแ แจแแกแแแแแแกแ แแแแแแแแ แแฆแฌแแ แแแ แแ แแแแแแแก แแแแขแแฅแกแขแจแ แแ แแก แฆแ แแ แแแ แแฃแแ แฅแกแแแแแ, แ แแแแแแแช แแแแแแแแแฃแแแ แแ แแแแแแขแฃแแ แแแฆแแแ แแแก แแแแแแแ, แแ แแแแแแขแแก แแแแฎแแแแแแ แแแแแแฃแ แกแแคแแฎแฃแ แแ แแแแแแ แแแแแก แแชแแ แ แแแฌแแแแก แแ แแแแ-แกแแ แแแก แแแแแงแแแแแแ.
Python-แจแ แแแฌแแ แแ แฆแ แแ แกแฌแแแแแแแก แฉแแ แฉแแแแก แแฅแแ แกแแแชแแแแฃแ แ แแแแกแแแ, แ แแแแแแแช แแฎแแ แชแแแแแแแ แแขแแ แแขแแ แแแก แแแแแชแแแแแแ แแแงแ แแแแแแ: แชแฎแ แแแแแ, แกแฃแ แแแแแ แกแแฅแแฆแแแแแแแจแ, แแ แแแแแ แคแแ แแแขแแแ แแ แ.แจ. แจแแแแซแแแแ แแแแแแงแแแแ แแแ แแแ แแแแขแแแ แแ แแแฌแแ แแ แกแแแฃแแแ แ แแแแแ แแขแฃแแ แแแแชแแแแแแกแแแแก. R-แจแ แจแแแแแซแแแ แแแกแแ แแแแแแ แแแแแแแก แแแแแแแแแแแก แงแแแแ แแแฎแแกแแแแแแแแ แแแ แแก แแแแแกแ แกแฎแแแแแกแฎแแ แแแฅแแแแแแแ แแแแแ แกแแฎแแแฌแแแแแแก แแแแแขแแก แแแแแงแแแแแแ, แ แแแแแแช แแแแแก แแฎแ แแ แแฃแจแแแแก แแแแแขแแก แแแแแ แแแแแแแ. แแก แฃแแแแแกแแแแแ แแแกแแฎแฃแ แแแก แชแแแแ แแ แชแแ แกแขแแขแแแก; แแก แแ แ แแฎแแแแ แกแแจแฃแแแแแแก แแแซแแแแ แแแฃแจแแแ แแแแแแแก แแแแ R-แแแ, แแ แแแแ แกแแจแฃแแแแแแก แแแซแแแแ แแแแแแขแแแแ แแแแแฅแขแแแ R แแ Python แกแแกแแแแก แจแแ แแก, แแแขแแแแขแฃแ แแ แจแแแกแ แฃแแแ แงแแแแ แกแแญแแ แ แขแแแแก แแแแแแ แขแแชแแ.
แฉแแแ แแแแแแแแกแฃแคแแแแ แงแแแแ แแแแแชแแแแก RAM-แจแ แจแแแแฎแแแก แแฃแชแแแแแแแแแแ MonetDBLite-แแก แแแแแงแแแแแแ, แงแแแแ โแแแ แแฃแแ แฅแกแแแแกโ แกแแแฃแจแแ แจแแกแ แฃแแแแแ แแ แแแแแแแฃแ แ แแแแแ Python-แจแ, แฉแแแ แฃแแ แแแแ แฃแแแ แแแแฌแแ แแ แแขแแ แแขแแ แ แแแแแชแแแแแแ, แ แแแแแ แแแแ แแ แแคแแ แแ. แแกแแแ แกแแขแฃแแชแแแกแแแแก แแ R แแ Python-แจแ. แแแก แแ แกแแแแแแ แแฎแแแแ แแ แ แแแแฎแแแแ แแฅแแก: แแแ แฃแแแ แแแแแ แฃแแแก แกแแ แแแแ แแแฃแแแแแแแ แชแแแแจแ แแ แจแแแแแฎแแก แแแกแ แแแแแแแ แแแแ แแแแแแ แแแแแก แจแแ แแก (แแก แฃแแแแแกแแแแแ R-แจแ แฎแแ แชแแแแแแแ แฃแแแ แขแแแแกแ แแแแ แแแฎแฃแ แแแก แแแแแงแแแแแแ). แแแ แ แกแแญแแ แ แแงแ R แแแกแแแแแแก แแแแคแแแ แแแแแฅแชแแแ แแขแแ แแขแแ แแก แจแแแแแ, แแแแ แแ แแแแแขแแก แแแแแแแแแแแ แแแ แกแแ แแแ แแก แแแแแแ แแแแแแแก.
แขแ แแแแแแแกแ แแ แแแแแแแชแแแก แแแแแชแแแแแแก แแแแแแแ แแแแแ แแฆแแแฉแแแ แจแแแแแแ:
Iterator แขแ แแแแแแแกแ แแ แแแแแแแชแแแก แแแแแชแแแแแแกแแแแก
train_generator <- function(db_connection = con,
samples_index,
num_classes = 340,
batch_size = 32,
scale = 1,
color = FALSE,
imagenet_preproc = FALSE) {
# ะัะพะฒะตัะบะฐ ะฐัะณัะผะตะฝัะพะฒ
checkmate::assert_class(con, "DBIConnection")
checkmate::assert_integerish(samples_index)
checkmate::assert_count(num_classes)
checkmate::assert_count(batch_size)
checkmate::assert_number(scale, lower = 0.001, upper = 5)
checkmate::assert_flag(color)
checkmate::assert_flag(imagenet_preproc)
# ะะตัะตะผะตัะธะฒะฐะตะผ, ััะพะฑั ะฑัะฐัั ะธ ัะดะฐะปััั ะธัะฟะพะปัะทะพะฒะฐะฝะฝัะต ะธะฝะดะตะบัั ะฑะฐััะตะน ะฟะพ ะฟะพััะดะบั
dt <- data.table::data.table(id = sample(samples_index))
# ะัะพััะฐะฒะปัะตะผ ะฝะพะผะตัะฐ ะฑะฐััะตะน
dt[, batch := (.I - 1L) %/% batch_size + 1L]
# ะััะฐะฒะปัะตะผ ัะพะปัะบะพ ะฟะพะปะฝัะต ะฑะฐััะธ ะธ ะธะฝะดะตะบัะธััะตะผ
dt <- dt[, if (.N == batch_size) .SD, keyby = batch]
# ะฃััะฐะฝะฐะฒะปะธะฒะฐะตะผ ัััััะธะบ
i <- 1
# ะะพะปะธัะตััะฒะพ ะฑะฐััะตะน
max_i <- dt[, max(batch)]
# ะะพะดะณะพัะพะฒะบะฐ ะฒััะฐะถะตะฝะธั ะดะปั ะฒัะณััะทะบะธ
sql <- sprintf(
"PREPARE SELECT drawing, label_int FROM doodles WHERE id IN (%s)",
paste(rep("?", batch_size), collapse = ",")
)
res <- DBI::dbSendQuery(con, sql)
# ะะฝะฐะปะพะณ keras::to_categorical
to_categorical <- function(x, num) {
n <- length(x)
m <- numeric(n * num)
m[x * n + seq_len(n)] <- 1
dim(m) <- c(n, num)
return(m)
}
# ะะฐะผัะบะฐะฝะธะต
function() {
# ะะฐัะธะฝะฐะตะผ ะฝะพะฒัั ัะฟะพั
ั
if (i > max_i) {
dt[, id := sample(id)]
data.table::setkey(dt, batch)
# ะกะฑัะฐััะฒะฐะตะผ ัััััะธะบ
i <<- 1
max_i <<- dt[, max(batch)]
}
# ID ะดะปั ะฒัะณััะทะบะธ ะดะฐะฝะฝัั
batch_ind <- dt[batch == i, id]
# ะัะณััะทะบะฐ ะดะฐะฝะฝัั
batch <- DBI::dbFetch(DBI::dbBind(res, as.list(batch_ind)), n = -1)
# ะฃะฒะตะปะธัะธะฒะฐะตะผ ัััััะธะบ
i <<- i + 1
# ะะฐััะธะฝะณ JSON ะธ ะฟะพะดะณะพัะพะฒะบะฐ ะผะฐััะธะฒะฐ
batch_x <- cpp_process_json_vector(batch$drawing, scale = scale, color = color)
if (imagenet_preproc) {
# ะจะบะฐะปะธัะพะฒะฐะฝะธะต c ะธะฝัะตัะฒะฐะปะฐ [0, 1] ะฝะฐ ะธะฝัะตัะฒะฐะป [-1, 1]
batch_x <- (batch_x - 0.5) * 2
}
batch_y <- to_categorical(batch$label_int, num_classes)
result <- list(batch_x, batch_y)
return(result)
}
}
แคแฃแแฅแชแแ แจแแกแแงแแแแแ แแฆแแแก แชแแแแแก, แ แแแแแแช แแแแแแจแแ แแแฃแแแ แแแแแชแแแแ แแแแแกแแแ, แแแแแงแแแแแฃแแ แฎแแแแแแก แ แแแแแแแแ, แแแแกแแแแก แ แแแแแแแแ, แฏแแฃแคแแก แแแแ, แแแกแจแขแแแ (scale = 1
แจแแแกแแแแแแแ 256x256 แแแฅแกแแแแแแ แกแฃแ แแแแแแก แแแแแชแแแแก, scale = 0.5
- 128x128 แแแฅแกแแแ), แคแแ แแก แแแฉแแแแแแแแ (color = FALSE
แแแแแแ แแขแแแก แ แแแแแ แแ แแแแก แแแชแ แแกแคแแ แคแแ แแแจแ แแแแแงแแแแแแกแแก color = TRUE
แแแแแแฃแแ แกแขแ แแฅแแแ แจแแแแแแแแแ แแฎแแ แคแแ แจแ) แแ แฌแแแแกแฌแแ แ แแแแฃแจแแแแแแก แแแแแแแขแแ แ แฅแกแแแแแแกแแแแก, แ แแแแแแแช แฌแแแแกแฌแแ แแแแแแแแแฃแแแ แแ แแแ imagenet-แแ. แแก แฃแแแแแกแแแแแ แกแแญแแ แแ แแแแกแแแแแก, แ แแ แแแฎแแแก แแแฅแกแแแแก แแแแจแแแแแแแแแแก แแแกแจแขแแแแ แแแ [0, 1] แแแขแแ แแแแแแแ [-1, 1] แแแขแแ แแแแแแแ, แ แแแแแแช แแแแแแงแแแแแแแ แแแฌแแแแแแก แแแ แฏแแจแแก แแ แแก. แแแ แแก แแแแแแแแ.
แแแ แ แคแฃแแฅแชแแ แจแแแชแแแก แแ แแฃแแแแขแแก แขแแแแก แจแแแแฌแแแแแก, แชแฎแ แแแก data.table
แจแแแแฎแแแแแ แจแแ แแฃแแ แฎแแแแก แแแแ แแแแ samples_index
แแ แกแฃแ แแแแแแก แแแแ แแแ, แแ แแชแฎแแแแ แแ แแแ แขแแแแแก แแแฅแกแแแแแฃแ แ แ แแแแแแแแ, แแกแแแ SQL แแแแแฎแแขแฃแแแแ แแแแแชแแแแ แแแแแแแ แแแแแแขแแแ แแแแกแแแแก. แแแ แแ แแแแกแ, แฉแแแ แแแแแกแแแฆแแ แแ แจแแแแแ แคแฃแแฅแชแแแก แกแฌแ แแคแ แแแแแแแ keras::to_categorical()
. แฉแแแ แแแแแแแงแแแแ แแแแฅแแแก แงแแแแ แแแแแชแแแ แแแ แฏแแจแแกแแแแก, แแแฎแแแแ แ แแ แแชแแแขแ แแแแขแแแแ แแแแแแแชแแแกแแแแก, แแแแขแแ แแแแฅแแก แแแแ แจแแแแแคแแ แแแแแแแ แแแ แแแแขแ แแ steps_per_epoch
แ แแชแ แแแ แแแแก keras::fit_generator()
แแ แแแแแแแ แแแแ if (i > max_i)
แแฃแจแแแแแ แแฎแแแแ แแแแแแแชแแแก แแขแแ แแขแแ แแ.
แจแแแ แคแฃแแฅแชแแแจแ, แกแขแ แแฅแแแแแแก แแแแแฅแกแแแแก แแแซแแแแ แฎแแแแ แจแแแแแแ แแแ แขแแแกแแแแก, แฉแแแแฌแแ แแแ แแขแแแ แแแแ แแแแแชแแแแ แแแแแแแ แแ แแชแฎแแแแแก แแแแ แแแ, JSON แแแ แกแแ แแแ (แคแฃแแฅแชแแ cpp_process_json_vector()
, แแแฌแแ แแแ C++) แแ แแแฎแแขแแแแก แจแแกแแแแแแกแ แแแกแแแแแแก แจแแฅแแแ. แจแแแแแ แแฅแแแแแ แแ แแ แชแฎแแแ แแแฅแขแแ แแแ แแแแกแแก แแขแแแแขแแแแ, แแแกแแแแแ แแแฅแกแแแแก แแแแจแแแแแแแแแแ แแ แแแแแแแแ แแแแ แแแแแแแฃแแแ แกแแแจแ, แ แแช แแ แแก แแแแ แฃแแแแแก แแแแจแแแแแแแ. แกแแแฃแจแแแก แแแกแแฉแฅแแ แแแแแ แแแแแแแงแแแแ แชแฎแ แแแแแจแ แแแแแฅแกแแแแก แจแแฅแแแ data.table
แแ แแแแแคแแแแชแแ แแแฃแแแก แกแแจแฃแแแแแแ - แแ แแแแแขแแก "แฉแแแแแแก" แแแ แแจแ แแแแแชแแแแแ. แแแแแแ แกแแแแแแ แ แแฃแแ แฌแแ แแแกแแแแแแแ แ -แจแ แ แแแแ แแแแจแแแแแแแแแ แแแชแฃแแแแแก แแแแแชแแแแแแแ แแคแแฅแขแฃแ แแ แแฃแจแแแแ.
Core i5 แแแแขแแแแ แกแแฉแฅแแ แแก แแแแแแแแก แจแแแแแแแ แจแแแแแแแ:
แแขแแ แแขแแ แแก แกแแแ แแแแขแแชแแ แแแจแแแ
library(Rcpp)
library(keras)
library(ggplot2)
source("utils/rcpp.R")
source("utils/keras_iterator.R")
con <- DBI::dbConnect(drv = MonetDBLite::MonetDBLite(), Sys.getenv("DBDIR"))
ind <- seq_len(DBI::dbGetQuery(con, "SELECT count(*) FROM doodles")[[1L]])
num_classes <- DBI::dbGetQuery(con, "SELECT max(label_int) + 1 FROM doodles")[[1L]]
# ะะฝะดะตะบัั ะดะปั ะพะฑััะฐััะตะน ะฒัะฑะพัะบะธ
train_ind <- sample(ind, floor(length(ind) * 0.995))
# ะะฝะดะตะบัั ะดะปั ะฟัะพะฒะตัะพัะฝะพะน ะฒัะฑะพัะบะธ
val_ind <- ind[-train_ind]
rm(ind)
# ะะพัััะธัะธะตะฝั ะผะฐัััะฐะฑะฐ
scale <- 0.5
# ะัะพะฒะตะดะตะฝะธะต ะทะฐะผะตัะฐ
res_bench <- bench::press(
batch_size = 2^(4:10),
{
it1 <- train_generator(
db_connection = con,
samples_index = train_ind,
num_classes = num_classes,
batch_size = batch_size,
scale = scale
)
bench::mark(
it1(),
min_iterations = 50L
)
}
)
# ะะฐัะฐะผะตััั ะฑะตะฝัะผะฐัะบะฐ
cols <- c("batch_size", "min", "median", "max", "itr/sec", "total_time", "n_itr")
res_bench[, cols]
# batch_size min median max `itr/sec` total_time n_itr
# <dbl> <bch:tm> <bch:tm> <bch:tm> <dbl> <bch:tm> <int>
# 1 16 25ms 64.36ms 92.2ms 15.9 3.09s 49
# 2 32 48.4ms 118.13ms 197.24ms 8.17 5.88s 48
# 3 64 69.3ms 117.93ms 181.14ms 8.57 5.83s 50
# 4 128 157.2ms 240.74ms 503.87ms 3.85 12.71s 49
# 5 256 359.3ms 613.52ms 988.73ms 1.54 30.5s 47
# 6 512 884.7ms 1.53s 2.07s 0.674 1.11m 45
# 7 1024 2.7s 3.83s 5.47s 0.261 2.81m 44
ggplot(res_bench, aes(x = factor(batch_size), y = median, group = 1)) +
geom_point() +
geom_line() +
ylab("median time, s") +
theme_minimal()
DBI::dbDisconnect(con, shutdown = TRUE)
แแฃ แแฅแแแ แแแฅแแ แกแแแแแ แแกแ แแแแ แแขแแฃแแ แแแฎแกแแแ แแแ, แจแแแแซแแแแ แกแแ แแแแฃแแแ แแแแฉแฅแแ แแ แแแแแชแแแแ แแแแแก แแฃแจแแแแ แแแแแ RAM-แแ แแแแแขแแแแ (แฉแแแแ แแแแชแแแแกแแแแก แกแแแแแ แแกแแ 32 แแ). Linux-แจแ แแแแแงแแคแ แแแแแแขแแแแแฃแแแ แแแแฃแแแกแฎแแแแแ /dev/shm
, แแแแแแแก RAM-แแก แขแแแแแแแแก แแแฎแแแแ แก. แแแขแแก แแแแแจแแแ แจแแแแซแแแแ แ แแแแฅแขแแ แแแแ /etc/fstab
แ แแ แแแแฆแแ แแกแแแแกแ แฉแแแแฌแแ แ tmpfs /dev/shm tmpfs defaults,size=25g 0 0
. แแแ แฌแแฃแแแแ, แ แแ แแแแแขแแแ แแแ แแ แจแแแแแฌแแแ แจแแแแแ แแ แซแแแแแแก แแแจแแแแแ df -h
.
แขแแกแขแแก แแแแแชแแแแแแก แแแแแแ แแแ แแแแ แแ แฃแคแ แ แแแ แขแแแแ, แ แแแแแ แขแแกแขแแก แแแแแชแแแแ แแแแ แแแ แแแแแแแแ แฏแแแแ RAM-แจแ:
Iterator แขแแกแขแแก แแแแแชแแแแแแกแแแแก
test_generator <- function(dt,
batch_size = 32,
scale = 1,
color = FALSE,
imagenet_preproc = FALSE) {
# ะัะพะฒะตัะบะฐ ะฐัะณัะผะตะฝัะพะฒ
checkmate::assert_data_table(dt)
checkmate::assert_count(batch_size)
checkmate::assert_number(scale, lower = 0.001, upper = 5)
checkmate::assert_flag(color)
checkmate::assert_flag(imagenet_preproc)
# ะัะพััะฐะฒะปัะตะผ ะฝะพะผะตัะฐ ะฑะฐััะตะน
dt[, batch := (.I - 1L) %/% batch_size + 1L]
data.table::setkey(dt, batch)
i <- 1
max_i <- dt[, max(batch)]
# ะะฐะผัะบะฐะฝะธะต
function() {
batch_x <- cpp_process_json_vector(dt[batch == i, drawing],
scale = scale, color = color)
if (imagenet_preproc) {
# ะจะบะฐะปะธัะพะฒะฐะฝะธะต c ะธะฝัะตัะฒะฐะปะฐ [0, 1] ะฝะฐ ะธะฝัะตัะฒะฐะป [-1, 1]
batch_x <- (batch_x - 0.5) * 2
}
result <- list(batch_x)
i <<- i + 1
return(result)
}
}
4. แแแแแแแก แแ แฅแแขแแฅแขแฃแ แแก แจแแ แฉแแแ
แแแ แแแแ แแแแแงแแแแแฃแแ แแ แฅแแขแแฅแขแฃแ แ แแงแ (batch, height, width, 3)
, แแแฃ แแ แฎแแแแก แ แแแแแแแแ แแแ แจแแแชแแแแแ. Python-แจแ แแกแแแ แจแแแฆแฃแแแ แแ แแ แกแแแแแก, แแแแขแแ แฉแแแ แแแฉแฅแแ แแ แแ แแแแฌแแ แแ แแ แแ แฅแแขแแฅแขแฃแ แแก แกแแแฃแแแ แ แแแแแแแแแขแแชแแ, แแแแแแแแ แแแแ แกแขแแขแแแก แจแแแแแ (แแแ แแแชแแแแก แแแ แแจแ, แ แแแแแแช แแ แแก keras แแแ แกแแแจแ):
Mobilenet v1 แแ แฅแแขแแฅแขแฃแ แ
library(keras)
top_3_categorical_accuracy <- custom_metric(
name = "top_3_categorical_accuracy",
metric_fn = function(y_true, y_pred) {
metric_top_k_categorical_accuracy(y_true, y_pred, k = 3)
}
)
layer_sep_conv_bn <- function(object,
filters,
alpha = 1,
depth_multiplier = 1,
strides = c(2, 2)) {
# NB! depth_multiplier != resolution multiplier
# https://github.com/keras-team/keras/issues/10349
layer_depthwise_conv_2d(
object = object,
kernel_size = c(3, 3),
strides = strides,
padding = "same",
depth_multiplier = depth_multiplier
) %>%
layer_batch_normalization() %>%
layer_activation_relu() %>%
layer_conv_2d(
filters = filters * alpha,
kernel_size = c(1, 1),
strides = c(1, 1)
) %>%
layer_batch_normalization() %>%
layer_activation_relu()
}
get_mobilenet_v1 <- function(input_shape = c(224, 224, 1),
num_classes = 340,
alpha = 1,
depth_multiplier = 1,
optimizer = optimizer_adam(lr = 0.002),
loss = "categorical_crossentropy",
metrics = c("categorical_crossentropy",
top_3_categorical_accuracy)) {
inputs <- layer_input(shape = input_shape)
outputs <- inputs %>%
layer_conv_2d(filters = 32, kernel_size = c(3, 3), strides = c(2, 2), padding = "same") %>%
layer_batch_normalization() %>%
layer_activation_relu() %>%
layer_sep_conv_bn(filters = 64, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 128, strides = c(2, 2)) %>%
layer_sep_conv_bn(filters = 128, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 256, strides = c(2, 2)) %>%
layer_sep_conv_bn(filters = 256, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(2, 2)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 512, strides = c(1, 1)) %>%
layer_sep_conv_bn(filters = 1024, strides = c(2, 2)) %>%
layer_sep_conv_bn(filters = 1024, strides = c(1, 1)) %>%
layer_global_average_pooling_2d() %>%
layer_dense(units = num_classes) %>%
layer_activation_softmax()
model <- keras_model(
inputs = inputs,
outputs = outputs
)
model %>% compile(
optimizer = optimizer,
loss = loss,
metrics = metrics
)
return(model)
}
แแ แแแแแแแแก แฃแแ แงแแคแแแ แแฎแแ แแแแ แแจแแแ แแ. แแแแ แ แแแแแแแก แแแแแชแแ แแแแแ, แแแแ แแ แแแ แแฅแแ, แแ แแแแแ แแแแแแฃแแ แแ แฅแแขแแฅแขแฃแ แแก แฎแแแแ แแแแแฌแแ แ. แฉแแแ แแกแแแ แฌแแแแแ แแแแก แจแแกแแซแแแแแแแ, แแแแแแแแงแแแแแแแ แฌแแแแกแฌแแ แแแฌแแ แแแแแ แแแแแแแแแก แฌแแแ. แ แแแแ แช แงแแแแแแแแก, แแแแฃแแแแขแแชแแแก แจแแกแฌแแแแ แแแแฎแแแ แ. แคแฃแแฅแชแแ get_config()
แกแแจแฃแแแแแแก แแแซแแแแ แแแแฆแแ แแแแแแแก แแฆแฌแแ แ แ แแแแฅแขแแ แแแแกแแแแก แจแแกแแคแแ แแกแ แคแแ แแแ (base_model_conf$layers
- แ แแแฃแแแ แฃแแ R แกแแ) แแ แคแฃแแฅแชแแ from_config()
แแกแ แฃแแแแก แกแแแแ แแกแแแ แ แแแแแแ แขแแชแแแก แแแแแแแก แแแแแฅแขแแ:
base_model_conf <- get_config(base_model)
base_model_conf$layers[[1]]$config$batch_input_shape[[4]] <- 1L
base_model <- from_config(base_model_conf)
แแฎแแ แซแแแแ แแ แแ แแก แฃแแแแแ แกแแแฃแ แ แคแฃแแฅแชแแแก แแแฌแแ แ แ แแแแแแแ แแแฌแแแแแฃแแแก แแแกแแฆแแแแ แแแ แแก imagenet-แแ แแแแแแแแแฃแแ แฌแแแแแแ แแ แแแก แแแ แแจแ แแแแแแแแ:
แแแ แแ แฅแแขแแฅแขแฃแ แแแแก แฉแแขแแแ แแแแก แคแฃแแฅแชแแ
get_model <- function(name = "mobilenet_v2",
input_shape = NULL,
weights = "imagenet",
pooling = "avg",
num_classes = NULL,
optimizer = keras::optimizer_adam(lr = 0.002),
loss = "categorical_crossentropy",
metrics = NULL,
color = TRUE,
compile = FALSE) {
# ะัะพะฒะตัะบะฐ ะฐัะณัะผะตะฝัะพะฒ
checkmate::assert_string(name)
checkmate::assert_integerish(input_shape, lower = 1, upper = 256, len = 3)
checkmate::assert_count(num_classes)
checkmate::assert_flag(color)
checkmate::assert_flag(compile)
# ะะพะปััะฐะตะผ ะพะฑัะตะบั ะธะท ะฟะฐะบะตัะฐ keras
model_fun <- get0(paste0("application_", name), envir = asNamespace("keras"))
# ะัะพะฒะตัะบะฐ ะฝะฐะปะธัะธั ะพะฑัะตะบัะฐ ะฒ ะฟะฐะบะตัะต
if (is.null(model_fun)) {
stop("Model ", shQuote(name), " not found.", call. = FALSE)
}
base_model <- model_fun(
input_shape = input_shape,
include_top = FALSE,
weights = weights,
pooling = pooling
)
# ะัะปะธ ะธะทะพะฑัะฐะถะตะฝะธะต ะฝะต ัะฒะตัะฝะพะต, ะผะตะฝัะตะผ ัะฐะทะผะตัะฝะพััั ะฒั
ะพะดะฐ
if (!color) {
base_model_conf <- keras::get_config(base_model)
base_model_conf$layers[[1]]$config$batch_input_shape[[4]] <- 1L
base_model <- keras::from_config(base_model_conf)
}
predictions <- keras::get_layer(base_model, "global_average_pooling2d_1")$output
predictions <- keras::layer_dense(predictions, units = num_classes, activation = "softmax")
model <- keras::keras_model(
inputs = base_model$input,
outputs = predictions
)
if (compile) {
keras::compile(
object = model,
optimizer = optimizer,
loss = loss,
metrics = metrics
)
}
return(model)
}
แแ แแแ แฎแแแแ แกแฃแ แแแแแแก แแแแแงแแแแแแกแแก แแ แแแแแแงแแแแแ แฌแแแแกแฌแแ แแแแแแแแแฃแแ แฌแแแ. แแก แจแแแซแแแแ แแแแแกแฌแแ แแแก: แคแฃแแฅแชแแแก แแแแแงแแแแแแ get_weights()
แแแแฆแแ แแแแแแแก แฌแแแ R แแแกแแแแแแก แกแแแก แกแแฎแแ, แจแแชแแแแแ แแ แกแแแก แแแ แแแแ แแแแแแแขแแก แแแแแแแแแแแ (แแ แแ แคแแ แแแ แแ แฎแแก แแฆแแแแ แแ แกแแแแแ แกแแจแฃแแแแ) แแ แจแแแแแ แฉแแขแแแ แแแ แฌแแแ แแแแแแจแ แคแฃแแฅแชแแแ. set_weights()
. แฉแแแ แแ แแกแแ แแก แแแแแแแขแแ แแก แคแฃแแฅแชแแแแแ แแแ, แ แแแแแ แแ แแขแแแแ แฃแแแ แแแแแแ แแงแ, แ แแ แฃแคแ แ แแ แแแฃแฅแขแแฃแแ แแงแ แคแแ แแ แกแฃแ แแแแแแแ แแฃแจแแแแ.
แฉแแแ แฉแแแแขแแ แแ แแฅแกแแแ แแแแแขแแแแก แฃแแแขแแกแแแ mobilenet แแแ แกแแแแแก 1 แแ 2, แแกแแแ แ แแแแ แช resnet34 แแแแแงแแแแแแ. แฃแคแ แ แแแแแแแแ แแแ แแ แฅแแขแแฅแขแฃแ แแแแ, แ แแแแ แแชแแ SE-ResNeXt, แแแ แแแ แแแแแแจแแก แแ แแแแแฃแ แกแจแ. แกแแแฌแฃแฎแแ แแ, แฉแแแ แฎแแแ แแ แแแฅแแแแ แแแ แแแแแแแแแขแแชแแแแ แแ แแ แช แฉแแแแ แแแแแแฌแแ แแ (แแแแ แแ แแฃแชแแแแแแแ แแแแฌแแ แ).
5. แกแแ แแแขแแแแก แแแ แแแแขแ แแแแชแแ
แแแฎแแ แฎแแแฃแแแแแกแแแแก, แขแ แแแแแแแก แแแฌแงแแแแก แงแแแแ แแแแ แจแแแฅแแแ, แ แแแแ แช แแ แแ แกแแ แแแขแ, แแแ แแแแขแ แแ แแแฃแแ แแแแแงแแแแแแ
doc <- '
Usage:
train_nn.R --help
train_nn.R --list-models
train_nn.R [options]
Options:
-h --help Show this message.
-l --list-models List available models.
-m --model=<model> Neural network model name [default: mobilenet_v2].
-b --batch-size=<size> Batch size [default: 32].
-s --scale-factor=<ratio> Scale factor [default: 0.5].
-c --color Use color lines [default: FALSE].
-d --db-dir=<path> Path to database directory [default: Sys.getenv("db_dir")].
-r --validate-ratio=<ratio> Validate sample ratio [default: 0.995].
-n --n-gpu=<number> Number of GPUs [default: 1].
'
args <- docopt::docopt(doc)
แแแแแขแ แแแแแแขแ แฌแแ แแแแแแแแก แแแแฎแแ แชแแแแแแแก Rscript bin/train_nn.R -m resnet50 -c -d /home/andrey/doodle_db
แแ ./bin/train_nn.R -m resnet50 -c -d /home/andrey/doodle_db
, แแฃ แคแแแแ train_nn.R
แแ แแก แจแแกแ แฃแแแแแแ (แแก แแ แซแแแแแ แแแแฌแงแแแก แแแแแแแก แกแฌแแแแแแแก resnet50
128x128 แแแฅแกแแแแก แแแแแก แกแแแคแแ แแแแ แกแฃแ แแแแ แแแแแชแแแแ แแแแ แฃแแแ แแงแแก แแแแแแแกแแแฃแแ แกแแฅแแฆแแแแแจแ /home/andrey/doodle_db
). แแฅแแแ แจแแแแซแแแแ แแแแแแขแแ แกแฌแแแแแก แกแแฉแฅแแ แ, แแแขแแแแแแขแแ แแก แขแแแ แแ แแแแแกแแแแ แ แกแฎแแ แแแแคแแแฃแ แแ แแแแแ แแแ แแแแขแ แ แกแแแจแ. แแฃแแแแแแชแแแก แแแแแแแแแแก แแ แแชแแกแจแ แแฆแแแฉแแแ, แ แแ แแ แฅแแขแแฅแขแฃแ แ mobilenet_v2
แแแแแแแแ แ แแแ แกแแแแแ แแแ แแก R แแแแแงแแแแแแจแ
แแ แแแแแแแแ แจแแกแแซแแแแแแ แแแฎแแแ แแแแจแแแแแแแแแ แแแฉแฅแแ แแแฃแแแงแ แแฅแกแแแ แแแแแขแแแ แกแฎแแแแแกแฎแแ แแแแแแแแแแ แจแแแแ แแแแ RStudio-แจแ แกแแ แแแขแแแแก แฃแคแ แ แขแ แแแแชแแฃแ แแแจแแแแแกแแแ แจแแแแ แแแแ (แฉแแแ แแฆแแแแจแแแแ แแแแแขแก, แ แแแแ แช แจแแกแแซแแ แแแขแแ แแแขแแแแก
6. แกแแ แแแขแแแแก แแแแแ แแแแชแแ
แฉแแแ แแแแแแแงแแแแ Docker แแแ แแแแก แแแ แขแแแแแฃแ แแแแก แฃแแ แฃแแแแแกแแงแแคแแ แแฃแแแแก แฌแแแ แแแก แจแแ แแก แขแ แแแแแแแก แแแแแแแแแกแแแแก แแ แฆแ แฃแแแแจแ แกแฌแ แแคแ แแแแแแแแแแกแแแแก. แแฅแแแ แจแแแแซแแแแ แแแแฌแงแแ R แแ แแแ แแแแกแขแแกแแแแก แจแแแแ แแแแ แฃแฉแแแฃแแ แแ แฎแแแกแแฌแงแแก แแแชแแแแ
Docker แแแซแแแแ แกแแจแฃแแแแแแก แจแแฅแแแแ แแฅแแแแ แกแแแฃแแแ แ แกแฃแ แแแแแ แแฃแแแแแ แแ แแแแแแงแแแแ แกแฎแแ แกแฃแ แแแแแ, แ แแแแ แช แกแแคแฃแซแแแแ แกแแแฃแแแ แแก แจแแกแแฅแแแแแแ. แฎแแแแแกแแฌแแแแแ แแแ แแแแขแแแแก แแแแแแแแแแแแกแแก แแแแแแแ แแแกแแแแแแแ, แ แแ NVIDIA, CUDA+cuDNN แแ แแแแแ แแแแก แแ Python แแแแแแแแแแแแแก แแแงแแแแแ แกแฃแ แแแแก แกแแแแแแ แแแชแฃแแแแแแ แแแฌแแแแ แแ แแแแแแฌแงแแแขแแ แกแแคแฃแซแแแแ แแแแแฆแ แแคแแชแแแแฃแ แ แกแฃแ แแแ. tensorflow/tensorflow:1.12.0-gpu
, แแฅ แแแแแแขแแ แกแแญแแ แ R แแแแแขแแแ.
แกแแแแแแ แแแแแ แแก แคแแแแ แแกแ แแแแแแงแฃแ แแแแแ:
dockerfile
FROM tensorflow/tensorflow:1.12.0-gpu
MAINTAINER Artem Klevtsov <[email protected]>
SHELL ["/bin/bash", "-c"]
ARG LOCALE="en_US.UTF-8"
ARG APT_PKG="libopencv-dev r-base r-base-dev littler"
ARG R_BIN_PKG="futile.logger checkmate data.table rcpp rapidjsonr dbi keras jsonlite curl digest remotes"
ARG R_SRC_PKG="xtensor RcppThread docopt MonetDBLite"
ARG PY_PIP_PKG="keras"
ARG DIRS="/db /app /app/data /app/models /app/logs"
RUN source /etc/os-release &&
echo "deb https://cloud.r-project.org/bin/linux/ubuntu ${UBUNTU_CODENAME}-cran35/" > /etc/apt/sources.list.d/cran35.list &&
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9 &&
add-apt-repository -y ppa:marutter/c2d4u3.5 &&
add-apt-repository -y ppa:timsc/opencv-3.4 &&
apt-get update &&
apt-get install -y locales &&
locale-gen ${LOCALE} &&
apt-get install -y --no-install-recommends ${APT_PKG} &&
ln -s /usr/lib/R/site-library/littler/examples/install.r /usr/local/bin/install.r &&
ln -s /usr/lib/R/site-library/littler/examples/install2.r /usr/local/bin/install2.r &&
ln -s /usr/lib/R/site-library/littler/examples/installGithub.r /usr/local/bin/installGithub.r &&
echo 'options(Ncpus = parallel::detectCores())' >> /etc/R/Rprofile.site &&
echo 'options(repos = c(CRAN = "https://cloud.r-project.org"))' >> /etc/R/Rprofile.site &&
apt-get install -y $(printf "r-cran-%s " ${R_BIN_PKG}) &&
install.r ${R_SRC_PKG} &&
pip install ${PY_PIP_PKG} &&
mkdir -p ${DIRS} &&
chmod 777 ${DIRS} &&
rm -rf /tmp/downloaded_packages/ /tmp/*.rds &&
rm -rf /var/lib/apt/lists/*
COPY utils /app/utils
COPY src /app/src
COPY tests /app/tests
COPY bin/*.R /app/
ENV DBDIR="/db"
ENV CUDA_HOME="/usr/local/cuda"
ENV PATH="/app:${PATH}"
WORKDIR /app
VOLUME /db
VOLUME /app
CMD bash
แแแฎแแ แฎแแแฃแแแแแกแแแแก แแแแแงแแแแแฃแแ แแแแแขแแแ แแแแแแกแแ แชแแแแแแแจแ; แแแฌแแ แแแ แกแแ แแแขแแแแก แฃแแแขแแกแ แแแฌแแแ แแแแแ แแแฃแแแ แแแแขแแแแแ แแแจแ แจแแแ แแแแก แแ แแก. แฉแแแ แแกแแแ แจแแแชแแแแแ แแ แซแแแแแแก แญแฃแ แแ /bin/bash
แจแแแแแ แกแแก แแแ แขแแแแ แแแแแงแแแแแแกแแแแก /etc/os-release
. แแแแ แแแแแแแ แแแชแแแ OS-แแก แแแ แกแแแก แแแแจแ แแแแแแแแแก แแฃแชแแแแแแแแ.
แแแ แแ แแแแกแ, แแแแฌแแ แ แแแขแแ แ bash แกแแ แแแขแ, แ แแแแแแช แกแแจแฃแแแแแแก แแแซแแแแ แแแฃแจแแแ แแแแขแแแแแ แ แกแฎแแแแแกแฎแแ แแ แซแแแแแแแแ. แแแแแแแแแ, แแก แจแแแซแแแแ แแงแแก แกแแ แแแขแแแ แแแ แแฃแแ แฅแกแแแแแแก แแแแแแแแแแกแแแแก, แ แแแแแแแช แแแ แ แแงแ แแแแแแแกแแแฃแแ แแแแขแแแแแ แแก แจแแแแแ, แแ แแ แซแแแแแแก แแแ แกแ แแแแขแแแแแ แแก แแฃแจแแแแแก แแแแแ แแแแกแ แแ แแแแแขแแ แแแแแกแแแแก:
แกแแ แแแขแ แแแแขแแแแแ แแก แแแกแแจแแแแแ
#!/bin/sh
DBDIR=${PWD}/db
LOGSDIR=${PWD}/logs
MODELDIR=${PWD}/models
DATADIR=${PWD}/data
ARGS="--runtime=nvidia --rm -v ${DBDIR}:/db -v ${LOGSDIR}:/app/logs -v ${MODELDIR}:/app/models -v ${DATADIR}:/app/data"
if [ -z "$1" ]; then
CMD="Rscript /app/train_nn.R"
elif [ "$1" = "bash" ]; then
ARGS="${ARGS} -ti"
else
CMD="Rscript /app/train_nn.R $@"
fi
docker run ${ARGS} doodles-tf ${CMD}
แแฃ แแก bash แกแแ แแแขแ แแแจแแแแฃแแแ แแแ แแแแขแ แแแแก แแแ แแจแ, แกแแ แแแขแ แแแแแแซแแฎแแแ แแแแขแแแแแ แแก แจแแแแแ train_nn.R
แแแแฃแแแกแฎแแแแ แแแแจแแแแแแแแแแ; แแฃ แแแ แแแแ แแแแแชแแฃแ แ แแ แแฃแแแแขแ แแ แแก "bash", แแแจแแ แแแแขแแแแแ แ แแแแฌแงแแแ แแแขแแ แแฅแขแแฃแแแ แแ แซแแแแแแก แญแฃแ แแแ. แงแแแแ แกแฎแแ แจแแแแฎแแแแแจแ, แแแแแชแแฃแ แ แแ แแฃแแแแขแแแแก แแแแจแแแแแแแแแ แแชแแแแแ: CMD="Rscript /app/train_nn.R $@"
.
แแฆแกแแแแจแแแแแ, แ แแ แแแ แแฅแขแแ แแแแ แฌแงแแ แแก แแแแแชแแแแแแ แแ แแแแแชแแแแ แแแแแแแ, แแกแแแ แ แแแแ แช แแแฌแแ แแแแแ แแแแแแแแแก แจแแแแฎแแแก แแแ แแฅแขแแ แแ, แแแแแแขแแแแแฃแแแ แแแแขแแแแแ แจแ แแแกแแแแซแแแ แกแแกแขแแแแแแ, แ แแช แกแแจแฃแแแแแแก แแแซแแแแ แแแแฆแแ แกแแ แแแขแแแแก แจแแแแแแแ แแแแแแขแ แแแแแแฃแแแชแแแแแก แแแ แแจแ.
7. แ แแแแแแแแ GPU-แแก แแแแแงแแแแแ Google Cloud-แแ
แแแแแฃแ แกแแก แแ แ-แแ แแ แแแฎแแกแแแแแแแแ แแงแ แซแแแแแ แฎแแแฃแ แแแแ แแแแแชแแแแแ (แแฎแแแแ แกแแแแฃแ แแก แกแฃแ แแแ, แแแกแแกแฎแแแ @Leigh.plt-แแแ ODS slack-แแแ). แแแแ แแแ แขแแแแ แแแแฎแแแ แแแ แแแแก แฌแแแแแฆแแแแ แแ แซแแแแจแ แแ แแแแแแฃแขแแ แแ แแฅแกแแแ แแแแแขแแแแก แจแแแแแ, 1 GPU-แแ, แแแแแแฌแงแแแขแแ แแแแฃแคแแแ แขแ แแแแแแแก แแแแแแแแก แ แแแแแแแแ GPU-แแ แฆแ แฃแแแแจแ. แแแแแงแแแแแฃแแ GoogleCloud (dev/shm
.
แงแแแแแแ แกแแแแขแแ แแกแแ แแแแแก แคแ แแแแแแขแ, แ แแแแแแช แแแกแฃแฎแแกแแแแแแแแ แแ แแแแแ GPU-แแก แแแแแงแแแแแแแ. แแแ แแแแ, แแแแแแ แแฅแแแแแ CPU-แแ แแแแขแแฅแกแขแฃแ แ แแแแแฏแแ แแก แแแแแงแแแแแแ, แแกแแแ แ แแแแ แช แแแแแแจแ:
with(tensorflow::tf$device("/cpu:0"), {
model_cpu <- get_model(
name = model_name,
input_shape = input_shape,
weights = weights,
metrics =(top_3_categorical_accuracy,
compile = FALSE
)
})
แจแแแแแ แแแฃแแแแแแแฅแขแแแแแ (แแก แแแแจแแแแแแแแแแ) แแแแแแ แแแแแ แแแแ แฎแแแแแกแแฌแแแแแ GPU-แแแแก แแแชแแแฃแ แ แแแแแแแแแแ แแ แแฎแแแแ แแแแก แจแแแแแ แฎแแแแ แแแกแ แจแแแแแแ:
model <- keras::multi_gpu_model(model_cpu, gpus = n_gpu)
keras::compile(
object = model,
optimizer = keras::optimizer_adam(lr = 0.0004),
loss = "categorical_crossentropy",
metrics = c(top_3_categorical_accuracy)
)
แงแแแแ แคแแแแก แแแงแแแแแก แแแแกแแแฃแ แ แขแแฅแแแแ, แแแ แแ แฃแแแแแกแแแแแแกแ, แแแแ แคแแแแก แแแ แฏแแจแ, แแแงแแแแ แแ แแแแแ แแแแแแแก แแแแแแแแแแแ แ แแแแแแแแ GPU-แกแแแแก, แแแ แแแแฎแแ แชแแแแแ.
แขแ แแแแแแแก แแแแแขแแ แแแแ แฎแแแแแแ แแแแแงแแแแแแก แแแ แแจแ. แขแแแกแแ แแแ แแ, แจแแแแแแคแแ แแแแแแ แแฃแ แแแแแแแก แฉแแฌแแ แแ แแ แแแแแแแแแก แจแแแแฎแแแ แแแคแแ แแแชแแฃแแ แกแแฎแแแแแแ แงแแแแแ แแแแฅแแก แจแแแแแ:
แแแแแซแแฎแแแแแ
# ะจะฐะฑะปะพะฝ ะธะผะตะฝะธ ัะฐะนะปะฐ ะปะพะณะฐ
log_file_tmpl <- file.path("logs", sprintf(
"%s_%d_%dch_%s.csv",
model_name,
dim_size,
channels,
format(Sys.time(), "%Y%m%d%H%M%OS")
))
# ะจะฐะฑะปะพะฝ ะธะผะตะฝะธ ัะฐะนะปะฐ ะผะพะดะตะปะธ
model_file_tmpl <- file.path("models", sprintf(
"%s_%d_%dch_{epoch:02d}_{val_loss:.2f}.h5",
model_name,
dim_size,
channels
))
callbacks_list <- list(
keras::callback_csv_logger(
filename = log_file_tmpl
),
keras::callback_early_stopping(
monitor = "val_loss",
min_delta = 1e-4,
patience = 8,
verbose = 1,
mode = "min"
),
keras::callback_reduce_lr_on_plateau(
monitor = "val_loss",
factor = 0.5, # ัะผะตะฝััะฐะตะผ lr ะฒ 2 ัะฐะทะฐ
patience = 4,
verbose = 1,
min_delta = 1e-4,
mode = "min"
),
keras::callback_model_checkpoint(
filepath = model_file_tmpl,
monitor = "val_loss",
save_best_only = FALSE,
save_weights_only = FALSE,
mode = "min"
)
)
8. แแแกแแแแแก แแแชแแแแ
แแแแแ แ แแแ แแ แแแแแแแแ, แ แแแแแแแช แจแแแแฎแแแ แฏแแ แแแแแ แแ แแ แแก แแแซแแแฃแแ:
- ะฒ แแแ แแก แแ แแ แกแแแแแก แแแ แคแฃแแฅแชแแ แแแขแแแแแฃแ แ แกแฌแแแแแก แกแแฉแฅแแ แแก แแแขแแแแขแฃแ แแ แแแกแแซแแแแแ (แแแแแแแฃแ แ
lr_finder
แแแแแแแแแแแจแ แกแฌแ แแคแแ.แแ); แแแ แแแแฃแแ แซแแแแกแฎแแแแแ, แจแแกแแซแแแแแแแ แแแกแแแ แแฎแแ แแก แแแแแแแแแขแแชแแแแแก แแแ แขแแ แแแ R-แแ, แแแแแแแแแ,แแก ; - แฌแแแ แแฃแแฅแขแแก แจแแแแแแ, แ แแแแแแแแ GPU-แก แแแแแงแแแแแแกแแก แจแแฃแซแแแแแแ แแงแ แแแ แฏแแจแแก แกแฌแแ แ แกแแฉแฅแแ แแก แจแแ แฉแแแ;
- แแ แกแแแแแก แแแแแแแแ แแแ แแแ แแฃแแ แฅแกแแแแแแก แแ แฅแแขแแฅแขแฃแ แแก แแแแแแแแแ, แแแแกแแแฃแแ แแแแ แแแแฏแแแขแแ แฌแแแแกแฌแแ แแแแแแแแแฃแแ;
- แแ แแแแก แชแแแแแก แแแแแขแแแ แแ แกแฌแแแแแก แแแกแแ แแแแแแชแแฃแแ แแแฉแแแแแแแแแ (แแแกแแแฃแกแฃแ แ แแแแแแ แแแ แแงแ แฉแแแแ แแแแฎแแแแแ
แแแแฎแแ แชแแแแแ , แแแแแแแแกแแแแแแแ ).
แ แ แกแแกแแ แแแแแ แ แแ แแแกแฌแแแแแ แแ แแแแแฃแ แกแแแแ:
- แจแแแแ แแแแ แแแแแแ แกแแแซแแแแ แแก แแแแ แแขแแ, แจแแแแซแแแแ แแแฃแจแแแ แแแแแชแแแแ แฆแแ แกแแฃแแ (แ แแแแแแฏแแ แแแขแ แแแแ แแขแแฃแแ แแแฎแกแแแ แแแแ) แแแชแฃแแแแแ, แขแแแแแแแก แแแ แแจแ. แแแแกแขแแแฃแ แ แฉแแแแ แแแแแชแแแแแ. แแแแแแ แแแแแแก แแแฎแกแแแ แแแแก แชแฎแ แแแแแแก แแแแแแแ แแแแแคแแชแแ แแแแก แแแแ, แ แแช แแแแแแแ แแแชแแแแแก แแแ แแแแแ แแแแก แแ แกแฌแแ แแ แแแแแงแแแแแแกแแก, แแแกแ แจแแกแแซแแแแแแแแแ แแแแฅแแแก แงแแแแแแแแก แแฉแแแแแแก แฃแแแฆแแแก แกแแฉแฅแแ แแก แกแแ แแแขแแ แแแแก แแแแแแกแแแแก แฉแแแแแแแก แชแแแแแ แงแแแแ แฎแแแกแแฌแงแแก แจแแ แแก. แแแแแชแแแแ แแแแแจแ แจแแแแฎแแ แกแแจแฃแแแแแแก แแแซแแแแ, แฎแจแแ แจแแแแฎแแแแแจแ, แกแแแ แแแ แแ แแคแแฅแ แแ แแแแแ แแแแแชแแแแ RAM-แจแ แจแแแฃแแจแแแก แแฃแชแแแแแแแแแแ.
- R-แจแ แแแแ แคแฃแแฅแชแแแแ แจแแแซแแแแ แจแแแชแแแแแก แกแฌแ แแคแ แคแฃแแฅแชแแแแแ C++-แจแ แแแแแขแแก แแแแแงแแแแแแ Rcpp. แแฃ แแแแแงแแแแแแก แแแ แแ RcppThread แแ Rcppแแแ แแแแแฃแ แ, แแแฆแแแ แแ แแก แแแแขแคแแ แแแก แแ แแแแ แฎแ แแฎแแแแ แแแแแแแแแขแแชแแแก, แแแแขแแ แแ แแ แแก แกแแญแแ แ แแแแแก แแแ แแแแแแแแแ R แแแแแแ.
- แแแแแขแ Rcpp แจแแแซแแแแ แแแแแงแแแแแฃแ แแฅแแแก C++-แแก แกแแ แแแแฃแแ แชแแแแแก แแแ แแจแ, แแกแแฎแฃแแแ แกแแญแแ แ แแแแแแฃแแ
แแฅ . แกแแแแฃแ แแก แคแแแแแแ แแ แแแแแ แแแแแ แ C-แแแแแแแแแแแกแแแแก, แ แแแแ แแชแแ xtensor แฎแแแแแกแแฌแแแแแแ CRAN-แแ, แแแฃ แแฅแแแแแ แแแคแ แแกแขแ แฃแฅแขแฃแ แ แแ แแแฅแขแแแแก แแแแกแแฎแแ แชแแแแแแแแ, แ แแแแแแแช แแแ แแแแแแแก แแแ แแแฆแแแ แฎแแ แแกแฎแแก C++ แแแแก R-แจแ. แแแแแขแแแแแ แแแฎแแ แฎแแแฃแแแแ แแ แแก แกแแแขแแฅแกแแก แฎแแแแแกแแ แแ แกแขแแขแแแฃแ แ C++ แแแแแก แแแแแแแแขแแ แ RStudio-แจแ. - แแแแแแขแ แกแแจแฃแแแแแแก แแแซแแแแ แแแฃแจแแแ แแแแแฃแแแแแแแแ แกแแ แแแขแแแ แแแ แแแแขแ แแแแ. แแก แแแกแแฎแแ แฎแแแแแแ แแแกแขแแแชแแฃแ แกแแ แแแ แแ แแแแแกแแงแแแแแแแ, แแแ แจแแ แแก. แแแแแ แแก แฅแแแจ. RStudio-แจแ แแ แแกแแกแแแแแแแแ แแ แแแแแกแแแแแแแ แแฅแกแแแ แแแแแขแแแแก แฉแแขแแ แแแ แแแ แแฃแแ แฅแกแแแแแแก แแแ แฏแแจแแ แแ แแแแแ แกแแ แแแ แแ IDE-แแก แแแงแแแแแ แงแแแแแแแแก แแ แแ แแก แแแแแ แแแแแฃแแ.
- Docker แฃแแ แฃแแแแแงแแคแก แแแแแก แแแ แขแแแแแฃแ แแแแก แแ แจแแแแแแแแก แแแแแแ แแแแก แแแแแแแแแ แแแก แจแแ แแก OS-แแก แแ แแแแแแแแแแแแแก แกแฎแแแแแกแฎแแ แแแ แกแแแ, แแกแแแ แกแแ แแแ แแแแ แจแแกแ แฃแแแแแก แแแ แขแแแแแแก. แแฅแแแ แจแแแแซแแแแ แแแฃแจแแแ แแแแแ แกแแกแฌแแแแ แแแแกแแแแแ แแฎแแแแ แแ แแ แแ แซแแแแแแ.
- Google Cloud แแ แแก แกแแแแฃแฏแแขแ แแแ แซแแแ แแแฆแแ แแแฃแแ แแแแ แแขแฃแ แแก แแฅแกแแแ แแแแแขแแแแกแแแแก, แแแแ แแ แแฅแแแ แฃแแแ แแแ แฉแแแ แแแแคแแแฃแ แแชแแแแ แคแ แแฎแแแแ.
- แแแแแแแแฃแแแฃแ แ แแแแแก แคแ แแแแแแขแแแแก แกแแฉแฅแแ แแก แแแแแแแ แซแแแแแ แกแแกแแ แแแแแแ, แแแแกแแแฃแแ แแแแ R แแ C++-แแก แแแแแแแแ แแแแกแแก แแ แแแแแขแแแ แแ แแแ. bench - แแกแแแ แซแแแแแ แแแแแแแ.
แกแแแ แแ แฏแแแจแ, แแก แแแแแชแแแแแแ แซแแแแแ แกแแกแแ แแแแแ แแงแ แแ แฉแแแ แแแแ แซแแแแแ แแฃแจแแแแแก แฌแแแแญแ แแแ แแแแแแ แแ แกแแแแแฎแแก แแแกแแแแแ แแแแแ.
แฌแงแแ แ: www.habr.com