mxnet model convert to onnx success but ort.InferenceSession(model) failed - mxnet

Ask a Question
I success convert mxnet model to onnx but it failed when inference .The model 's shape is (1,1,100,100)
convert code
sym = 'single-symbol.json'
params = '/single-0090.params'
input_shape = (1, 1, 100, 100)
onnx_file = './model.onnx'
converted_model_path = onnx_mxnet.export_model(sym, params, [input_shape], np.float32, onnx_file,verbose=True)
model= onnx.load_model(converted_model_path)
checker.check_graph(model.graph)
checker.check_model(model)
output
INFO:root:Input shape of the model [(1, 1, 100, 100)]
INFO:root:Exported ONNX file ./model.onnx saved to disk
inference code
sess = ort.InferenceSession("./model.onnx")
output
onnxruntime.capi.onnxruntime_pybind11_state.RuntimeException:
[ONNXRuntimeError] : 6 : RUNTIME_EXCEPTION :
Exception during initialization:
/onnxruntime/core/providers/cpu/nn/pool_attributes.h:77
onnxruntime::PoolAttributes::PoolAttributes(const OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext> &,
const std::string &, int) pads[dim] < kernel_shape[dim] &&
pads[dim + kernel_shape.size()] < kernel_shape[dim] was false.
Pad should be smaller than kernel.
Question
mxnet pooling node json
{
"op": "Pooling",
"name": "pool1_fwd",
"attrs": {
"count_include_pad": "True",
"global_pool": "False",
"kernel": "(4, 4)",
"layout": "NCHW",
"pad": "(4, 4)",
"pool_type": "avg",
"pooling_convention": "valid",
"stride": "(4, 4)"
},
"inputs": [[46, 0, 0]]
}
I change the "pad": "(4, 4)" to "pad": "(3, 3)" smaller than "kernel": "(4, 4), then try convert again.
sess = ort.InferenceSession("./model.onnx")
output = sess.run(None, {"data": data.astype(np.float32)})
it worked,but the output value is not right.
how to fix it ?
BTW:convert the mxnet model to ncnn all is right(not change anything,pad=(4,4),kernel=(4,4))
Further information
python:3.8
onnx:1.10.2
mxnet:1.8.0

I fix it,recode model by pytorch and copy weights,use nn.ZeroPad2d(4) before avgpooling:
self.pad = nn.ZeroPad2d(4)
self.pool = nn.AvgPool2d(kernel_size=(4,4),stride=(4,4))
X = self.pool(self.pad(self.conv(X)))

Related

tensorflow2 how to print tensor value

I try to print the actual value of the tensor which is loaded from my custom tfds dataset.
I can't figure out how to do it. I am using Tensorflow2 so the session is no longer encouraged.
I tried using .numpy() tf.print. tf.executing.eagerly() but nothing works. It either prints
just the tensor object showing me the shape or in case of .numpy() it throws the error in the title.
I need the value of tensors and I need to bring it back to numpy in order to debugg the code.
This is how I create the dataset:
class dt(tfds.core.GeneratorBasedBuilder):
''' Dataset builder'''
# DOuble check
VERSION = tfds.core.Version('1.0.0')
RELEASE_NOTES = {
'1.0.0': 'Initial release.',
}
def _info(self) ->tfds.core.DatasetInfo:
'''Dataset metadata'''
return tfds.core.DatasetInfo(
builder=self,
features=tfds.features.FeaturesDict({
"id": tf.int64,
"image": tfds.features.Image(shape=(IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), encoding_format='png'),
"mask": tfds.features.Image(shape=(IMG_HEIGHT, IMG_WIDTH, 1), encoding_format='png'),
"label": tfds.features.ClassLabel(names=CLASSES),
}),
supervised_keys=('image', 'mask')
)
def _split_generators(self, dl_manager: tfds.download.DownloadManager):
'''Splitgenerator for train and test splits'''
path = DATASETS_ROOT
return {
"train": self._generate_examples(
images_path=os.path.join(path, "train/rgb"),
masks_path=os.path.join(path, "train/masks")
),
"test": self._generate_examples(
images_path=os.path.join(path, "test/rgb"),
masks_path=os.path.join(path, "test/masks")
)
}
def _generate_examples(self, images_path, masks_path):
'''Generator of examples for each split'''
for i, (image, mask) in enumerate(zip(glob.glob(images_path + "/*.png"), glob.glob(masks_path + "/*.png"))):
yield i, {
"id": i,
"image": image,
"mask": mask,
"label": CLASSES[3],
}
This is how I try to extract the numpy array
def custom_load_X_Y(training=True):
if training:
dt, dt_info = tfds.load("dt", split="train", shuffle_files=True, as_supervised=True, with_info=True)
print(f'EAGERLY {tf.executing_eagerly()}')
print(f'MOde type {type(dt)}')
tf.print(f"aaaaa {dt.numpy()} aaaaaa")
Console output:
Console output
You can print the image dataset by using tfds.show_examples()
import tensorflow_datasets as tfds
ds, ds_info = tfds.load('cifar10', split='train', with_info=True)
fig = tfds.show_examples(ds, ds_info)
output:
For more details please refer to this gist.Thank You.

tensorflow 2.8 dataset get single element error

I would like to use "get_single_element" to get the one batch dataset as dict. The keys in dict are features names. The values are values.
My code is in tf2.8 on EC2 instance and run from jupyter.
import pandas as pd
import tensorflow as tf
df = pd.DataFrame({
'id': [1, 2, 6, 3, 5, 0],
'value_1': [10.892561, 7.210528, 1.2278101, -9.251782, 0.2118367, 6.9128551],
'value_2': ['large', 'small', 'mid','small','large', 'mid'],
'name_1': ['tyne', 'wnhp', 'ebhg','lpzhn','tyne', 'ebhg'],
'label': [0, 1, 0, 1, 1, 1]
})
dataset = tf.data.Dataset.from_tensor_slices(dict(df))
dataset = dataset.batch(2)
print(type(dataset))
print(dataset)
print(len(dataset))
class Features(object):
feature_data = {
"id": tf.io.FixedLenFeature((1,), dtype=tf.int8),
"value_1": tf.io.VarLenFeature(dtype=tf.float32),
"value_2": tf.io.FixedLenFeature((1,), dtype=tf.string),
"name_1": tf.io.FixedLenFeature((1,), dtype=tf.string)
}
label_data = {"label": tf.io.FixedLenFeature((1,), dtype=tf.int8)}
def process_sample(ds):
print(f"ds type is {type(ds)}")
features = tf.io.parse_single_example(ds, Features.feature_data) # error !
labels = tf.io.parse_single_example(ds, Features.label_data)['label']
return (features, labels)
dataset = dataset.map(lambda x: process_sample(x), num_parallel_calls=tf.data.AUTOTUNE)
dataset = tf.data.Dataset.get_single_element(dataset.batch(len(dataset)))
print(f"dataset type is {type(dataset)} dataset is {dataset}")
def get_dict(input_ds):
feature_dict_tensors = dict(input_ds)
print(f"\feature_dict_tensors type is {type(feature_dict_tensors)}, feature_dict_tensors is {feature_dict_tensors}")
return feature_dict_tensors
ds = dataset.map(get_dict)
print(f"ds type is {type(ds)}")
print(ds)
I got error:
File "<ipython-input-4-e9407f42e0a7>", line 37, in None *
lambda x: process_sample(x), num_parallel_calls=tf.data.AUTOTUNE)
File "<ipython-input-4-e9407f42e0a7>", line 33, in process_sample *
features = tf.io.parse_single_example(ds, Features.feature_data)
TypeError: Expected any non-tensor type, but got a tensor instead.
Based on https://www.tensorflow.org/api_docs/python/tf/io/parse_single_example, the first argument should be
A scalar string Tensor, a single serialized Example.
Why I got this error ?
thanks

How can i use 38 classes instead of 1000 in model.predict decode predictions

i am founding an error in plant disease detection using resnet50 deep learning model every time it raises an error message in decode_predictions
error
expects a batch of predictions (i.e. a 2D array of shape (samples, 1000)). Found array with shape: (1, 38)"
enter code here
model = ResNet50(weights='imagenet',include_top=False,classes=38)
try:
model = load_model('/content/drive/My
Drive/color/checkpoints/ResNet50_model_weights.h5')
print("model loaded")
except:
print("model not loaded")
img_path = '/content/drive/My Drive/color/test/0/appleblackrot188.jpg'
img = image.load_img(img_path, target_size=(300, 300))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = model.predict(x)
print('Predicted:', decode_predictions(preds,top=3)[0])
You can try using the preprocesing function:
import tensorflow as tf
# Using the keras wrapper on tensorflow (it must be the same using just keras).
IMAGE = [] # From image source, i did it from the camera.
toPred = tf.keras.applications.resnet50.preprocess_input(np.expand_dims(tf.keras.preprocessing.image.img_to_array(IMAGE), axis=0))
Maybe that can help :)
decode_predictions works only for ImageNet (no. of classes = 1000). For these 38 classes of plants, you have to write your own decode predictions based on the ground truth label you've assigned for each plant.
First, you need an index JSON file and create a new decode_predictions function.
For example
This HAM10000 that has 7 classes and you need to split to each folder like this
then make an index JSON file like this
{
"0" : [
"AKIEC",
"akiec"
],
"1" : [
"BCC",
"bcc"
],
"2" : [
"BKL",
"bkl"
],
"3" : [
"DF",
"df"
],
"4" : [
"MEL",
"mel"
],
"5" : [
"NV",
"nv"
],
"6" : [
"VASC",
"vasc"
]
}
Then try this code
def decode_predictions(preds, top=4, class_list_path='/content/SKIN_DATA/HAM10000_index.json'):
if len(preds.shape) != 2 or preds.shape[1] != 7: # your classes number
raise ValueError('`decode_predictions` expects '
'a batch of predictions '
'(i.e. a 2D array of shape (samples, 1000)). '
'Found array with shape: ' + str(preds.shape))
index_list = json.load(open(class_list_path))
results = []
for pred in preds:
top_indices = pred.argsort()[-top:][::-1]
result = [tuple(index_list[str(i)]) + (pred[i],) for i in top_indices]
result.sort(key=lambda x: x[2], reverse=True)
results.append(result)
return results

Error Processing Input for GCP ML Engine Prediction

I have a TensorFlow model on GCP ML Engine, however I have a problem with the JSON string below:
from googleapiclient import discovery
from oauth2client.client import GoogleCredentials
import json
credentials = GoogleCredentials.get_application_default()
api = discovery.build('ml', 'v1', credentials=credentials,
discoveryServiceUrl='https://storage.googleapis.com/cloud-ml/discovery/ml_v1_discovery.json')
request_data = {'instances':
[{
'inputs':{
'clump_thickness': 2,
'size_uniformity': 1,
'shape_uniformity': 1,
'marginal_adhesion': 1,
'epithelial_size': 2,
'bland_chromatin': 1,
'bare_nucleoli': 2,
'normal_nucleoli': 1,
'mitoses': 1
}
}]
}
parent = 'projects/%s/models/%s/versions/%s' % (PROJECT,
'breastCancer_optimized_06152018_2_2_a', 'v1')
response = api.projects().predict(body=request_data, name=parent).execute()
print(response)
I get the following error:
{'error': "Prediction failed: Error processing input: Expected string, got {u'epithelial_size': 2, u'marginal_adhesion': 1, u'clump_thickness': 2, u'size_uniformity': 1, u'shape_uniformity': 1, u'normal_nucleoli': 1, u'mitoses': 1, u'bland_chromatin': 1, u'bare_nucleoli': 2} of type 'dict' instead."}
I can't seem to format request_data properly. Does anyone see what is wrong?
original serving function:
clump_thickness = tf.feature_column.numeric_column("clump_thickness");
size_uniformity = tf.feature_column.numeric_column("size_uniformity");
shape_uniformity = tf.feature_column.numeric_column("shape_uniformity");
marginal_adhesion = tf.feature_column.numeric_column("marginal_adhesion");
epithelial_size = tf.feature_column.numeric_column("epithelial_size");
bare_nucleoli = tf.feature_column.numeric_column("bare_nucleoli");
bland_chromatin = tf.feature_column.numeric_column("bland_chromatin");
normal_nucleoli = tf.feature_column.numeric_column("normal_nucleoli");
mitoses = tf.feature_column.numeric_column("mitoses");
feature_columns = [clump_thickness, size_uniformity, shape_uniformity, marginal_adhesion, epithelial_size,
bare_nucleoli, bland_chromatin, normal_nucleoli, mitoses];
feature_spec = tf.feature_column.make_parse_example_spec(feature_columns);
export_input_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(feature_spec);
estimator.export_savedmodel(output_dir, export_input_fn, as_text=False)
Then I tried:
def serving_input_fn():
feature_placeholders = {
'clump_thickness' : tf.placeholder(tf.float32, [None]),
'size_uniformity' : tf.placeholder(tf.float32, [None]),
'shape_uniformity' : tf.placeholder(tf.float32, [None]),
'marginal_adhesion' : tf.placeholder(tf.float32, [None]),
'epithelial_size' : tf.placeholder(tf.float32, [None]),
'bare_nucleoli' : tf.placeholder(tf.float32, [None]),
'bland_chromatin' : tf.placeholder(tf.float32, [None]),
'normal_nucleoli' : tf.placeholder(tf.float32, [None]),
'mitoses' : tf.placeholder(tf.float32, [None]),
}
features = feature_placeholders # no transformation needed
return tf.estimator.export.ServingInputReceiver(features, feature_placeholders)
And in the train_and_eval function:
estimator.export_savedmodel(output_dir, serving_input_fn, as_text=False)
But now I get the following error:
{'error': "Prediction failed: Expected tensor name: inputs, got tensor name: [u'epithelial_size', u'marginal_adhesion', u'clump_thickness', u'size_uniformity', u'shape_uniformity', u'normal_nucleoli', u'mitoses', u'bland_chromatin', u'bare_nucleoli']."}
The estimator.export_savedmodel appears to create a model which requires a tensor input(in the request_data line).
When I use the model created with either serving function the following works fine:
predict_fn = tf.contrib.predictor.from_saved_model("gs://test-
203900/breastCancer_optimized_06182018/9/1529432417")
# Test inputs represented by Pandas DataFrame.
inputs = pd.DataFrame({
'clump_thickness': [2,5,4],
'size_uniformity': [1,10,8],
'shape_uniformity': [1,10,6],
'marginal_adhesion': [1,3,4],
'epithelial_size': [2,7,3],
'bland_chromatin': [1,3,4],
'bare_nucleoli': [2,8,10],
'normal_nucleoli': [1,10,6],
'mitoses': [1,2,1],
})
# Convert input data into serialized Example strings.
examples = []
for index, row in inputs.iterrows():
feature = {}
for col, value in row.iteritems():
feature[col] =
tf.train.Feature(float_list=tf.train.FloatList(value=[value]))
example = tf.train.Example(
features=tf.train.Features(
feature=feature
)
)
examples.append(example.SerializeToString())
# Make predictions.
predictions = predict_fn({'inputs': examples})
It depends on what your serving input function is. It appears from the error message that 'inputs' needs to be a string (maybe comma-separated?)
Try this:
saved_model_cli show --dir $MODEL_LOCATION --tag_set serve --signature_def serving_default
It will tell you what your serving input function is set to.
I suspect that what you want is for your serving input function to be:
def serving_input_fn():
feature_placeholders = {
'size_uniformity' : tf.placeholder(tf.float32, [None]),
'shape_uniformity' : tf.placeholder(tf.float32, [None])
}
features = feature_placeholders # no transformation needed
return tf.estimator.export.ServingInputReceiver(features, feature_placeholders)
and for your input format to be:
request_data = {'instances':
[
{
'size_uniformity': 1,
'shape_uniformity': 1
}
]
}

Trouble setting up the SimpleVector encoder

Using the commits from breznak for the encoders (I wasn't able to figure out "git checkout ..." with GitHub, so I just carefully copied over the three files - base.py, multi.py, and multi_test.py).
I ran multi_test.py without any problems.
Then I adjusted my model parameters (MODEL_PARAMS), so that the encoders portion of 'sensorParams' looks like this:
'encoders': {
'frequency': {
'fieldname': u'frequency',
'type': 'SimpleVector',
'length': 5,
'minVal': 0,
'maxVal': 210
}
},
I also adjusted the modelInput portion of my code, so it looked like this:
model = ModelFactory.create(model_params.MODEL_PARAMS)
model.enableInference({'predictedField': 'frequency'})
y = [1,2,3,4,5]
modelInput = {"frequency": y}
result = model.run(modelInput)
But I get the final error, regardless if I instantiate 'y' as a list or a numpy.ndarray
File "nta/eng/lib/python2.7/site-packages/nupic/encoders/base.py", line 183, in _getInputValue
return getattr(obj, fieldname)
AttributeError: 'list' object has no attribute 'idx0'
I also tried initializing a SimpleVector encoder inline with my modelInput, directly encoding my array, then passing it through modelInput. That violated the input parameters of my SimpleVector, because I was now double encoding. So I removed the encoders portion of my model parameters dictionary. That caused a spit up, because some part of my model was looking for that portion of the dictionary.
Any suggestions on what I should do next?
Edit: Here're the files I'm using with the OPF.
sendAnArray.py
import numpy
from nupic.frameworks.opf.modelfactory import ModelFactory
import model_params
class sendAnArray():
def __init__(self):
self.model = ModelFactory.create(model_params.MODEL_PARAMS)
self.model.enableInference({'predictedField': 'frequency'})
for i in range(100):
self.run()
def run(self):
y = [1,2,3,4,5]
modelInput = {"frequency": y}
result = self.model.run(modelInput)
anomalyScore = result.inferences['anomalyScore']
print y, anomalyScore
sAA = sendAnArray()
model_params.py
MODEL_PARAMS = {
'model': "CLA",
'version': 1,
'predictAheadTime': None,
'modelParams': {
'inferenceType': 'TemporalAnomaly',
'sensorParams': {
'verbosity' : 0,
'encoders': {
'frequency': {
'fieldname': u'frequency',
'type': 'SimpleVector',
'length': 5,
'minVal': 0,
'maxVal': 210
}
},
'sensorAutoReset' : None,
},
'spEnable': True,
'spParams': {
'spVerbosity' : 0,
'globalInhibition': 1,
'columnCount': 2048,
'inputWidth': 5,
'numActivePerInhArea': 60,
'seed': 1956,
'coincInputPoolPct': 0.5,
'synPermConnected': 0.1,
'synPermActiveInc': 0.1,
'synPermInactiveDec': 0.01,
},
'tpEnable' : True,
'tpParams': {
'verbosity': 0,
'columnCount': 2048,
'cellsPerColumn': 32,
'inputWidth': 2048,
'seed': 1960,
'temporalImp': 'cpp',
'newSynapseCount': 20,
'maxSynapsesPerSegment': 32,
'maxSegmentsPerCell': 128,
'initialPerm': 0.21,
'permanenceInc': 0.1,
'permanenceDec' : 0.1,
'globalDecay': 0.0,
'maxAge': 0,
'minThreshold': 12,
'activationThreshold': 16,
'outputType': 'normal',
'pamLength': 1,
},
'clParams': {
'regionName' : 'CLAClassifierRegion',
'clVerbosity' : 0,
'alpha': 0.0001,
'steps': '5',
},
'anomalyParams': {
u'anomalyCacheRecords': None,
u'autoDetectThreshold': None,
u'autoDetectWaitRecords': 2184
},
'trainSPNetOnlyIfRequested': False,
},
}
The problem seems to be that the SimpleVector class is accepting an array instead of a dict as its input, and then reconstructs that internally as {'list': {'idx0': 1, 'idx1': 2, ...}} (ie as if this dict had been the input). This is fine if it is done consistently, but your error shows that it's broken down somewhere. Have a word with #breznak about this.
Working through the OPF was difficult. I wanted to input an array of indices into the temporal pooler, so I opted to interface directly with the algorithms (I relied heavy on hello_tp.py). I ignored SimpleVector all together, and instead worked through the BitmapArray encoder.
Subutai has a useful email on the nupic-discuss listserve, where he breaks down the three main areas of the NuPIC API: algorithms, networks/regions, & the OPF. That helped me understand my options better.