Getting a Tensors value in Java - java

I habe trained a recurrent neural network with tensorflow using python. I saved the model and restored it in a Java-Application. This is working. Now i feed my input-Tensors to the pretrained modell and fetch the output. My problem now is, that the output is a Tensor and I don´t know hot to get the Tensors value (it is a simple integer-tensor of shape 1).
The python code looks like this:
sess = tf.InteractiveSession()
X = tf.placeholder(tf.float32, [None, n_steps, n_inputs], name="input_x")
y = tf.placeholder(tf.int32, [ None])
keep_prob = tf.placeholder(tf.float32, name="keep_prob")
basic_cell = tf.contrib.rnn.OutputProjectionWrapper(tf.contrib.rnn.BasicRNNCell(num_units=n_neurons),output_size=n_outputs)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
logits = tf.layers.dense(states, n_outputs, name="logits")
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)
loss = tf.reduce_mean(xentropy)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(loss)
correct = tf.nn.in_top_k(logits, y,1, name="correct")
pred = tf.argmax(logits, 1, name="prediction")
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
init = tf.global_variables_initializer()
def train_and_save_rnn():
# create a Saver object as normal in Python to save your variables
saver = tf.train.Saver()
# Use a saver_def to get the "magic" strings to restore
saver_def = saver.as_saver_def()
print (saver_def.filename_tensor_name)
print (saver_def.restore_op_name)
# Loading the Train-DataSet
data_train, labels_train = load_training_data("Train.csv")
data_test, labels_test = load_training_data("Test.csv")
#labels_train=reshape_labels_to_sequences(labels_train)
#labels_test=reshape_labels_to_sequences(labels_test)
dt_train = reshape_data(data_train)
dt_test = reshape_data(data_test)
X_test = dt_test
X_test = X_test.reshape((-1, n_steps, n_inputs))
y_test = labels_test-1
sess.run(tf.global_variables_initializer())
# START TRAINING ...
for epoch in range(n_epochs):
for iteration in range(dt_train.shape[0]-1):
X_batch, y_batch = dt_train[iteration], labels_train[iteration]-1
X_batch = X_batch.reshape((-1, n_steps, n_inputs))
y_batch = y_batch.reshape((1))
sess.run(training_op, feed_dict={X: X_batch, y: y_batch})
acc_train = accuracy.eval(feed_dict={X: X_batch, y: y_batch})
acc_test = accuracy.eval(feed_dict={X: X_test, y: y_test})
print(epoch, "Train accuracy:", acc_train, "Test accuracy:", acc_test)
# SAVE THE TRAINED MODEL ...
builder.add_meta_graph_and_variables(sess, [tf.saved_model.tag_constants.SERVING])
builder.save(True) #true for human-readable
What I do in Java is:
byte[] graphDef = readAllBytesOrExit(Paths.get(IMPORT_DIRECTORY, "/saved_model.pbtxt"));
/*List<String> labels =
readAllLinesOrExit(Paths.get(IMPORT_DIRECTORY, "trained_model.txt"));
*/
try (SavedModelBundle b = SavedModelBundle.load(IMPORT_DIRECTORY, "serve")) {
// create the session from the Bundle
Session sess = b.session();
s = sess;
g = b.graph();
// This is just a sample Tensor for debugging:
Tensor t = Tensor.create(new float[][][] {{{(float)0.8231331,(float)-5.2657013,(float)-1.1111984,(float)0.0074825287,(float)0.075252056,(float)0.07835889,(float)-0.035752058,(float)-0.035610847,(float)0.045247793,(float)1.5594741,(float)57.78549,(float)-0.21489286,(float)0.011989355,(float)0.15965772,(float)13.370155,(float)3.4708557,(float)3.7776794,(float)-1.1115816,(float)0.72939104,(float)-0.44342846,(float)11.001129,(float)10.549805,(float)-50.719162,(float)-0.8261242,(float)0.71805984,(float)-0.1849739,(float)9.334606,(float)3.0003967,(float)-52.456577,(float)-0.1875816,(float)0.19306469,(float)0.004947722,(float)5.4054375,(float)-0.8630371,(float)-24.599575,(float)1.3387873,(float)-1.1488495,(float)-2.8362968,(float)22.174248,(float)-32.095154,(float)10.069847}}});
runTensor(t);
}
public static void runTensor(Tensor inputTensor) throws IOException, FileNotFoundException {
try (Graph graph = g;
Session sess = s;) {
Integer gesture = null;
Tensor y_ph = Tensor.create(new int[]{0});
Tensor result = sess.runner()
.feed("input_x", inputTensor)
.feed("Placeholder", y_ph)
.fetch("pred")
.run().get(0);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
The output should (I´m not sure if it´s working) be an Integer between 0 and 10 for the predicted class. How can I extract the Integer in Java from the Tensor?
Thank you in advance.

Use Tensor.intValue() if it is a scalar, or Tensor.copyTo() if it is not. (So System.out.println(result.intValue());)

Related

"No Operation named [input] in the Graph" in Java

Following this Colab exeercise from Google's ML Crash Course, I generated a model in Python for the MNIST database. The code looks as follows:
import pandas as pd
import tensorflow as tf
def create_model(my_learning_rate):
model = tf.keras.models.Sequential()
model.add(tf.keras.Input(shape=(28, 28), name='input'))
model.add(tf.keras.layers.Flatten(input_shape=(28, 28)))
model.add(tf.keras.layers.Dense(units=256, activation='relu'))
model.add(tf.keras.layers.Dense(units=128, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=0.2))
model.add(tf.keras.layers.Dense(units=10, activation='softmax', name='output'))
model.compile(optimizer=tf.keras.optimizers.Adam(lr=my_learning_rate),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
def train_model(model, train_features, train_label, epochs,
batch_size=None, validation_split=0.1):
history = model.fit(x=train_features, y=train_label, batch_size=batch_size,
epochs=epochs, shuffle=True,
validation_split=validation_split)
epochs = history.epoch
hist = pd.DataFrame(history.history)
return epochs, hist
if __name__ == '__main__':
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train_normalized = x_train / 255.0
x_test_normalized = x_test / 255.0
learning_rate = 0.003
epochs = 50
batch_size = 4000
validation_split = 0.2
my_model = create_model(learning_rate)
epochs, hist = train_model(my_model, x_train_normalized, y_train,
epochs, batch_size, validation_split)
my_model.save('my_model')
The model is saved to the "my_model" folder, as it should. Now I load it again in my Java program:
public class HelloTensorFlow {
public static void main(final String[] args) {
final String filePath = Paths.get("my_model").toAbsolutePath().toString();
try (final SavedModelBundle b = SavedModelBundle.load(filePath, "serve")) {
final Session sess = b.session();
final Tensor<Float> x = Tensor.create(new float[1][28 * 28], Float.class);
final List<Tensor<?>> run = sess.runner()
.feed("input", x)
.fetch("output")
.run();
final float[] y = run.get(0).copyTo(new float[1]);
System.out.println(y[0]);
}
}
}
The model is loaded but the runner does not work. When I execute the program, I get "No Operation named [input] in the Graph", even though my Input has this name. What am I doing wrong. I have the newest TensorFlow versions: 2.3.0 (Python) and 1.15.0 (Java).
I solved it. TensorFlow 2 seems to have odd naming schemes, but using the MetaGraphDef, this can be deciphered. First, you need the org.tensorflow.proto dependency. Then, you can extract the information from the meta graph like so:
final MetaGraphDef metaGraphDef = MetaGraphDef.parseFrom(bundle.metaGraphDef());
final SignatureDef signatureDef = metaGraphDef.getSignatureDefMap().get("serving_default");
final TensorInfo inputTensorInfo = signatureDef.getInputsMap()
.values()
.stream()
.filter(Objects::nonNull)
.findFirst()
.orElseThrow(() -> ...);
final TensorInfo outputTensorInfo = signatureDef.getOutputsMap()
.values()
.stream()
.filter(Objects::nonNull)
.findFirst()
.orElseThrow(() -> ...);
Now you can feed the tensor you created into the name from inputTensorInfo.getName() and fetch the results from outputTensorInfo.getName().

How to get java class in CF

I want to access the return value from a java method in my coldfusion file. I have loaded all the jar files in coldfusion file and got the java class object successfully. Using the class object, I want to access java class method which returns a Set; but I can't get any return value.
Here is my Java Code:
public Set getSession(String url) {
result+="hello";
try {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setJavascriptEnabled(true);
caps.setCapability("takesScreenshot", false);
caps.setCapability(
PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,
"E:\\TicketScraper\\phantomjs\\phantomjs.exe"
);
driver = new PhantomJSDriver(caps);
driver.get(url);
driver.findElement(By.id("login:loginName")).sendKeys("XXXX");
driver.findElement(By.id("login:password")).sendKeys("XXXX");
waitForJQueryProcessing(driver, 5);
driver.findElement(By.id("login:j_idt145")).click();
Thread.sleep(10000);
Set<org.openqa.selenium.Cookie> allCookies=driver.manage().getCookies();
for ( org.openqa.selenium.Cookie loadedCookie : allCookies) {
System.out.println(String.format("%s -> %s", loadedCookie.getName(),loadedCookie.getValue()));
}
} catch(Exception e) {
System.out.println(e);
}
return allCookies;
}
The java code runs the Phantom JS driver, logs in to the URL in the above code, and gets all cookies. All cookies are collected in a Set variable and returned from the method. I want to get this set variable in CF code.
But when I have tried to access the java method's Set variable in CF it doesn't return any value. By contrast, when I have commented out all the Phantom JS code and return only a String variable then CF can access the string value.
Here is my CF code:
<cfscript>
paths = arrayNew(1);
paths[1] = expandPath("lib\apache-mime4j-0.6.jar");
paths[2] = expandPath("lib\bsh-1.3.0.jar");
paths[3] = expandPath("lib\cglib-nodep-2.1_3.jar");
paths[4] = expandPath("lib\commons-codec-1.9.jar");
paths[5] = expandPath("lib\commons-collections-3.2.1.jar");
paths[6] = expandPath("lib\commons-exec-1.1.jar");
paths[7] = expandPath("lib\commons-io-2.4.jar");
paths[8] = expandPath("lib\commons-jxpath-1.3.jar");
paths[9] = expandPath("lib\commons-lang3-3.3.2.jar");
paths[10] = expandPath("lib\commons-logging-1.1.3.jar");
paths[11] = expandPath("lib\Counsel_Cookies_Phantom.jar");
paths[12] = expandPath("lib\cssparser-0.9.14.jar");
paths[13] = expandPath("lib\gson-2.3.jar");
paths[14] = expandPath("lib\guava-18.0.jar");
paths[15] = expandPath("lib\hamcrest-core-1.3.jar");
paths[16] = expandPath("lib\hamcrest-library-1.3.jar");
paths[17] = expandPath("lib\htmlunit-2.15.jar");
paths[18] = expandPath("lib\htmlunit-core-js-2.15.jar");
paths[19] = expandPath("lib\httpclient-4.3.4.jar");
paths[20] = expandPath("lib\httpcore-4.3.2.jar");
paths[21] = expandPath("lib\httpmime-4.3.4.jar");
paths[22] = expandPath("lib\ini4j-0.5.2.jar");
paths[23] = expandPath("lib\jcommander-1.29.jar");
paths[24] = expandPath("lib\jetty-websocket-8.1.8.jar");
paths[25] = expandPath("lib\jna-3.4.0.jar");
paths[26] = expandPath("lib\jna-platform-3.4.0.jar");
paths[27] = expandPath("lib\junit-dep-4.11.jar");
paths[28] = expandPath("lib\netty-3.5.7.Final.jar");
paths[29] = expandPath("lib\nekohtml-1.9.21.jar");
paths[30] = expandPath("lib\operadriver-1.5.jar");
paths[31] = expandPath("lib\phantomjsdriver-1.1.0.jar");
paths[32] = expandPath("lib\protobuf-java-2.4.1.jar");
paths[33] = expandPath("lib\sac-1.3.jar");
paths[34] = expandPath("lib\selenium-java-2.44.0.jar");
paths[35] = expandPath("lib\selenium-java-2.44.0-srcs.jar");
paths[36] = expandPath("lib\serializer-2.7.1.jar");
paths[37] = expandPath("lib\testng-6.8.5.jar");
paths[38] = expandPath("lib\xalan-2.7.1.jar");
paths[39] = expandPath("lib\xercesImpl-2.11.0.jar");
paths[40] = expandPath("lib\xml-apis-1.4.01.jar");
paths[41] = expandPath("lib\Selenium_Cookies.jar");
paths[42] = expandPath("lib\selenium-server-2.0b2.jar");
//writeDump(paths);
//create the loader
loader = createObject("component", "javaloader.JavaLoader").init(paths,true);
//writeDump(loader);
excelObject = loader.create("counsel_cookies_phantom.Counsel_Cookies_Phantom");
//writeDump(excelObject);
//abort;
</cfscript>
<cfdump var=#excelObject.getSession("https://pacer.login.uscourts.gov/csologin/login.jsf")#/>
<cfabort>
Please provide your suggestions of how to access the Phantom JS value in CF.
Assuming your Set is a java.util.Set, then calling toArray() would give you an array that's easily accessible in CF.
e.g.
<cfscript>
s = createObject("java", "java.util.HashSet").init();
s.add("foo");
s.add("bar");
s.add("bob");
arr = s.toArray();
writeDump(arr);
</cfscript>
Run this on TryCF.com

What is a cleaner, more elegant way to initialize all of these?

I am naming all of these one by one. Is there a method that takes less space?
public class Matt{
PImage matt,
imgLS1, imgLS2, imgLS3, imgRS1, imgRS2, imgRS3,
imgLSB1, imgLSB2, imgLSB3, imgRSB1, imgRSB2, imgRSB3,
imgLW1, imgLW2, imgLW3, imgRW1, imgRW2, imgRW3,
imgLWB1, imgLWB2, imgLWB3, imgRWB1, imgRWB2, imgRWB3;
public Matt(){
imgLS1 = loadImage("./Images/Matt/MattLS1.png");
imgLS2 = loadImage("./Images/Matt/MattLS2.png");
imgLS3 = loadImage("./Images/Matt/MattLS3.png");
imgRS1 = loadImage("./Images/Matt/MattRS1.png");
imgRS2 = loadImage("./Images/Matt/MattRS2.png");
imgRS3 = loadImage("./Images/Matt/MattRS3.png");
imgLSB1 = loadImage("./Images/Matt/MattLSB1.png");
imgLSB2 = loadImage("./Images/Matt/MattLSB2.png");
imgLSB3 = loadImage("./Images/Matt/MattLSB3.png");
imgRSB1 = loadImage("./Images/Matt/MattRSB1.png");
imgRSB2 = loadImage("./Images/Matt/MattRSB2.png");
imgRSB3 = loadImage("./Images/Matt/MattRSB3.png");
imgLW1 = loadImage("./Images/Matt/MattLW1.png");
imgLW2 = loadImage("./Images/Matt/MattLW2.png");
imgLW3 = loadImage("./Images/Matt/MattLW3.png");
imgRW1 = loadImage("./Images/Matt/MattRW1.png");
imgRW2 = loadImage("./Images/Matt/MattRW2.png");
imgRW3 = loadImage("./Images/Matt/MattRW3.png");
imgLWB1 = loadImage("./Images/Matt/MattLWB1.png");
imgLWB2 = loadImage("./Images/Matt/MattLWB2.png");
imgLWB3 = loadImage("./Images/Matt/MattLWB3.png");
imgRWB1 = loadImage("./Images/Matt/MattRWB1.png");
imgRWB2 = loadImage("./Images/Matt/MattRWB2.png");
imgRWB3 = loadImage("./Images/Matt/MattRWB3.png");
}
}
Put your images in a Map<String,PImage>, organizing the map by image suffix. As far as accessing the images is concerned, this approach may be slightly less convenient/efficient than using variables directly, but it will save you a lot of space:
static final String[] suffixes = new String[] {"LS1", "LS2", "LS3", ..., "RWB3"};
Map<String,PImage> images = new HashMap<String,PImage>();
public Matt() {
for (String suffix : suffixes) {
PImage image = loadImage("./Images/Matt/Matt"+suffix+".png");
images.put(suffix, image);
}
}
Since the "LS", etc., seem to have semantic meaning, I'd suggest a variation of the solution by #dasblinkenlight that uses an enum:
final int N_FILES = 3; // files/position -- could also be a variable
enum Position {
LS, RS, LSB, RSB, LW, RW, LWB, LRB
}
Map<Position, String[]> files = new EnumMap<>(Position.class);
for (Position pos : Position.values()) {
String[] posFiles = new String[N_FILES];
files.put(pos, posFiles);
for (int i = 1; i <= N_FILES; ++i) {
posFiles[i-1] = "./Images/Matt/Matt" + pos.name() + i + ".png";
}
}
Then you can access any element with code like this:
Position p = RS; // or any other value
int index = 0; // 0..(N_FILES-1), corresponding to suffixes 1..N_FILES
String fileName = files.get(p)[i];

How to add a test step in HP QC from Java

I am trying to access and modify test cases in HP QC by JAVA. The code is running successfully but the Step, status, Exec dates are not being updated.
Here is my code
for (Com4jObject obj : testInstances)
{
ITSTest testInstance = obj.queryInterface(ITSTest.class);
ITSTest tstest = obj.queryInterface(ITSTest.class);
IRunFactory runfactory = tstest.runFactory().queryInterface(IRunFactory.class);
IRun run=runfactory.addItem("RunNew").queryInterface(IRun.class);
Com4jObject step = run.stepFactory();
// run.field("Step #", "Step1");
run.status("Passed");
// Com4jObject steps = run.stepFactory();
// System.out.println(run.field("Actual Result"));
// run.field("Actual Result", "As Expected. Please find attachment with TC001");
if(tstest.name().contains("[1]TC001"))
{
try {
String fileName = new File(files.get(i)).getName();
String folderName = new File(files.get(i)).getParent();
System.out.println("FILE: "+fileName);
System.out.println("FOLDER: "+folderName);
IAttachmentFactory attachfac = tstest.attachments().queryInterface(IAttachmentFactory.class);
IAttachment attach = attachfac.addItem(fileName).queryInterface(IAttachment.class);
IExtendedStorage extAttach = attach.attachmentStorage().queryInterface(IExtendedStorage.class);
extAttach.clientPath(folderName);
extAttach.save(fileName, true);
//attach.description(Actual);
attach.post();
attach.refresh();
} catch(Exception e) {
System.out.println("QC Exceptione : "+e.getMessage());
}
}
run.post();
//AppLog.info(" Test Instance: %s", testInstance.name());
System.out.println(("Test Instance: %s"+ testInstance.name()));
}
You need to call post() on each item separately: Test run and each created step.
Example in C# starting from the point where you retrieve the step factory.
// Create test run
var oRunInstance = (QcClient.RunFactory)oTsTest.RunFactory;
var oRun = (QcClient.Run)oRunInstance.AddItem("Performance Test");
oRun.Status = "Passed";
oRun.Post();
oRun.Refresh();
// Create test run steps
var oTest = (QcClient.Test)oTsTest.Test;
var tsDesignStepList = oTest.DesignStepFactory.NewList("");
var oStepFactory = (QcClient.StepFactory)oRun.StepFactory;
foreach (QcClient.DesignStep oDesignStep in tsDesignStepList)
{
var oStep = (QcClient.Step)oStepFactory.AddItem(oDesignStep.StepName);
oStep.Status = "Passed";
oStep.Post();
}

Format data to JSON like format

I'm using a charting library that needs that the input looks like some format. This format looks like JSON but it isn't, and here I share some data to get an idea about the format:
[{
year: 2005,
income: 23.5,
expenses: 18.1
}, {
year: 2006,
income: 26.2,
expenses: 22.8
}, {
year: 2007,
income: 30.1,
expenses: 23.9
}, {
year: 2008,
income: 29.5,
expenses: 25.1
}, {
year: 2009,
income: 24.6,
expenses: 25.0
}];
You can see the complete example in this link.
In my first test, I've used String.concat(anotherString) but I assure you that it's not comfortable. So is there any java API that provides this format?
Thanks in advance.
well, the only difference between that format and JSON looks like you just need to remove double quotes from the strings. So data.replaceAll("\"", ""); shall do the job.
but actually, reading the example, it shall accepts valid JSON. You shall try using a $.ajax() method, something that would look like :
AmCharts.ready(function () {$.ajax({
url: '/mydata/',
dataType: 'json',
data: undefined,
success: function(chartData) {
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
chart.categoryField = "year";
// AXES
// category
var categoryAxis = chart.categoryAxis;
categoryAxis.gridAlpha = 0.1;
categoryAxis.axisAlpha = 0;
categoryAxis.gridPosition = "start";
// value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.stackType = "regular";
valueAxis.gridAlpha = 0.1;
valueAxis.axisAlpha = 0;
chart.addValueAxis(valueAxis);
// GRAPHS
// first graph
var graph = new AmCharts.AmGraph();
graph.title = "Europe";
graph.labelText = "[[value]]";
graph.valueField = "europe";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#C72C95";
chart.addGraph(graph);
// second graph
graph = new AmCharts.AmGraph();
graph.title = "North America";
graph.labelText = "[[value]]";
graph.valueField = "namerica";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#D8E0BD";
chart.addGraph(graph);
// third graph
graph = new AmCharts.AmGraph();
graph.title = "Asia-Pacific";
graph.labelText = "[[value]]";
graph.valueField = "asia";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#B3DBD4";
chart.addGraph(graph);
// LEGEND
var legend = new AmCharts.AmLegend();
chart.addLegend(legend);
// WRITE
chart.write("chartdiv");
});
}
});
(sorry, I'm far from being good at writing javascript, but I think the idea is there). Also, maybe the API of amCharts enables you to direcly check a local URL. And then, you'll only have to route your JSON data as a REST call.
chk this API's data related blog page
http://blog.amcharts.com/2011/03/amcharts-javascript-tutorials-part-2.html
I think this tutorial tells about all the nitty gritties of handling the data in this API, with lots of examples and code snippets
the solution is simple:
var chartData = eval(json_data);
Best Regards

Categories

Resources