Package tensorflow is a Go binding to TensorFlow.
The API is subject to change and may break at any time.
TensorFlow (www.tensorflow.org) is an open source software library for numerical computation using data flow graphs. This package provides functionality to build and execute such graphs and depends on TensorFlow being available. For installation instructions see https://github.com/tensorflow/tensorflow/blob/master/tensorflow/go/README.md
package main import ( "archive/zip" "bufio" "flag" "fmt" "io" "log" "net/http" "os" "path/filepath" tf "github.com/tensorflow/tensorflow/tensorflow/go" "github.com/tensorflow/tensorflow/tensorflow/go/op" ) func main() { // An example for using the TensorFlow Go API for image recognition // using a pre-trained inception model (http://arxiv.org/abs/1512.00567). // // Sample usage: <program> -dir=/tmp/modeldir -image=/path/to/some/jpeg // // The pre-trained model takes input in the form of a 4-dimensional // tensor with shape [ BATCH_SIZE, IMAGE_HEIGHT, IMAGE_WIDTH, 3 ], // where: // - BATCH_SIZE allows for inference of multiple images in one pass through the graph // - IMAGE_HEIGHT is the height of the images on which the model was trained // - IMAGE_WIDTH is the width of the images on which the model was trained // - 3 is the (R, G, B) values of the pixel colors represented as a float. // // And produces as output a vector with shape [ NUM_LABELS ]. // output[i] is the model-implied probability of the input image having // the i-th label. // // A separate file contains a list of string labels corresponding to the // integer indices of the output. // // This example: // - Loads the serialized representation of the pre-trained model into a Graph // - Creates a Session to execute operations on the Graph // - Converts an image file to a Tensor to provide as input to a Session run // - Executes the Session and prints out the label with the highest probability // // To convert an image file to a Tensor suitable for input to the Inception model, // this example: // - Constructs another TensorFlow graph to normalize the image into a // form suitable for the model (for example, resizing the image) // - Creates and executes a Session to obtain a Tensor in this normalized form. modeldir := flag.String( "dir", "testdata/saved_model/inception5h", "Directory containing the trained model files. The directory will be"+ "created and the model downloaded into it if necessary", ) imagefile := flag.String( "image", "testdata/label_image/grace_hopper.jpg", "Path of a JPEG-image to extract labels for", ) flag.Parse() // Load the serialized GraphDef from a file. modelfile, labelsfile, err := modelFiles(*modeldir) if err != nil { log.Fatal(err) } labels, err := readLabelsFile(labelsfile) if err != nil { log.Fatal(err) } model, err := os.ReadFile(modelfile) if err != nil { log.Fatal(err) } // Construct an in-memory graph from the serialized form. graph := tf.NewGraph() if err := graph.Import(model, ""); err != nil { log.Fatal(err) } // Create a session for inference over graph. session, err := tf.NewSession(graph, nil) if err != nil { log.Fatal(err) } defer session.Close() // Run inference on *imageFile. // For multiple images, session.Run() can be called in a loop (and // concurrently). Alternatively, images can be batched since the model // accepts batches of image data as input. tensor, err := makeTensorFromImage(*imagefile) if err != nil { log.Fatal(err) } output, err := session.Run( map[tf.Output]*tf.Tensor{ graph.Operation("input").Output(0): tensor, }, []tf.Output{ graph.Operation("output").Output(0), }, nil) if err != nil { log.Fatal(err) } // output[0].Value() is a vector containing probabilities of // labels for each image in the "batch". The batch size was 1. // Find the most probable label index. probabilities := output[0].Value().([][]float32)[0] printBestLabel(probabilities, labels) // // Output: // // BEST MATCH: (29% likely) military uniform } func printBestLabel(probabilities []float32, labels []string) { idx := argmax(probabilities) fmt.Printf( "BEST MATCH: (%2.0f%% likely) %s", probabilities[idx]*100.0, labels[idx], ) } // Convert the image in filename to a Tensor suitable as input to the Inception model. func makeTensorFromImage(filename string) (*tf.Tensor, error) { bytes, err := os.ReadFile(filename) if err != nil { return nil, err } // DecodeJpeg uses a scalar String-valued tensor as input. tensor, err := tf.NewTensor(string(bytes)) if err != nil { return nil, err } // Construct a graph to normalize the image graph, input, output, err := constructGraphToNormalizeImage() if err != nil { return nil, err } // Execute that graph to normalize this one image session, err := tf.NewSession(graph, nil) if err != nil { return nil, err } defer session.Close() normalized, err := session.Run( map[tf.Output]*tf.Tensor{input: tensor}, []tf.Output{output}, nil) if err != nil { return nil, err } return normalized[0], nil } // The inception model takes as input the image described by a Tensor in a very // specific normalized format (a particular image size, shape of the input tensor, // normalized pixel values etc.). // // This function constructs a graph of TensorFlow operations which takes as // input a JPEG-encoded string and returns a tensor suitable as input to the // inception model. func constructGraphToNormalizeImage() (graph *tf.Graph, input, output tf.Output, err error) { // Some constants specific to the pre-trained model at: // https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip // // - The model was trained after with images scaled to 224x224 pixels. // - The colors, represented as R, G, B in 1-byte each were converted to // float using (value - Mean)/Scale. const ( H, W = 224, 224 Mean = float32(117) Scale = float32(1) ) // - input is a String-Tensor, where the string the JPEG-encoded image. // - The inception model takes a 4D tensor of shape // [BatchSize, Height, Width, Colors=3], where each pixel is // represented as a triplet of floats // - Apply normalization on each pixel and use ExpandDims to make // this single image be a "batch" of size 1 for ResizeBilinear. s := op.NewScope() input = op.Placeholder(s, tf.String) output = op.Div(s, op.Sub(s, op.ResizeBilinear(s, op.ExpandDims(s, op.Cast(s, op.DecodeJpeg(s, input, op.DecodeJpegChannels(3)), tf.Float), op.Const(s.SubScope("make_batch"), int32(0))), op.Const(s.SubScope("size"), []int32{H, W})), op.Const(s.SubScope("mean"), Mean)), op.Const(s.SubScope("scale"), Scale)) graph, err = s.Finalize() return graph, input, output, err } func modelFiles(dir string) (modelfile, labelsfile string, err error) { const URL = "https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip" var ( model = filepath.Join(dir, "tensorflow_inception_graph.pb") labels = filepath.Join(dir, "imagenet_comp_graph_label_strings.txt") zipfile = filepath.Join(dir, "inception5h.zip") ) if filesExist(model, labels) == nil { return model, labels, nil } log.Println("Did not find model in", dir, "downloading from", URL) if err := os.MkdirAll(dir, 0755); err != nil { return "", "", err } if err := download(URL, zipfile); err != nil { return "", "", fmt.Errorf("failed to download %v - %v", URL, err) } if err := unzip(dir, zipfile); err != nil { return "", "", fmt.Errorf("failed to extract contents from model archive: %v", err) } os.Remove(zipfile) return model, labels, filesExist(model, labels) } func filesExist(files ...string) error { for _, f := range files { if _, err := os.Stat(f); err != nil { return fmt.Errorf("unable to stat %s: %v", f, err) } } return nil } func download(URL, filename string) error { resp, err := http.Get(URL) if err != nil { return err } defer resp.Body.Close() file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0644) if err != nil { return err } defer file.Close() _, err = io.Copy(file, resp.Body) return err } func unzip(dir, zipfile string) error { r, err := zip.OpenReader(zipfile) if err != nil { return err } defer r.Close() for _, f := range r.File { src, err := f.Open() if err != nil { return err } log.Println("Extracting", f.Name) dst, err := os.OpenFile(filepath.Join(dir, f.Name), os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return err } if _, err := io.Copy(dst, src); err != nil { return err } dst.Close() } return nil } func readLabelsFile(f string) ([]string, error) { var labels []string file, err := os.Open(f) if err != nil { return nil, err } defer file.Close() scanner := bufio.NewScanner(file) for i := 0; scanner.Scan(); i++ { labels = append(labels, scanner.Text()) } if err := scanner.Err(); err != nil { return nil, err } return labels, nil } // argmax returns the index the maximal element in slice a. func argmax(a []float32) int { var idx int for i := 0; i < len(a); i++ { if a[i] > a[idx] { idx = i } } return idx }
This section is empty.
This section is empty.
TypeOf converts from a DataType and Shape to the equivalent Go type.
Version returns a string describing the version of the underlying TensorFlow runtime.
Consumer identifies a specific input of an operation that consumes the output of another operation.
DataType returns the type of the input.
Producer returns the Output that is connected to this Consumer.
Context for executing operations eagerly.
A Context allows operations to be executed immediately. It encapsulates information such as the available devices, resource manager etc. It also allows the user to configure execution using a ConfigProto, as they can configure a Session when executing a Graph.
NewContext creates a new context for eager execution. options may be nil to use the default options.
ListDevices returns the list of devices associated with a Context.
type ContextOptions struct { Config []byte Async bool }
ContextOptions contains configuration information for a session
DataType holds the type for a scalar value. E.g., one slot in a tensor.
Types of scalar values in the TensorFlow type system.
type Device struct { Name, Type string MemoryLimitBytes int64 }
Device structure contains information about a device associated with a session, as returned by ListDevices()
String describes d and implements fmt.Stringer.
Graph represents a computation graph. Graphs may be shared between sessions.
NewGraph returns a new Graph.
AddGradients adds operations to compute the partial derivatives of the sum of tensors in y with respect to tensors in x, i.e., d(y[0] + y[1] + ...) / d x[0], d(y[0] + y[1] + ... ) / d x[1] etc.
prefix, if non-empty, is the name prefix used for all operations added to the graph to compute these gradients.
AddOperation adds an operation to g.
Import imports the nodes and edges from a serialized representation of another Graph into g.
Names of imported nodes will be prefixed with prefix.
ImportWithOptions imports the nodes and edges from a serialized representation of another Graph into g.
Multiple options can be specified for the newly imported nodes.
Operation returns the Operation named name in the Graph, or nil if no such operation is present.
Operations returns a list of all operations in the graph
WriteTo writes out a serialized representation of g to w.
Implements the io.WriterTo interface.
type GraphImportOptions struct { Prefix string Device string }
The GraphImportOptions struct holds parameters for the ImportWithOptions function.
AddInputMapping adds a mapping between an Output in the imported graph and an Output in the destination graph that it should be replaced with, where src:srcIndex is the name of the Operation and Output index to replace and dst is the output to replace it with.
Input is the interface for specifying inputs to an operation being added to a Graph.
Operations can have multiple inputs, each of which could be either a tensor produced by another operation (an Output object), or a list of tensors produced by other operations (an OutputList). Thus, this interface is implemented by both Output and OutputList.
See OpSpec.Input for more information.
type LibraryHandler ¶type LibraryHandler struct { }
Load library content into current context, useful to load ops implementation into non-monolithic TF build. Returns LibraryHandler or nil and error
OpSpec is the specification of an Operation to be added to a Graph (using Graph.AddOperation).
type Operation struct { }
Operation that has been added to the graph.
Attr returns the value of an attribute on op. It returns an error if the attribute does not exist.
Device returns a specification of the device on which this operation will be executed, or the empty string if there is no such specification.
Name returns the name of the operation.
NumInputs returns the number of inputs of op.
NumOutputs returns the number of outputs of op.
Output returns the i-th output of op.
OutputListSize returns the size of the list of Outputs that is produced by a named output of op.
An Operation has multiple named outputs, each of which produces either a single tensor or a list of tensors. This method returns the size of the list of tensors for a specific output of the operation, identified by its name.
Type returns the name of the operator used by this operation.
Output represents one of the outputs of an operation in the graph. Has a DataType (and eventually a Shape). May be passed as an input argument to a function for adding operations to a graph, or to a Session's Run() method to fetch that output as a tensor.
Consumers returns the inputs that consume this output.
DataType returns the type of elements in the tensor produced by p.
Shape returns the (possibly incomplete) shape of the tensor produced p.
OutputList represents a list of Outputs that can be provided as input to another operation.
type PartialRun struct { }
PartialRun enables incremental evaluation of graphs.
PartialRun allows the caller to pause the evaluation of a graph, run arbitrary code that depends on the intermediate computation of the graph, and then resume graph execution. The results of the arbitrary code can be fed into the graph when resuming execution. In contrast, Session.Run executes the graph to compute the requested fetches using the provided feeds and discards all intermediate state (e.g., value of intermediate tensors) when it returns.
For example, consider a graph for unsupervised training of a neural network model. PartialRun can be used to pause execution after the forward pass of the network, let the caller actuate the output (e.g., play a game, actuate a robot etc.), determine the error/loss and then feed this calculated loss when resuming the backward pass of the graph.
var ( // Create a graph: a + 2 + 3 + b. // // Skipping error handling for brevity of this example. // The 'op' package can be used to make graph construction code // with error handling more succinct. g = NewGraph() a, _ = Placeholder(g, "a", Int32) b, _ = Placeholder(g, "b", Int32) two, _ = Const(g, "Two", int32(2)) three, _ = Const(g, "Three", int32(3)) plus2, _ = Add(g, "plus2", a, two) // a + 2 plus3, _ = Add(g, "plus3", plus2, three) // (a + 2) + 3 plusB, _ = Add(g, "plusB", plus3, b) // ((a + 2) + 3) + b ) sess, err := NewSession(g, nil) if err != nil { panic(err) } defer sess.Close() // All the feeds, fetches and targets for subsequent PartialRun.Run // calls must be provided at setup. pr, err := sess.NewPartialRun( []Output{a, b}, []Output{plus2, plusB}, []*Operation{plus3.Op}, ) if err != nil { panic(err) } // Feed 'a=1', fetch 'plus2', and compute (but do not fetch) 'plus3'. // Imagine this to be the forward pass of unsupervised neural network // training of a robot. val, _ := NewTensor(int32(1)) fetches, err := pr.Run( map[Output]*Tensor{a: val}, []Output{plus2}, nil) if err != nil { panic(err) } v1 := fetches[0].Value().(int32) // Now, feed 'b=4', fetch 'plusB=a+2+3+b' // Imagine this to be the result of actuating the robot to determine // the error produced by the current state of the neural network. val, _ = NewTensor(int32(4)) fetches, err = pr.Run( map[Output]*Tensor{b: val}, []Output{plusB}, nil) if err != nil { panic(err) } v2 := fetches[0].Value().(int32) fmt.Println(v1, v2)
Output: 3 10
Run resumes execution of the graph to compute the requested fetches and targets with the provided feeds.
SavedModel represents the contents of loaded SavedModel. TODO(jhseu): Add and document metagraphdef when we pregenerate protobufs.
LoadSavedModel creates a new SavedModel from a model previously exported to a directory on disk.
Exported models contain a set of graphs and, optionally, variable values. Tags in the model identify a single graph. LoadSavedModel initializes a session with the identified graph and with variables initialized to from the checkpoints on disk.
The tensorflow package currently does not have the ability to export a model to a directory from Go. This function thus currently targets loading models exported in other languages, such as using tf.saved_model.builder in Python. See: https://www.tensorflow.org/code/tensorflow/python/saved_model/
Session drives a TensorFlow graph computation.
When a Session is created with a given target, a new Session object is bound to the universe of resources specified by that target. Those resources are available to this session to perform computation described in the GraphDef. After creating the session with a graph, the caller uses the Run() API to perform the computation and potentially fetch outputs as Tensors. A Session allows concurrent calls to Run().
NewSession creates a new execution session with the associated graph. options may be nil to use the default options.
Close a session. This contacts any other processes associated with this session, if applicable. Blocks until all previous calls to Run have returned.
ListDevices returns the list of devices associated with a Session.
NewPartialRun sets up the graph for incremental evaluation.
All values of feeds, fetches and targets that may be provided to Run calls on the returned PartialRun need to be provided to NewPartialRun.
See documentation for the PartialRun type.
Run the graph with the associated session starting with the supplied feeds to compute the value of the requested fetches. Runs, but does not return Tensors for operations specified in targets.
On success, returns the fetched Tensors in the same order as supplied in the fetches argument. If fetches is set to nil, the returned Tensor fetches is empty.
type SessionOptions struct { Target string Config []byte }
SessionOptions contains configuration information for a session.
Shape represents the (possibly partially known) shape of a tensor that will be produced by an operation.
The zero-value of a Shape represents a shape with an unknown number of dimensions.
MakeShape returns a Shape with the provided size of each dimension.
A value of -1 implies that the size of the corresponding dimension is not known.
ScalarShape returns a Shape representing a scalar.
IsFullySpecified returns true iff the size of all the dimensions of s are known.
NumDimensions returns the number of dimensions represented by s, or -1 if unknown.
Size returns the size of the dim-th dimension of the shape, or -1 if it is unknown.
REQUIRES: 0 <= dim < s.NumDimensions()
ToSlice returns the (possibly partially known) shape represented by s as a slice, or an error if the number of dimensions is not known.
A Signature defines the signature of a computation supported by a TensorFlow graph.
For example, a model with two loss computations, sharing a single input, might have the following signature_def map.
Note that across the two Signatures "loss_A" and "loss_B", the input key, output key, and method_name are identical, and will be used by system(s) that implement or rely upon this particular loss method. The output tensor names differ, demonstrating how different outputs can exist for the same method.
signature_def { key: "loss_A" value { inputs { key: "input" value { name: "input:0" dtype: DT_STRING tensor_shape: ... } } outputs { key: "loss_output" value { name: "loss_output_A:0" dtype: DT_FLOAT tensor_shape: ... } } } ... method_name: "some/package/compute_loss" }
signature_def { key: "loss_B" value { inputs { key: "input" value { name: "input:0" dtype: DT_STRING tensor_shape: ... } } outputs { key: "loss_output" value { name: "loss_output_B:0" dtype: DT_FLOAT tensor_shape: ... } } } ... method_name: "some/package/compute_loss" }
Tensor holds a multi-dimensional array of elements of a single data type.
NewTensor converts from a Go value to a Tensor. Valid values are scalars, slices, and arrays. Every element of a slice must have the same length so that the resulting Tensor has a valid shape.
ReadTensor constructs a Tensor with the provided type and shape from the serialized tensor contents in r.
See also WriteContentsTo.
DataType returns the scalar datatype of the Tensor.
Reshape updates tensor's shape in place if this is possible or returns an error otherwise.
Shape returns the shape of the Tensor.
Value converts the Tensor to a Go value. For now, not all Tensor types are supported, and this function may panic if it encounters an unsupported DataType.
The type of the output depends on the Tensor type and dimensions. For example: Tensor(int64, 0): int64 Tensor(float64, 3): [][][]float64
WriteContentsTo writes the serialized contents of t to w.
Returns the number of bytes written. See ReadTensor for reconstructing a Tensor from the serialized form.
WARNING: WriteContentsTo is not comprehensive and will fail if t.DataType() is non-numeric (e.g., String). See https://github.com/tensorflow/tensorflow/issues/6003.
type TensorHandle ¶ added in v1.12.1type TensorHandle struct { }
TensorHandle is a handle to a tensor on a device.
A Tensor referenced by a TensorHandle may be on any device, whereas a Tensor always resides in the host CPU's memory.
A Tensor referenced by a TensorHandle may not have been computed yet. For example, a TensorHandle might reference the output of an operation that has not finished executing. Because of this, various methods, such as Shape() may block until the tensor has been instantiated.
This allows multiple operations to be performed on tensors on a device (e.g. a GPU) without sending these values back to the host CPU in between every operation.
func NewTensorHandle ¶ added in v1.12.1NewTensorHandle creates a new tensor handle from a tensor.
func (*TensorHandle) BackingDeviceName ¶ added in v1.12.1BackingDeviceName returns the name of the device in whose memory tensor handle th resides. This function will block till the operation that produces th has completed.
func (*TensorHandle) CopyToDevice ¶ added in v1.12.1CopyToDevice creates a new TensorHandle with the same contents as this TensorHandle but placed in the memory of the device 'deviceName'. If source and destination are the same device, then this creates a new handle that shares the underlying buffer. Otherwise, it currently requires at least one of the source or destination devices to be CPU (i.e., for the source or destination tensor to be placed in host memory).
func (*TensorHandle) DataType ¶ added in v1.12.1DataType returns the TensorHandle's datatype.
func (*TensorHandle) DeviceName ¶ added in v1.12.1DeviceName returns the name of the device of the operation that produced the TensorHandle. If the handle was produced by a copy, it returns the destination device of the copy. Note that returned device name is not always the device holding the tensor handle's memory. If you want the latter, use BackingDeviceName. This function will block till the operation that produces th has completed.
func (*TensorHandle) Shape ¶ added in v1.12.1Shape returns the shape of the Tensor referenced by th.
func (*TensorHandle) ToTensor ¶ added in v1.12.1ToTensor returns the Tensor referenced by th. It may block if this tensor is not yet computed.
A TensorInfo contains the information about a Tensor necessary for feeding or retrieval.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4