% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/torch-code-gen.R
\name{nn_module_generator}
\alias{nn_module_generator}
\title{Generalized Neural Network Module Expression Generator}
\usage{
nn_module_generator(
  nn_name = "nnModule",
  nn_layer = NULL,
  out_nn_layer = NULL,
  nn_layer_args = list(),
  layer_arg_fn = NULL,
  forward_extract = NULL,
  before_output_transform = NULL,
  after_output_transform = NULL,
  last_layer_args = list(),
  hd_neurons,
  no_x,
  no_y,
  activations = NULL,
  output_activation = NULL,
  bias = TRUE,
  eval = FALSE,
  .env = parent.frame(),
  ...
)
}
\arguments{
\item{nn_name}{Character string specifying the name of the generated neural network module class.
Default is \code{"nnModule"}.}

\item{nn_layer}{The type of neural network layer to use. Can be specified as:
\itemize{
\item \code{NULL} (default): Uses \code{nn_linear()} from \code{{torch}}
\item Character string: e.g., \code{"nn_linear"}, \code{"nn_gru"}, \code{"nn_lstm"}, \code{"some_custom_layer"}
\item Named function: A function object that constructs the layer
\item Anonymous function: e.g., \verb{\\() nn_linear()} or \code{function() nn_linear()}
}

The layer constructor is first searched in the current environment, then in parent
environments, and finally falls back to the \code{{torch}} namespace. This allows you to
use custom layer implementations alongside standard torch layers.}

\item{out_nn_layer}{Default \code{NULL}. If supplied, it forces to be the neural network layer to be used
on the last layer. Can be specified as:
\itemize{
\item Character string, e.g. \code{"nn_linear"}, \code{"nn_gru"}, \code{"nn_lstm"}, \code{"some_custom_layer"}
\item Named function: A function object that constructs the layer
\item Formula interface, e.g. \code{~torch::nn_linear}, \code{~some_custom_layer}
}

Internally, it almost works the same as \code{nn_layer} parameter.}

\item{nn_layer_args}{Named list of additional arguments passed to the layer constructor
specified by \code{nn_layer}. These arguments are applied to all layers. For layer-specific
arguments, use \code{layer_arg_fn}. Default is an empty list.}

\item{layer_arg_fn}{Optional function or formula that generates layer-specific construction arguments.
Can be specified as:
\itemize{
\item \strong{Formula}: \code{~ list(input_size = .in, hidden_size = .out)} where \code{.in}, \code{.out}, \code{.i}, and \code{.is_output} are available
\item \strong{Function}: \verb{function(i, in_dim, out_dim, is_output)} with signature as before
}

The formula/function should return a named list of arguments to pass to the layer constructor.
Available variables in formula context:
\itemize{
\item \code{.i} or \code{i}: Integer, the layer index (1-based)
\item \code{.in} or \code{in_dim}: Integer, input dimension for this layer
\item \code{.out} or \code{out_dim}: Integer, output dimension for this layer
\item \code{.is_output} or \code{is_output}: Logical, whether this is the final output layer
}

If \code{NULL}, defaults to FFNN-style arguments: \code{list(in_dim, out_dim, bias = bias)}.}

\item{forward_extract}{Optional formula or function that processes layer outputs in the forward pass.
Useful for layers that return complex structures (e.g., RNNs return \code{list(output, hidden)}).
Can be specified as:
\itemize{
\item \strong{Formula}: \code{~ .[[1]]} or \code{~ .$output} where \code{.} represents the layer output
\item \strong{Function}: \verb{function(expr)} that accepts/returns a language object
}

Common patterns:
\itemize{
\item Extract first element: \code{~ .[[1]]}
\item Extract named element: \code{~ .$output}
\item Extract with method: \code{~ .$get_output()}
}

If \code{NULL}, layer outputs are used directly.}

\item{before_output_transform}{Optional formula or function that transforms input before the output layer.
This is applied after the last hidden layer (and its activation) but before the output layer.
Can be specified as:
\itemize{
\item \strong{Formula}: \code{~ .[, .$size(2), ]} where \code{.} represents the current tensor
\item \strong{Function}: \verb{function(expr)} that accepts/returns a language object
}

Common patterns:
\itemize{
\item Extract last timestep: \code{~ .[, .$size(2), ]}
\item Flatten: \code{~ .$flatten(start_dim = 1)}
\item Global pooling: \code{~ .$mean(dim = 2)}
\item Extract token: \code{~ .[, 1, ]}
}

If \code{NULL}, no transformation is applied.}

\item{after_output_transform}{Optional formula or function that transforms the output after the output layer.
This is applied after \code{self$out(x)} (the final layer) but before returning the result.
Can be specified as:
\itemize{
\item \strong{Formula}: \code{~ .$mean(dim = 2)} where \code{.} represents the output tensor
\item \strong{Function}: \verb{function(expr)} that accepts/returns a language object
}

Common patterns:
\itemize{
\item Global average pooling: \code{~ .$mean(dim = 2)}
\item Squeeze dimensions: \code{~ .$squeeze()}
\item Reshape output: \code{~ .$view(c(-1, 10))}
\item Extract specific outputs: \code{~ .[, , 1:5]}
}

If \code{NULL}, no transformation is applied.}

\item{last_layer_args}{Optional named list or formula specifying additional arguments
for the output layer only. These arguments are appended to the output layer constructor
after the arguments from \code{layer_arg_fn}. Can be specified as:
\itemize{
\item \strong{Formula}: \code{~ list(kernel_size = 2L, bias = FALSE)}
\item \strong{Named list}: \code{list(kernel_size = 2L, bias = FALSE)}
}

This is useful when you need to override or add specific parameters to the final layer
without affecting hidden layers. For example, in CNNs you might want a different kernel
size for the output layer, or in RNNs you might want to disable bias in the final linear
projection. Arguments in \code{last_layer_args} will override any conflicting arguments from
\code{layer_arg_fn} when \code{.is_output = TRUE}. Default is an empty list.}

\item{hd_neurons}{Integer vector specifying the number of neurons (hidden units) in each
hidden layer. The length determines the number of hidden layers in the network.
Must contain at least one element.}

\item{no_x}{Integer specifying the number of input features (input dimension).}

\item{no_y}{Integer specifying the number of output features (output dimension).}

\item{activations}{Activation function specifications for hidden layers. Can be:
\itemize{
\item \code{NULL}: No activation functions applied
\item Character vector: e.g., \code{c("relu", "sigmoid", "tanh")}
\item \code{activation_spec} object: Created using \code{act_funs()}, which allows
specifying custom arguments. See examples.
}

If a single activation is provided, it will be replicated across all hidden layers.
Otherwise, the length should match the number of hidden layers.}

\item{output_activation}{Optional activation function for the output layer.
Same format as \code{activations}, but should specify only a single activation.
Common choices include \code{"softmax"} for classification or \code{"sigmoid"} for
binary outcomes. Default is \code{NULL} (no output activation).}

\item{bias}{Logical indicating whether to include bias terms in layers.
Default is \code{TRUE}. Note that this is passed to \code{layer_arg_fn} if provided,
so custom layer argument functions should handle this parameter appropriately.}

\item{eval}{Logical indicating whether to evaluate the generated expression immediately.
If \code{TRUE}, returns an instantiated \code{nn_module} class that can be called directly
(e.g., \code{model()}). If \code{FALSE} (default), returns the unevaluated language expression
that can be inspected or evaluated later with \code{eval()}. Default is \code{FALSE}.}

\item{.env}{Default is \code{\link[=parent.frame]{parent.frame()}}. The environment in which the generated expression is to be evaluated}

\item{...}{Additional arguments passed to layer constructors or for future extensions.}
}
\value{
If \code{eval = FALSE} (default): A language object (unevaluated expression) representing
a \code{torch::nn_module} definition. This expression can be evaluated with \code{eval()} to
create the module class, which can then be instantiated with \code{eval(result)()} to
create a model instance.

If \code{eval = TRUE}: An instantiated \code{nn_module} class constructor that can be called
directly to create model instances (e.g., \code{result()}).
}
\description{
\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}}

\code{nn_module_generator()} is a generalized function that generates neural network
module expressions for various architectures. It provides a flexible framework for creating
custom neural network modules by parameterizing layer types, construction arguments, and
forward pass behavior.

While designed primarily for \code{{torch}} modules, it can work with custom layer implementations
from the current environment, including user-defined layers like RBF networks, custom
attention mechanisms, or other novel architectures.

This function serves as the foundation for specialized generators like \code{ffnn_generator()}
and \code{rnn_generator()}, but can be used directly to create custom architectures.
}
\examples{
\dontrun{
\donttest{
if (torch::torch_is_installed()) {
    # Basic usage with formula interface
    nn_module_generator(
        nn_name = "MyGRU",
        nn_layer = "nn_gru",
        layer_arg_fn = ~ if (.is_output) {
            list(.in, .out)
        } else {
            list(input_size = .in, hidden_size = .out, 
                 num_layers = 1L, batch_first = TRUE)
        },
        forward_extract = ~ .[[1]],
        before_output_transform = ~ .[, .$size(2), ],
        hd_neurons = c(128, 64, 32),
        no_x = 20,
        no_y = 5,
        activations = "relu"
    )
    
    # LSTM with cleaner syntax
    nn_module_generator(
        nn_name = "MyLSTM",
        nn_layer = "nn_lstm",
        layer_arg_fn = ~ list(
            input_size = .in,
            hidden_size = .out,
            batch_first = TRUE
        ),
        forward_extract = ~ .[[1]],
        before_output_transform = ~ .[, .$size(2), ],
        hd_neurons = c(64, 32),
        no_x = 10,
        no_y = 2
    )
    
    # CNN with global average pooling
    nn_module_generator(
        nn_name = "SimpleCNN",
        nn_layer = "nn_conv1d",
        layer_arg_fn = ~ list(
            in_channels = .in,
            out_channels = .out,
            kernel_size = 3L,
            padding = 1L
        ),
        before_output_transform = ~ .$mean(dim = 2),
        hd_neurons = c(16, 32, 64),
        no_x = 1,
        no_y = 10,
        activations = "relu"
    )
    
    # CNN with after_output_transform (pooling applied AFTER output layer)
    nn_module_generator(
        nn_name = "CNN1DClassifier",
        nn_layer = "nn_conv1d",
        layer_arg_fn = ~ if (.is_output) {
            list(.in, .out)
        } else {
            list(
                in_channels = .in,
                out_channels = .out,
                kernel_size = 3L,
                stride = 1L,
                padding = 1L 
            )
        },
        after_output_transform = ~ .$mean(dim = 2),
        last_layer_args = list(kernel_size = 1, stride = 2),
        hd_neurons = c(16, 32, 64),
        no_x = 1,
        no_y = 10,
        activations = "relu"
    )
    
} else {
  message("torch not installed - skipping examples")
}
}
}

}
