Documentation
¶
Overview ¶
Package context defines the Context and Variable types: Context organizes variablesMap and variablesMap manages the storage of values typically used as variablesMap.
Index ¶
- Constants
- func EscapeScopeName(scopeName string) string
- func GetGraphParam[T any](ctx *Context, graph *Graph, name string, defaultValue T) T
- func GetParam[T any](ctx *Context, name string, defaultValue T) T
- type Context
- func (ctx *Context) CalculateGradientsGraph(loss *Node) []*Node
- func (ctx *Context) Checked(checked bool) *Context
- func (ctx *Context) EnumerateGraphParams(graph *Graph, fn func(scope, key string, value any))
- func (ctx *Context) EnumerateParams(fn func(scope, key string, value any))
- func (ctx *Context) EnumerateVariables(fn func(v *Variable))
- func (ctx *Context) Error() error
- func (ctx *Context) ExecPopulateGraphParamsMap(graph *Graph, params ml.ParamsMap)
- func (ctx *Context) ExecSetVariablesInParams(params ml.ParamsMap, graph *ml.Graph)
- func (ctx *Context) GetGraphParam(graph *Graph, key string) (value any, found bool)
- func (ctx *Context) GetParam(key string) (value any, found bool)
- func (ctx *Context) In(scope string) *Context
- func (ctx *Context) InAbsPath(scopePath string) *Context
- func (ctx *Context) InitializeVariables()
- func (ctx *Context) InspectVariable(scope, name string) *Variable
- func (ctx *Context) IsChecked() bool
- func (ctx *Context) IsReuse() bool
- func (ctx *Context) IsTraining(graph *Graph) bool
- func (ctx *Context) Loader() Loader
- func (ctx *Context) NeedsInitialization() bool
- func (ctx *Context) NumVariables() int
- func (ctx *Context) Ok() bool
- func (ctx *Context) ResetError()
- func (ctx *Context) Reuse() *Context
- func (ctx *Context) Scope() string
- func (ctx *Context) SetError(err error)
- func (ctx *Context) SetErrorf(format string, args ...any)
- func (ctx *Context) SetGraphParam(graph *Graph, key string, value any)
- func (ctx *Context) SetLoader(loader Loader)
- func (ctx *Context) SetParam(key string, value any)
- func (ctx *Context) SetTraining(graph *Graph, value bool)
- func (ctx *Context) Unique() *Context
- func (ctx *Context) VariableWithShape(name string, shape shapes.Shape) *Variable
- func (ctx *Context) VariableWithValue(name string, value any) *Variable
- func (ctx *Context) WithInitializer(initializer VariableInitializer) *Context
- type ContextExecGraphFn
- type Exec
- func (e *Exec) Call(args ...any) ([]tensor.Tensor, error)
- func (e *Exec) CallWithGraph(args ...any) (outputs []tensor.Tensor, g *Graph, err error)
- func (e *Exec) Context() *Context
- func (e *Exec) Finalize()
- func (e *Exec) GetNodeLogger() graph.LoggerFn
- func (e *Exec) InDevice(deviceNum int) *Exec
- func (e *Exec) Name() string
- func (e *Exec) SetContext(context *Context) *Exec
- func (e *Exec) SetMaxCache(maxCacheSize int) *Exec
- func (e *Exec) SetNodeLogger(loggerFn graph.LoggerFn)
- func (e *Exec) WithName(name string) *Exec
- type Graph
- type Loader
- type Manager
- type Node
- type ScopedParams
- type Shape
- type Variable
- func (v *Variable) ChangedInGraph(g *Graph) bool
- func (v *Variable) InUseByGraph(g *Graph) bool
- func (v *Variable) Name() string
- func (v *Variable) Ok() bool
- func (v *Variable) ParamNode(g *Graph) *Node
- func (v *Variable) ParameterName() string
- func (v *Variable) Scope() string
- func (v *Variable) SetTrainable(trainable bool) *Variable
- func (v *Variable) SetValue(value tensor.Tensor)
- func (v *Variable) SetValueGraph(value *Node)
- func (v *Variable) SetValuePreservingOld(value tensor.Tensor)
- func (v *Variable) Shape() shapes.Shape
- func (v *Variable) String() string
- func (v *Variable) Value() tensor.Tensor
- func (v *Variable) ValueGraph(g *Graph) *Node
- type VariableInitializer
Constants ¶
const ParameterPrefix = "var:"
ParameterPrefix is used to prefix parameter names for variablesMap.
const ScopeSeparator = "/"
ScopeSeparator is used between levels of scope. Scope names cannot use this character.
const TrainingGraphParamKey = "training"
Variables ¶
This section is empty.
Functions ¶
func EscapeScopeName ¶
EscapeScopeName replaces ScopeSeparator in the string and replaces them by "_".
func GetGraphParam ¶
GetGraphParam from Context object and cast to the give type. If parameter name is not defined, or if it cannot be cast to the given type, return defaultValue instead.
It's a typed wrapper to Context.GetGraphParam()
Types ¶
type Context ¶
type Context struct {
// contains filtered or unexported fields
}
Context organizes information shared in a model (or anything else). A model can spawn multiple computation graphs, e.g: one computation for a training step, one for an evaluation step running on batch, and one for a prediction computation on exactly one example. All these computation graphs should share the same variable (weight) values (and other information). These variables and (hyper-) parameters are organized here.
The Context organizes 3 types of information used by a model, and its graphs:
- Variables: model variables or weights.
- Parameters (normal): hyperparameters and also any arbitrary information that needs sharing among the graph building functions using the Context.
- Per-graph parameters: each graph will have it's own value. E.g: the parameter "training" indicates if the model is being used for training or inference, and this value will be different for a training or evaluation graph.
All 3 types of information are organized in "scopes". The Context object is actually a thin wrapper that contains the current scope (similar to a current directory) and a link to the actual data. One can change scopes by using Context.In("new_scope"): it returns a new Context with the new scope set, but still pointing (sharing) all the data with the previous Context. E.g:
One could create a new context with:
```
func main() {
ctx := context.NewContext(manager)
ctx.SetParam("dropout_rate") = 0.2 // Set default dropout to 0.2
...
}
func ModelGraph(ctx *context.Context, inputs []*Node) (logits *Node) {
...
{
ctx := ctx.In("output_layer) // Enter "output_layer" scope in temporary new context (same data, different scope)
ctx.SetParam("dropout_rate", 0.6 // Let's say we want the "output_layer" only to have dropout=0.6
logits = Dense(ctx, logits, output_dim)
} // Exiting "output_later" scope, ctx is back to it's original scope.
}
Finally, Context also allows one to checkpoint the variable values (save and load). See checkpoint package.
TODO: Handling of devices with multiple instances (e.g.: multiple GPUs/TPUs).
func NewContext ¶
NewContext constructs a new and empty context.
func (*Context) CalculateGradientsGraph ¶
CalculateGradientsGraph returns the gradient of the loss with respect to each trainable variable in the context that was used in the current graph. It returns a tuple Node. Non-trainable variables (Variable.Trainable == false) are not touched.
Typically, this is used by an optimizer.
Note, if during the computation graph the value of the variable is changed with Variable.SetValueGraph, this will calculate the gradient with respect to the new value (*Node) set.
func (*Context) Checked ¶
Checked returns a new context with the checked flag set accordingly. If checked is true checks for reuse/uniqueness are checked according to IsReuse(). If checked is false Variables are dynamically reused or created when needed, without any checks. Usually it is set to true when building models -- to prevent layers to overstepping on each other -- and set to false for supporting variables (like optimizers, metrics and preprocessing).
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) EnumerateGraphParams ¶
EnumerateGraphParams enumerates all parameters for the graph, for all scopes calls fn with their values.
func (*Context) EnumerateParams ¶
EnumerateParams enumerates all parameters for all scopes calls fn with their values.
func (*Context) EnumerateVariables ¶
EnumerateVariables will call fn for each variable in the context. Notice the order of visitation is deterministic.
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) Error ¶
Error holds an error when creating this Context reference. If it is set, all variables are also created in error, and everything fails (gracefully). This allows one to defer error handling. Only the first error is stored. After an error is set all operations in Context are no-ops.
Notice that Error is part of the "data" component, so it's shared among all the connected Context references.
func (*Context) ExecPopulateGraphParamsMap ¶
ExecPopulateGraphParamsMap will enter the parameter values for every variable used in the given graph.
`Exec*` methods are used by those implementing an executor (context.Exec) or related tests, not normally needed by end users.
func (*Context) ExecSetVariablesInParams ¶
ExecSetVariablesInParams adds all variables (all scopes) used by the graph to the ParamsMap objects.
`Exec*` methods are used by those implementing an executor (context.Exec) or related tests, not normally needed by end users.
func (*Context) GetGraphParam ¶
GetGraphParam returns, for the givne graph, the value for the given param key, searching successively from the current scope back to the root scope ("/"), in case the key is not found.
E.g: if current scope is "/a/b", it will search for the key in "/a/b" scope, then in "/a" and finally in "/", and return the first result found.
This is very similar to GetParam, but used for parameters that are graph specific. For example Context.IsTraining and Context.SetTraining uses a Graph parameter to set this state, as the same Context is used for evaluation/inference graphs and training graphs, and they should have different values.
func (*Context) GetParam ¶
GetParam returns the value for the given param key, searching successively from the current scope back to the root scope ("/"), in case the key is not found.
E.g: if current scope is "/a/b", it will search for the key in "/a/b" scope, then in "/a" and finally in "/", and return the first result found.
See also GetGraphParam for parameters that are graph specific.
func (*Context) In ¶
In returns a new reference to the Context with the extra given scope. No ScopeSeparator ("/") is allowed in scope.
Notice that Scope is part of the "reference" component of a Context.
func (*Context) InAbsPath ¶
InAbsPath returns a new reference to the Context with the extra given scope. It should start and have each element separated by ScopeSeparator.
Notice that Scope is part of the "reference" component of a Context.
func (*Context) InitializeVariables ¶
func (ctx *Context) InitializeVariables()
InitializeVariables initializes all variables in the Context that don't yet have a value. Variables create with VariableWithValue or for which values were preloaded are not initialized. Errors are returned in Context.Error().
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) InspectVariable ¶
InspectVariable returns the variable with the given name for inspection. This shouldn't be used during building of models, since this bypass the Reuse checks. It returns nil if a variable with the given name hasn't been created.
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) IsChecked ¶
IsChecked returns whether context is checking reuse rules.
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) IsReuse ¶
IsReuse returns whether Context is marked for reuse. This is irrelevant if IsChecked is false.
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) IsTraining ¶
IsTraining returns whether context is being used for training. This is only a convention and is defined by having Globals["training"] == true. See SetTraining to change this value.
Notice that global parameters is part of the "reference" component of a Context, so this change won't affect other connected context references.
func (*Context) Loader ¶
Loader returns the current configured Loader for this context. See SetLoader for details on how the Loader is used.
Notice that loader configuration is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) NeedsInitialization ¶
NeedsInitialization returns whether there are variables that needs initialization.
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) NumVariables ¶
NumVariables return the number of variables in this Context.
func (*Context) Ok ¶
Ok returns whether Context is still valid, the same as saying it has no error.
Notice that Error is part of the "data" component, so it's shared among all the connected Context references.
func (*Context) ResetError ¶
func (ctx *Context) ResetError()
ResetError clears the error in a Context, and allows it to function normally.
Notice that Error is part of the "data" component, so it's shared among all the connected Context references.
func (*Context) Reuse ¶
Reuse returns a new reference to the Context set to reuse of variables, if it is not already in reuse mode. Otherwise, returns itself. If checked is false, this setting is irrelevant.
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) Scope ¶
Scope returns the full scope path.
Notice that Scope is part of the "reference" component of a Context.
func (*Context) SetError ¶
SetError sets the Context into error. After this all operations become no-ops. Only the first error is stored, the following errors are discarded. If stackTrace is set to true, includes a stack trace of the error.
Notice that Error is part of the "data" component, so it's shared among all the connected Context references.
func (*Context) SetErrorf ¶
SetErrorf is similar to SetError, but allows formatting in place. It also automatically adds stack trace.
Notice that Error is part of the "data" component, so it's shared among all the connected Context references.
func (*Context) SetGraphParam ¶
SetGraphParam sets the given Graph param in the current scope. It will be visible (by GetGraphParam) for this Graph within this scope and descendant scopes (but not by other scopes).
This is very similar to SetParam, but used for parameters that are graph specific. For example Context.IsTraining and Context.SetTraining uses a Graph parameter to set this state, as the same Context is used for evaluation/inference graphs and training graphs, and they should have different values.
func (*Context) SetLoader ¶
SetLoader configures given loader to be used as the default Loader for this Context.
Loader is used just after any new variable is created, either with VariableWithValue or VariableWithShape. If the Loader has a value of the variable created, it will override the value given in VariableWithValue, or skip the initializer for VariableWithShape.
An example of a loader in gomlx/context/checkpoints.
Notice that loader configuration is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) SetParam ¶
SetParam sets the given param in the current scope. It will be visible (by GetParam) within this scope and descendant scopes (but not by other scopes).
See also SetGraphParam for parameters that are graph specific.
func (*Context) SetTraining ¶
SetTraining marks the context for the given graph as training. This is a convention adopted by the library components, and it simply sets Context.Globals["training"] to the given value. See IsTraining to check for this value.
Notice that global parameters is part of the "reference" component of a Context, so this change won't affect other connected context references.
func (*Context) Unique ¶
Unique returns a new reference to the Context, set to only allow new variables, if it is not already in unique mode. If checked is false, this setting is irrelevant.
Notice that re-usability is part of the "reference" component of a Context.
func (*Context) VariableWithShape ¶
VariableWithShape creates or returns an existing variable with the given shape in the current scope. It is initialized with the current variable initializer set for the context. By default, variables are marked as trainable.
If a Loader is configured (see SetLoader), and the value is available to load, it will override the value given here -- e.g.: the value could be actually loaded from the last checkpoint.
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) VariableWithValue ¶
VariableWithValue creates a variable that is initialized with the given value in the current scope. By default, variables are marked as trainable. The value given must be concrete, that is a tensor or a normal Go value, that can be converted to a tensor -- a graph *Node does not work here, this is assumed to be a constant.
If a Loader is configured (see SetLoader), and the value is available to load, it will override the value given here -- e.g.: the value could be actually loaded from the last checkpoint.
Notice that variables information is stored in the "data" component of Context objects, and is shared among all connected context references.
func (*Context) WithInitializer ¶
func (ctx *Context) WithInitializer(initializer VariableInitializer) *Context
WithInitializer returns a new reference to the Context, with the initializer set.
Notice that default variable initialization is part of the "reference" component of a Context, so this change won't affect other context references.
type ContextExecGraphFn ¶
type ContextExecGraphFn interface {
func(*Context, *Node) |
func(*Context, *Node, *Node) |
func(*Context, *Node, *Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) |
func(*Context, *Node) *Node | func(*Context, *Node, *Node) *Node |
func(*Context, *Node, *Node, *Node) *Node |
func(*Context, *Node, *Node, *Node, *Node) *Node |
func(*Context, *Node, *Node, *Node, *Node, *Node) *Node |
func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) *Node |
func(*Context, *Node) (*Node, *Node) | func(*Context, *Node, *Node) (*Node, *Node) |
func(*Context, *Node, *Node, *Node) (*Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node) (*Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node, *Node) (*Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) (*Node, *Node) |
func(*Context, *Node) (*Node, *Node, *Node) |
func(*Context, *Node, *Node) (*Node, *Node, *Node) |
func(*Context, *Node, *Node, *Node) (*Node, *Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node) (*Node, *Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node, *Node) (*Node, *Node, *Node) |
func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) (*Node, *Node, *Node) |
func(*Context, *Node) []*Node | func(*Context, *Node, *Node) []*Node |
func(*Context, *Node, *Node, *Node) []*Node |
func(*Context, *Node, *Node, *Node, *Node) []*Node |
func(*Context, *Node, *Node, *Node, *Node, *Node) []*Node |
func(*Context, *Node, *Node, *Node, *Node, *Node, *Node) []*Node |
func(*Context, []*Node) |
func(*Context, []*Node) *Node |
func(*Context, []*Node) (*Node, *Node) |
func(*Context, []*Node) (*Node, *Node, *Node) |
func(*Context, []*Node) []*Node |
func(*Context, *Graph) |
func(*Context, *Graph) *Node |
func(*Context, *Graph) (*Node, *Node) |
func(*Context, *Graph) (*Node, *Node, *Node) |
func(*Context, *Graph) []*Node
}
ContextExecGraphFn is a type parameter for accepted function types for NewExec constructor.
type Exec ¶
type Exec struct {
// contains filtered or unexported fields
}
Exec creates and executes computation graphs that take as input a Context as needed based on the inputs shapes, to allow the function to access (both read and set) variables and everything in the Context. Otherwise very similar to graph.Exec.
It simplifies the process of executing a graph building function with real values.
For example, assume you wrote:
def LogitsGraph(ctx *context.Context, inputs *Node) *Node {
logits := layers.Dense(ctx.In("dense0", inputs, 5))
logits = layers.Dense(ctx.In("dense1", logits, 5))
logits = Sigmoid(logits)
return logits
}
And then with Exec one can do:
ctx := context.NewContext(manager)
var logitsFn = context.NewExec(manager, ctx, LogitsGraph)
batch := [][]float32{ {1, 2, 3}, {4, 5, 6} } // 2 examples with 3 features (shape=[2,3])
fmt.Printf("Logits(%v) = %v\n", batch, logitsFn.Call(batch)[0].Value())
Call method always outputs a slice with all the outputs, even when there are no outputs (in which case it returns nil). Call takes as input the materialized values (tensors) you want to execute the graph with -- you don't need to path the *Context of *Graph to Call, those are filled automatically by Exec.
Notice ctxGraphFn, the function that builds the computation graph, is only called the first time Call is used -- so it's slower the first time, since it has to compile the graph. After that the execution is much faster. But that means that changes to Context.SetParams() or Context.SetGraphParams() after the frist execution will not have any effect.
Exec also manages updates to variables automatically. Example: we implement a counter, which takes no input values (just the *Graph object), it just creates a variable if not there yet, increments it and returns its value.
```
ctx := context.NewContext(manager)
counter := context.NewExec(manager, ctx, func(ctx *context.Context, g *Graph) *Node {
dtype := types.Int64
counterVar := ctx.WithInitializer(initializers.Zeros).VariableWithShape("counter", types.MakeShape(dtype))
counterNode := counterVar.ValueGraph(graph)
counterNode = Add(counterNode, OnesLike(counterNode))
counterVar.SetValueGraph(counterNode)
return counterNode
})
fmt.Printf("%s\n", counter.Call()[0]) // == 1
fmt.Printf("%s\n", counter.Call()[0]) // == 2
fmt.Printf("%s\n", ctx.InspectVariable(ctx.Scope(), "counter").Value()) // == 2
```
Behind the scenes it automatically adds the used variables (Variable.ValueGraph) as side inputs, and the updated variables (Variable.SetValueGraph) as extra outputs of the graph, and during the graph execution it automatically use these values to update the materialized variable values in Context variables. It will also automatically initialize Context variables when needed.
Notice, like with graph.Exec, the need to build different graphs for different shapes can be expensive when sizes of the inputs varies a lot. The usual solution is to use shapes with size in a power scale (for instance powers of 2) and masking of tensors for unused slices. For safety concerns there are a maximum number of different instantiations of the graph. It can be set or disabled with SetMaxCache.
Errors in Call are returned inside the returned tensors.
There is concurrency safety with the cache of Graphs, but XLA concurrency is not documented. TODO: figure it out.
func NewExec ¶
func NewExec[F ContextExecGraphFn](manager *Manager, ctx *Context, ctxGraphFn F) *Exec
NewExec constructs an Exec object that uses the given ctxGraphFn to build computation graphs with a Context. ctxGraphFn must take a *Context input parameter followed by one or more *Node parameters as input and return one or more *Node.
The Context ctx passed will be passed to all computation graph construction calls (ctxGraphFn), as well as during the graph execution later. If set to nil, it automatically creates a new one.
Before the execution of a graph, if needed, it initializes the variables in the context.
This is a generic wrapper around NewExecAny that check that types are correct (but doesn't support all possible types of ctxGraphFn).
func NewExecAny ¶
NewExecAny constructs an Exec object that uses the given ctxGraphFn to build computation graphs with a Context. ctxGraphFn must take a *Context input parameter followed by one or more *Node parameters as input and return one or more *Node. Alternatively it can, instead of *Node inputs, take a *Graph object -- if effectively no tensors will be used as input.
The Context ctx passed will be passed to all computation graph construction calls (ctxGraphFn), as well as during the graph execution later. If set to nil, it automatically creates a new one.
Before the execution of a graph, if needed, it initializes the variables in the context. And updated variables in the graph are updated also during execution. More details see Exec.
If any input or output parameter of ctxGraphFn is not a *Node (except the *Context and optionally a *Graph), or if there are no inputs or outputs, it returns an error.
func (*Exec) Call ¶
Call parses the arguments into tensors (if they are not yet) and executes the graph corresponding to the shapes of the arguments.
Notice Context shouldn't be passed by Call, it will use automatically the context stored in context.Exec -- you can change it with SetContext.
If a graph does not yet exist one is created, compiled and cached for the shapes. It passes the context to the registered ctxGraphFn. After the very first invocation of Call the context is marked as Context.Reuse().
It returns the outputs in a slice, even if there is only one output, or an error.
func (*Exec) CallWithGraph ¶
CallWithGraph is similar to Call, but it also returns the computation graph used in the call. Since Exec creates different computation graphs for different set of parameters, this can help disambiguate in case the user needs to use the Graph for something else.
It returns the outputs in a slice, even if there is only one output, and the graph used to execute the computation or an error.
func (*Exec) Context ¶
Context returns the associated Context object, usually created during the creation of the Exec object. It can be set to something different with SetContext().
func (*Exec) Finalize ¶
func (e *Exec) Finalize()
Finalize clears the cache, finalizing the graphs. The Exec object shouldn't be used after that.
func (*Exec) GetNodeLogger ¶
GetNodeLogger returns the currently registered LoggerFn.
func (*Exec) InDevice ¶
InDevice sets the device num to be used by graphs constructed by Exec. This should be called before any invocations of Call(). It returns a reference to itself so calls can be cascaded.
func (*Exec) SetContext ¶
SetContext associates the given Context to the Exec object. Should be called before the first Call is made. Notice that only after the first time context is used to build a graph, it is set to Reuse. If the Context variables were already created, it should be marked with Context.Reuse. It returns a reference to itself so calls can be cascaded.
func (*Exec) SetMaxCache ¶
SetMaxCache sets the maximum size of the cache. Set it to -1 to have unlimited cache size. It returns a reference to itself so calls can be cascaded.
func (*Exec) SetNodeLogger ¶
SetNodeLogger with the function to be called for the nodes marked for logging during execution. If set to nil nothing will be logged.
type Loader ¶
type Loader interface {
// LoadVariable tries to load the variable v, usually specified by its scope and name.
// If it's not found, returns false, and initialization continues as usual.
// Errors can be reported with Context.SetError.
LoadVariable(ctx *Context, v *Variable) (value tensor.Tensor, found bool)
}
Loader can be implemented by any library providing loading of variables for Context. Loader implementations need to provide values on demand -- as a variables are used, even if they load everything up-front.
An example of a loader in gomlx/context/checkpoints. An example for testing can be found in context_test.go:ConstantLoader.
type ScopedParams ¶
type ScopedParams struct {
// contains filtered or unexported fields
}
ScopedParams provides a mapping from string to any data type that is "scoped":
- For every scope there is a map of string to data.
- Accessing a key triggers a search from the current scope up to the root scope, the first result found is returned.
Example: let's say the current ScopedParams hold:
Scope: "/": { "x":10, "y": 20, "z": 40 }
Scope: "/a": { "y": 30 }
Scope: "/a/b": { "x": 100 }
ScopedParams.Get("/a/b", "x") -> 100
ScopedParams.Get("/a/b", "y") -> 30
ScopedParams.Get("/a/b", "z") -> 40
ScopedParams.Get("/a/b", "w") -> Not found.
Notice that "/" (== ScopeSeparator constant) separates parts of the scope path, and the root scope is referred to as "/". There is no "empty" scope, and every scope name must start with a ScopeSeparator.
func NewScopedParams ¶
func NewScopedParams() *ScopedParams
NewScopedParams create an empy ScopedParams.
func (*ScopedParams) Enumerate ¶
func (p *ScopedParams) Enumerate(fn func(scope, key string, value any))
Enumerate enumerates all parameters stored in the ScopedParams structure and calls the given closure with them.
func (*ScopedParams) Get ¶
func (p *ScopedParams) Get(scope, key string) (value any, found bool)
Get retrieves the value for the given key in the given scope or any parent scope. E.g: Get("/a/b", "myKey") will search for "myKey" in scopes "/a/b", "/a" and "/" consecutively until "myKey" is found.
It returns the first value found if any, and whether some value was found.
func (*ScopedParams) Set ¶
func (p *ScopedParams) Set(scope, key string, value any)
Set sets the value for the given key, in the given scope.
type Variable ¶
type Variable struct {
// Trainable indicates whether variable is trainable. If set to false it won't be
// touched by trainers of the model.
Trainable bool
// contains filtered or unexported fields
}
Variable is a value shared among computation graphs, or across multiple executions of the same graph. It's commonly used to store the weights (aka. parameters) of an ML model. It's defined in a scope in a Context.
The materialized value can be accessed in between graph executions by Value and SetValue methods.
During the computation graph building, for a particular graph, one can access the graph value (Node) of a variable with the methods
They are only initialized when Context.InitializeVariables. That is, they are created and used in graph building possibly before they are actually initialized -- when building a graph they are passed as parameters (the corresponding graph node is called ParameterNode), and have their values passed only during execution.
func (*Variable) ChangedInGraph ¶
ChangedInGraph returns whether the variable is in use and was changed in the computation graph g.
func (*Variable) InUseByGraph ¶
InUseByGraph returns whether the variable is currently in use by the given graph.
func (*Variable) Ok ¶
Ok returns whether the variable is valid. If something went wrong during creation, the variable will not be Ok. The error can be read from Context.Error().
func (*Variable) ParamNode ¶
ParamNode returns the given Graph g's Node that corresponds to the parameter that will be fed with the current variable value when the graph is executed. It's the initial value of the variable in the computation Graph.
If parameter Node hasn't been created for the Graph g yet, one is created.
Since the value of a variable can change in the middle of the graph (e.g: something that uses the variable after a gradient descent is applied) consider using ValueGraph to read the current associated value of a variable in a graph.
func (*Variable) ParameterName ¶
ParameterName used when creating a parameter node in a Graph to access the variable.
func (*Variable) SetTrainable ¶
SetTrainable sets the variable trainable status. Returns itself, so calls can be cascated.
func (*Variable) SetValue ¶
SetValue updates the tensor holding the variable value. NOTE: Because often variables are large in size, the previous value is immediately freed (as opposed to wait for garbage collection). If the previous value is used somewhere else, use SetValuePreservingOld.
func (*Variable) SetValueGraph ¶
SetValueGraph sets the Node associated with the current value of the variable for the computation graph where value is defined.
This is used to "communicate" among different parts of the graph building that this value Node should be used as the variable value.
train.Trainer will use the last value set here during graph building and use it as output of the graph execution and then update the variables (with SetValue) accordingly after each graph execution, for example, after each Trainer.TrainStep call.
func (*Variable) SetValuePreservingOld ¶
SetValuePreservingOld updates the tensor holding the variable value, and dont' free old value. If previous value is not used, use SetValue instead that will free it immediately.
func (*Variable) Value ¶
Value returns the tensor holding the variable value. Use this to manipulate the value in Go. If building a computation Graph use Node().
WARNING: memory management here is tricky: a call to SetValue will trigger the current value to be deallocated, and what is returned by a previous call to Value to become invalid. The recommendation is not to use this is a concurrent set up -- or to create proper locking mechanisms.
func (*Variable) ValueGraph ¶
ValueGraph returns the Node of the Graph that holds the current value of the variable. It can be changed for the graph (for instance when applying a gradient descent) by SetGraph.
type VariableInitializer ¶
type VariableInitializer = initializers.VariableInitializer
VariableInitializer builds a valueNode that returns a value to initialize a variable of the given shape. It is defined in the Context.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package checkpoints implements checkpoint management: saving and loading of checkpoints.
|
Package checkpoints implements checkpoint management: saving and loading of checkpoints. |
|
Package ctxtest holds test utilities for packages that depend on context package.
|
Package ctxtest holds test utilities for packages that depend on context package. |
|
Package initializers include several weight initializers, to be used with context.
|
Package initializers include several weight initializers, to be used with context. |