Running a tensorflow model in Android - android

I'm trying to run a simple iris classifier in an Android app. I created a MLP in keras, converted it into .pb format and put it into an assets folder. The keras model:
data = sklearn.datasets.load_iris()
x=data.data
y=data.target
x=np.array(x)
y=np.array(y)
x_train, x_test, y_train, y_test= train_test_split(x, y, test_size = 0.25)
inputs=Input(shape=(4,))
x=Dense(10,activation="relu",name="input_layer")(inputs)
x=Dense(10,activation="relu")(x)
x=Dense(15,activation="relu")(x)
x=Dense(3,activation="softmax",name="output_layer")(x)
model=Model(inputs,x)
sgd = SGD(lr=0.05, momentum=0.9, decay=0.0001, nesterov=False)
model.compile(optimizer=sgd, loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(x_train,y_train,batch_size=20, epochs=100, verbose=0)
The code in AndroidStudio(I have 4 fields for input numbers,1 output field and 1 Button. The predictClick method gets called when the button gets clicked):
static{
System.loadLibrary("tensorflow_inference");
}
String model_name ="file:///android_asset/iris_model.pb";
String output_name = "output_layer";
String input_name = "input_data";
TensorFlowInferenceInterface tfinterface;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tfinterface = new TensorFlowInferenceInterface(getAssets(),model_name);
}
public void predictClick(View v){
TextView antwort = (TextView)findViewById(R.id.antwort);
EditText number1 = (EditText)findViewById(R.id.number1);
EditText number2 = (EditText)findViewById(R.id.number2);
EditText number3 = (EditText)findViewById(R.id.number3);
EditText number4 = (EditText)findViewById(R.id.number4);
Button predict = (Button)findViewById(R.id.button);
float[] result = {};
String zahl1 = number1.getText().toString();
String zahl2 = number2.getText().toString();
String zahl3 = number3.getText().toString();
String zahl4 = number4.getText().toString();
float n1 = Float.parseFloat(zahl1);
float n2 = Float.parseFloat(zahl2);
float n3 = Float.parseFloat(zahl3);
float n4 = Float.parseFloat(zahl4);
float[] inputs={n1,n2,n3,n4};
//im pretty sure these lines cause the error
tfinterface.feed(input_name,inputs,4,1);
tfinterface.run(new String[]{output_name});
tfinterface.fetch(output_name,result);
antwort.setText(Float.toString(result[0]));
}
The build runs without error, but when I hit the predict button the app chrashes. When I leave the the lines
tfinterface.feed(input_name,inputs,4,1);
tfinterface.run(new String[]{output_name});
tfinterface.fetch(output_name,result);
out the app runs correctly, so I think that's were the error comes from.

Your model's input layer is named "input_layer" in the python code, but "input_data" in the Java code.
Also check your logcat output. You should get an error message stating, that the model doesn't have the input layer you're searching for.

Related

Android How to: pass and store user Input and return it back to main class(MainActivity)

I am new to android development,
I want to get a user input via EditText store it as a String. Pass that string to c via JNI. When I press a button it that string should be displayed on a TextView showing what was typed and the length of the string.
in android:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b1 = (Button) findViewById(R.id.bb1);
b1.setOnClickListener(
new Button.OnClickListener(){
public void onClick(View v){
TextView tv = (TextView) findViewById(R.id.sample_text);
EditText e1 = (EditText) findViewById(R.id.ee1);
TextView t2 = (TextView) findViewById(R.id.test1);
String str =e1.getText().toString();
tv.setText(HelloWorld(str)); // This should text
t2.setText("This should show length"HelloWorld(l)); //This should show length
}
}
);
}
public native String HelloWorld(String stri);`
and in c file:
`#include "HelloWorld.h"
#include <jni.h>
#include <string.h>
JNIEXPORT jstring JNICALL
Java_com_example_james_myapplication_MainActivity_HelloWorld(JNIEnv *env,jobject jobj,jstring jstring1,jint l /* this */) {
const char *str = (*env) ->GetStringUTFChars(env,jstring1,NULL);
return (*env) ->NewStringUTF(env,str);}`
I am unable to do show the length of input (I get error 'cannot resolve symbol l'. I'm not sure if I am even doing the code right by this I meant passing the input to c
Please help! Thanks in advance.
HelloWorld(l) does not get you the length of a string. I'm not sure why you thought it would. To get the length of a string, you call variablename.length(). So here it would be
String result = HelloWorld(str);
tv.setText(result); // This should text
t2.setText("This should show length" + result.length()); //This should show length

ReplaceAll not working

I'm using google volley to retrieve source code from website. Some looping was done to capture the value in the code. I've successfully captured the data I wanted, but error was shown: NumberFormatException: Invalid float: "2,459.00"
My intention was to store the value after the class=ListPrice>
Sample:
RM 2,899.00
The example value of the source code I wanted to save is "RM2,459.00 "
Below is the code I've written:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lazada_result);
lelongResult = (TextView) findViewById(R.id.lelong_result);
RequestQueue lelong = MyVolley.getRequestQueue(this);
StringRequest myLel = new StringRequest(
Method.GET,
"http://list.lelong.com.my/Auc/List/List.asp?DA=A&TheKeyword=iphone&x=0&y=0&CategoryID=&PriceLBound=&PriceUBound=",
RetrieveLelong(), createMyReqErrorListener());
lelong.add(myLel);
}
private Response.Listener<String> RetrieveLelong() {
return new Response.Listener<String>() {
#Override
public void onResponse(String response) {
ArrayList<Float> integers = new ArrayList<>();
String to = "class=ListPrice>";
String remainingText = response;
String showP = "";
while (remainingText.indexOf(to) >= 0) {
String tokenString = remainingText.substring(remainingText
.indexOf(to) + to.length());
String priceString = tokenString.substring(0,
tokenString.indexOf("<"));
float price = Float.parseFloat(priceString.replaceAll("[^\\d,]+", "").trim());
integers.add((price / 100));
remainingText = tokenString;
}
for (int i = 0; i < integers.size(); i++) {
String test1 = Float.toString(integers.get(i));
showP += test1 + "\n";
}
lelongResult.setText(showP);
}
};
}
The problem was as below:
I've tried all sort of replaceAll(),
1)replaceAll("[^\d,]+","") result:2,89900
replace all character except digits and comma works.
2)replaceAll("[^\d]+","") result:Invalid int""
replace all character include comma and dot ,not working
3)replaceAll("[^\d.]+,"") result:Invalid int""
replace all character exclude digits and dot, not working
From the experiment 2&3 coding above,I've noticed that if the comma were removed,i cant parseFloat as the value received by it is: "".NumberFormatException:Invalid Float:"" shown.
From the experiment 1,NumberFormatException:Invalid Float "2,45900" is showned.
The problem was replacing comma ,the code will not work but with the presence of comma ,the value cannot be stored into string
try this:
float price = Float.parseFloat(priceString.replaceAll("RM", "").trim());
use `replaceAll(Pattern.quote(","), "");
EDIT
if you want only numbers then use this
String s1= s.replaceAll("\D+","");
Try to parse the number by specifying the Locale.
NumberFormat format = NumberFormat.getInstance(Locale.KOREAN);
Number number = format.parse(priceString.replaceAll("RM", ""));
double d = number.doubleValue();
I'm just guessing the locale, don't know what you should use, depends on country
You need to do it one by one
priceString=priceString.replaceAll("\\D", "");
priceString=priceString.replaceAll("\\s", "");
now
priceString=priceString.trim();
float price = Float.parseFloat(priceString);
the problem is that in your code:
priceString.replaceAll(Pattern.quote(","), "");
float price = Float.parseFloat(priceString.replaceAll("\\D+\\s+", "").trim());
You are replacing coma but not storing the value!
you have to do:
priceString = priceString.replaceAll(",", "");
float price = Float.parseFloat(priceString.replaceAll("\\D+\\s+", "").trim());
I'm not sure of the pattern "\D+\s" because if you remove the coma you don't need to replace anything else (except "RM" that i assume you already removed)
Update: set locale and parse a number:
NumberFormat format = NumberFormat.getInstance(Locale.KOREAN);
Number number = format.parse(priceString.replaceAll("RM", ""));
double d = number.doubleValue();

How to save number from user input?

Recently I've started to mess around with Android Studio and decided to make an app. I've made the most of my app, but I encounter a little problem. I need to memorize in a variable a number from user input, but I don't know how to that, I've tried solutions found on the internet, even here but I get an error.
Can somebody help me with some ideas or the code edited which I must put in my app ?
This is the java code for the activity:
public class calc_medie_teza extends ActionBarActivity implements View.OnClickListener {
EditText adaug_nota;
static final int READ_BLOCK_SIZE = 100;
TextView afisare;
TextView afisare2;
Button calc;
EditText note_nr;
EditText nota_teza;
int suma;
double medie;
double medieteza;
int nr_note = 0;
int notamedie;
int notateza;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calc_medie_teza);
afisare = (TextView) findViewById(R.id.afisare);
afisare2 = (TextView) findViewById(R.id.afisare2);
calc = (Button) findViewById(R.id.calc);
calc.setOnClickListener(this);
note_nr = (EditText) findViewById(R.id.note_nr);
nota_teza = (EditText) findViewById(R.id.nota_teza);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_calc_medie_teza, menu); // creare meniu
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId(); // meniu
return id == R.id.action_settings || super.onOptionsItemSelected(item);
}
public void onClick(View v) // afisare medie
{
calcul_medie();
}
public void buton_adauga(View v)
{
if(note_nr == )
suma = suma + notamedie;
nr_note = nr_note + 1;
}
public double calcul_medie() // calculul mediei
{
medie = suma / nr_note;
medieteza = ((medie * 3)+ notateza)/4;
return medieteza;
}
Here is a photo with the activity: http://onlypro.ro/img/images/ootllv2f55hnwdgi0xlv.png
Basically the app needs to add the input number to variable when I press the "Adauga nota" [Add grade] button and then I have to insert the "teza" number and when press the "Calculeaza media" [Calculate] the app will then calculate the calcul_medie() and return a decimal number. Between "Introduceti notele aici" [Add grades here] and "Adaugata nota"[Add grade] I have a Number enter text, the same is between "Introduceti teza aici" [Add thesis bere] and "Calculeaza media" [Calculate]. I don't know how to store the number the user puts in and sum it in "notamedie" variable.
I hope you understand my problem.
For any questions you'll have I'll respond as soon as I can.
Thanks in advance !
Well, I think your probably asked how to get the input of the String from the UI and translate them into Integer/BigDecimal. If so, here is some solution:
first, you get get the string from the UI:
String input = note_nr.getText().toString().trim();
change the string input to integer/BigDecimal:
int number1 = Integer.parseInt(input);
BigDecimal number2 = new BigDecimal(input);
Correct me if misunderstood your questions. Thanks.
I did not understand the problem at all. Please clearly define the problem and use english if you can. As fas the I understood there will be a Edittext to which the user will input the value. Gets its value in the activity and then use it.
EditText edittext;
editext = (EditText) findViewById(R.id.editext);
String value = edit text.getText().toString(); // the value that the user inputted in String data format
// Here for addition you will need the value in int or decimal for that
int valueInt = Integer.parse(value); // this will be the value in int type
double valueInt = = Double.parseDouble(value); // this will be the value (user inputted) in double data type ( which you will need if you want to use decimal numbers).
When you press a button just retrieve the appropriate value from the edittext in the following way
edittext = (EditText)layout.findViewById(R.id.txtDescription);
String string = edittext.getText().toString();
to retrieve the text do this
String string = note_nr.getText().toString();
// Converting String to int
int myValue =Integer.parseInt(string);
I tried that one more time, but the IDE says that the variable I used for "string" is never used, but I've used it.
number1= (EditText) findViewById(R.id.number1);
String number_1 = number1.getText().toString();
number2= (EditText) findViewById(R.id.number2);
String number_2= number2.getText().toString();
R3muSGFX, can you post the whole codes?
String number_1 = number1.getText().toString(); this line codes just mean that you initialized a String variable "number_1".
and you will used it when app perform a math function, like you wrote in the beginning:
public double calcul_medie()
{
medie = suma / nr_note;
medieteza = ((medie * 3)+ notateza)/4;
return medieteza;
}
but if you did not use "number_1" at all, IDE will imply you the warning message
:the variable I used for "string" is never used

How to call setText() using a Float? [duplicate]

This question already has an answer here:
How to call setText() using a Float data type?
(1 answer)
Closed 8 years ago.
i tried to call the setText() using the float but it dosnt seem to work can somone help me fix the problem?
public class Bmi extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bmi);
final EditText h = (EditText)findViewById(R.id.editText2);
final EditText w = (EditText)findViewById(R.id.editText3);
final TextView r = (TextView)findViewById(R.id.textView4);
Button calculate = (Button) findViewById(R.id.button1);
calculate.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
float height=0;
float weight=0;
float result=0;
height= Float.parseFloat(h.getText().toString());
weight= Float.parseFloat(w.getText().toString());
result = (weight/(height * height));
r.setText(result);
}
});
}
}
im trying to make a simple bmi calculator just as practice but im having issues on making it work
You should convert your float to a String by
r.setText(String.valueOf(result));
Or the quick and dirty way
r.setText("" + result);
If you want it localized (Dot or Comma seperated decimal number)
String text = NumberFormat.getInstance(YOURCONTEXT.getResources().getConfiguration().locale).format(result);
r.setText(text);
Just replace YOURCONTEXT with MainActivity.this if you are in the MainActivity or getActivity() if you are in a Fragment
If you want to set min or max fraction digits try this:
NumberFormat numberformat = NumberFormat.getInstance(YOURCONTEXT.getResources().getConfiguration().locale);
numberformat.setMaximumFractionDigits(2);
numberformat.setMaximumIntegerDigits(1);
numberformat.setMinimumFractionDigits(2);
String text = numberformat.format(result);
r.setText(text);
You can use
r.setText(String.valueOf(result));
In order to display float value inside TextView you'll need to convert it to String first.
You can convert any primitive data type(int, float, double,boolean,etc) to String by using String.valueOf(value) method.
Here value is the variable which you want to convert to String.
You can use
String str = String.valueOf(result);
r.setText(str);
Alternatively
r.setText(String.valueOf(result));
Please comment if further help is required.

Force close on clicking on radio button

Whenever I try to press a radio button on my emulator, it just force closes!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b = (Button)this.findViewById(R.id.btn_confirm);
b.setOnClickListener(this);
RadioButton radio_ctf = (RadioButton) findViewById(R.id.radio_ctf);
RadioButton radio_ftc = (RadioButton) findViewById(R.id.radio_ftc);
radio_ctf.setOnClickListener(this);
radio_ftc.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
TextView tv = (TextView)this.findViewById(R.id.tv_result);
EditText et = (EditText)this.findViewById(R.id.et_name);
RadioButton radio_ctf = (RadioButton) findViewById(R.id.radio_ctf);
RadioButton radio_ftc = (RadioButton) findViewById(R.id.radio_ftc);
double y = 0;
int x = Integer.parseInt(et.getText().toString());
if(radio_ctf.isChecked())
{
y = ((double)x * 1.8) + 32;
}
if(radio_ftc.isChecked())
{
y = ((double)x - 32) * 0.555;
}
String text = "Result:" + y;
tv.setText(text);
first of all, look at the error (DDMS button, if you use eclipse) in the DDMS console.
There are a lot of reason for such error. Practically it mean, that there is unhandled java exception.
my guess that you are getting an Exception due to the value that you pass to Integer.parseInt()
you need to validate the string before parsing it.
to validate the string read the following post:
Java library to check whether a String contains a number without exceptions

Categories

Resources