"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 训练过程中作为消息而不是打印返回(如果我理解正确的话)。
所以,这归结为两个问题:
- 有没有办法让
renderPrint()
一出现就打印输出?
- 有没有办法让
renderPrint()
使用 message()
而不是 print()
生成的输出?
感谢您的帮助。
一种解决方案是将 withCallingHandlers
与 shinyjs
包 (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)
})
})
}
))
我目前正在开发一个基于 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 训练过程中作为消息而不是打印返回(如果我理解正确的话)。
所以,这归结为两个问题:
- 有没有办法让
renderPrint()
一出现就打印输出? - 有没有办法让
renderPrint()
使用message()
而不是print()
生成的输出?
感谢您的帮助。
一种解决方案是将 withCallingHandlers
与 shinyjs
包 (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)
})
})
}
))