Подтвердить что ты не робот

Как я могу печатать при использовании% dopar%

У меня есть цикл foreach, который использует %dopar% с doSNOW как фоновый. Как я могу получить цикл на каждой итерации?

Мой код ниже - это то, что я сейчас использую, но его ничего не печатать.

foreach(ntree=rep(25,2),.combine=combine,.packages='randomForest',
    .inorder=FALSE) %dopar% {
        print("RANDOM FOREST")
        randomForest(classForm,data=data,na.action=na.action,do.trace=do.trace,ntree=ntree,mtry=mtry)
    }   
4b9b3361

Ответ 1

Здесь есть несколько хороших решений, но мне легче всего войти в сокет и использовать отдельный процесс для вывода вызовов журнала в консоли.

Я использую следующую функцию:

log.socket <- make.socket(port=4000)

Log <- function(text, ...) {
  msg <- sprintf(paste0(as.character(Sys.time()), ": ", text, "\n"), ...)
  cat(msg)
  write.socket(log.socket, msg)
}

Затем вы можете размещать логические операторы в коде, например:

Log("Processing block %d of %d", i, n.blocks)

Выход журнала можно просматривать в режиме реального времени с помощью любого простого инструмента прослушивания сокетов. Например, используя netcat в Linux:

nc -l 4000

Вышеуказанный оператор журнала будет отображаться в терминале netcat следующим образом:

2014-06-25 12:30:45: Processing block 2 of 13

Этот метод имеет преимущество в том, что он работает удаленно и предоставляет подробный вывод по мере необходимости.

p.s. Для тех, кто в Windows, см. порт Netcat Jon Craton.

p.p.s Я предполагаю, что функция write.socket R, вероятно, не является потокобезопасной, но если вы не регистрируетесь на высокой частоте, вы вряд ли столкнетесь с какой-либо проблемой. Что-то, о чем нужно знать.

Ответ 2

Вывод, производимый работниками снега, отбрасывается по умолчанию, но вы можете использовать опцию makefile для makeCluster, чтобы изменить это. Установка outfile в пустую строку ("") предотвратит перенаправление снега на выход, часто приводя к выходу из ваших сообщений печати, отображаемых на терминале основного процесса.

Просто создайте и зарегистрируйте свой кластер с чем-то вроде:

library(doSNOW)
cl <- makeCluster(4, outfile="")
registerDoSNOW(cl)

Ваш цикл foreach не нуждается в изменении вообще.

Это работает для меня как с кластерами SOCK, так и с кластерами MPI с использованием Rmpi, созданного с помощью Open MPI. В Windows вы не увидите никакого выхода, если используете Rgui. Если вы используете Rterm.exe, вы будете.

Обратите внимание, что помимо вашего собственного вывода вы увидите сообщения, созданные снегом, которые также могут быть полезны.


Чтобы использовать индикатор выполнения, doSNOW версии 1.0.14 имеет параметр progress. Вот полный пример:

library(doSNOW)
library(tcltk)
library(randomForest)
cl <- makeSOCKcluster(3)
registerDoSNOW(cl)

ntasks <- 100
pb <- tkProgressBar(max=ntasks)
progress <- function(n) setTkProgressBar(pb, n)
opts <- list(progress=progress)

x <- matrix(runif(500), 100)
y <- gl(2, 50)

rf <- foreach(ntree=rep(25, ntasks), .combine=combine,
        .multicombine=TRUE, .packages='randomForest',
        .options.snow=opts) %dopar% {
  randomForest(x, y, ntree=ntree)
}

Параметр progress довольно общий, поэтому вы можете просто распечатать сообщение с помощью функции, например:

progress <- function(n) cat(sprintf("task %d is complete\n", n))

Ответ 3

Способ отслеживания прогресса на узлах во время длительных операций - создать индикатор выполнения с помощью tkProgressBar из пакета tcltk. Это не совсем то, о чем вы просили, но это должно позволить вам увидеть что-то из узлов. По крайней мере, это происходит, когда кластер является кластером сокетов, работающим на локальном хосте (который является машиной Windows). Потенциальная проблема заключается в том, что индикатор выполнения либо остается, либо загромождает ваш монитор, либо получает close d, а печатная информация исчезла. Для меня это не проблема, потому что я просто хотел узнать, каков был текущий статус.

library(parallel)
library(doSNOW)
cl<-makeCluster(detectCores(),type="SOCK")
registerDoSNOW(cl)

Используя ваш код,

foreach(ntree=rep(25,2),.combine=combine,.packages=c('randomForest','tcltk'),
    .inorder=FALSE) %dopar% {
        mypb <- tkProgressBar(title = "R progress bar", label = "",
          min = 0, max = 1, initial = 0, width = 300)
        setTkProgressBar(mypb, 1, title = "RANDOM FOREST", label = NULL)
    ans <- randomForest(classForm,data=data,na.action=na.action,do.trace=do.trace,ntree=ntree,mtry=mtry)
    close(mypb)
    ans
    }

Здесь приведен более общий пример использования:

jSeq <- seq_len(30)

foreach(i = seq_len(2), .packages = c('tcltk', 'foreach')) %dopar% {
    mypb <- tkProgressBar(title = "R progress bar", label = "",
        min = 0, max = max(jSeq), initial = 0, width = 300)
    foreach(j = jSeq) %do% {
        Sys.sleep(.1)
        setTkProgressBar(mypb, j, title = "RANDOM FOREST", label = NULL)
    }
    NULL
}

Ответ 4

У меня была такая же проблема. Я настраивал параметры для случайного леса, используя пакет foreach, и хотел напечатать строку "Результаты" после каждой итерации, но не мог понять, не просматривая отображение индикатора выполнения и т.д.

Вот что я сделал, В моей функции, Я добавил эту строку

write.table(result, file=paste("RF_ntree_",ntree,"_dims_",dims,".txt", sep=""),
  sep="\t", row.names=F)

Итак, после каждой итерации результаты записываются в текстовый файл с такими именами, как RF_ntree_250_dims_100.txt.

Итак, если я хочу отслеживать прогресс, я просто обновляю папку, в которую записываются текстовые файлы.

PS: результаты также накапливаются в кадре данных.

Ответ 5

Альтернативой является использование ведение журнала файлов (например, пакет log4r) и отдельная печать вывода на экране (например, "tail -f" ).

Это хорошо работает, если вы все равно планируете создавать журналы, и вы можете использовать существующие пакеты со всеми связанными с ними колокольчиками.