pytorch2keras
pytorch2keras copied to clipboard
converts torch model with dtype double (float64) to keras with float32
I don't know whether this issue is actually with this project (the "pytorch2onnx" part) or rather onnx2keras. Please move it if applicable.
Describe the bug
I'm trying to convert a model that uses double (float64) datatype throughout, it looks like this, created with torch.jit.script
.
graph(%input_0 : Double(1, 2, strides=[2, 1], requires_grad=0, device=cpu),
%layers.0.weight : Double(100, 2, strides=[2, 1], requires_grad=0, device=cpu),
%layers.0.bias : Double(100, strides=[1], requires_grad=0, device=cpu),
%layers.2.weight : Double(100, 100, strides=[100, 1], requires_grad=0, device=cpu),
%layers.2.bias : Double(100, strides=[1], requires_grad=0, device=cpu),
%layers.4.weight : Double(2, 100, strides=[100, 1], requires_grad=0, device=cpu),
%layers.4.bias : Double(2, strides=[1], requires_grad=0, device=cpu)):
%7 : Double(1, 100, strides=[100, 1], device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1](%input_0, %layers.0.weight, %layers.0.bias) # python3.7/site-packages/torch/nn/functional.py:1848:11
%8 : Double(1, 100, strides=[100, 1], device=cpu) = onnx::Relu(%7) # python3.7/site-packages/torch/nn/functional.py:1299:17
%9 : Double(1, 100, strides=[100, 1], device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1](%8, %layers.2.weight, %layers.2.bias) # python3.7/site-packages/torch/nn/functional.py:1848:11
%10 : Double(1, 100, strides=[100, 1], device=cpu) = onnx::Relu(%9) # python3.7/site-packages/torch/nn/functional.py:1299:17
%output_0 : Double(1, 2, strides=[2, 1], requires_grad=0, device=cpu) = onnx::Gemm[alpha=1., beta=1., transB=1](%10, %layers.4.weight, %layers.4.bias) # python3.7/site-packages/torch/nn/functional.py:1848:11
return (%output_0)
DEBUG:onnx2keras:Output TF Layer -> KerasTensor(type_spec=TensorSpec(shape=(None, 100), dtype=tf.float32, name=None), name='7/BiasAdd:0', description="created by layer '7'")
DEBUG:onnx2keras:Output TF Layer -> KerasTensor(type_spec=TensorSpec(shape=(None, 100), dtype=tf.float32, name=None), name='8/Relu:0', description="created by layer '8'")
DEBUG:onnx2keras:Output TF Layer -> KerasTensor(type_spec=TensorSpec(shape=(None, 100), dtype=tf.float32, name=None), name='9/BiasAdd:0', description="created by layer '9'")
DEBUG:onnx2keras:Output TF Layer -> KerasTensor(type_spec=TensorSpec(shape=(None, 100), dtype=tf.float32, name=None), name='10/Relu:0', description="created by layer '10'")
DEBUG:onnx2keras:Output TF Layer -> KerasTensor(type_spec=TensorSpec(shape=(None, 2), dtype=tf.float32, name=None), name='output_0/BiasAdd:0', description="created by layer 'output_0'")
Expected behavior double -> double
Script
# 1) load PyTorch model
model = torch.jit.load(args.torch)
# 2) create dummy variable with correct shape
shape = (2)
input_np = np.random.uniform(low=0, high=1, size=(1,2))
input_var = Variable(torch.DoubleTensor(input_np))
# 3) trace the model using dummy variable
k_model = pytorch_to_keras(model, input_var, [shape], verbose=True)
# 4) save keras (Tensorflow format) model
# https://www.tensorflow.org/guide/keras/save_and_serialize#how_to_save_and_load_a_model
k_model.save(args.keras)
I was able to overcome this by this method: https://stackoverflow.com/questions/47895494/how-to-convert-all-layers-of-a-pretrained-keras-model-to-a-different-dtype-from
i.e. since my model uses only float64, I changed converter.py of onnx2keras thusly:
@@ -3,6 +3,7 @@
"""
from tensorflow import keras
+from tensorflow.keras import backend as K
import logging
import inspect
import collections
@@ -48,6 +49,8 @@
:param change_ordering: change ordering to HWC (experimental)
:return: Keras model
"""
+ K.set_floatx('float64')
+
# Use channels first format by default.
keras_fmt = keras.backend.image_data_format()
keras.backend.set_image_data_format('channels_first')
However I'm posting this here merely as a hardcoded workaround, so this still should be addressed properly by someone who actually understands how the converter works.