onnx

package module
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 21, 2022 License: MIT Imports: 7 Imported by: 0

README

ONNX Logo Go Logo

Mentioned in Awesome Go GoDoc Go Report Card Build Status CodeCov

This is a Go Interface to Open Neural Network Exchange (ONNX).

Overview

onnx-go contains primitives to decode a onnx binary model into a computation backend, and use it like any other library in your go code. for more information about onnx, please visit onnx.ai.

The implementation of the the spec of ONNX is partial on the import, and non-existent for the export.

Vision statement

For the Go developer who needs to add a machine learning capability to his/her code, onnx-go is a package that facilitates the use of neural network models (software 2.0) and unlike any other computation library, this package does not require special skills in data-science.

Warning The API is experimental and may change.

Disclaimer

This is a new version of the API.
The tweaked version of Gorgonia have been removed. It is now compatible with the master branch of Gorgonia.
Some operators are not yet available though.

A utility has been added in order to run models from the zoo.
check the `examples` subdirectory.

Install

Install it via go get

go get github.com/tynrol/onnx-go

onnx-go is compatible with go modules.

Example

Those examples assumes that you have a pre-trained model.onnx file available. You can download pre-trained modles from the onnx model zoo.

Very simple example

This example does nothing but decoding the graph into a simple backend. Then you can do whatever you want with the generated graph.

// Create a backend receiver
	backend := simple.NewSimpleGraph()
	// Create a model and set the execution backend
	model := onnx.NewModel(backend)

	// read the onnx model
	b, _ := ioutil.ReadFile("model.onnx")
	// Decode it into the model
	err := model.UnmarshalBinary(b)

Simple example to run a pre-trained model

This example uses Gorgonia as a backend.

import "github.com/tynrol/onnx-go/backend/x/gorgonnx"

At the present time, Gorgonia does not implement all the operators of ONNX. Therefore, most of the model from the model zoo will not work. Things will go better little by little by adding more operators to the backend.

You can find a list of tested examples and a coverage here.

func Example_gorgonia() {
	// Create a backend receiver
	backend := gorgonnx.NewGraph()
	// Create a model and set the execution backend
	model := onnx.NewModel(backend)

	// read the onnx model
	b, _ := ioutil.ReadFile("model.onnx")
	// Decode it into the model
	err := model.UnmarshalBinary(b)
	if err != nil {
		log.Fatal(err)
	}
	// Set the first input, the number depends of the model
	model.SetInput(0, input)
	err = backend.Run()
	if err != nil {
		log.Fatal(err)
	}
	// Check error
	output, _ := model.GetOutputTensors()
	// write the first output to stdout
	fmt.Println(output[0])
}

Model zoo

In the examples subdirectory, you will find a utility to run a model from the zoo, as well as a sample utility to analyze a picture with Tiny YOLO v2

Internal

ONNX protobuf definition

The protobuf definition of onnx has is compiled into Go with the classic protoc tool. The definition can be found in the internal directory. The definition is not exposed to avoid external dependencies to this repo. Indeed, the pb code can change to use a more efficient compiler such as gogo protobuf and this change should be transparent to the user of this package.

Execution backend

In order to execute the neural network, you need a backend able to execute a computation graph (for more information on computation graphs, please read this blog post

This picture represents the mechanism:

Schema

onnx-go do not provide any executable backend, but for a reference, a simple backend that builds an information graph is provided as an example (see the simple subpackage). Gorgonia is the main target backend of ONNX-Go.

Backend implementation

a backend is basically a Weighted directed graph that can apply on Operation on its nodes. It should fulfill this interface:

type Backend interface {
	OperationCarrier
	graph.DirectedWeightedBuilder
}
type OperationCarrier interface {
	// ApplyOperation on the graph nodes
	// graph.Node is an array because it allows to handle multiple output
	// for example a split operation returns n nodes...
	ApplyOperation(Operation, ...graph.Node) error
}

An Operation is represented by its name and a map of attributes. For example the Convolution operator as described in the spec of onnx will be represented like this:

convOperator := Operation{
		Name: "Conv",
		Attributes: map[string]interface{}{
			"auto_pad":  "NOTSET",
			"dilations": []int64{1, 1},
			"group":     1,
			"pads":      []int64{1, 1},
			"strides":   []int64{1, 1},
		},
	}

Besides, operators, a node can carry a value. Values are described as tensor.Tensor To carry data, a Node of the graph should fulfill this interface:

type DataCarrier interface {
	SetTensor(t tensor.Tensor) error
	GetTensor() tensor.Tensor
}
Backend testing

onnx-go provides a some utilities to test a backend. Visit the testbackend package for more info.

Contributing

Contributions are welcome. A contribution guide will be eventually written. Meanwhile, you can raise an issue or send a PR. You can also contact me via Twitter or on the gophers' slack (I am @tynrol on both)

This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

Author

Olivier Wulveryck

License

MIT.

Documentation

Overview

Example (Gorgonia)
package main

import (
	"fmt"
	"io/ioutil"
	"log"

	"github.com/tynrol/onnx-go"
	"github.com/tynrol/onnx-go/backend/x/gorgonnx"
	"gorgonia.org/tensor"
)

var input tensor.Tensor

func main() {
	// Create a backend receiver
	backend := gorgonnx.NewGraph()
	// Create a model and set the execution backend
	model := onnx.NewModel(backend)

	// read the onnx model
	b, _ := ioutil.ReadFile("model.onnx")
	// Decode it into the model
	err := model.UnmarshalBinary(b)
	if err != nil {
		log.Fatal(err)
	}
	// Set the first input, the number depends of the model
	model.SetInput(0, input)
	err = backend.Run()
	if err != nil {
		log.Fatal(err)
	}
	// Check error
	output, _ := model.GetOutputTensors()
	// write the first output to stdout
	fmt.Println(output[0])
}
Output:

Example (Simple)
// START SIMPLE
// Create a backend receiver
backend := simple.NewSimpleGraph()
// Create a model and set the execution backend
model := onnx.NewModel(backend)

// read the onnx model
b, _ := ioutil.ReadFile("model.onnx")
// Decode it into the model
err := model.UnmarshalBinary(b)
// END SIMPLE
if err != nil {
	log.Fatal(err)
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewTensor

func NewTensor(b []byte) (tensor.Tensor, error)

NewTensor from onnx value

Types

type Backend

type Backend interface {
	OperationCarrier
	graph.DirectedWeightedBuilder
}

Backend represent any backend able to receive a computation graph

type DataCarrier

type DataCarrier interface {
	SetTensor(t tensor.Tensor) error
	GetTensor() tensor.Tensor
}

DataCarrier is node with the ability to carry a tensor data

type Documenter

type Documenter interface {
	graph.Node
	SetDescription(string)
	GetDescription() string
}

Documenter is an interface that describe any object able to document itself

type ErrNotImplemented

type ErrNotImplemented struct {
	Operator       string
	AttributeName  string
	AttributeValue interface{}
	Message        string
}

ErrNotImplemented is returned for any operator or attribute

func (*ErrNotImplemented) Error

func (e *ErrNotImplemented) Error() string

type InvalidUnmarshalError

type InvalidUnmarshalError struct {
	Type reflect.Type
}

An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. (The argument to Unmarshal must be a non-nil pointer.)

func (*InvalidUnmarshalError) Error

func (e *InvalidUnmarshalError) Error() string

type Model

type Model struct {
	Input  []int64
	Output []int64
	// contains filtered or unexported fields
}

Model is a wrapper around a computation graph. Input and Output are containing the ID of the corresponding nodes.

func NewModel

func NewModel(dst Backend) *Model

NewModel with dst as backend. dst should be a non-nil pointer.

func (*Model) GetInputTensors

func (m *Model) GetInputTensors() []tensor.Tensor

GetInpuTensors from the graph. This function is useful to get informations if the tensor is a placeholder and does not contain any data yet.

func (*Model) GetNodeByName

func (m *Model) GetNodeByName(name string) (graph.Node, bool)

GetNodeByName is a utility method that returns a node of the computation graph

func (*Model) GetOutputTensors

func (m *Model) GetOutputTensors() ([]tensor.Tensor, error)

GetOutputTensors of the graph

func (*Model) SetInput

func (m *Model) SetInput(i int, t tensor.Tensor) error

SetInput assign a tensor to the i-th input of the graph

func (*Model) UnmarshalBinary

func (m *Model) UnmarshalBinary(data []byte) error

UnmarshalBinary decodes the binary data in onnx format into the model

type Namer

type Namer interface {
	graph.Node
	SetName(string)
	GetName() string
}

Namer is a node that know its own name

type Operation

type Operation struct {
	Name       string
	Attributes map[string]interface{}
}

Operation defined by its name and its attribute

type OperationCarrier

type OperationCarrier interface {
	// ApplyOperation on the graph nodes
	// graph.Node is an array because it allows to handle multiple output
	// for example a split operation returns n nodes...
	ApplyOperation(Operation, ...graph.Node) error
}

OperationCarrier should be a method of the graph because the operation needs the topology of the graph to check the arity of the node for example

Directories

Path Synopsis
simple
Package simple holds a very simple graph structure suitable to receive an onnx model
Package simple holds a very simple graph structure suitable to receive an onnx model
testbackend
Package testbackend provides a set of testing helper functions that test backend interface implementations.
Package testbackend provides a set of testing helper functions that test backend interface implementations.
testbackend/onnx
Package onnxtest contains an export of the onnx test files
Package onnxtest contains an export of the onnx test files
x/gorgonnx
Package gorgonnx creates a temporary graph that is compatible with backend.ComputationBackend.
Package gorgonnx creates a temporary graph that is compatible with backend.ComputationBackend.
doc
introduction
Present displays slide presentations and articles.
Present displays slide presentations and articles.
examples
internal
misc

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL