###########################################
## Functions to plot training statistics ##
###########################################
#' @rdname trainCurveFactors
#' @name trainCurveFactors
#' @title Training curve for the number of active factors
#' @description The MOFA model starts with an initial number of factors and inactive factors
#' can be dropped during training if they explain small amounts of variation
#' (as defined in \code{\link{getDefaultModelOptions}}).
#' This allows the model to automatically infer the dimensionality of the latent space.
#' The corresponding hyperparameters are defined in \code{\link{prepareMOFA}}. \cr
#' All training statistics, including the number of active factors, can be fetch from the
#' TrainStats slot of \code{\link{MOFAmodel}} .
#' @param object a \code{\link{MOFAmodel}} object.
#' @return plot of number of active factors during training
#' @import ggplot2 scales
#' @export
#' @examples
#' # Example on the CLL data
#' filepath <- system.file("extdata", "CLL_model.hdf5", package = "MOFAdata")
#' MOFA_CLL <- loadModel(filepath)
#' trainCurveFactors(MOFA_CLL)
#' # Example on the scMT data
#' filepath <- system.file("extdata", "scMT_model.hdf5", package = "MOFAdata")
#' MOFA_scMT <- loadModel(filepath)
#' trainCurveFactors(MOFA_scMT)
trainCurveFactors <- function(object) {
# Sanity checks
if (!is(object, "MOFAmodel")) { stop("'object' has to be an instance of MOFAmodel") }
# Collect training statistics
if(is.null(TrainOptions(object)[["freqdrop"]])) {
freqdrop <- 1
} else {
freqdrop <- TrainOptions(object)[["freqdrop"]]
}
idx = seq(1, length(TrainStats(object)[["activeK"]]), freqdrop)
stat = TrainStats(object)[["activeK"]][idx]
data <- data.frame(time=idx, value=stat)
# Plot
p <- ggplot(data, aes_string(x="time", y="value")) +
geom_line() +
labs(title="", x="Iteration", y="Number of active latent varaibles")
# scale_y_discrete(limits=c(min(data$value)-1, max(data$value)+1)) +
# scale_y_continuous(limits=c(min(data$value)-1, max(data$value)+1), breaks=scales::pretty_breaks()) +
theme(
axis.title.x=element_text(colour="black",size=rel(1.75), margin=margin(20,0,3,0)),
axis.title.y=element_text(colour="black",size=rel(1.75), margin=margin(0,20,0,3)),
axis.text.x=element_text(colour="black",size=rel(1.5)),
axis.text.y=element_text(colour="black",size=rel(1.5)),
axis.ticks.x = element_line(colour="black"),
axis.ticks.y = element_line(colour="black"),
axis.line.x = element_line(color="black"),
axis.line.y = element_line(color="black"),
legend.position="none",
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank()
)
return(p)
}
#' @title Training curve for Evidence Lower Bound (ELBO)
#' @name trainCurveELBO
#' @rdname trainCurveELBO
#' @param object a \code{\link{MOFAmodel}} object.
#' @param logScale boolean indicating whether to apply log transform
#' @return plot of ELBO values during training
#' @description MOFA inference is done using the variational Bayes algorithm,
#' which maximises a quantity called the Evidence Lower Bound (ELBO).
#' The ELBO is supposed to increase monotonically up to convergence,
#' but it can decrease substantially when dropping inactive factors.
#' For more details read the supplementary methods.
#' The frequency of ELBO computation as well as the convergence criteria are defined
#' as hyperparameters in \code{\link{prepareMOFA}}. \cr
#' All Training statistics, including the ELBO,
#' can be fetch from the TrainStats slot of \code{\link{MOFAmodel}} .
#' @import ggplot2 scales
#' @export
#' @examples
#' # Example on the CLL data
#' filepath <- system.file("extdata", "CLL_model.hdf5", package = "MOFAdata")
#' MOFA_CLL <- loadModel(filepath)
#' trainCurveELBO(MOFA_CLL)
#' trainCurveELBO(MOFA_CLL, logScale= TRUE)
#'
#' # Example on the scMT data
#' filepath <- system.file("extdata", "scMT_model.hdf5", package = "MOFAdata")
#' MOFA_scMT <- loadModel(filepath)
#' trainCurveELBO(MOFA_scMT)
trainCurveELBO <- function(object, logScale = FALSE) {
# Sanity checks
if (!is(object, "MOFAmodel")) {
stop("'object' has to be an instance of MOFAmodel")
}
if (Status(object) != "trained") {
stop("MOFAmodel is untrained. Use runMOFA to train it.")
}
# Fetch ELBO from TrainStats
if(is.null(TrainOptions(object)[["elbofreq"]])) {
elbofreq <- 1
} else {
elbofreq <- TrainOptions(object)[["elbofreq"]]
}
idx = seq(1,length(TrainStats(object)[["elbo"]]), elbofreq)
stat = TrainStats(object)[["elbo"]][idx]
# Apply log transform
if (logScale==TRUE) { stat <- -log(-stat) }
data <- data.frame(time=idx, value=stat)
p <- ggplot2::ggplot(data, aes_string(x="time", y="value")) +
geom_line() +
labs(title="", x="Iteration", y="ELBO")
theme(
axis.title.x=element_text(colour="black",size=rel(1.75), margin=margin(20,0,3,0)),
axis.title.y=element_text(colour="black",size=rel(1.75), margin=margin(0,20,0,3)),
axis.text.x=element_text(colour="black",size=rel(1.5)),
axis.text.y=element_text(colour="black",size=rel(1.5)),
axis.ticks.x = element_line(colour="black"),
axis.ticks.y = element_line(colour="black"),
axis.line.x = element_line(color="black"),
axis.line.y = element_line(color="black"),
legend.position="none",
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank()
)
if (logScale==FALSE) {
scientific_10 <- function(x) {
parse(text=gsub("e", " %*% 10^", scales::scientific_format()(x)))
}
p <- p + scale_y_continuous(labels=scientific_10)
}
return(p)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.