I've been playing around with tfhub using the Keras API, and had a pretty confusing experience trying to fine-tune weights. It took me a while to realize this, but even though I was setting trainable=True when loading the module, the embedding weights weren't changing at all.
Here's a small repro. I build a model that takes a string and outputs the component-wise average of its embedding. Then I train it to try to push certain words to have very large embeddings. But the embeddings don't change.
Eventually, I figured out that a Keras model will only train variables that belong to the 'trainable_weights' property of one of its layers (it's not enough that a variable is part of the model's calculations and belongs to the 'trainable_variables' collection). So to accomplish any fine-tuning, I needed to add some code like this when creating the embedding layer:
embed_layer = keras.layers.Lambda(embed_lambda)
all_trainables = tf.get_default_graph().get_collection('trainable_variables')
for vars in embedder.variable_map.values():
if not isinstance(vars, list):
vars = [vars]
for var in vars:
if var in all_trainables:
embed_layer.trainable_weights.append(var)
I found this pretty surprising. In the "build a simple text classifier" tutorial which uses the estimator framework, finetuning just works when trainable is set to True, with no further configuration required.
I wonder whether this should be documented somewhere? Or better yet, maybe the hub API could include a text_embedding_layer and image_embedding_layer (in the same way that they export the text_embedding_column and image_embedding_column helpers for the estimator framework).