Le but de cet article est de décrire la façon de sauvegarder les valeurs des noeuds values et de les restaurer.
La meilleure chose à faire de suite est de de sauvegarder la valeur des noeuds correspondants et de les restaurer.
Les tenseurs remplissent les contrats d’interface GobEncode
et GobDecode
, ce qui représente la meilleure option. On peut aussi sauvegarder le tableau d’éléments sous-jascent au tenseur, mais c’est un peu plus complexe.
Voici un simple code à réaliser de cette façon (il n’est pas du tout optimisé, n’hésitez pas à le modifier):
package main
import (
"encoding/gob"
"fmt"
"log"
"os"
"gorgonia.org/gorgonia"
"gorgonia.org/tensor"
)
var (
backup = "/tmp/example_gorgonia"
)
func main() {
g := gorgonia.NewGraph()
var x, y, z *gorgonia.Node
var err error
// Create the graph
x = gorgonia.NewTensor(g,
gorgonia.Float64,
2,
gorgonia.WithShape(2, 2),
gorgonia.WithName("x"))
y = gorgonia.NewTensor(g,
gorgonia.Float64,
2,
gorgonia.WithShape(2, 2),
gorgonia.WithName("y"))
if z, err = gorgonia.Add(x, y); err != nil {
log.Fatal(err)
}
// Init variables
xT, yT, err := readFromBackup()
if err != nil {
log.Println("cannot read backup, doing init", err)
xT = tensor.NewDense(gorgonia.Float64, []int{2, 2}, tensor.WithBacking([]float64{0, 1, 2, 3}))
yT = tensor.NewDense(gorgonia.Float64, []int{2, 2}, tensor.WithBacking([]float64{0, 1, 2, 3}))
}
err = gorgonia.Let(x, xT)
if err != nil {
log.Fatal(err)
}
err = gorgonia.Let(y, yT)
if err != nil {
log.Fatal(err)
}
// create a VM to run the program on
machine := gorgonia.NewTapeMachine(g)
defer machine.Close()
if err = machine.RunAll(); err != nil {
log.Fatal(err)
}
fmt.Printf("%v", z.Value())
err = save([]*gorgonia.Node{x, y})
if err != nil {
log.Fatal(err)
}
}
func readFromBackup() (tensor.Tensor, tensor.Tensor, error) {
f, err := os.Open(backup)
if err != nil {
return nil, nil, err
}
defer f.Close()
dec := gob.NewDecoder(f)
var xT, yT *tensor.Dense
log.Println("decoding xT")
err = dec.Decode(&xT)
if err != nil {
return nil, nil, err
}
log.Println("decoding yT")
err = dec.Decode(&yT)
if err != nil {
return nil, nil, err
}
return xT, yT, nil
}
func save(nodes []*gorgonia.Node) error {
f, err := os.Create(backup)
if err != nil {
return err
}
defer f.Close()
enc := gob.NewEncoder(f)
for _, node := range nodes {
err := enc.Encode(node.Value())
if err != nil {
return err
}
}
return nil
}
Qui donne:
$ go run main.go
2019/10/28 08:07:26 cannot read backup, doing init open /tmp/example_gorgonia: no such file or directory
⎡0 2⎤
⎣4 6⎦
$ go run main.go
2019/10/28 08:07:29 decoding xT
2019/10/28 08:07:29 decoding yT
⎡0 2⎤
⎣4 6⎦