I want to predict on my trained Model from Python Tensorflow API with the Java API, but have problems to feed in the features to predict in Java.
My Python Code is like this:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
from six.moves.urllib.request import urlopen
import numpy as np
import tensorflow as tf
feature_names = [
'Attribute1',
'Attribute2',
'Attribute3',
'Attribute4',
'Attribute5',
'Attribute6',
'Attribute7',
'Attribute8',
'Attribute9',
'Attribute10',
'Attribute11',
'Attribute12',
'Attribute13',
'Attribute14',
'Attribute15',
'Attribute16',
'Attribute17',
'Attribute18',
'Attribute19',
'Attribute20']
#prediction_input = np.array([['A11', 6, 'A34', 'A43', 1169, 'A65', 'A75', 4, 'A93', 'A101', 4, 'A121', 67, 'A143', 'A152', 2, 'A173', 1, 'A192', 'A201'],
# ['A12', 18, 'A34', 'A43', 1795, 'A61', 'A75', 3, 'A92', 'A103', 4, 'A121', 48, 'A141', 'A151', 2, 'A173', 1, 'A192', 'A201']])
prediction_input = [["A12 12 A32 A40 7472 A65 A71 1 A92 A101 2 A121 24 A143 A151 1 A171 1 A191 A201"],
["A11 36 A32 A40 9271 A61 A74 2 A93 A101 1 A123 24 A143 A152 1 A173 1 A192 A201"],
["A12 15 A30 A40 1778 A61 A72 2 A92 A101 1 A121 26 A143 A151 2 A171 1 A191 A201"]]
def predict_input_fn():
def decode(zeile):
parsed_line = tf.decode_csv(zeile, [[''], [0], [''], [''], [0], [''], [''], [0], [''], [''], [0], [''], [0], [''], [''], [0], [''], [0], [''], ['']], field_delim=' ')
#x = tf.split(x, 20) # Need to split into our 20 features
# When predicting, we don't need (or have) any labels
return dict(zip(feature_names, parsed_line)) # Then build a dict from them
# The from_tensor_slices function will use a memory structure as input
dataset = tf.data.Dataset.from_tensor_slices(prediction_input)
dataset = dataset.map(decode)
dataset = dataset.batch(1)
iterator = dataset.make_one_shot_iterator()
next_feature_batch = iterator.get_next()
return next_feature_batch, None # In prediction, we have no labels
# Data sets
def train_test_input_fn(dateipfad, mit_shuffle=False, anzahl_wiederholungen=1):
def parser(zeile):
parsed_line = tf.decode_csv(zeile, [[''], [0], [''], [''], [0], [''], [''], [0], [''], [''], [0], [''], [0], [''], [''], [0], [''], [0], [''], [''], [0]], field_delim=' ')
label = parsed_line[-1:] # Last element is the label
del parsed_line[-1] # Delete last element
features = parsed_line # Everything (but last element) are the features
d = dict(zip(feature_names, features)), label
return d
dataset = tf.data.TextLineDataset(dateipfad)
dataset = dataset.map(parser)
if mit_shuffle:
dataset = dataset.shuffle(buffer_size=100)
dataset = dataset.batch(1)
dataset = dataset.repeat(anzahl_wiederholungen)
iterator = dataset.make_one_shot_iterator()
# `features` is a dictionary in which each value is a batch of values for
# that feature; `labels` is a batch of labels.
batch_features, batch_labels = iterator.get_next()
return batch_features, batch_labels
def main():
feature_columns = [tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute1', ['A11', 'A12', 'A13', 'A14'])),
tf.feature_column.numeric_column('Attribute2', shape=[1]),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute3', ['A30', 'A31', 'A32', 'A33'])),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute4', ['A40', 'A41', 'A42', 'A43', 'A44', 'A45', 'A46', 'A47', 'A48', 'A49', 'A410'])),
tf.feature_column.numeric_column('Attribute5', shape=[1]),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute6', ['A61', 'A62', 'A63', 'A64', 'A65'])),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute7', ['A71', 'A72', 'A73', 'A74', 'A75'])),
tf.feature_column.numeric_column('Attribute8', shape=[1]),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute9', ['A91', 'A92', 'A93', 'A94', 'A95'])),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute10', ['A101', 'A102', 'A103'])),
tf.feature_column.numeric_column('Attribute11', shape=[1]),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute12', ['A121', 'A122', 'A123', 'A124'])),
tf.feature_column.numeric_column('Attribute13', shape=[1]),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute14', ['A141', 'A142', 'A143'])),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute15', ['A151', 'A152', 'A153'])),
tf.feature_column.numeric_column('Attribute16', shape=[1]),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute17', ['A171', 'A172', 'A173', 'A174'])),
tf.feature_column.numeric_column('Attribute18', shape=[1]),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute19', ['A191', 'A192'])),
tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('Attribute20', ['A201', 'A202']))]
classifier = tf.estimator.DNNClassifier(feature_columns=feature_columns,
hidden_units=[100],
n_classes=2,
model_dir="./summaries")
# Trainieren des Models
classifier.train(input_fn=lambda: train_test_input_fn("german.data.train.txt", True, 10))
# Errechne die Genauigkeit ("accuracy").
accuracy_score = classifier.evaluate(input_fn=lambda: train_test_input_fn("german.data.test.txt", False, 4))["accuracy"]
print("\nTest Genauigkeit: {0:f}\n".format(accuracy_score))
feature_spec = tf.feature_column.make_parse_example_spec(feature_columns)
serving_input_receiver_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(feature_spec)
classifier.export_savedmodel("./export" , serving_input_receiver_fn, as_text=True)
predict_results = classifier.predict(input_fn=predict_input_fn)
for idx, prediction in enumerate(predict_results):
type = prediction["class_ids"][0] # Get the predicted class (index)
if type == 0:
print("Ich denke: {}, ist nicht kreditwürdig".format(prediction_input[idx]))
elif type == 1:
print("Ich denke: {}, ist kreditwürdig".format(prediction_input[idx]))
if __name__ == "__main__":
main()
But I found nothing, how I can feed such categorical columns in Java Clients? Can you please provide a sample how I can make this?
My current state is something like this, but without any idea which Tensor I have to create, to predict on the trained model in Java:
public static void main(String[] args) throws Exception {
String pfad = System.getProperty("user.dir") + "\\1511523781";
Session session = SavedModelBundle.load(pfad, "serve").session();
String example = "A12 12 A32 A40 7472 A65 A71 1 A92 A101 2 A121 24 A143 A151 1 A171 1 A191 A201";
final String xName = "input_example_tensor";
final String scoresName = "dnn/head/predictions/probabilities:0";
List<Tensor<?>> outputs = session.runner()
.feed(xName, example)
.fetch(scoresName)
.run();
// Outer dimension is batch size; inner dimension is number of classes
float[][] scores = new float[2][3];
outputs.get(0).copyTo(scores);
System.out.println(Arrays.deepToString(scores));
}
Thanks!
Since you're using tf.estimator.export.build_parsing_serving_input_receiver_fn, the exported saved model you've created expects a serialized tf.Example protocol buffer as input.
You can use the tf.Example protocol buffer in Java (maven, javadoc), using something like this:
import com.google.protobuf.ByteString;
import java.util.Arrays;
import org.tensorflow.*;
import org.tensorflow.example.*;
public class Main {
// Returns a Feature containing a BytesList, where each element of the list
// is the UTF-8 encoded bytes of the Java string.
public static Feature feature(String... strings) {
BytesList.Builder b = BytesList.newBuilder();
for (String s : strings) {
b.addValue(ByteString.copyFromUtf8(s));
}
return Feature.newBuilder().setBytesList(b).build();
}
public static Feature feature(float... values) {
FloatList.Builder b = FloatList.newBuilder();
for (float v : values) {
b.addValue(v);
}
return Feature.newBuilder().setFloatList(b).build();
}
public static void main(String[] args) throws Exception {
Features features =
Features.newBuilder()
.putFeature("Attribute1", feature("A12"))
.putFeature("Attribute2", feature(12))
.putFeature("Attribute3", feature("A32"))
.putFeature("Attribute4", feature("A40"))
.putFeature("Attribute5", feature(7472))
.putFeature("Attribute6", feature("A65"))
.putFeature("Attribute7", feature("A71"))
.putFeature("Attribute8", feature(1))
.putFeature("Attribute9", feature("A92"))
.putFeature("Attribute10", feature("A101"))
.putFeature("Attribute11", feature(2))
.putFeature("Attribute12", feature("A121"))
.putFeature("Attribute13", feature(24))
.putFeature("Attribute14", feature("A143"))
.putFeature("Attribute15", feature("A151"))
.putFeature("Attribute16", feature(1))
.putFeature("Attribute17", feature("A171"))
.putFeature("Attribute18", feature(1))
.putFeature("Attribute19", feature("A191"))
.putFeature("Attribute20", feature("A201"))
.build();
Example example = Example.newBuilder().setFeatures(features).build();
String pfad = System.getProperty("user.dir") + "\\1511523781";
try (SavedModelBundle model = SavedModelBundle.load(pfad, "serve")) {
Session session = model.session();
final String xName = "input_example_tensor";
final String scoresName = "dnn/head/predictions/probabilities:0";
try (Tensor<String> inputBatch = Tensors.create(new byte[][] {example.toByteArray()});
Tensor<Float> output =
session
.runner()
.feed(xName, inputBatch)
.fetch(scoresName)
.run()
.get(0)
.expect(Float.class)) {
System.out.println(Arrays.deepToString(output.copyTo(new float[1][2])));
}
}
}
}
Much of the boilerplate here is to construct the protocol buffer example. Alternatively, you could use something other than build_arsing_serving_input_receiver_fn to setup the exported model to accept input in a different format.
Side note: You can use the saved_model_cli command-line tool that is included with TensorFlow Python installation to inspect the saved model. For example, something like:
saved_model_cli show \
--dir ./export/1511523781 \
--tag_set serve \
--signature_def predict
will show something like:
The given SavedModel SignatureDef contains the following input(s):
inputs['examples'] tensor_info:
dtype: DT_STRING
shape: (-1)
name: input_example_tensor:0
The given SavedModel SignatureDef contains the following output(s):
...
outputs['probabilities'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 2)
name: dnn/head/predictions/probabilities:0
Suggesting that the saved model takes a single input - a batch of DT_STRING elements and the output probabilities are a batch of 2-dimensional float vectors.
Hope that helps.
Related
I have been trying to build a CNN model using dl4j, but it is giving me an error. The code:
RecordReader rr;
rr = new CSVRecordReader();
rr.initialize(new FileSplit(new File(dataLocalPath, nameTrain)));
DataSetIterator trainIter = new RecordReaderDataSetIterator(rr, batchSize, 0, 2);
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder().seed(123).updater(new Adam(0.1))
.list()
.layer(0,new Convolution1DLayer.Builder().kernelSize(3).padding(1).nIn(371).nOut(64).build())
.layer(1,new Subsampling1DLayer.Builder().kernelSize(3).padding(1).build())
.layer(2,new Convolution1DLayer.Builder().kernelSize(3).activation(Activation.RELU).padding(1).nIn(64)
.nOut(32).build())
.layer(3,new Subsampling1DLayer.Builder().kernelSize(3).padding(1).build())
.layer(4,new DenseLayer.Builder().activation(Activation.RELU).nIn(32).nOut(16).build())
.layer(5,new OutputLayer.Builder(LossFunction.RECONSTRUCTION_CROSSENTROPY).activation(Activation.SIGMOID)
.nIn(16).nOut(2).build())
.build();
MultiLayerNetwork model = new MultiLayerNetwork(conf);
model.init();
model.setListeners(new ScoreIterationListener(10));
final DataSet trainData = trainIter.next();
INDArray a = trainData.getFeatures();
final INDArray b = trainData.getLabels();
a = a.reshape(new int[] { (int) a.size(0), (int) a.size(1), 1 });
model.fit(a, b);
Added the error below,
Exception in thread "main" org.deeplearning4j.exception.DL4JInvalidInputException: Input that is not a matrix; expected matrix (rank 2), got rank 3 array with shape [128, 32, 1]. Missing preprocessor or wrong input type? (layer name: layer4, layer index: 4, layer type: DenseLayer)
at org.deeplearning4j.nn.layers.BaseLayer.preOutputWithPreNorm(BaseLayer.java:306)
at org.deeplearning4j.nn.layers.BaseLayer.preOutput(BaseLayer.java:289)
at org.deeplearning4j.nn.layers.BaseLayer.activate(BaseLayer.java:337)
at org.deeplearning4j.nn.layers.AbstractLayer.activate(AbstractLayer.java:257)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.ffToLayerActivationsInWs(MultiLayerNetwork.java:1129)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.computeGradientAndScore(MultiLayerNetwork.java:2741)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.computeGradientAndScore(MultiLayerNetwork.java:2699)
at org.deeplearning4j.optimize.solvers.BaseOptimizer.gradientAndScore(BaseOptimizer.java:170)
at org.deeplearning4j.optimize.solvers.StochasticGradientDescent.optimize(StochasticGradientDescent.java:63)
at org.deeplearning4j.optimize.Solver.optimize(Solver.java:52)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.fitHelper(MultiLayerNetwork.java:2303)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.fit(MultiLayerNetwork.java:2261)
at org.deeplearning4j.nn.multilayer.MultiLayerNetwork.fit(MultiLayerNetwork.java:2248)
at com.rssoftware.efrm.AnnModelFromKeras.trainModel(AnnModelFromKeras.java:73)
at com.rssoftware.efrm.AnnModelFromKeras.main(AnnModelFromKeras.java:89)
I have tried using input pre-processor, CNN to feed forward pre processor, but it is not working.
The expected input shape into a conv1d layer is [minibatchSize, convNIn, length] or [minibatchSize, featuresSize, sequenceLength] in terms of a time series. The reshape in your code sets your length to 1. Maybe you intended to set featuresize/convNIn to 1?
I am trying to load a tensorflow model in Java.
tf.saved_model.simple_save(
sess,
"/tmp/model/"+timestamp,
inputs={"input_x" : cnn.input_x},
outputs={"input_y" : cnn.input_y})
This is how I save a tensorflow model in python.
public static void main( String[] args ) throws IOException
{
// good idea to print the version number, 1.2.0 as of this writing
System.out.println(TensorFlow.version());
final int NUM_PREDICTIONS = 1;
Random r = new Random();
long[] shape = new long[] {1,56};
IntBuffer buf = IntBuffer.allocate(1*56);
for (int i = 0; i < 56; i++) {
buf.put(r.nextInt());
}
buf.flip();
// load the model Bundle
try (SavedModelBundle b = SavedModelBundle.load("/tmp/model/1549001254", "serve")) {
Session sess = b.session();
// run the model and get the result, 4.0f.
try(Tensor x = Tensor.create(shape, buf)){
float[] result = sess.runner()
.feed("input_x", x)
.fetch("input_y")
.run()
.get(0)
.copyTo(new float[1][2])[0];
// print out the result.
System.out.println(result[0]);
}
}
}
This is how I load it in Java.
The given SavedModel SignatureDef contains the following input(s):
inputs['input_x'] tensor_info:
dtype: DT_INT32
shape: (-1, 56)
name: input_x:0
The given SavedModel SignatureDef contains the following output(s):
outputs['input_y'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 2)
name: input_y:0
Method name is: tensorflow/serving/predict
The input and output are saved well.
1.12.0
2019-02-01 15:58:59.065677: I tensorflow/cc/saved_model/reader.cc:31] Reading SavedModel from: /tmp/model/1549001254
2019-02-01 15:58:59.072601: I tensorflow/cc/saved_model/reader.cc:54] Reading meta graph with tags { serve }
2019-02-01 15:58:59.085912: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2
2019-02-01 15:58:59.132271: I tensorflow/cc/saved_model/loader.cc:162] Restoring SavedModel bundle.
2019-02-01 15:58:59.199331: I tensorflow/cc/saved_model/loader.cc:138] Running MainOp with key legacy_init_op on SavedModel bundle.
2019-02-01 15:58:59.199435: I tensorflow/cc/saved_model/loader.cc:259] SavedModel load for tags { serve }; Status: success. Took 133774 microseconds.
Exception in thread "main" java.lang.IllegalArgumentException: You must feed a value for placeholder tensor 'input_y' with dtype float and shape [?,2]
[[{{node input_y}} = Placeholder[_output_shapes=[[?,2]], dtype=DT_FLOAT, shape=[?,2], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]
at org.tensorflow.Session.run(Native Method)
at org.tensorflow.Session.access$100(Session.java:48)
at org.tensorflow.Session$Runner.runHelper(Session.java:314)
at org.tensorflow.Session$Runner.run(Session.java:264)
at Use_model.main(Use_model.java:38)
But It cannot load the model... The error message is like this.
I don't know what is the problem and how to fix it.
There is some confusion about input_y in your code. The exception says:
You must feed a value for placeholder tensor 'input_y' with dtype float and shape [?,2]
This means that, in your python code, input_y is defined to be a placeholder. I guess this is the placeholder that contains labels of the input_x items. Then input_y should be used in your loss function to compare the last layer of your cnn (let's call it cnn.output) with the actual labels (cnn.input_y), e.g.:
loss = tf.square(cnn.input_y - cnn.output)
Then, you python code should save cnn.output in the outputs dictionary, and not cnn.input_y:
tf.saved_model.simple_save(
sess,
"/tmp/model/"+timestamp,
inputs={"input_x" : cnn.input_x},
outputs={"output" : cnn.output})
In your java code you should then fetch "output":
float[] result = sess.runner()
.feed("input_x", x)
.fetch("output")
.run()
.get(0)
.copyTo(new float[1][2])[0];
I have a problem and I can't find what it's wrong with my code.
From beginning. I have application to recognize digits and math operators, the basic one +, -, /, *. I have a model ready which creates a graph. This graph is imported by an Android application. In my opinion, it should work but I don't know why it isn't?
Model.py
import tensorflow as tf
import numpy as np
import _pickle as pickle
from matplotlib import pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
# mnist_data = input_data.read_data_sets('MNIST_data', one_hot=True)
# read CROHME_test_data
with open("test.pickle", 'rb') as f:
data = pickle.load(f)
# np.random.shuffle(data)
CROHME_test_data = {"features": np.array([d["features"] for d in data]), "labels": np.array([d["label"] for d in data])}
# read CROHME_train_data
with open("train.pickle", 'rb') as f:
data = pickle.load(f)
# np.random.shuffle(data)
CROHME_train_data = {"features": np.array([d["features"] for d in data]),
"labels": np.array([d["label"] for d in data])}
# function for pulling batches from custom data
def next_batch(num, data):
idx = np.arange(0, len(data["features"]))
np.random.shuffle(idx)
idx = idx[:num]
features_shuffle = [data["features"][i] for i in idx]
labels_shuffle = [data["labels"][i] for i in idx]
return np.asarray(features_shuffle), np.asarray(labels_shuffle)
# Function to create a weight neuron using a random number. Training will assign a real weight later
def weight_variable(shape, name):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial, name=name)
# Function to create a bias neuron. Bias of 0.1 will help to prevent any 1 neuron from being chosen too often
def biases_variable(shape, name):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial, name=name)
# Function to create a convolutional neuron. Convolutes input from 4d to 2d. This helps streamline inputs
def conv_2d(x, W, name):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME', name=name)
# Function to create a neuron to represent the max input. Helps to make the best prediction for what comes next
def max_pool(x, name):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name=name)
labels_number = 14
# A way to input images (as 784 element arrays of pixel values 0 - 1)
x_input = tf.placeholder(dtype=tf.float32, shape=[None, 784], name='x_input')
# A way to input labels to show model what the correct answer is during training
y_input = tf.placeholder(dtype=tf.float32, shape=[None, labels_number], name='y_input')
# First convolutional layer - reshape/resize images
# A weight variable that examines batches of 5x5 pixels, returns 32 features (1 feature per bit value in 32 bit float)
W_conv1 = weight_variable([5, 5, 1, 32], 'W_conv1')
# Bias variable to add to each of the 32 features
b_conv1 = biases_variable([32], 'b_conv1')
# Reshape each input image into a 28 x 28 x 1 pixel matrix
x_image = tf.reshape(x_input, [-1, 28, 28, 1], name='x_image')
# Flattens filter (W_conv1) to [5 * 5 * 1, 32], multiplies by [None, 28, 28, 1] to associate each 5x5 batch with the
# 32 features, and adds biases
h_conv1 = tf.nn.relu(conv_2d(x_image, W_conv1, name='conv1') + b_conv1, name='h_conv1')
# Takes windows of size 2x2 and computes a reduction on the output of h_conv1 (computes max, used for better prediction)
# Images are reduced to size 14 x 14 for analysis
h_pool1 = max_pool(h_conv1, name='h_pool1')
# Second convolutional layer, reshape/resize images
# Does mostly the same as above but converts each 32 unit output tensor from layer 1 to a 64 feature tensor
W_conv2 = weight_variable([5, 5, 32, 64], 'W_conv2')
b_conv2 = biases_variable([64], 'b_conv2')
h_conv2 = tf.nn.relu(conv_2d(h_pool1, W_conv2, name='conv2') + b_conv2, name='h_conv2')
# Images at this point are reduced to size 7 x 7 for analysis
h_pool2 = max_pool(h_conv2, name='h_pool2')
# First dense layer, performing calculation based on previous layer output
# Each image is 7 x 7 at the end of the previous section and outputs 64 features, we want 32 x 32 neurons = 1024
W_dense1 = weight_variable([7 * 7 * 64, 1024], name='W_dense1')
# bias variable added to each output feature
b_dense1 = biases_variable([1024], name='b_dense1')
# Flatten each of the images into size [None, 7 x 7 x 64]
h_pool_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64], name='h_pool_flat')
# Multiply weights by the outputs of the flatten neuron and add biases
h_dense1 = tf.nn.relu(tf.matmul(h_pool_flat, W_dense1, name='matmul_dense1') + b_dense1, name='h_dense1')
# Dropout layer prevents overfitting or recognizing patterns where none exist
# Depending on what value we enter into keep_prob, it will apply or not apply dropout layer
keep_prob = tf.placeholder(dtype=tf.float32, name='keep_prob')
# Dropout layer will be applied during training but not testing or predicting
h_drop1 = tf.nn.dropout(h_dense1, keep_prob, name='h_drop1')
# Readout layer used to format output
# Weight variable takes inputs from each of the 1024 neurons from before and outputs an array of 14 elements
W_readout1 = weight_variable([1024, labels_number], name='W_readout1')
# Apply bias to each of the 14 outputs
b_readout1 = biases_variable([labels_number], name='b_readout1')
# Perform final calculation by multiplying each of the neurons from dropout layer by weights and adding biases
y_readout1 = tf.add(tf.matmul(h_drop1, W_readout1, name='matmul_readout1'), b_readout1, name='y_readout1')
# Softmax cross entropy loss function compares expected answers (labels) vs actual answers (logits)
cross_entropy_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_input, logits=y_readout1))
# Adam optimizer aims to minimize loss
train_step = tf.train.AdamOptimizer(0.0001).minimize(cross_entropy_loss)
# Compare actual vs expected outputs to see if highest number is at the same index, true if they match and false if not
correct_prediction = tf.equal(tf.argmax(y_input, 1), tf.argmax(y_readout1, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# Used to save the graph and weights
saver = tf.train.Saver()
# Run in with statement so session only exists within it
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# Save the graph shape and node names to pbtxt file
tf.train.write_graph(sess.graph_def, '.', 'advanced_mnist.pbtxt', False)
# Train the model, running through data 20000 times in batches of 50
# Print out step # and accuracy every 100 steps and final accuracy at the end of training
# Train by running train_step and apply dropout by setting keep_prob to 0.5
for i in range(1000):
batch = next_batch(50, CROHME_train_data)
if i % 100 == 0:
train_accuracy = accuracy.eval(feed_dict={x_input: batch[0], y_input: batch[1], keep_prob: 1.0})
print("step %d, training accuracy %g" % (i, train_accuracy))
train_step.run(feed_dict={x_input: batch[0], y_input: batch[1], keep_prob: 0.5})
print("test accuracy %g" % accuracy.eval(feed_dict={x_input: CROHME_test_data["features"],
y_input: CROHME_test_data["labels"], keep_prob: 1.0}))
# Save the session with graph shape and node weights
saver.save(sess, './advanced_mnist.ckpt')
# Make a prediction of random image
img_num = np.random.randint(0, len(CROHME_test_data["features"]))
print("expected :", CROHME_test_data["labels"][img_num])
print("predicted :",
sess.run(y_readout1, feed_dict={x_input: [CROHME_test_data["features"][img_num]], keep_prob: 1.0}))
for j in range(28):
print(CROHME_test_data["features"][img_num][j * 28:(j + 1) * 28])
# this code can be used for image displaying
first_image = CROHME_test_data["features"][img_num]
first_image = np.array(first_image, dtype='float')
pixels = first_image.reshape((28, 28))
plt.imshow(pixels, cmap='gray')
plt.show()
Graph.py
import tensorflow as tf
from tensorflow.python.tools import freeze_graph, optimize_for_inference_lib
# Saving the graph as a pb file taking data from pbtxt and ckpt files and providing a few operations
freeze_graph.freeze_graph('advanced_mnist.pbtxt',
'',
True,
'advanced_mnist.ckpt',
'y_readout1',
'save/restore_all',
'save/Const:0',
'frozen_advanced_mnist.pb',
True,
'')
# Read the data form the frozen graph pb file
input_graph_def = tf.GraphDef()
with tf.gfile.Open('frozen_advanced_mnist.pb', 'rb') as f:
data = f.read()
input_graph_def.ParseFromString(data)
# Optimize the graph with input and output nodes
output_graph_def = optimize_for_inference_lib.optimize_for_inference(
input_graph_def,
['x_input', 'keep_prob'],
['y_readout1'],
tf.float32.as_datatype_enum)
# Save the optimized graph to the optimized pb file
f = tf.gfile.FastGFile('optimized_advanced_mnist.pb', 'w')
f.write(output_graph_def.SerializeToString())
MainActivity
package com.example.owl.advanced_mnist_android;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.tensorflow.contrib.android.TensorFlowInferenceInterface;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
TextView resultsTextView;
static {
System.loadLibrary("tensorflow_inference");
}
private static final String MODEL_FILE = "file:///android_asset/optimized_advanced_mnist.pb";
private static final String INPUT_NODE = "x_input";
private static final int[] INPUT_SIZE = {1, 784};
private static final String KEEP_PROB = "keep_prob";
private static final int[] KEEP_PROB_SIZE = {1};
private static final String OUTPUT_NODE = "y_readout1";
private TensorFlowInferenceInterface inferenceInterface;
private int imageIndex = 10;
private int[] imageResourceIDs = {
R.drawable.digit0,
R.drawable.digit1,
R.drawable.digit2,
R.drawable.digit3,
R.drawable.digit4,
R.drawable.digit5,
R.drawable.digit6,
R.drawable.digit7,
R.drawable.digit8,
R.drawable.digit9,
R.drawable.rsz_przechwytywanie,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.image_view);
resultsTextView = (TextView) findViewById(R.id.results_text_view);
inferenceInterface = new TensorFlowInferenceInterface();
inferenceInterface.initializeTensorFlow(getAssets(), MODEL_FILE);
}
public void loadImageAction(View view) {
imageIndex = (imageIndex == 10) ? 0 : imageIndex + 1 ;
imageView.setImageResource(imageResourceIDs[imageIndex]);
}
public void predictDigitAction(View view) {
float[] pixelBuffer = convertImage();
float[] results = predictDigit(pixelBuffer);
formatResults(results);
}
private void formatResults(float[] results) {
float max = 0;
float secondMax = 0;
int maxIndex = 0;
int secondMaxIndex = 0;
for (int i = 0; i < 15; i++) {
if (results[i] > max) {
secondMax = max;
secondMaxIndex = maxIndex;
max = results[i];
maxIndex = i;
} else if (results[i] < max && results[i] > secondMax) {
secondMax = results[i];
secondMaxIndex = i;
}
}
String output = "Model predicts: " + String.valueOf(maxIndex) +
", second choice: " + String.valueOf(secondMaxIndex);
resultsTextView.setText(output);
}
private float[] predictDigit(float[] pixelBuffer) {
inferenceInterface.fillNodeFloat(INPUT_NODE, INPUT_SIZE, pixelBuffer);
inferenceInterface.fillNodeFloat(KEEP_PROB, KEEP_PROB_SIZE, new float[] {0.5f});
inferenceInterface.runInference(new String[] {OUTPUT_NODE});
float[] outputs = new float[14];
inferenceInterface.readNodeFloat(OUTPUT_NODE, outputs);
return outputs;
}
private float[] convertImage() {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imageResourceIDs[imageIndex]);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, 28, 28, true);
imageView.setImageBitmap(scaledBitmap);
int[] intArray = new int[784];
float[] floatArray = new float[784];
scaledBitmap.getPixels(intArray, 0, 28, 0, 0, 28, 28);
for (int i = 0; i < 784; i++) {
floatArray[i] = intArray[i] / -16777216;
}
return floatArray;
}
}
Everything looks good, but I have an error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.owl.advanced_mnist_android, PID: 6855
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:6891)
at android.widget.TextView.performClick(TextView.java:12651)
at android.view.View$PerformClick.run(View.java:26083)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6891)
at android.widget.TextView.performClick(TextView.java:12651)
at android.view.View$PerformClick.run(View.java:26083)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.IllegalArgumentException: No Operation named [x_input] in the Graph
at org.tensorflow.Session$Runner.operationByName(Session.java:297)
at org.tensorflow.Session$Runner.feed(Session.java:115)
at org.tensorflow.contrib.android.TensorFlowInferenceInterface.addFeed(TensorFlowInferenceInterface.java:437)
at org.tensorflow.contrib.android.TensorFlowInferenceInterface.fillNodeFloat(TensorFlowInferenceInterface.java:186)
at com.example.owl.advanced_mnist_android.MainActivity.predictDigit(MainActivity.java:89)
at com.example.owl.advanced_mnist_android.MainActivity.predictDigitAction(MainActivity.java:63)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6891)
at android.widget.TextView.performClick(TextView.java:12651)
at android.view.View$PerformClick.run(View.java:26083)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
I have developed a Tensorflow model with python in Linux based on the tutorial here: "http://cv-tricks.com/tensorflow-tutorial/training-convolutional-neural-network-for-image-classification/". I trained and saved the model using "tf.train.Saver". I am able to deploy the model in Linux environment and perform prediction successfully. Now I need to be able to load this saved model in JAVA on WINDOWS. Through extensive research online I have read that it does not work with "tf.train.Saver" and I have to change my code to use "Serving" to be able to load a saved TF model in java! Therefore, I followed the tutorial here:
"https://github.com/tensorflow/serving/blob/master/tensorflow_serving/example/mnist_saved_model.py
" and changed my code. However, I have an error with "tf.FixedLenFeature" where it is asking me to use "FixedLenSequenceFeature". Here is the complete error message:
"ValueError: First dimension of shape for feature x unknown. Consider using FixedLenSequenceFeature."
which is happening here:
feature_configs = {'x': tf.FixedLenFeature(shape=[None, img_size,img_size,num_channels], dtype=tf.float32),}
I am not sure this is the right path to go since I have batch of images of size [batchsize*128*128*3] and should not be using the sequence feature! It would be great if someone could clear this out for me and answer these questions:
1- Do I have to change my code from "tf.train.Saver" to "serving" to be able to load the saved model and deploy it in JAVA?
2- If the answer to the above question is yes, how can I feed the data correctly and solve the aforementioned ERROR?
3- Is there any example of how to DEPLOY the model that was saved using "serving"?
Here is my training code that throws the error:
import dataset
import tensorflow as tf
import time
from datetime import timedelta
import math
import random
import numpy as np
import os
#Adding Seed so that random initialization is consistent
from numpy.random import seed
seed(1)
from tensorflow import set_random_seed
set_random_seed(2)
batch_size = 32
#Prepare input data
classes = ['class1','class2','class3']
num_classes = len(classes)
# 20% of the data will automatically be used for validation
validation_size = 0.2
img_size = 128
num_channels = 3
train_path='/home/user1/Downloads/Expression/Augmented/Data/Train'
# We shall load all the training and validation images and labels into memory using openCV and use that during training
data = dataset.read_train_sets(train_path, img_size, classes, validation_size=validation_size)
print("Complete reading input data. Will Now print a snippet of it")
print("Number of files in Training-set:\t\t{}".format(len(data.train.labels)))
print("Number of files in Validation-set:\t{}".format(len(data.valid.labels)))
session = tf.Session()
serialized_tf_example = tf.placeholder(tf.string, name='tf_example')
feature_configs = {'x': tf.FixedLenFeature(shape=[None, img_size,img_size,num_channels], dtype=tf.float32),}
tf_example = tf.parse_example(serialized_tf_example, feature_configs)
x = tf.identity(tf_example['x'], name='x') # use tf.identity() to assign name
# x = tf.placeholder(tf.float32, shape=[None, img_size,img_size,num_channels], name='x')
## labels
y_true = tf.placeholder(tf.float32, shape=[None, num_classes], name='y_true')
y_true_cls = tf.argmax(y_true, dimension=1)
##Network graph params
filter_size_conv1 = 3
num_filters_conv1 = 32
filter_size_conv2 = 3
num_filters_conv2 = 32
filter_size_conv3 = 3
num_filters_conv3 = 64
fc_layer_size = 128
def create_weights(shape):
return tf.Variable(tf.truncated_normal(shape, stddev=0.05))
def create_biases(size):
return tf.Variable(tf.constant(0.05, shape=[size]))
def create_convolutional_layer(input,
num_input_channels,
conv_filter_size,
num_filters):
## We shall define the weights that will be trained using create_weights function.
weights = create_weights(shape=[conv_filter_size, conv_filter_size, num_input_channels, num_filters])
## We create biases using the create_biases function. These are also trained.
biases = create_biases(num_filters)
## Creating the convolutional layer
layer = tf.nn.conv2d(input=input,
filter=weights,
strides=[1, 1, 1, 1],
padding='SAME')
layer += biases
## We shall be using max-pooling.
layer = tf.nn.max_pool(value=layer,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1],
padding='SAME')
## Output of pooling is fed to Relu which is the activation function for us.
layer = tf.nn.relu(layer)
return layer
def create_flatten_layer(layer):
#We know that the shape of the layer will be [batch_size img_size img_size num_channels]
# But let's get it from the previous layer.
layer_shape = layer.get_shape()
## Number of features will be img_height * img_width* num_channels. But we shall calculate it in place of hard-coding it.
num_features = layer_shape[1:4].num_elements()
## Now, we Flatten the layer so we shall have to reshape to num_features
layer = tf.reshape(layer, [-1, num_features])
return layer
def create_fc_layer(input,
num_inputs,
num_outputs,
use_relu=True):
#Let's define trainable weights and biases.
weights = create_weights(shape=[num_inputs, num_outputs])
biases = create_biases(num_outputs)
# Fully connected layer takes input x and produces wx+b.Since, these are matrices, we use matmul function in Tensorflow
layer = tf.matmul(input, weights) + biases
if use_relu:
layer = tf.nn.relu(layer)
return layer
layer_conv1 = create_convolutional_layer(input=x,
num_input_channels=num_channels,
conv_filter_size=filter_size_conv1,
num_filters=num_filters_conv1)
layer_conv2 = create_convolutional_layer(input=layer_conv1,
num_input_channels=num_filters_conv1,
conv_filter_size=filter_size_conv2,
num_filters=num_filters_conv2)
layer_conv3= create_convolutional_layer(input=layer_conv2,
num_input_channels=num_filters_conv2,
conv_filter_size=filter_size_conv3,
num_filters=num_filters_conv3)
layer_flat = create_flatten_layer(layer_conv3)
layer_fc1 = create_fc_layer(input=layer_flat,
num_inputs=layer_flat.get_shape()[1:4].num_elements(),
num_outputs=fc_layer_size,
use_relu=True)
layer_fc2 = create_fc_layer(input=layer_fc1,
num_inputs=fc_layer_size,
num_outputs=num_classes,
use_relu=False)
y_pred = tf.nn.softmax(layer_fc2,name='y_pred')
y_pred_cls = tf.argmax(y_pred, dimension=1)
values, indices = tf.nn.top_k(y_pred, 3)
table = tf.contrib.lookup.index_to_string_table_from_tensor(
tf.constant([str(i) for i in xrange(3)]))
prediction_classes = table.lookup(tf.to_int64(indices))
session.run(tf.global_variables_initializer())
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=layer_fc2,
labels=y_true)
cost = tf.reduce_mean(cross_entropy)
optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cost)
correct_prediction = tf.equal(y_pred_cls, y_true_cls)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
session.run(tf.global_variables_initializer())
def show_progress(epoch, feed_dict_train, feed_dict_validate, val_loss):
acc = session.run(accuracy, feed_dict=feed_dict_train)
val_acc = session.run(accuracy, feed_dict=feed_dict_validate)
msg = "Training Epoch {0} --- Training Accuracy: {1:>6.1%}, Validation Accuracy: {2:>6.1%}, Validation Loss: {3:.3f}"
print(msg.format(epoch + 1, acc, val_acc, val_loss))
total_iterations = 0
# saver = tf.train.Saver()
def train(num_iteration):
global total_iterations
for i in range(total_iterations,
total_iterations + num_iteration):
x_batch, y_true_batch, _, cls_batch = data.train.next_batch(batch_size)
x_valid_batch, y_valid_batch, _, valid_cls_batch = data.valid.next_batch(batch_size)
feed_dict_tr = {x: x_batch,
y_true: y_true_batch}
feed_dict_val = {x: x_valid_batch,
y_true: y_valid_batch}
session.run(optimizer, feed_dict=feed_dict_tr)
if i % int(data.train.num_examples/batch_size) == 0:
print(i)
val_loss = session.run(cost, feed_dict=feed_dict_val)
epoch = int(i / int(data.train.num_examples/batch_size))
show_progress(epoch, feed_dict_tr, feed_dict_val, val_loss)
print("Saving the model Now!")
# saver.save(session, save_path_full, global_step=i)
total_iterations += num_iteration
train(num_iteration=10000)#3000
# Export model
# WARNING(break-tutorial-inline-code): The following code snippet is
# in-lined in tutorials, please update tutorial documents accordingly
# whenever code changes.
export_path_base = './SavedModel/'
export_path = os.path.join(
tf.compat.as_bytes(export_path_base),
tf.compat.as_bytes(str(1)))
print 'Exporting trained model to', export_path
builder = tf.saved_model.builder.SavedModelBuilder(export_path)
# Build the signature_def_map.
classification_inputs = tf.saved_model.utils.build_tensor_info(
serialized_tf_example)
classification_outputs_classes = tf.saved_model.utils.build_tensor_info(
prediction_classes)
classification_outputs_scores = tf.saved_model.utils.build_tensor_info(values)
classification_signature = (
tf.saved_model.signature_def_utils.build_signature_def(
inputs={
tf.saved_model.signature_constants.CLASSIFY_INPUTS:
classification_inputs
},
outputs={
tf.saved_model.signature_constants.CLASSIFY_OUTPUT_CLASSES:
classification_outputs_classes,
tf.saved_model.signature_constants.CLASSIFY_OUTPUT_SCORES:
classification_outputs_scores
},
method_name=tf.saved_model.signature_constants.CLASSIFY_METHOD_NAME))
tensor_info_x = tf.saved_model.utils.build_tensor_info(x)
tensor_info_y = tf.saved_model.utils.build_tensor_info(y_pred)
prediction_signature = (
tf.saved_model.signature_def_utils.build_signature_def(
inputs={'images': tensor_info_x},
outputs={'scores': tensor_info_y},
method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME))
legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op')
builder.add_meta_graph_and_variables(
sess, [tf.saved_model.tag_constants.SERVING],
signature_def_map={
'predict_images':
prediction_signature,
tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
classification_signature,
},
legacy_init_op=legacy_init_op)
builder.save()
print 'Done exporting!'
I am trying to convert a python class into Java byte code with Jython (on mac osx lion)
./jython -m compileall /Users/owengerig/Downloads/Code\
Downloads/cryptPYTHON.py
but get this error, which gives no indication of whats wrong
Listing /Users/owengerig/Downloads/Code Downloads/cryptPYTHON.py ...
Can't list /Users/owengerig/Downloads/Code Downloads/cryptPYTHON.py
How my python class is setup (used this post as example):
from Crypto.Cipher import AES
import base64
import os
class Crypticle(CryptInterface):
"""Authenticated encryption class
* #param string $key base64-encoded encryption key
* #param integer $key_len length of raw key in bits
Encryption algorithm: AES-CBC
Signing algorithm: HMAC-SHA256
"""
AES_BLOCK_SIZE = 16
#JAVA
def __init__(self, key_string, key_size=192):
assert not key_size % 8
self.key = self.extract_key(key_string, key_size)
self.key_size = key_size
#classmethod
def generate_key_string(cls, key_size=192):
key = os.urandom(key_size / 8)
return base64.urlsafe_b64encode(str(key))
#classmethod
def extract_key(cls, key_string, key_size):
key = base64.urlsafe_b64decode(str(key_string))
assert len(key) == key_size / 8, "invalid key"
return key
#JAVA(String, String)
def encrypt(self, data):
"""encrypt data with AES-CBC"""
aes_key = self.key
pad = self.AES_BLOCK_SIZE - len(data) % self.AES_BLOCK_SIZE
data = data + pad * chr(pad)
iv_bytes = os.urandom(self.AES_BLOCK_SIZE)
cypher = AES.new(aes_key, AES.MODE_CBC, iv_bytes)
data = iv_bytes + cypher.encrypt(data)
data_str = base64.urlsafe_b64encode(str(data))
return data_str
#JAVA(String, String)
def decrypt(self, data_str):
"""decrypt data with AES-CBC"""
aes_key = self.key
data = base64.urlsafe_b64decode(data_str)
iv_bytes = data[:self.AES_BLOCK_SIZE]
data = data[self.AES_BLOCK_SIZE:]
cypher = AES.new(aes_key, AES.MODE_CBC, iv_bytes)
data = cypher.decrypt(data)
return data[:-ord(data[-1])]
Also tried this code (per comments below) but go the same error:
class Employee(Object):
def __init__(self):
self.first = "Josh"
self.last = "Juneau"
self.id = "myempid"
def getEmployeeFirst(self):
return self.first
def getEmployeeLast(self):
return self.last
def getEmployeeId(self):
return self.id
-m compileall takes a directory, not a filename. So you need to execute the following:
./jython -m compileall /Users/owengerig/Downloads/Code\ Downloads/
Long Explanation
If you open jythondirectory/Lib/compileall.py:
try:
names = os.listdir(dir)
except os.error:
print "Can't list", dir
names = []
os.listdir() throws an error if it isn't passed a directory as its argument. Since this is the function used to compile the command-line arguments, and the main() function does not check if the arguments are directories, this will fail.
for dir in args:
if not compile_dir(dir, maxlevels, ddir,
force, rx, quiet):
success = 0
/Long Explanation