"Live updates" 在 r shiny 中训练机器学习模型时

"Live updates" when training a machine learning model in r shiny

我目前正在开发一个基于 R markdown 和 shiny 的用户界面,以便为不精通 R 的其他用户轻松执行机器学习训练过程。这个训练过程是通过围绕 R 的自定义构建函数完成的package mxnet 并在 运行 in a "normal" R脚本。但是,当 运行 在 R markdown 中使用此应用程序时,浏览器不会打印任何内容。以下脚本显示了一个最小的可重现示例(训练过程替换为简单的 "dummy" 函数):

---
title: "Training of a Neural Network"
output: html_document
runtime: shiny
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r start_training, echo=F}
inputPanel(
  actionButton("button_start_training", "Start training")
)
```

```{r dummy_function, echo=F}
dummy_function <- function(){
  for(i in 1:5){
    message(paste0("Test: "),i)
    Sys.sleep(0.5)
  }
}
```

```{r actual_training, echo=F}
event_training = eventReactive(input$button_start_training,{

  dummy_function()

})

renderPrint({
          event_training()

          })
```

dummy_function()的控制台输出不显示在浏览器中,而只显示在控制台中。如果 message()print() 替换,结果中显示 ,但只有 after 功能完成而不是"live"。因为实际的训练过程需要几个小时,所以我想在控制台中提供这些更新。此外,将 message() 替换为 print() 可能会导致一些问题,因为训练错误之类的东西在 mxnet 训练过程中作为消息而不是打印返回(如果我理解正确的话)。

所以,这归结为两个问题:

  1. 有没有办法让 renderPrint() 一出现就打印输出?
  2. 有没有办法让 renderPrint() 使用 message() 而不是 print() 生成的输出?

感谢您的帮助。

一种解决方案是将 withCallingHandlersshinyjs 包 (https://github.com/daattali/shinyjs) 结合使用。使用它,您可以更改页面上元素的内部 HTML,该元素会立即显示。从一个空元素开始,可以在每次函数调用message的时候给元素添加一个日志,如下:

dummy_function <- function(){
  for(i in 1:5){
    message(paste0("Test: "),i)
    Sys.sleep(0.5)
  }

runApp(shinyApp(
  ui = fluidPage(
    shinyjs::useShinyjs(),
    actionButton("button_start_training", "Start training"),
    textOutput("logs")
  ),
  server = function(input, output, session) {
    observeEvent(input$button_start_training, {
      withCallingHandlers({
        shinyjs::html("logs", "")
        dummy_function()
      },
        message = function(m) {
          shinyjs::html(id = "logs", html = m$message, add = TRUE)
      })
    })
  }
))