我想使用 R 和 Python 创建一个 Shiny 应用程序,因为 Yolov8 模型是用 Python 开发的。但是,我尝试使用我的应用程序在我的应用程序目录中调用一些 *py 代码(
setup.py
,image_classification.py
),但它不起作用,尽管在 Posit 中使用 Python 和 R 来协调这两种语言取得了进步.
在我的例子中我尝试:
library(shiny)
library(shinydashboard)
library(rsconnect)
library(tidyverse)
library(reticulate)
library(purrr)
library(stringr)
# Read setup.py with Yolov8 in Python
#setup.py file content: ---------------------
# # install yolov8
# from ultralytics import YOLO
#-------------------------------------------
header1<-"# install yolov8"
write.table(header1,file="setup.py",row.names = FALSE,quote=FALSE,col.names=FALSE)
header2<-"from ultralytics import YOLO"
write.table(header2,file="setup.py",append=TRUE,row.names = FALSE,col.names=FALSE)
#
# Create conda env if not exist
if(!("yolodetec_py1" %in% conda_list()$name)){
# conda_create("yolodetec_py1", python_version = "3.7")
use_condaenv("yolodetec_py1", required = TRUE)
# Set up python libraries for object detection
source_python("setup.py")
}
# Open the training YOLOv8 *pt image_classification.py
# image_classification.py file content: ----
#
# Import my trained model
# model = YOLO (r"https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt")
#-------------------------------------------
header1<-"#Import my trained model",
write.table(header1,file="image_classification.py",row.names = FALSE,quote=FALSE,col.names=FALSE)
header2<-"model = YOLO (r"https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt")"
write.table(header2,file="image_classification.py",append=TRUE,row.names = FALSE,quote=FALSE,col.names=FALSE)
# Load detection model
# detection_model = reticulate::model.detect()
#-------------------------------------------
# Load model and prediction functions
source_python("image_classification.py")
# Load the model
model <- model # from imagem_classification.py
# Define the UI
ui <- fluidPage(
# App title ----
titlePanel("Hello YOLOv8!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: File upload
fileInput("image_path", label = "Input a JPEG image")
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
textOutput(outputId = "prediction"),
plotOutput(outputId = "image")
)
)
)
# Define server logic required to draw a histogram ----
server <- function(input, output) {
image <- reactive({
req(input$image_path)
jpeg::readJPEG(input$image_path$datapath)
})
output$prediction <- renderText({
img <- image() %>%
array_reshape(., dim = c(1, dim(.), 1))
paste0("The predicted class is ", reticulate::detection_model(img)) # from imagem_classification.py
})
output$image <- renderPlot({
plot(as.raster(image()))
})
}
shinyApp(ui, server)
但是错误总是:
Erro: 'model' is not an exported object from 'namespace:reticulate'
请帮忙吗?
提前致谢,
亚历山大
我明白这是怎么回事了。您正在尝试在 R Shiny 应用程序中使用 Python 代码,这是个好主意!但是,您的方法存在一些问题。
问题 1:
source_python
无法按您的预期工作
source_python
并不意味着以与 source
执行 R 代码相同的方式执行 Python 代码。相反,它将 Python 模块加载到 R 环境中,允许您访问其函数和变量。但是,它不会执行文件中的 Python 代码。
问题2:
reticulate
不会自动导入Python变量
当您使用
source_python
加载 Python 模块时,您需要显式导入要在 R 中使用的变量或函数。在您的情况下,您尝试从 model
文件访问 image_classification.py
变量,但你还没有导入它。
问题3:
detection_model
未定义
您尝试使用
reticulate::detection_model
就好像它是一个函数一样,但它没有在代码中的任何地方定义。
要解决这些问题,您需要修改您的方法。这是建议的解决方案:
第 1 步:创建一个带有加载模型函数的 Python 模块
创建一个新的 Python 文件,例如
yolov8_loader.py
,其中包含以下内容:
import ultralytics as yolo
def load_model():
model = yolo.YOLO("https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt")
return model
此文件定义了一个加载 YOLOv8 模型的
load_model
函数。
第2步:在R中加载Python模块并导入函数
在 R 代码中,使用
yolov8_loader
加载 source_python
模块:
library(reticulate)
# Load the Python module
yolov8_loader <- source_python("yolov8_loader.py")
# Import the load_model function
load_model <- yolov8_loader$load_model
第3步:使用导入的函数加载模型
现在,您可以使用
load_model
函数加载YOLOv8模型:
# Load the model
model <- load_model()
第 4 步:修改您的 Shiny 应用程序以使用加载的模型
更新您的 Shiny 应用程序以使用加载的模型:
server <- function(input, output) {
image <- reactive({
req(input$image_path)
jpeg::readJPEG(input$image_path$datapath)
})
output$prediction <- renderText({
img <- image() %>%
array_reshape(., dim = c(1, dim(.), 1))
# Use the loaded model to make predictions
prediction <- model(img)
paste0("The predicted class is ", prediction)
})
output$image <- renderPlot({
plot(as.raster(image()))
})
}
这应该可以解决您面临的问题。请注意,您需要修改
image_classification.py
文件来定义一个将图像作为输入并返回预测的函数,然后在 R 代码中导入该函数。