// Convert the image in filename to a Tensor suitable as input to the Inception model. func makeTensorFromImage(filename string) (*tf.Tensor, error) { bytes, err := ioutil.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 }
// Conver the image in filename to a Tensor suitable as input to the Inception model. func makeTensorFromImage(filename string) (*tf.Tensor, error) { // Load the pixels from the file file, err := os.Open(filename) if err != nil { return nil, err } img, _, err := image.Decode(file) file.Close() if err != nil { return nil, err } // Represent the image as [H][W][B,G,R]byte contents := make([][][3]byte, img.Bounds().Size().Y) for y := 0; y < len(contents); y++ { contents[y] = make([][3]byte, img.Bounds().Size().X) for x := 0; x < len(contents[y]); x++ { px := x + img.Bounds().Min.X py := y + img.Bounds().Min.Y r, g, b, _ := img.At(px, py).RGBA() // image.Image uses 16-bits for each color. // We want 8-bits. contents[y][x][0] = byte(b >> 8) contents[y][x][1] = byte(g >> 8) contents[y][x][2] = byte(r >> 8) } } tensor, err := tf.NewTensor(contents) 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 }
func Example() { // 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 probability that the input image was recognized as // 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 an executes a Session to obtain a Tensor in this normalized form. modeldir := flag.String("dir", "", "Directory containing the trained model files. The directory will be created and the model downloaded into it if necessary") imagefile := flag.String("image", "", "Path of a JPEG-image to extract labels for") flag.Parse() if *modeldir == "" || *imagefile == "" { flag.Usage() return } // Load the serialized GraphDef from a file. modelfile, labelsfile, err := modelFiles(*modeldir) if err != nil { log.Fatal(err) } model, err := ioutil.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 probably label index. probabilities := output[0].Value().([][]float32)[0] printBestLabel(probabilities, labelsfile) }
func Example() { // An example for using the TensorFlow Go API for image recognition // using a pre-trained inception model (http://arxiv.org/abs/1512.00567). // // 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 probability that the input image was recognized as // 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 for Graph execution // - Exectues the graph and prints out the label with the highest probability const ( // Path to a pre-trained inception model. // The two files are extracted from a zip archive as so: /* curl -L https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip -o /tmp/inception5h.zip unzip /tmp/inception5h.zip -d /tmp */ modelFile = "/tmp/tensorflow_inception_graph.pb" labelsFile = "/tmp/imagenet_comp_graph_label_strings.txt" // Image file to "recognize". testImageFilename = "/tmp/test.jpg" ) // Load the serialized GraphDef from a file. model, err := ioutil.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 testImageFilename. // For multiple images, session.Run() can be called in a loop (and // concurrently). Furthermore, images can be batched together since the // model accepts batches of image data as input. tensor, err := makeTensorFromImageForInception(testImageFilename) 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 probably label index. probabilities := output[0].Value().([][]float32)[0] printBestLabel(probabilities, labelsFile) }