Skip to content
This repository has been archived by the owner on Oct 13, 2021. It is now read-only.

WIP #709

Closed

WIP #709

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions .azure-pipelines/linux-conda-CI-tf-keras.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:
pip install -r requirements.txt
pip install -r requirements-dev.txt
$(INSTALL_ORT)
pip install git+https://github.com/onnx/tensorflow-onnx@tom/test_keras_tf1
displayName: 'Install dependencies'

- script: |
Expand All @@ -84,3 +85,129 @@ jobs:
testResultsFiles: '**/test-results.xml'
testRunTitle: 'Python $(python.version)'
condition: succeededOrFailed()

- job: 'NightlyTest'
timeoutInMinutes: 180
pool:
vmImage: 'Ubuntu-16.04'
strategy:
matrix:
Python36-onnx1.2:
python.version: '3.6'
ONNX_PATH: onnx==1.2.3
INSTALL_KERAS: pip install keras==2.1.6
UNINSTALL_KERAS:
INSTALL_TENSORFLOW: pip install tensorflow==1.15.0
INSTALL_ORT: pip install onnxruntime==1.1.1
INSTALL_KERAS_RESNET:
INSTALL_TRANSFORMERS:
NIGHTLY_BUILD_TEST: python run_all.py --exclude "test_keras_applications_v2.py"

Python36-onnx1.5:
python.version: '3.6'
ONNX_PATH: onnx==1.5.0
INSTALL_KERAS: pip install keras==2.2.4
UNINSTALL_KERAS:
INSTALL_TENSORFLOW: pip install tensorflow==1.15.0
INSTALL_ORT: pip install onnxruntime==1.1.1
INSTALL_KERAS_RESNET: pip install keras-resnet
INSTALL_TRANSFORMERS:
NIGHTLY_BUILD_TEST: python run_all.py --exclude "test_keras_applications_v2.py"

Python37:
python.version: '3.7.3'
ONNX_PATH: onnx==1.8.0
INSTALL_KERAS: pip install keras==2.3.1
UNINSTALL_KERAS:
INSTALL_TENSORFLOW: pip install tensorflow==1.15.0
INSTALL_ORT: pip install -i https://test.pypi.org/simple/ ort-nightly
INSTALL_KERAS_RESNET: pip install keras-resnet
INSTALL_TRANSFORMERS:
NIGHTLY_BUILD_TEST: python run_all.py --exclude "test_keras_applications_v2.py"

Python37-official-ort:
python.version: '3.7.3'
ONNX_PATH: onnx==1.6.0
INSTALL_KERAS: pip install keras==2.3.1
UNINSTALL_KERAS:
INSTALL_TENSORFLOW: pip install tensorflow==1.15.0
INSTALL_ORT: pip install onnxruntime==1.3.0
INSTALL_KERAS_RESNET: pip install keras-resnet
INSTALL_TRANSFORMERS:
NIGHTLY_BUILD_TEST: python run_all.py --exclude "test_keras_applications_v2.py"

Python38-tf2:
python.version: '3.8'
ONNX_PATH: onnx==1.8.0
INSTALL_KERAS:
UNINSTALL_KERAS: pip uninstall keras -y
INSTALL_TENSORFLOW: pip install tensorflow==2.2.0
INSTALL_ORT: pip install -i https://test.pypi.org/simple/ ort-nightly
INSTALL_KERAS_RESNET: pip install keras-resnet
INSTALL_TRANSFORMERS: pip install transformers==3.4.0
NIGHTLY_BUILD_TEST: python run_all_v2.py

maxParallel: 3

steps:
- script: sudo install -d -m 0777 /home/vsts/.conda/envs
displayName: Fix Conda permissions

- task: CondaEnvironment@1
inputs:
createCustomEnvironment: true
environmentName: 'py$(python.version)'
packageSpecs: 'python=$(python.version)'

- script: |
python -m pip install --upgrade pip
conda config --set always_yes yes --set changeps1 no
pip install $(ONNX_PATH)
pip install h5py==2.9.0
$(INSTALL_TENSORFLOW)
$(INSTALL_KERAS)
pip install git+https://github.com/microsoft/onnxconverter-common
pip install -r requirements.txt
pip install -r requirements-dev.txt
$(INSTALL_ORT)
pip install opencv-python
pip install tqdm
pip install keras-segmentation==0.2.0
git clone https://github.com/matterport/Mask_RCNN
cd Mask_RCNN
pip install -r requirements.txt
python setup.py install
cd ..
pip install matplotlib
git clone https://github.com/qqwweee/keras-yolo3
$(INSTALL_KERAS_RESNET)
pip install git+https://www.github.com/keras-team/keras-contrib.git
pip install keras-tcn==2.8.3
$(UNINSTALL_KERAS)
pip install git+https://github.com/qubvel/efficientnet
$(INSTALL_TRANSFORMERS)
pip install keras-self-attention
pip install git+https://github.com/onnx/tensorflow-onnx@tom/test_keras_tf1
displayName: 'Install dependencies'

- script: |
pip install -e .
python -c "import onnxruntime"
pytest tests --doctest-modules --junitxml=junit/test-results.xml
cd applications/nightly_build
$(NIGHTLY_BUILD_TEST)
displayName: 'pytest'

- script: |
pip install -e .
python -c "import onnxruntime"
coverage run --include=keras2onnx/* -m pytest tests/test_layers.py
coverage report -m
coverage html
displayName: 'coverage'

- task: PublishTestResults@2
inputs:
testResultsFiles: '**/test-results-*.xml'
testRunTitle: 'Python $(python.version)'
condition: succeededOrFailed()
1 change: 1 addition & 0 deletions .azure-pipelines/linux-conda-CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ jobs:
pip install -r requirements.txt
pip install -r requirements-dev.txt
$(INSTALL_ORT)
pip install git+https://github.com/onnx/tensorflow-onnx@tom/test_keras_tf1
displayName: 'Install dependencies'

- script: |
Expand Down
128 changes: 128 additions & 0 deletions .azure-pipelines/win32-conda-CI-tf-keras.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ jobs:
pip install -r requirements.txt
pip install -r requirements-dev.txt
%INSTALL_ORT%
pip install git+https://github.com/onnx/tensorflow-onnx@tom/test_keras_tf1
displayName: 'Install dependencies'

- script: |
Expand All @@ -84,3 +85,130 @@ jobs:
testResultsFiles: '**/test-results.xml'
testRunTitle: 'Python $(python.version)'
condition: succeededOrFailed()

- job: 'NightlyTest'
timeoutInMinutes: 180
pool:
vmImage: 'vs2017-win2016'
strategy:
matrix:
# No python 2.x since no available ONNX package for Windows
Python36-onnx1.2:
python.version: '3.6'
ONNX_PATH: onnx==1.2.3
INSTALL_KERAS: pip install keras==2.1.6
UNINSTALL_KERAS:
INSTALL_TENSORFLOW: pip install tensorflow==1.14.0
INSTALL_ORT: pip install onnxruntime==1.1.1
INSTALL_KERAS_RESNET:
INSTALL_TRANSFORMERS:
NIGHTLY_BUILD_TEST: python run_all.py --exclude "test_keras_applications_v2.py test_mask_rcnn.py"

Python36-onnx1.5:
python.version: '3.6'
ONNX_PATH: onnx==1.5.0
INSTALL_KERAS: pip install keras==2.2.4
UNINSTALL_KERAS:
INSTALL_TENSORFLOW: pip install tensorflow==1.14.0
INSTALL_ORT: pip install onnxruntime==1.1.1
INSTALL_KERAS_RESNET: pip install keras-resnet
INSTALL_TRANSFORMERS:
NIGHTLY_BUILD_TEST: python run_all.py --exclude "test_keras_applications_v2.py test_mask_rcnn.py"

Python37:
python.version: '3.7'
ONNX_PATH: onnx==1.8.0
INSTALL_KERAS: pip install keras==2.3.1
UNINSTALL_KERAS:
INSTALL_TENSORFLOW: pip install tensorflow==1.14.0
INSTALL_ORT: pip install -i https://test.pypi.org/simple/ ort-nightly
INSTALL_KERAS_RESNET: pip install keras-resnet
INSTALL_TRANSFORMERS:
NIGHTLY_BUILD_TEST: python run_all.py --exclude "test_keras_applications_v2.py test_mask_rcnn.py"

Python37-official-ort:
python.version: '3.7'
ONNX_PATH: onnx==1.6.0
INSTALL_KERAS: pip install keras==2.3.1
UNINSTALL_KERAS:
INSTALL_TENSORFLOW: pip install tensorflow==1.14.0
INSTALL_ORT: pip install onnxruntime==1.1.1
INSTALL_KERAS_RESNET: pip install keras-resnet
INSTALL_TRANSFORMERS:
NIGHTLY_BUILD_TEST: python run_all.py --exclude "test_keras_applications_v2.py test_mask_rcnn.py"

Python38-tf2:
python.version: '3.8'
ONNX_PATH: onnx==1.8.0
INSTALL_KERAS:
UNINSTALL_KERAS: pip uninstall keras -y
INSTALL_TENSORFLOW: pip install tensorflow==2.2.0
INSTALL_ORT: pip install onnxruntime==1.7.0
INSTALL_KERAS_RESNET: pip install keras-resnet
INSTALL_TRANSFORMERS: pip install transformers==3.4.0
NIGHTLY_BUILD_TEST: python run_all_v2.py

maxParallel: 3

steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(python.version)'
architecture: 'x64'

- powershell: Write-Host "##vso[task.prependpath]$env:CONDA\Scripts"
displayName: Add conda to PATH

- script: conda create --yes --quiet --name py$(python.version) -c conda-forge python=$(python.version) numpy protobuf
displayName: Create Anaconda environment

- script: |
call activate py$(python.version)
python -m pip install --upgrade pip numpy
echo Test numpy installation... && python -c "import numpy"
pip install %ONNX_PATH%
pip install h5py==2.9.0
%INSTALL_TENSORFLOW%
%INSTALL_KERAS%
pip install git+https://github.com/microsoft/onnxconverter-common
pip install -r requirements.txt
pip install -r requirements-dev.txt
%INSTALL_ORT%
pip install opencv-python
pip install tqdm
pip install keras-segmentation==0.2.0
pip install matplotlib
git clone https://github.com/qqwweee/keras-yolo3
%INSTALL_KERAS_RESNET%
pip install git+https://www.github.com/keras-team/keras-contrib.git
pip install keras-tcn==2.8.3
%UNINSTALL_KERAS%
pip install git+https://github.com/qubvel/efficientnet
%INSTALL_TRANSFORMERS%
pip install keras-self-attention
pip install git+https://github.com/onnx/tensorflow-onnx@tom/test_keras_tf1
displayName: 'Install dependencies'

- script: |
call activate py$(python.version)
pip install -e .
echo Test onnxruntime installation... && python -c "import onnxruntime"
pytest tests --doctest-modules --junitxml=junit/test-results.xml
cd applications/nightly_build
%NIGHTLY_BUILD_TEST%
displayName: 'pytest'

- script: |
call activate py$(python.version)
pip install -e .
echo Test onnxruntime installation... && python -c "import onnxruntime"
coverage run --include=keras2onnx/* -m pytest tests/test_layers.py
coverage report -m
coverage html
displayName: 'coverage'

- task: PublishTestResults@2
inputs:
testResultsFiles: '**/test-results-*.xml'
testRunTitle: 'Python $(python.version)'
condition: succeededOrFailed()
1 change: 1 addition & 0 deletions .azure-pipelines/win32-conda-CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ jobs:
pip install -r requirements.txt
pip install -r requirements-dev.txt
%INSTALL_ORT%
pip install git+https://github.com/onnx/tensorflow-onnx@tom/test_keras_tf1
displayName: 'Install dependencies'

- script: |
Expand Down
4 changes: 2 additions & 2 deletions keras2onnx/_tf_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ def tf_attrs_to_onnx(node):
return attrs


def to_tf_tensor_spec(onnx_type, name=None):
shp = [1 if isinstance(n_, str) else n_ for n_ in onnx_type.shape]
def to_tf_tensor_spec(onnx_type, name=None, unknown_dim=1):
shp = [unknown_dim if isinstance(n_, str) else n_ for n_ in onnx_type.shape]
return tensorflow.TensorSpec(shp,
mapping.TENSOR_TYPE_TO_NP_TYPE[onnx_type.to_onnx_type().tensor_type.elem_type],
name=name)
27 changes: 23 additions & 4 deletions keras2onnx/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from ._parser_tf import build_layer_output_from_model


def _process_initial_types(initial_types):
def _process_initial_types(initial_types, unknown_dim=1):
if initial_types is None:
return None

Expand All @@ -30,15 +30,33 @@ def _process_initial_types(initial_types):
if isinstance(initial_types[c_], str):
name = initial_types[c_]
type_idx = c_ + 1
ts_spec = to_tf_tensor_spec(initial_types[type_idx], name)
ts_spec = to_tf_tensor_spec(initial_types[type_idx], name, unknown_dim)
input_specs.append(ts_spec)
c_ += 1 if name is None else 2

return input_specs


def convert_keras(model, name=None, doc_string='', target_opset=None, initial_types=None,
channel_first_inputs=None, debug_mode=False, custom_op_conversions=None):
def convert_keras_tf2onnx(model, name=None, doc_string='', target_opset=None, initial_types=None,
channel_first_inputs=None, debug_mode=False, custom_op_conversions=None):
if target_opset is None:
target_opset = get_maximum_opset_supported()
input_signature = _process_initial_types(initial_types, unknown_dim=None)


import tf2onnx
model, external_tensor_storage = tf2onnx.convert.from_keras(model, input_signature, opset=target_opset,
inputs_as_nchw=channel_first_inputs)

return model


def convert_keras(*args, **kwargs):
return convert_keras_tf2onnx(*args, **kwargs)


def convert_keras_old(model, name=None, doc_string='', target_opset=None, initial_types=None,
channel_first_inputs=None, debug_mode=False, custom_op_conversions=None):
# type: (keras.Model, str, str, int, [], [], bool, {}) -> onnx.ModelProto
"""
:param model: keras model
Expand All @@ -51,6 +69,7 @@ def convert_keras(model, name=None, doc_string='', target_opset=None, initial_ty
:param custom_op_conversions: the handler for custom operator conversion
:return an ONNX ModelProto
"""
print("Hello! I'm a test")
if isinstance(model, tf.keras.Model) and not is_tf_keras:
raise Exception("This is a tensorflow keras model, but keras standalone converter is used." +
" Please set environment variable TF_KERAS = 1 before importing keras2onnx.")
Expand Down
3 changes: 2 additions & 1 deletion tests/test_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1982,10 +1982,11 @@ def test_LSTM_with_initializer(runner):
reason="None seq_length LSTM is not supported before opset 5.")
def test_LSTM_seqlen_none(runner):
lstm_dim = 2
np.random.seed(42)
data = np.random.rand(1, 5, 1).astype(np.float32)
for return_sequences in [True, False]:
inp = Input(batch_shape=(1, None, 1))
out = LSTM(lstm_dim, return_sequences=return_sequences, stateful=True)(inp)
out = LSTM(lstm_dim, return_sequences=return_sequences, stateful=False)(inp)
keras_model = keras.Model(inputs=inp, outputs=out)

onnx_model = keras2onnx.convert_keras(keras_model)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_subclassing.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def _tf_where(input_0):
return c

swm = SimpleWrapperModel(_tf_where)
const_in = [np.array([2, 4, 6, 8, 10]).astype(np.int32)]
const_in = np.array([2, 4, 6, 8, 10]).astype(np.int32)
expected = swm(const_in)
swm._set_inputs(const_in)
oxml = keras2onnx.convert_keras(swm)
Expand Down
2 changes: 2 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ def run_onnx_runtime(case_name, onnx_model, data, expected, model_files, rtol=1.
elif not isinstance(expected, list):
expected = [expected]

for n_ in range(len(expected)):
np.testing.assert_allclose(expected[n_], actual[n_], rtol=rtol, atol=atol)
res = all(np.allclose(expected[n_], actual[n_], rtol=rtol, atol=atol) for n_ in range(len(expected)))

if res and temp_model_file not in model_files: # still keep the failed case files for the diagnosis.
Expand Down