AI-TensorFlow-Libtensorflow
view release on metacpan or search on metacpan
lib/AI/TensorFlow/Libtensorflow/Manual/Notebook/InferenceUsingTFHubCenterNetObjDetect.pod view on Meta::CPAN
my $label_count = List::Util::max keys %labels_map;
say "We have a label count of $label_count. These labels include: ",
join ", ", List::Util::head( 5, @labels_map{ sort keys %labels_map } );
=head2 Load the model and session
We define the tag set C<[ 'serve' ]> which we will use to load the model.
my @tags = ( 'serve' );
We can examine what computations are contained in the graph in terms of the names of the inputs and outputs of an operation found in the graph by running C<saved_model_cli>.
if( File::Which::which('saved_model_cli')) {
local $ENV{TF_CPP_MIN_LOG_LEVEL} = 3; # quiet the TensorFlow logger for the following command
system(qw(saved_model_cli show),
qw(--dir) => $model_base,
qw(--tag_set) => join(',', @tags),
qw(--signature_def) => 'serving_default'
) == 0 or die "Could not run saved_model_cli";
} else {
say "Install the tensorflow Python package to get the `saved_model_cli` command.";
}
The above C<saved_model_cli> output shows that the model input is at C<serving_default_input_tensor:0> which means the operation named C<serving_default_input_tensor> at index C<0> and there are multiple outputs with different shapes.
Per the L<model description|https://tfhub.dev/tensorflow/centernet/hourglass_512x512/1> on TensorFlow Hub:
=over 2
B<Inputs>
A three-channel image of variable size - the model does NOT support batching. The input tensor is a C<tf.uint8> tensor with shape [1, height, width, 3] with values in [0, 255].
B<Outputs>
The output dictionary contains:
=over
=item -
C<num_detections>: a C<tf.int> tensor with only one value, the number of detections [N].
=item -
C<detection_boxes>: a C<tf.float32> tensor of shape [N, 4] containing bounding box coordinates in the following order: [ymin, xmin, ymax, xmax].
=item -
C<detection_classes>: a C<tf.int> tensor of shape [N] containing detection class index from the label file.
=item -
C<detection_scores>: a C<tf.float32> tensor of shape [N] containing detection scores.
=back
=back
Note that the above documentation has two errors: both C<num_detections> and C<detection_classes> are not of type C<tf.int>, but are actually C<tf.float32>.
Now we can load the model from that folder with the tag set C<[ 'serve' ]> by using the C<LoadFromSavedModel> constructor to create a C<::Graph> and a C<::Session> for that graph.
my $opt = AI::TensorFlow::Libtensorflow::SessionOptions->New;
my $graph = AI::TensorFlow::Libtensorflow::Graph->New;
my $session = AI::TensorFlow::Libtensorflow::Session->LoadFromSavedModel(
$opt, undef, $model_base, \@tags, $graph, undef, $s
);
AssertOK($s);
So let's use the names from the C<saved_model_cli> output to create our C<::Output> C<ArrayRef>s.
my %ops = (
in => {
op => $graph->OperationByName('serving_default_input_tensor'),
dict => {
input_tensor => 0,
}
},
out => {
op => $graph->OperationByName('StatefulPartitionedCall'),
dict => {
detection_boxes => 0,
detection_classes => 1,
detection_scores => 2,
num_detections => 3,
}
},
);
my %outputs;
%outputs = map {
my $put_type = $_;
my $op = $ops{$put_type}{op};
my $port_dict = $ops{$put_type}{dict};
$put_type => +{
map {
my $dict_key = $_;
my $index = $port_dict->{$_};
$dict_key => AI::TensorFlow::Libtensorflow::Output->New( {
oper => $op,
index => $index,
});
} keys %$port_dict
}
} keys %ops;
p %outputs;
Now we can get the following testing image from GitHub.
use HTML::Tiny;
my %images_for_test_to_uri = (
"beach_scene" => 'https://github.com/tensorflow/models/blob/master/research/object_detection/test_images/image2.jpg?raw=true',
);
( run in 0.390 second using v1.01-cache-2.11-cpan-f6376fbd888 )