1

my search for a possibility to convert a generated model into VHDL to program an FPGA has no solution so far.

The problem: caret -> Training -> Modell -> Modell.rds -> Modell.xml (PMML) --?--> VHDL-Code --?--> FPGA

The (simplified) task: A photo detector with 16 channels is measuring the intensity of 16 different wavelength ranges. These data are classified with the possible results “sunny”, “cloudy” and “rainy”. The model is trained, tested and finalized with „caret“ and saved as an .rds-file.

The solution with R: Import new data and classify them with that model.

The problem without R: How can the model be converted to other languages? (e.g. PMML, but this only supports a couple of models) How is PMML (*.xml) converted to VHDL to program an FPGA or MC? Do I first have to compile it to Python/Matlab/…? And how?

My question: Does anybody have experiences with this and/or a solution without uploading the model somewhere to translate it to VHDL?

Thank you all in advance

MWE for classification using "caret":

    ####################################################################################
#### Generate some data ############################################################
####################################################################################

set.seed(1)
exampledata <- matrix(nrow=100,ncol=17)
wheather <- c("sunny", "cloudy", "rainy")
wheathersample <- sample(wheather,100,replace=T)
exampledata[,1] <- wheathersample
for (i in 1:100){
  ifelse(exampledata[i,1]=="sunny", exampledata[i,2:17]<-abs(rnorm(16,0.8,0.1)),
         ifelse(exampledata[i,1]=="cloudy", exampledata[i,2:17]<-abs(rnorm(16,0.7,0.1)),
                exampledata[i,2:17]<-abs(rnorm(16,0.6,0.1))))
}
colnames(exampledata) <- c("Class",paste0("Channel_",1:16))

exampledata <- as.data.frame(exampledata)
indx <- sapply(exampledata, is.factor)
exampledata[indx] <- lapply(exampledata[indx], function(x) as.numeric(as.character(x)))
exampledata[,1] <- as.factor(wheathersample)

matplot(t(exampledata[,-1]), type="l",col=as.factor(exampledata[,1]))
str(exampledata)

####################################################################################
#### Separating data in Training und Test ##########################################
####################################################################################

#choose your destination to use file
#exampledata <- read.table("E:/R2FPGA/PMML/Test/exampledata.txt",header=T)
head0.sub <- exampledata[,1]
data0.sub <- exampledata[,-1]
require(lattice)
require(ggplot2)
require(caret)
set.seed(1) # influences the random separation

# create an index sample, which separates the data
trainIndex <- createDataPartition(head0.sub, p = .75, 
                                  list = FALSE, 
                                  times = 1)
data0_train <- data0.sub[trainIndex,]
data0_test <- data0.sub[-trainIndex,]
head0_train <- head0.sub[trainIndex]
head0_test <- head0.sub[-trainIndex]
stopifnot(sort(unique(as.character(head0_test)))==sort(unique(as.character(head0_train))))

#joining head and data
# First column will be the class, the others are the channels/features

Trainingset <- as.data.frame(cbind(head0_train,data0_train))
colnames(Trainingset)[1] <- "Class"
Trainingset$Class <- as.factor(Trainingset$Class)
Testingset <- as.data.frame(cbind(head0_test,data0_test))
colnames(Testingset)[1] <- "Class"
Testingset$Class <- as.factor(Testingset$Class)

dim(Trainingset)
summary(Testingset$Class)
str(Trainingset)
str(Trainingset$Class)
# delete unused variables
rm(data0_test,data0_train,head0_test,head0_train,trainIndex)

##############################################################################################
#### "...Control" sets global parameters                        ##############################
####              set number=1 to get a feeling for the runtime ##############################
#### "...Grid"    sets the tuning grid which safes the models   ##############################
####              parameters are named individually by models   ##############################
####                                                            ##############################
#### See "caret"-package documentation for further information  ##############################
##############################################################################################


####################################################################################
#### Neural Networks with Feature Selection #########################################
####################################################################################

require(nnet)
require(e1071)
require(NeuralNetTools)
set.seed(1)
ANNstart <- Sys.time()
nnetControl <- trainControl(number = 1,
                               verboseIter = TRUE)

nnetGrid <-  expand.grid(.size=1:10, .decay=c(0.01*(1:10)))
nnetFit <- train(Class~., Trainingset,
                    method = "nnet", tuneGrid = nnetGrid, trControl = nnetControl, scaled = TRUE,
                    MaxNWts=10000, 
                    maxit=1000  # number of iteration
)
nnetFit
confusionMatrix(nnetFit)
plot(nnetFit)
ANNPred <- predict(nnetFit, Testingset[,-1])
confusionMatrix(ANNPred,Testingset[,1])

#make predictions
nnetPred <- predict(nnetFit, Testingset[,-1])
confusionMatrix(nnetPred,Testingset[,1])
rm(nnetPred,nnetGrid,nnetControl) #grid and control are saved in fit

#save the model for later use
saveRDS(nnetFit$finalModel, "E:/R2FPGA/PMML/Test/Example_ANN_Nor_Avg5_Individual.rds")

#################################
## Saving the nnet model as xml ##
#################################
library(RGtk2)
library(cairoDevice)
library(XML)
library(pmml)

ANNpmml <- pmml(nnetFit$finalModel,model.name="NeuralNet_model", 
                description="Neural Network PMML Model")
saveXML(doc=ANNpmml,file="E:/R2FPGA/PMML/Test/Example_ANN_Nor_Avg5_Individual.xml")

0 Answers0