How to test Tensorflowlite model with multiple inputs? - android

I created a simple MLP Regression Keras model with 4 inputs and one output. I converted this model to TFlite now I'm just trying to find out how to test it on android studio. How can I input multiple 4D objects to test in Java?
The following gives an error when trying to run the model:
try{
tflite = new Interpreter(loadModelFile());
}
catch(Exception ex){
ex.printStackTrace();
}
double[][] inp= new double[1][4];
inp[0][1]= 0;
inp[0][0] = 0;
inp[0][2]= 0;
inp[0][3]=-2.01616982303105;
double[] output = new double[100];
tflite.run(inp,output);
EDIT:
Here is the model I originally created:
# create model
model = Sequential()
model.add(Dense(50, activation="tanh", input_dim=4,
kernel_initializer="random_uniform", name="input_tensor"))
model.add(Dense(50, activation="tanh",
kernel_initializer="random_uniform"))
model.add(Dense(1, activation="linear",
kernel_initializer='random_uniform', name="output_tensor"))

If your inputs are actually 4 separate tensors, then you should use the Interpreter.runForMultipleInputsAndOutputs API which allows multiple separate inputs. See also this example from the TensorFlow Lite repository. For example:
double[] input0 = {...};
double[] input1 = {...};
Object[] inputs = {input0, input1};
double[] output = new double[100];
Map<Integer, Object> outputs = new HashMap<>();
outputs.put(0, output);
interpreter.runForMultipleInputsOutputs(inputs, outputs);

This is my code:
Object[] inputArray = {iArray[0],iArray[1]};
tflite.runForMultipleInputsOutputs(inputArray,outputMap);
The 1st object works fine. But the 2nd object in the function fails in Tensor getInputTensor(int index) on this condition:
if(index >= 0 && index < this.inputTensors.length)
But the index is 1. Is there any problem with my code?

Related

Interpret output of TF lite on object detection API

I am using Object detection api to train on my custom data for a 2 class problem.
I am using SSD Mobilenet v2. I am converting the model to TF lite and I am trying to execute it on python interpreter.
The value of score and class is somewhat confusing for me and I am unable to make a valid justification for the same. I am getting the following values for score.
[[ 0.9998122 0.2795332 0.7827836 1.8154384 -1.1171713 0.152002
-0.90076405 1.6943774 -1.1098632 0.6275915 ]]
I am getting the following values for class:
[[ 0. 1.742706 0.5762139 -0.23641224 -2.1639721 -0.6644413
-0.60925585 0.5485272 -0.9775026 1.4633082 ]]
How can I get a score of greater than 1 or less than 0 for e.g. -1.1098632 or 1.6943774.
Also the classes should be integers ideally 1 or 2 as it is a 2 class object detection problem
I am using the following code
import numpy as np
import tensorflow as tf
import cv2
# Load TFLite model and allocate tensors.
interpreter = tf.contrib.lite.Interpreter(model_path="C://Users//Admin//Downloads//tflitenew//detect.tflite")
interpreter.allocate_tensors()
# Get input and output tensors.
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
print(input_details)
print(output_details)
input_shape = input_details[0]['shape']
print(input_shape)
# change the following line to feed into your own data.
#input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
input_data = cv2.imread("C:/Users/Admin/Pictures/fire2.jpg")
#input_data = cv2.imread("C:/Users/Admin/Pictures/images4.jpg")
#input_data = cv2.imread("C:\\Users\\Admin\\Downloads\\FlareModels\\lessimages\\video5_image_178.jpg")
input_data = cv2.resize(input_data, (300, 300))
input_data = np.expand_dims(input_data, axis=0)
input_data = (2.0 / 255.0) * input_data - 1.0
input_data=input_data.astype(np.float32)
interpreter.reset_all_variables()
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
output_data_scores = []
output_data_scores = interpreter.get_tensor(output_details[2]['index'])
print(output_data_scores)
output_data_class = []
output_data_class = interpreter.get_tensor(output_details[1]['index'])
print(output_data_class)
​
Looks like the problem is caused by the wrong input image channel order. Opencv imread reads images in 'BGR' format. You can try adding
input_data = cv2.cvtColor(input_data, cv2.COLOR_BGR2RGB)
to get a 'RGB' format image and then see if the result is reasonable.
Reference: ref
The output of tflite model requires post-processing. The model returns a fixed number (here, 10 detections) by default. Use the output tensor at index 3 to get the number of valid boxes, num_det. (i.e. top num_det detections are valid, ignore the rest)
num_det = int(interpreter.get_tensor(output_details[3]['index']))
boxes = interpreter.get_tensor(output_details[0]['index'])[0][:num_det]
classes = interpreter.get_tensor(output_details[1]['index'])[0][:num_det]
scores = interpreter.get_tensor(output_details[2]['index'])[0][:num_det]
Next, the box coordinates need to be scaled to the image size and adjusted so that the box is within the image (some visualization APIs require this).
df = pd.DataFrame(boxes)
df['ymin'] = df[0].apply(lambda y: max(1,(y*img_height)))
df['xmin'] = df[1].apply(lambda x: max(1,(x*img_width)))
df['ymax'] = df[2].apply(lambda y: min(img_height,(y*img_height)))
df['xmax'] = df[3].apply(lambda x: min(img_width,(x * img_width)))
boxes_scaled = df[['ymin', 'xmin', 'ymax', 'xmax']].to_numpy()
Here's a link to an inference script with input preprocessing, output post-processing and mAP evaluation.

How to set feature layer with graphic feature set Android Arcgis

I'm trying to fill a feature layer with graphics but have the problem that when using the FeatureLayer(graphics[]), instruction does not add the graphics to the feature layer. It shows the following
Error "method invocation may produce java.lang.nullpointerexception
I tried assigning a single value to the list level code does not generate any error and graphics list is filled correctly, or have any idea how that can fill a feature layer with a list of graphics?
I attached my code
MapView mMapView;
ArcGISFeatureLayer featurelayerpoints;
FeatureSet variablefeatureset = null;
Graphic[] graficos = new Graphic[listcount];
for (int i = 0; i < listcount; i++) {
Point wgspoint = new Point(routesinfolist[i].Longitude, routesinfolist[i].Latitude);
Point mapPoint = (Point) GeometryEngine.project(wgspoint, SpatialReference.create(4326),
mMapView.getSpatialReference());
Unit mapUnit = mMapView.getSpatialReference().getUnit();
double zoomWidth = Unit.convertUnits(SEARCH_RADIUS, Unit.create(LinearUnit.Code.MILE_US), mapUnit);
attributes.put(String.valueOf(routesinfolist[i].IDOrder), "IDOrder");
graficos[i] = new Graphic(mapPoint, new PictureMarkerSymbol(getResources().getDrawable(R.drawable.circler)), attributes, i);
}
variablefeatureset.setGraphics(graficos);
featurelayerpoints = new ArcGISFeatureLayer(null, variablefeatureset, null);
mMapView.addLayer(featurelayerpoints, 1);
Presently, your FeatureSet variablefeatureset is set to null. You need to initialize it using the constructor provided. [docs]
FeatureSet variablefeatureset = new FeatureSet();

Program just stops when trying to initiate a pattern for regex

I am trying to parse out all the toll information from a string that I have. I tested this in eclipse and it works fine but when I implement it in the android IDE and run the code the debugger just stops on the declaration of the pattern i pointed out below. So the program does not crash, there is no stack trace or exception thrown. The other patterns work no problem but the toll pattern just does something really weird.
g="routes:[{routeName:Dulles Toll Rd W; SR-28 S,routeDurationInMinutes:18,routeLengthKM:21.474,routeLengthMiles:13.343320854,toll:true},{routeName:Frying Pan Rd; SR-28 S,routeDurationInMinutes:18,routeLengthKM:19.437,routeLengthMiles:12.077588127,toll:false}],startPoint:12801 Worldgate Drive, Herndon, VA 20170,endPoint:14069 Lotus Ln, Centreville, VA,startLatitude:38.95459763380265,startLongitude:-77.38901112241822,endLatitude:38.954550193428965,endLongitude:-77.38874605682294";
ArrayList parse = new ArrayList();
ArrayList route = new ArrayList();
ArrayList time = new ArrayList();
ArrayList toll= new ArrayList();
final Pattern p = Pattern.compile("routeName?.+?routeLengthKM");
Matcher m = p.matcher(g);
Pattern p2 = Pattern.compile("routeName?.+?routeDurationInMinutes");
Pattern p3 = Pattern.compile("routeDurationInMinutes?.+?routeLengthKM");
Pattern ptoll = Pattern.compile("toll?.+?}"); //<-- dies here
Matcher m3 = p3.matcher(g);
Matcher mtoll = ptoll.matcher(g);
while (m.find()) {
parse.add(m.group());
}
while (m3.find()) {
time.add(m3.group());
}
while (mtoll.find()) {
toll.add(mtoll.group());
}
You need to fix your regular expression. I'm not sure why, but for some reason it doesn't like "toll?.+?}". You need to change that line to this:
Pattern ptoll = Pattern.compile("toll?.+?\\}");
The change being \\ which will escape the } and let Pattern know that it's a literal }.

Publishing by Air Android Flash 5.5 , showing me an error

I'm creating an android app using AS3 Flash CS5.5
it'a about simple library contains images that are uploaded to a web page , and i'm using this code that someone help me `
//THIS DEFINES THE ARRAY WHERE YOUR LOADERS WILL GO
var pictureArray:Array = new Array;
//THIS CODE TARGETS THE BUTTONS -- WHEN YOU CLICK THEM THE FUNCTIONS 'nextpic' and 'lastpic' WILL FIRE
nextbtn.addEventListener(MouseEvent.CLICK, nextpic)
backbtn.addEventListener(MouseEvent.CLICK, lastpic)
//YOUR LOADERS. I'VE PUT 3 PICTURES IN THE LIBRARY
//THE LAST LINE FOR EACH LOADER 'PUSHES' THE LOADER INTO THE ARRAY
var loader1 = new Loader();
loader1.load(new URLRequest("banana.jpg"));
pictureArray.push(loader1);
var loader2 = new Loader();
loader2.load(new URLRequest("big apple.jpg"));
pictureArray.push(loader2);
var loader3 = new Loader();
loader3.load(new URLRequest("pineapple.jpg"));
pictureArray.push(loader3);
//WE ADD THE FIRST 'CHILD' HERE
//NOTE THAT ARRAYS HOLD OBJECTS IN CONSECTUTIVE POSITIONS: 0 - WHATEVER
//THE FIRST OBJECT IN THE ARRAY IS ADDRESSED AT: ARRAYNAME[0], THE SECOND OBJECT IS
//AT ARRAYNAME[1], ETC.
addChild(pictureArray[0]);
pictureArray[0].x = 110; pictureArray[0].y = 80;
//n IS JUST A COUNTER THAT WILL MAKE IT EASIER TO ADDRESS THE ITEMS IN THE ARRAY
var n:int = 0;
Function nextpic(e)
{
removeChild(pictureArray[n]);
n = n+1;
//HERE WE RESET THE POSITION IN THE ARRAY IF WE'VE GONE PAST THE NUMBER OF PICTURES THAT WE HAVE
if (n>pictureArray.length - 1)
n=0;
addChild(pictureArray[n]);
pictureArray[n].x = 110; pictureArray[n].y = 80;
}
function lastpic(e)
{
removeChild(pictureArray[n]);
n = n-1;
if (n<0)
n=pictureArray.length - 1;
addChild(pictureArray[n]);
pictureArray[n].x = 110; pictureArray[n].y = 80;
}`
it's working well , but when I publish it by Android Air , it shows me this error
Scene 1, Layer 'Layer 1', Frame 1, Line 39 1071: Syntax error: expected a definition keyword (such as function) after attribute Function, not nextpic.
re-write Function as function Easy!

Unity3d BootCamp Tutorial UnityScript Array Order Anomaly in ImageEffectsOrder.js

I am new to Unity and grabbed the BootCamp project and ran it within Unity 4.1.5f1 as a Windows Build without any modification
I then tried to build to Android and had a bunch of errors (mostly variables not being declared)
But I have one remaining that I just don't understand...
In the following code in the file ImageEffectsOrder.js the javascript references an order method of the array sorted[] as sorted[i].order
The compiler errors with 'order' is not a member of object.
So I'm a little confused as to why the windows build supports this member but not android.
This makes me wonder what other surprises await when converting from platform to platform.
But for now can anyone point me to a workaround for the order member? And I'm not quite clear on what it is actually returning...it seems the variable i should give you the order.
The order just seems intrinsic from the code, it is never set to any value, so what 'order' is it? I can't seem to find any docs on this 'member' of the Array class.
Here is the code:
var sorted : Array = new Array();
var i : int = 0;
for (var fx : PostEffectsBase in GetComponents(PostEffectsBase))
{
if(fx && fx.enabled)
{
sorted[i++] = fx;
}
}
while (sorted.length)
{
var indexToUse : int = 0;
var orderValue : int = -1;
for(i = 0; i < sorted.length; i++) {
if(sorted[i].order > orderValue) {
orderValue = sorted[i].order;
indexToUse = i;
}
}
...more code...
I solved it. The problem is not with the Array Class as the fx that is being assigned to the sorted[] array is an object of class PostEffectsBase.
So the actual problem is one of casting when we try to use sorted[i].order
I changed the reference from sorted[i].order to (sorted[i] as PostEffectsBase).order and it worked.
I have to remember this. It seems there are a lot of these casts that have to be done between platforms.

Categories

Resources