How to export TF trained network to a h5 file

Viewed 765

I have a trained model saved in 3 files and some tensorflow (1.x) code lines to use it. I need to convert the model to .h5 (keras), in order to import it in Matlab.

The model is saved in 3 files:

  • xxx.ckpt.data-00000-of-00001
  • xxx.ckpt.index
  • xxx.ckpt.meta

The tensorflow code lines is like:

zzz = "a function of the previous line"
session_name = "a function of xxx"
sess = tf.Session()  
saver = tf.train.Saver()
saver.restore(sess,session_name)
output=sess.run(zzz, ...)

Is it possible to export the trained network to a H5 file? If yes, how to do it?

ADD: I've asked to a friend, and appartenly it is not possible directly because, first, I have to "translate" the network stucture in Keras. This step is too hard for my level in the domain.

1 Answers

To my knowledge currently, there is no method to use checkpoint file and covert to h5(keras) directly. Instead you can achieve this by doing little workaround as mentioned below.

  1. If you want the network architecture then you need to rewrite the code in Keras.
  2. If you want to convert only weights (suppose you have code for the same model), you have to create a model with random weights then read the TensorFlow .ckpt file with tf.train.NewCheckpointReader then call set_weights() method for each corresponding layer.

Sample code for the same mentioned below:

reader = tf.train.NewCheckpointReader(filename)

for key in reader.get_variable_to_shape_map():
    # not saving the following tensors
    if key == 'global_step':
        continue
    if 'AuxLogit' in key:
        continue

    # convert tensor name into the corresponding Keras layer weight name and save
    path = os.path.join(output_folder, get_filename(key))
    arr = reader.get_tensor(key)
    np.save(path, arr)

You can use the saved .npy file to output model weights in h5(keras) as below.

for layer in tqdm(model.layers):
    if layer.weights:
        weights = []
        for w in layer.weights:
            weight_name = os.path.basename(w.name).replace(':0', '')
            weight_file = layer.name + '_' + weight_name + '.npy'
            weight_arr = np.load(numpy_weight_file)

        # remove the "background class"
        if weight_file.startswith('Logits_bias'):
            weight_arr = weight_arr[1:]
        elif weight_file.startswith('Logits_kernel'):
            weight_arr = weight_arr[:, 1:]

        weights.append(weight_arr)
    layer.set_weights(weights)
model.save_weights("Keras_model.h5")
Related