otbtf issueshttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues2022-06-10T10:38:22+02:00https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/27Notes on how create quantized models2022-06-10T10:38:22+02:00Cresson RemiNotes on how create quantized modelsfrom `test_graph_transform` branch
```
python /opt/otbtf/lib/python3.8/site-packages/tensorflow/python/tools/freeze_graph.py --input_saved_model_dir sr4rs_sentinel2_bands4328_france2020_savedmodel --output_node_names "output_64" --outp...from `test_graph_transform` branch
```
python /opt/otbtf/lib/python3.8/site-packages/tensorflow/python/tools/freeze_graph.py --input_saved_model_dir sr4rs_sentinel2_bands4328_france2020_savedmodel --output_node_names "output_64" --output_graph sr4rs_graphdef.pb
/opt/otbtf/bin/graph_transforms/transform_graph --in_graph=sr4rs_graphdef.pb --out_graph=sr4rs_opt.pb --inputs="lr_input" --outputs="output_64" --transforms='add_default_attributes remove_nodes(op=CheckNumerics) fold_constants(ignore_errors=true) fold_batch_norms fold_old_batch_norms quantize_nodes(input_min=-1,input_max=1) strip_unused_nodes sort_by_execution_order'
rm -rf new_sm
python gd2sm.py
python sr4rs/code/sr.py --input image.tif --savedmodel new_sm/ --output hr.tif
```
With file `gd2sm.py`:
```python
import tensorflow as tf
from tensorflow.python.saved_model import signature_constants
from tensorflow.python.saved_model import tag_constants
version_str = tf.__version__
if int(version_str.split('.')[0]) == 2:
# tensorflow 2.x
del tf
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
# else tensorflow 1.x
export_dir = 'new_sm'
graph_pb = 'sr4rs_opt.pb'
builder = tf.saved_model.builder.SavedModelBuilder(export_dir)
with tf.gfile.GFile(graph_pb, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
sigs = {}
with tf.Session(graph=tf.Graph()) as sess:
tf.import_graph_def(graph_def, name="")
g = tf.get_default_graph()
values = g.get_tensor_by_name("lr_input:0")
predictions = g.get_tensor_by_name("output_64:0")
sigs[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY] = \
tf.saved_model.signature_def_utils.predict_signature_def(
{"lr_input": values}, {"output_64": predictions})
builder.add_meta_graph_and_variables(sess, [tag_constants.SERVING], signature_def_map=sigs)
builder.save()
```Cresson RemiCresson Remihttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/14Add TFRecords creation to OTBTF2022-05-10T12:13:39+02:00Narcon NicolasAdd TFRecords creation to OTBTFWe would need to define a new class TFRecord that handles all the dataset <-> tfrecord conversions. Inside `otbtf.py` ? Or we split `otbtf.py` into a python module:
```
otbtf
|───dataset.py
|───tfrecord.py
└───utils.py
```
Maybe add a m...We would need to define a new class TFRecord that handles all the dataset <-> tfrecord conversions. Inside `otbtf.py` ? Or we split `otbtf.py` into a python module:
```
otbtf
|───dataset.py
|───tfrecord.py
└───utils.py
```
Maybe add a method `to_tfrecords(out_dir)` inside Dataset class ?https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/8Support model with no-named inputs/outputs2021-11-23T19:53:49+01:00Narcon NicolasSupport model with no-named inputs/outputsOTBTF should handle a model that doesn't name inputs/outputs, e.g. a model created like that :
```python
import tensorflow as tf
# Input
x1 = tf.keras.Input(shape=[None, None, 4]) # [h, w, N]
x2 = tf.keras.Input(shape=[None, None, 4]) ...OTBTF should handle a model that doesn't name inputs/outputs, e.g. a model created like that :
```python
import tensorflow as tf
# Input
x1 = tf.keras.Input(shape=[None, None, 4]) # [h, w, N]
x2 = tf.keras.Input(shape=[None, None, 4]) # [h, w, N]
# Compute multiply
y = tf.math.multiply(x1, x2)
# Create model
model = tf.keras.Model(inputs=[x1, x2], outputs=y, name="multiply")
model.save("my_model_multiply")
```
When running `TensorflowModelServe`, the user could ommit the `source#.placeholder` and `output.names` argumentshttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/5Clang-format2022-07-21T15:58:09+02:00Cresson RemiClang-formatClang-format permet de formater le code c++.
On peur le lancer sur les fichiers `.hxx`, `.txx`, `.cxx`, `.h` de la façon suivante:
```
find . -regex '.*\.\(cxx\|hxx\|txx\|h\)' -exec clang-format -style=file -i {} \;
```
Il faut ajouter...Clang-format permet de formater le code c++.
On peur le lancer sur les fichiers `.hxx`, `.txx`, `.cxx`, `.h` de la façon suivante:
```
find . -regex '.*\.\(cxx\|hxx\|txx\|h\)' -exec clang-format -style=file -i {} \;
```
Il faut ajouter le fichier `.clang-format` qui définit les rêgles de formatage à la racine de otbtf (cf [celui d'OTB](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/blob/develop/.clang-format)).
J'ai essayé chez moi c'est pas mal du tout!https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/2Migration TF22022-03-07T19:18:58+01:00Narcon NicolasMigration TF2Commande utile pour visualiser un modèle .pb
```
saved_model_cli show --dir chemin/du/modele --tag_set serve --signature_def serving_default
```
### TF1
Les noms des noeuds sont du type `tower_0/s2_t`. On y accède via les nodes du Graph...Commande utile pour visualiser un modèle .pb
```
saved_model_cli show --dir chemin/du/modele --tag_set serve --signature_def serving_default
```
### TF1
Les noms des noeuds sont du type `tower_0/s2_t`. On y accède via les nodes du GraphDef
### TF2
Lors du parcours des nodes du GraphDef :
- Les noms des noeuds "inputs" sont du type `serving_default_s2_t`.
- Les noms des noeuds "outputs" sont du type `StatefulPartitionedCall`
A la place, il est plus pertinent de parcourir :
- `bundle.GetSignatures().at("serving_default").inputs()` qui est un mapping du type {"s2_t": node_info}
- `bundle.GetSignatures().at("serving_default").outputs()` qui est un mapping du type {"s2_t": node_info}
Ressources utiles :
- https://stackoverflow.com/a/64385815/13711499
- https://stackoverflow.com/questions/63181951/how-to-get-graph-or-graphdef-from-a-given-model
- https://stackoverflow.com/questions/58968918/accessing-input-and-output-tensors-of-a-tensorflow-2-0-savedmodel-via-the-c-apiNarcon NicolasNarcon Nicolashttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/1Complementary informations for GPU users2023-04-04T12:25:12+02:00Gaetano RaffaeleComplementary informations for GPU usersGreat job with the otftf docker suite, I grabbed the otbtf2.0:gpu docker and it really eases things up!
By the way, some additional information for gpu users might be included in the documentation, basically:
- the need to install the n...Great job with the otftf docker suite, I grabbed the otbtf2.0:gpu docker and it really eases things up!
By the way, some additional information for gpu users might be included in the documentation, basically:
- the need to install the nvidia-container-runtime package at the host level
- the need to specify the '--gpus' option when calling the container to make system gpus visible in the docker
Cheers!
Rafhttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/49Improve GDAL formats support2024-01-09T16:26:40+01:00Cresson RemiImprove GDAL formats support- zarr blosc compression
- geoparquet apache arrow
- libwebp- zarr blosc compression
- geoparquet apache arrow
- libwebphttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/48Bug with non overlapping multisources2023-10-06T12:41:07+02:00Cresson RemiBug with non overlapping multisourcespan="https://minio-api-dinamis.apps.okd.crocc.meso.umontpellier.fr/catalog/spot67/SPOT7_MS_202207121015304_SPOT7_P_202207121015304/COG_SPOT7_P_202207121015304_ORT_SPOT7_20220713_1331561rgekx3ul1x1g_1.tif"
xs="https://minio-api-dinamis.a...pan="https://minio-api-dinamis.apps.okd.crocc.meso.umontpellier.fr/catalog/spot67/SPOT7_MS_202207121015304_SPOT7_P_202207121015304/COG_SPOT7_P_202207121015304_ORT_SPOT7_20220713_1331561rgekx3ul1x1g_1.tif"
xs="https://minio-api-dinamis.apps.okd.crocc.meso.umontpellier.fr/catalog/spot67/SPOT7_MS_202207121015304_SPOT7_P_202207121015304/COG_SPOT7_MS_202207121015304_ORT_SPOT7_20220713_1331511awwhqclkre47_1.tif"
- rf 64
- rf 16
- ef 32
- spcsc 1https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/47Release 4.2.02023-09-12T22:12:48+02:00Cresson RemiRelease 4.2.0- [ ] release notes
- [ ] doc
- [ ] setup.py- [ ] release notes
- [ ] doc
- [ ] setup.pyhttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/46Add decloud in testing2023-08-26T21:34:11+02:00Cresson RemiAdd decloud in testinghttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/45Update docker image2023-08-22T20:11:23+02:00Cresson RemiUpdate docker imageIt looks like today's "CRC book" test failed, even we don't have changed OTB/TF versions.
To be investigated, maybe some change in python packages?It looks like today's "CRC book" test failed, even we don't have changed OTB/TF versions.
To be investigated, maybe some change in python packages?https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/44Add helpers for common preprocessing functions2023-08-22T20:11:23+02:00Cresson RemiAdd helpers for common preprocessing functionse.g.
```python
tf.one_hot(
tf.squeeze(tf.cast(sample["labels_patches"], tf.int32), axis=-1),
depth=nb_cls
)
```
```python
class DilatedMask(keras.layers.Layer):
def __init__(self, nodata_value, dilatation_radius, name=Non...e.g.
```python
tf.one_hot(
tf.squeeze(tf.cast(sample["labels_patches"], tf.int32), axis=-1),
depth=nb_cls
)
```
```python
class DilatedMask(keras.layers.Layer):
def __init__(self, nodata_value, dilatation_radius, name=None):
self.nodata_value = nodata_value
self.dilatation_radius = dilatation_radius
super().__init__(name=name)
def call(self, inp):
"""
:param inp: input layer
"""
# Compute a binary mask from the input
nodata_mask = tf.cast(tf.math.equal(inp, self.nodata_value), tf.uint8)
dilatation_size = 1 + 2 * self.dilatation_radius
# Create a morphological kernel suitable for binary dilatation, cf https://stackoverflow.com/q/54686895/13711499
kernel = tf.zeros((dilatation_size, dilatation_size, 1), dtype=tf.uint8)
return tf.cast(tf.nn.dilation2d(input=nodata_mask, filters=kernel, strides=[1, 1, 1, 1], padding="SAME",
data_format="NHWC", dilations=[1, 1, 1, 1], name="dilatation_tf"), tf.uint8)
class ApplyMask(keras.layers.Layer):
def __init__(self, out_nodata, name=None):
super().__init__(name=name)
self.out_nodata = out_nodata
def call(self, inputs):
"""
:param inputs: [mask, input]. Mask is a binary mask, where 1 indicate the values to be masked on the input.
"""
mask, inp = inputs
return tf.where(mask == 1, float(self.out_nodata), inp)
class ScalarsTile(keras.layers.Layer):
"""
Duplicate some scalars in an whole array.
Simple example with only one scalar = 0.152: output [[0.152, 0.152, 0.152],
[0.152, 0.152, 0.152],
[0.152, 0.152, 0.152]]
"""
def __init__(self, name=None):
super().__init__(name=name)
def call(self, inputs):
"""
:param inputs: [reference, scalar inputs]. Reference is the tensor whose shape has to be matched
"""
ref, scalar_inputs = inputs
inp = tf.stack(scalar_inputs, axis=-1)
inp = tf.expand_dims(tf.expand_dims(inp, axis=1), axis=1)
return tf.tile(inp, [1, tf.shape(ref)[1], tf.shape(ref)[2], 1])
class Argmax(keras.layers.Layer):
"""
Compute the argmax of a tensor. For example, for a vector A=[0.1, 0.3, 0.6], the output is 2 (A[2] is the max)
Useful to transform a probability multibands map into a categorical map
"""
def __init__(self, name=None):
super().__init__(name=name)
def call(self, inputs):
return tf.expand_dims(tf.math.argmax(inputs, axis=-1), axis=-1)
class Max(keras.layers.Layer):
"""
Compute the max of a tensor. For example, for a vector [0.1, 0.3, 0.6], the output is 0.6
Useful to transform a probability multibands map into a "confidence" map
"""
def __init__(self, name=None):
super().__init__(name=name)
def call(self, inputs):
return tf.expand_dims(tf.math.reduce_max(inputs, axis=-1), axis=-1)
```https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/43Ultra-lightweight OTBTF image with otbapps only2023-06-09T17:25:10+02:00Cresson RemiUltra-lightweight OTBTF image with otbapps onlyCould be great to have an ultralight image optimized for inference jobs in production environments.
- only OTB+TF binaries
- no TF python package, and none of its dependency
- in short, keep only libtensorflow*.so and throw everything e...Could be great to have an ultralight image optimized for inference jobs in production environments.
- only OTB+TF binaries
- no TF python package, and none of its dependency
- in short, keep only libtensorflow*.so and throw everything else. Keep the OTB stuff.https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/42TensorRT support2023-05-19T09:22:27+02:00Cresson RemiTensorRT support# Notes
à ajouter au docker file pour compiler avec le support de TensorRT
```
RUN TRTDIR=/opt/otbtf/local/lib/python3.10/dist-packages/tensorflow/include/third_party/tensorrt/ && \
mkdir $TRTDIR && \
ln -s $(find /usr/ -iname "...# Notes
à ajouter au docker file pour compiler avec le support de TensorRT
```
RUN TRTDIR=/opt/otbtf/local/lib/python3.10/dist-packages/tensorflow/include/third_party/tensorrt/ && \
mkdir $TRTDIR && \
ln -s $(find /usr/ -iname "nvinfer.h") $TRTDIR
```https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/41Improve documentation2023-04-24T16:15:07+02:00Cresson RemiImprove documentation- [ ] pip install otbtf (standalone)- [ ] pip install otbtf (standalone)https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/40TensorflowModelServe nodata value2023-05-23T22:39:28+02:00Cresson RemiTensorflowModelServe nodata value# Possible improvement
- if no-data value is not provided: do as usual
- if no-data value is provided: test if all pixels are nodata in current chunk. If yes, skip inference.# Possible improvement
- if no-data value is not provided: do as usual
- if no-data value is provided: test if all pixels are nodata in current chunk. If yes, skip inference.https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/39Documentation: readthedocs?2023-04-04T12:25:13+02:00Cresson RemiDocumentation: readthedocs?https://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/38Docker: push "latest" tag2022-10-04T14:35:46+02:00Cresson RemiDocker: push "latest" taghttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/37Release 3.3.22022-09-22T13:08:23+02:00Cresson RemiRelease 3.3.2Cresson RemiCresson Remihttps://gitlab.irstea.fr/remi.cresson/otbtf/-/issues/36Move to OTB 8.1.02022-09-21T17:35:21+02:00Cresson RemiMove to OTB 8.1.0