My react native tensorflow model gives the same prediction every result - reactjs

I have trained a keras model with 6 classes for CNN Image Recognition. Then, I converted it to tensorflowjs using this command:
tensorflowjs_converter --quantization_bytes 1 --input_format=keras {saved_model_path} {target_path}
which then gives me 2 files (model.json, group1-shard1of1.bin). After adding it to my react native project and test the prediction function, it always returns the same result. I am converting my image to tensor base on this github thread:
const processImagePrediction = async (base64Image: any) => {
const fileUri = base64Image.uri;
const imgB64 = await FileSystem.readAsStringAsync(fileUri, {
encoding: FileSystem.EncodingType.Base64,
});
const imgBuffer = tf.util.encodeString(imgB64, 'base64').buffer;
const raw = new Uint8Array(imgBuffer);
let imageTensor = decodeJpeg(raw);
const scalar = tf.scalar(255);
imageTensor = tf.image.resizeNearestNeighbor(imageTensor, [224, 224]);
const tensorScaled = imageTensor.div(scalar);
//Reshaping my tensor base on my model size (224, 224)
const img = tf.reshape(tensorScaled, [1, 224, 224, 3]);
console.log("IMG: ", img);
const results = model.predict(img);
let pred = results.dataSync();
console.log("PREDICTION: ", pred);
}
I was expecting to have a different result but no matter what image I capture it always returns this result:
LOG IMG: {"dataId": {"id": 23}, "dtype": "float32", "id": 38, "isDisposedInternal": false, "kept": false, "rankType": "4", "scopeId": 6, "shape": [1, 224, 224, 3], "size": 150528, "strides": [150528, 672, 3]} LOG PREDICTION: [-7.7249579429626465, 4.73449182510376, 2.609705924987793, 20.0458927154541, -7.944214344024658, -18.101320266723633]
The numbers somehow change slightly but it retains the highest prediction (which is class number 4).
P.S. I'm new to image recognition so any tips would be appreciated.

Related

How to copy an existing nested array into a new array in state

I am receiving a value from a previous screen that I want to use to retrieve a nested array from another file and set the nested array as a new array in state. So for example in the code below I am receiving the value of "Monday" and would like to set dayValues to {value1: 1, value2: 2, value3: 3}.
const days = [
{
Monday: {
value1: 1,
value2: 2,
value3: 3
},
Tuesday: {
value4: 4,
value5: 5,
value6: 6
}
}
]
const [ dayValues, setDayValues ] = useState({});
I understand how to use map to return individual values but haven't been able to find a way to create an entirely new array. Any help would be appreciated

How to display data from API in React.js

I have an api in that returns a result like:
[[{"AG":2707}],[{"AR":398}],[{"AI":28}],[{"BL":1085}],[{"BS":1318}],[{"BE":2964}],[{"GL":206}],[{"GR":845}],[{"JR":256}],[{"LU":1855}],[{"NW":297}],[{"OW":307}],[{"SH":307}],[{"SZ":1118}],[{"SO":945}],[{"SG":2029}],[{"TI":2146}],[{"TG":1038}],[{"UR":107}],[{"VS":1237}],[{"ZG":3714}],[{"ZH":8496}]]
So I want those data to display for example:
AG : {DATA.AG} => (there to be number 2707)
AR : {DATA.AR} => (there to be number 398)
I am new to react and I couldn't find a solution. What can I try next?
Actually, your data is inside an array so you cannot access it this way in an array, you should have to change your data from array type to object something like this,
const data = {
AG: 2707,
AR: 398,
AI: 28,
BL: 1085,
BS: 1318,
BE: 2964,
GL: 206,
GR: 845,
JR: 256,
LU: 1855,
NW: 297,
OW: 307,
SH: 307,
SZ: 1118,
SO: 945,
SG: 2029,
TI: 2146,
TG: 1038,
UR: 107,
VS: 1237,
ZG: 3714,
ZH: 8496,
};
console.log(data.AG)
But If you are strict to use the above data array you can do it something like,
const findVal = (key) => {
let obj = arr.find((el) => el[0][key]);
if(obj) return arr.find((el) => el[0][key])[0][key]
return -1;
}
console.log(findVal('AG'))

Tensorflow.js inconsistent prediction, returns 0 or works as intended

I'm trying to do a simple Tensorflow.js linear model but I get inconsistent results. It will either return 0 for any input value entered, or it will work as intended (for example if I enter 11 for the input it returns close to 110).
When the page loads up it either works or it doesn't. I can get it to work if I refresh the page 3 or 4 times. Once it works it seems to keep working.
What am I doing wrong?
import {Component, OnInit} from '#angular/core';
import * as tf from '#tensorflow/tfjs';
#Component({
selector: 'app-linear-model',
templateUrl: './linear-model.component.html',
styleUrls: ['./linear-model.component.css']
})
export class LinearModelComponent implements OnInit {
title = 'Linear Model example';
linearModel: tf.Sequential;
prediction: any;
xData: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
yData: number[] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
constructor() {
}
ngOnInit() {
this.trainNewModel();
}
async trainNewModel() {
// this is based on the following tutorial:
// https://angularfirebase.com/lessons/tensorflow-js-quick-start/#Step-2-Install-Tensorflow-js
const learningRate = 0.01;
const optimizerVar = tf.train.sgd(learningRate);
// Define a model for linear regression.
this.linearModel = tf.sequential();
this.linearModel.add(tf.layers.dense({units: 1, inputShape: [1], activation: 'relu'}));
// Prepare the model for training: Specify the loss and the optimizer.
this.linearModel.compile({loss: 'meanSquaredError', optimizer: optimizerVar});
// Training data defined at top
const x = tf.tensor1d(this.xData);
const y = tf.tensor1d(this.yData);
// Train
await this.linearModel.fit(x, y, {epochs: 10});
console.log('model trained!');
}
predict(val) {
val = parseFloat(val);
const output = this.linearModel.predict(tf.tensor2d([val], [1, 1])) as any;
this.prediction = Array.from(output.dataSync())[0];
console.log(output.toString());
}
}
Your issue has to do with the random initialization of the kernel of the dense layer.
Given the value of the weights and the bias, it might happen that the learning rate causes the loss not to decrease. One can keep track of the loss value and if that happens to lower the learning rate.
Another way to solve the issue would be to set an initializer matrix for the dense layers.
this.linearModel.add(tf.layers.dense({units: 1, inputShape: [1], activation: 'relu', kernelInitializer:'ones'}
live code here

ImmutableJS Map, how to iterate over a map and return a modified result

I am trying to remove the keys listed in the skipheaders array from the submissionsInForm.
const skipHeaders = [ 'layout', 'modules', 'enabled', 'captcha', 'settings'];
submissionsInForm.map((submission) => {
const updatedSubmission = submission.deleteAll(skipHeaders);
return updatedSubmission;
});
That code doesn't seem to be working, as it is returning the full data. Is there anyway to achieve this without having to converting to Vanilla JS?
blacklist
You could use Map#filter to remove any key/value pairs where the key appears in the blacklist
// where Map is Immutable.Map
const m = Map({a: 1, b: 2, c: 3, d: 4})
const blacklist = ['a', 'b']
m.filter((v,k) => !blacklist.includes(k))
// => {"c": 3, "d": 4}
whitelist
Your object is called submissionsInForm so I'm guessing these are user-supplied values. In such a case, I think it is much better to whitelist your fields instead of blacklisting like we did above
Notice we'll add some more fields to the input m this time but our result will be the same, without having to change the whitelist. This is good when you want to explicitly declare which fields the user can submit – all other fields will be rejected.
const m = Map({a: 1, b: 2, c: 3, d: 4, admin: 1, superuser: true})
const whitelist = ['c', 'd']
m.filter((v,k) => whitelist.includes(k))
// => {"c": 3, "d": 4}

soapUI - Parse JSON Response containing arrays

Given the following JSON response from a previous test step (request) in soapUI:
{
"AccountClosed": false,
"AccountId": 86270,
"AccountNumber": "2915",
"AccountOwner": 200000000001,
"AccountSequenceNumber": 4,
"AccountTotal": 6,
"ActiveMoneyBeltSession": true,
"CLMAccountId": "",
"CustomerName": "FRANK",
"Lines": [{
"AndWithPreviousLine": false,
"IngredientId": 10000025133,
"OrderDestinationId": 1,
"PortionTypeId": 1,
"Quantity": 1,
"QuantityAsFraction": "1",
"SentToKitchen": true,
"TariffPrice": 6,
"Id": 11258999068470003,
"OriginalRingUpTime": "2014-10-29T07:37:38",
"RingUpEmployeeName": "Andy Bean",
"Seats": []
}, {
"Amount": 6,
"Cashback": 0,
"Change": 0,
"Forfeit": 0,
"InclusiveTax": 1,
"PaymentMethodId": 1,
"ReceiptNumber": "40/1795",
"Tip": 0,
"Id": 11258999068470009,
"Seats": []
}],
"MoaOrderIdentifier": "A2915I86270",
"OutstandingBalance": 0,
"SaveAccount": false,
"ThemeDataRevision": "40",
"TrainingMode": false
}
I have the following groovy script to parse the information from the response:
import groovy.json.JsonSlurper
//Define Variables for each element on JSON Response
String AccountID, AccountClosed, AccountOwner, AccountSeqNumber, AccountTotal, ActMoneyBelt
String CLMAccountID, ThemeDataRevision, Lines, MoaOrderIdentifier, OutstandingBalance, SaveAccount, TrainingMode, CustName, AccountNumber
String AndWithPreviousLine, IngredientId, OrderDestinationId, PortionTypeId, Quantity, SentToKitchen, TariffPrice, Id, OriginalRingUpTime, RingUpEmployeeName, Seats
int AccSeqNumInt
def responseContent = testRunner.testCase.getTestStepByName("ReopenAcc").getPropertyValue("response")
// Create JsonSlurper Object to parse the response
def Response = new JsonSlurper().parseText(responseContent)
//Parse each element from the JSON Response and store in a variable
AccountClosed = Response.AccountClosed
AccountID = Response.AccountId
AccountNumber = Response.AccountNumber
AccountOwner = Response.AccountOwner
AccountSeqNumber = Response.AccountSequenceNumber
AccountTotal = Response.AccountTotal
ActMoneyBelt = Response.ActiveMoneyBeltSession
CLMAccountID = Response.CLMAccountId
CustName = Response.CustomerName
Lines = Response.Lines
/*Lines Variables*/
AndWithPreviousLine = Response.Lines.AndWithPreviousLine
IngredientId = Response.Lines.IngredientId
OrderDestinationId = Response.Lines.OrderDestinationId
PortionTypeId = Response.Lines.PortionTypeId
Quantity = Response.Lines.Quantity
SentToKitchen = Response.Lines.SentToKitchen
TariffPrice = Response.Lines.TariffPrice
Id = Response.Lines.Id
OriginalRingUpTime = Response.Lines.OriginalRingUpTime
RingUpEmployeeName = Response.Lines.RingUpEmployeeName
Seats = Response.Lines.Seats
/*End Lines Variables*/
MoaOrderIdentifier = Response.MoaOrderIdentifier
OutstandingBalance = Response.OutstandingBalance
SaveAccount = Response.SaveAccount
ThemeDataRevision = Response.ThemeDataRevision
TrainingMode = Response.TrainingMode
As you can see above there is an element (Array) called "Lines". I am looking to get the individual element value within this array. My code above when parsing the elements is returning the following:
----------------Lines Variables----------------
INFO: AndWithPreviousLine: [false, null]
INFO: IngredientId: [10000025133, null]
INFO: OrderDestinationId: [1, null]
INFO: PortionTypeId: [1, null]
INFO: Quantity: [1.0, null]
INFO: SentToKitchen: [true, null]
INFO: TariffPrice: [6.0, null]
INFO: Id: [11258999068470003, 11258999068470009]
INFO: OriginalRingUpTime: [2014-10-29T07:37:38, null]
INFO: RingUpEmployeeName: [Andy Bean, null]
INFO: Seats: [[], []]
How can i get the required element from the above, also note the the 2 different data contracts contain the same element "ID". Is there a way to differenciate between the 2.
any help appreciated, thanks.
The "Lines" in the Response can be treated as a simple list of maps.
Response["Lines"].each { println it }
[AndWithPreviousLine:false, Id:11258999068470003, IngredientId:10000025133, OrderDestinationId:1, OriginalRingUpTime:2014-10-29T07:37:38, PortionTypeId:1, Quantity:1, QuantityAsFraction:1, RingUpEmployeeName:Andy Bean, Seats:[], SentToKitchen:true, TariffPrice:6]
[Amount:6, Cashback:0, Change:0, Forfeit:0, Id:11258999068470009, InclusiveTax:1, PaymentMethodId:1, ReceiptNumber:40/1795, Seats:[], Tip:0]
The Response is just one huge map, with the Lines element a list of maps.
Using groovysh really helps here to interactively play with the data, i did the following commands after starting a "groovysh" console:
import groovy.json.JsonSlurper
t = new File("data.json").text
r = new JsonSlurper().parse(t)
r
r["Lines"]
r["Lines"][0]
etc
Edit: In response to your comment, here's a better way to get the entry with a valid AndWithPreviousLine value.
myline = r["Lines"].find{it.AndWithPreviousLine != null}
myline.AndWithPreviousLine
>>> false
myline.IngredientId
>>> 10000025133
If you use findAll instead of find you'll get an array of maps and have to index them, but for this case there's only 1 and find gives you the first whose condition is true.
By using Response["Lines"].AndWithPreviousLine [0] you're assuming AndWithPreviousLine exists on each entry, which is why you're getting nulls in your lists. If the json responses had been reversed, you'd have to use a different index of [1], so using find and findAll will work better for you than assuming the index value.

Resources