示例#1
0
    def testTensorflowjsToKerasConversionSucceeds(self):
        with tf.Graph().as_default(), tf.Session():
            sequential_model = keras.models.Sequential([
                keras.layers.Dense(3,
                                   input_shape=(2, ),
                                   use_bias=True,
                                   kernel_initializer='ones',
                                   name='Dense1'),
                keras.layers.Dense(1,
                                   use_bias=False,
                                   kernel_initializer='ones',
                                   name='Dense2')
            ])
            h5_path = os.path.join(self._tmp_dir, 'SequentialModel.h5')
            sequential_model.save(h5_path)
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, output_dir=self._tmp_dir)
            old_model_json = sequential_model.to_json()

        # Convert the tensorflowjs artifacts to a new H5 file.
        new_h5_path = os.path.join(self._tmp_dir, 'new.h5')
        converter.dispatch_tensorflowjs_to_keras_h5_conversion(
            os.path.join(self._tmp_dir, 'model.json'), new_h5_path)

        # Load the new H5 and compare the model JSONs.
        with tf.Graph().as_default(), tf.Session():
            new_model = keras.models.load_model(new_h5_path)
            self.assertEqual(old_model_json, new_model.to_json())
示例#2
0
    def testConvertTfjsLayersModelWithUint8Quantization(self):
        with tf.Graph().as_default(), tf.compat.v1.Session():
            model = self._createSimpleSequentialModel()
            weights = model.get_weights()
            total_weight_bytes = sum(np.size(w) for w in weights) * 4

            # Save the keras model to a .h5 file.
            h5_path = os.path.join(self._tmp_dir, 'model.h5')
            model.save(h5_path)

            # Convert the keras SavedModel to tfjs format.
            tfjs_output_dir = os.path.join(self._tmp_dir, 'tfjs')
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, tfjs_output_dir)

            weight_shard_size_bytes = int(total_weight_bytes * 2)
            # Due to the shard size, there ought to be 1 shard after conversion.

            # Convert the tfjs model to another tfjs model, with quantization.
            sharded_model_path = os.path.join(self._tmp_dir, 'sharded_model')
            converter.dispatch_tensorflowjs_to_tensorflowjs_conversion(
                os.path.join(tfjs_output_dir, 'model.json'),
                sharded_model_path,
                quantization_dtype=np.uint8,
                weight_shard_size_bytes=weight_shard_size_bytes)

            # Check the number of quantized files and their sizes.
            weight_files = sorted(
                glob.glob(os.path.join(sharded_model_path, 'group*.bin')))
            self.assertEqual(len(weight_files), 1)
            weight_file_size = os.path.getsize(weight_files[0])

            # The size of the saved weight file should reflect the result of the
            # uint16 quantization.
            self.assertEqual(weight_file_size, total_weight_bytes / 4)
示例#3
0
    def testConvertTfjsLayersModelWithShardSizeGreaterThanTotalWeightSize(
            self):
        with tf.Graph().as_default(), tf.compat.v1.Session():
            model = self._createSimpleSequentialModel()
            weights = model.get_weights()
            total_weight_bytes = sum(np.size(w) for w in weights) * 4

            # Save the keras model to a .h5 file.
            h5_path = os.path.join(self._tmp_dir, 'model.h5')
            model.save(h5_path)

            # Convert the keras SavedModel to tfjs format.
            tfjs_output_dir = os.path.join(self._tmp_dir, 'tfjs')
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, tfjs_output_dir)

            weight_shard_size_bytes = int(total_weight_bytes * 2)
            # Due to the shard size, there ought to be 1 shard after conversion.

            # Convert the tfjs model to another tfjs model, with a specified weight
            # shard size.
            sharded_model_path = os.path.join(self._tmp_dir, 'sharded_model')
            converter.dispatch_tensorflowjs_to_tensorflowjs_conversion(
                os.path.join(tfjs_output_dir, 'model.json'),
                sharded_model_path,
                weight_shard_size_bytes=weight_shard_size_bytes)

            # Check the number of sharded files and their sizes.
            weight_files = sorted(
                glob.glob(os.path.join(sharded_model_path, 'group*.bin')))
            self.assertEqual(len(weight_files), 1)
            weight_file_sizes = [os.path.getsize(f) for f in weight_files]
            self.assertEqual(sum(weight_file_sizes), total_weight_bytes)
示例#4
0
    def testWrongConverterRaisesCorrectErrorMessage(self):
        with tf.Graph().as_default(), tf.compat.v1.Session():
            model = self._createSimpleSequentialModel()
            keras.experimental.export_saved_model(model, self._tmp_dir)

            # Convert the keras SavedModel to tfjs format.
            tfjs_output_dir = os.path.join(self._tmp_dir, 'tfjs')
            # Use wrong dispatcher.
            with self.assertRaisesRegexp(  # pylint: disable=deprecated-method
                    ValueError,
                    r'Expected path to point to an HDF5 file, but it points to a '
                    r'directory'):
                converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                    self._tmp_dir, tfjs_output_dir)
示例#5
0
    def testWeightsOnly(self):
        with tf.Graph().as_default(), tf.Session():
            input_tensor = keras.layers.Input((3, ))
            dense1 = keras.layers.Dense(4,
                                        use_bias=True,
                                        kernel_initializer='ones',
                                        bias_initializer='zeros',
                                        name='MyDense1')(input_tensor)
            output = keras.layers.Dense(2,
                                        use_bias=False,
                                        kernel_initializer='ones',
                                        name='MyDense2')(dense1)
            model = keras.models.Model(inputs=[input_tensor], outputs=[output])
            h5_path = os.path.join(self._tmp_dir, 'MyModel.h5')
            model.save_weights(h5_path)

        # Load the saved weights as a JSON string.
        model_json, groups = (
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, output_dir=self._tmp_dir))
        self.assertIsNone(model_json)

        # Check the loaded weights.
        self.assertEqual(1, len(groups))
        self.assertEqual(3, len(groups[0]))
        # contents of weights are verified in tests of the library code

        # Check the content of the output directory.
        output_json = json.load(
            open(os.path.join(self._tmp_dir, 'model.json'), 'rt'))
        self.assertEqual(model_json, output_json['modelTopology'])
        self.assertIsInstance(output_json['weightsManifest'], list)
        self.assertTrue(glob.glob(os.path.join(self._tmp_dir, 'group*-*')))
示例#6
0
    def testConvertWeightsFromSequentialModel(self):
        with tf.Graph().as_default(), tf.Session():
            sequential_model = keras.models.Sequential([
                keras.layers.Dense(3,
                                   input_shape=(2, ),
                                   use_bias=True,
                                   kernel_initializer='ones',
                                   name='Dense1'),
                keras.layers.Dense(1,
                                   use_bias=False,
                                   kernel_initializer='ones',
                                   name='Dense2')
            ])
            h5_path = os.path.join(self._tmp_dir, 'SequentialModel.h5')
            sequential_model.save_weights(h5_path)

        # Load the saved weights as a JSON string.
        model_json, groups = (
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, output_dir=self._tmp_dir))
        self.assertIsNone(model_json)

        # Check the loaded weights.
        self.assertEqual(1, len(groups))
        self.assertEqual(3, len(groups[0]))
        # contents of weights are verified in tests of the library code

        # Check the content of the output directory.
        output_json = json.load(
            open(os.path.join(self._tmp_dir, 'model.json'), 'rt'))
        self.assertEqual(model_json, output_json['modelTopology'])
        self.assertIsInstance(output_json['weightsManifest'], list)
        self.assertTrue(glob.glob(os.path.join(self._tmp_dir, 'group*-*')))
示例#7
0
    def testOutpuDirAsAnExistingFileLeadsToValueError(self):
        output_path = os.path.join(self._tmp_dir, 'foo_model')
        with open(output_path, 'wt') as f:
            f.write('\n')

        with tf.Graph().as_default(), tf.Session():
            sequential_model = keras.models.Sequential([
                keras.layers.Dense(3,
                                   input_shape=(2, ),
                                   use_bias=True,
                                   kernel_initializer='ones',
                                   name='Dense1')
            ])
            h5_path = os.path.join(self._tmp_dir, 'SequentialModel.h5')
            sequential_model.save_weights(h5_path)

        with self.assertRaisesRegexp(  # pylint: disable=deprecated-method
                ValueError, r'already exists as a file'):
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, output_dir=output_path)
示例#8
0
    def testConvertModelForNonexistentDirCreatesDir(self):
        with tf.Graph().as_default(), tf.Session():
            output_dir = os.path.join(self._tmp_dir, 'foo_model')
            sequential_model = keras.models.Sequential([
                keras.layers.Dense(3,
                                   input_shape=(2, ),
                                   use_bias=True,
                                   kernel_initializer='ones',
                                   name='Dense1')
            ])
            h5_path = os.path.join(self._tmp_dir, 'SequentialModel.h5')
            sequential_model.save_weights(h5_path)
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, output_dir=output_dir)

        # Check the content of the output directory.
        output_json = json.load(
            open(os.path.join(output_dir, 'model.json'), 'rt'))
        self.assertIsNone(output_json['modelTopology'])
        self.assertIsInstance(output_json['weightsManifest'], list)
        self.assertTrue(glob.glob(os.path.join(output_dir, 'group*-*')))
示例#9
0
    def testTensorflowjsToKerasConversionFailsOnExistingDirOutputPath(self):
        with tf.Graph().as_default(), tf.Session():
            sequential_model = keras.models.Sequential([
                keras.layers.Dense(3,
                                   input_shape=(2, ),
                                   use_bias=True,
                                   kernel_initializer='ones',
                                   name='Dense1'),
                keras.layers.Dense(1,
                                   use_bias=False,
                                   kernel_initializer='ones',
                                   name='Dense2')
            ])
            h5_path = os.path.join(self._tmp_dir, 'SequentialModel.h5')
            sequential_model.save(h5_path)
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, output_dir=self._tmp_dir)

        with self.assertRaisesRegexp(  # pylint: disable=deprecated-method
                ValueError, r'but received an existing directory'):
            converter.dispatch_tensorflowjs_to_keras_h5_conversion(
                os.path.join(self._tmp_dir, 'model.json'), self._tmp_dir)
示例#10
0
    def testTfjsLayer2TfjsLayersConversionWithExistingFilePathFails(self):
        with tf.Graph().as_default(), tf.compat.v1.Session():
            model = self._createSimpleSequentialModel()

            # Save the keras model to a .h5 file.
            h5_path = os.path.join(self._tmp_dir, 'model.h5')
            model.save(h5_path)

            # Convert the keras SavedModel to tfjs format.
            tfjs_output_dir = os.path.join(self._tmp_dir, 'tfjs')
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, tfjs_output_dir)

            # Convert the tfjs model to another tfjs model, with a specified weight
            # shard size.
            sharded_model_path = os.path.join(self._tmp_dir, 'sharded_model')
            with open(sharded_model_path, 'wt') as f:
                # Create a fie at the path to elicit the error.
                f.write('hello')
            with self.assertRaisesRegexp(  # pylint: disable=deprecated-method
                    ValueError, r'already exists as a file'):
                converter.dispatch_tensorflowjs_to_tensorflowjs_conversion(
                    os.path.join(tfjs_output_dir, 'model.json'),
                    sharded_model_path)
示例#11
0
    def testConvertSavedKerasModelSplitByLayer(self):
        with tf.Graph().as_default(), tf.Session():
            input_tensor = keras.layers.Input((3, ))
            dense1 = keras.layers.Dense(4,
                                        use_bias=True,
                                        kernel_initializer='ones',
                                        bias_initializer='zeros',
                                        name='MergedDense1')(input_tensor)
            output = keras.layers.Dense(2,
                                        use_bias=False,
                                        kernel_initializer='ones',
                                        name='MergedDense2')(dense1)
            model = keras.models.Model(inputs=[input_tensor], outputs=[output])
            h5_path = os.path.join(self._tmp_dir, 'MyModelMerged.h5')
            model.save(h5_path)

        # Load the saved weights as a JSON string.
        model_json, groups = (
            converter.dispatch_keras_h5_to_tensorflowjs_conversion(
                h5_path, output_dir=self._tmp_dir,
                split_weights_by_layer=True))
        # check the model topology was stored
        self.assertIsInstance(model_json['model_config'], dict)
        self.assertIsInstance(model_json['model_config']['config'], dict)
        self.assertIn('layers', model_json['model_config']['config'])

        # Check the loaded weights.
        self.assertEqual(keras.__version__, model_json['keras_version'])
        self.assertEqual('tensorflow', model_json['backend'])
        self.assertEqual(2, len(groups))
        self.assertEqual(2, len(groups[0]))
        self.assertEqual(1, len(groups[1]))
        # contents of weights are verified in tests of the library code

        # Check the content of the output directory.
        output_json = json.load(
            open(os.path.join(self._tmp_dir, 'model.json'), 'rt'))
        self.assertEqual(model_json, output_json['modelTopology'])
        self.assertIsInstance(output_json['weightsManifest'], list)
        self.assertTrue(glob.glob(os.path.join(self._tmp_dir, 'group*-*')))
def convert_tfjs(path_output_dir):
    print("Saving converted tfjs model...")
    dispatch_keras_h5_to_tensorflowjs_conversion(
        path_output_dir + TEMP_MODEL_NAME, path_output_dir)