I trained a very simple autoencoder network similar to this example:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
layers.Dense(128, activation="relu"),
layers.Dense(64, activation="relu"),
layers.Dense(32, activation="relu"),
layers.Dense(16, activation="relu"),
layers.Dense(8, activation="relu", name="latent_space"),
layers.Dense(16, activation="relu"),
layers.Dense(32, activation="relu", name="decode_32"),
layers.Dense(64, activation="relu"),
layers.Dense(128, activation="sigmoid"),
])
model.compile(...)
model.fit(...)
# Extract subnetwork here after training
I would like to know if it is possible to feed data to the latent_space layer such that I can afterwards extract the activations from layer decode_32? Ideally I would like to crop a subnetwork after training with the latent_space layer as the input and the decode_32 layer as the output layer. Is that possible?
Does this answer fits your question?
def extract_layers(main_model, starting_layer_ix, ending_layer_ix) :
# create an empty model
new_model = Sequential()
for ix in range(starting_layer_ix, ending_layer_ix + 1):
curr_layer = main_model.get_layer(index=ix)
# copy this layer over to the new model
new_model.add(curr_layer)
return new_model
If you prefer selecting your subnetwork with the names of the first and last layers, the get_layer method also has an argument for the layer's name, but an easier solution would be to retrieve the indexes of the layers to select thanks to the layer.name argument.
That way, you just have to modify the previous function by adding
layer_names = [layer.name for layer in main_model.layers]
starting_layer_ix = layer_names.index(starting_layer_name)
ending_layer_ix = layer_names.index(ending_layer_name)
Related
I am trying to reproduce the image classification problem cat or dog using tensorflow and transfer learning (Xception model pretrained with imagenet). The code is:
base_model = keras.applications.Xception(
weights='imagenet',
# image shape = 128x128x3
input_shape=(128, 128, 3),
include_top=False)
# freeze layers
base_model.trainable = False
inputs = keras.Input(shape=(128, 128, 3))
x = data_augmentation(inputs)
x = tf.keras.applications.xception.preprocess_input(x)
x = base_model(x, training=False)
x = keras.layers.Flatten()(x)
x = keras.layers.Dense(128, activation='relu')(x)
outputs = keras.layers.Dense(1, activation='sigmoid')(x)
model = keras.Model(inputs, outputs)
I am now trying to make use of models.Sequential. So far my code looks like this:
theModel=models.Sequential([
tf.keras.Input(shape=(128, 128, 3)),
tf.keras.applications.xception.preprocess_input(), <-------- how to pass tensor as argument?
base_model,
Flatten(),
Dense(128, activation='relu'),
Dense(1,activation='sigmoid')
])
My question, is there a way to make use of models.Sequentials, defining everything as I've done but passing the tensor as argument like in the first code snipped?
Thanks in advance,
metc
You cannot use tf.keras.applications.xception.preprocess_input() inside the sequential model. You have to define it outside the model and can pass the output of it to the sequential model by assigning values to the tensor argument in the input layer.
x=tf.random.uniform(shape=(1,128,128,3))
x= tf.keras.applications.xception.preprocess_input(x)
theModel=tf.keras.models.Sequential([
tf.keras.Input(tensor=x),
base_model,
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(1,activation='sigmoid')
])
For more details, Please refer to this gist.Thank You!
Could you help me with the code such that along with the dense layers also the last convolutional layer of Efficientnet is trained as well ?
features_url ="https://tfhub.dev/google/imagenet/efficientnet_v2_imagenet21k_b3/feature_vector/2"
img_shape = (299,299,3)
features_layer = hub.KerasLayer(features_url,
input_shape=img_shape)
# below commented code keeps all the cnn layers frozen, thus it does not work for me at the moment
#features_layer.trainable = False
model = tf.keras.Sequential([
features_layer,
tf.keras.layers.Dense(256, activation = 'relu'),
tf.keras.layers.Dense(64, activation = 'relu'),
tf.keras.layers.Dense(4, activation = 'softmax')
])
In addition how can I save in a variable the name of the last convolutional layer ?
Good day, everyone.
I want to have two separate TensorFlow models (f and g) and train both of them on the loss of f(g(x)). However, I want to use them separately, like g(x) or f(e), where e is an embedded vector but received not from g.
For example, the classical way to create the model with embedding looks like this:
# First block
model = Sequential([
vectorize_layer,
Embedding(vocab_size, embedding_dim, name="embedding"),
GlobalAveragePooling1D(),
Dense(16, activation='relu'),
Dense(1)
])
I want to have an option to pass data through embedding layer and all other layers separately, but still train the model as a whole unit, like:
# Second block
g = Sequential([
vectorize_layer,
Embedding(vocab_size, embedding_dim, name="embedding")
])
f = Sequential([
GlobalAveragePooling1D(),
Dense(16, activation='relu'),
Dense(1)
])
Can I do that without going to low-level TensorFlow? The first block of code is exactly what I want to train and I can leave it like that, but I need to pass data through the specific layers somehow.
This can be achieved by weight sharing or shared layers. To share layers in different models in keras, you just need to pass the same instance of layer to both of the models.
Example Codes:
#initialize them beforehand
em_layer=Embedding(vocab_size, embedding_dim, name="embedding")
firstfc=Dense(16, activation='relu')
secondfc=Dense(1)
main_model = Sequential([
vectorize_layer,
em_layer,
GlobalAveragePooling1D(),
firstfc,
secondfc
])
g = Sequential([
vectorize_layer,
em_layer
])
f = Sequential([
GlobalAveragePooling1D(),
firstfc,
secondfc
])
Training using f.fit()/g.fit() will be reflected on main_model and vice versa.
The paper I'm implementing is using an RNN with autoencoder to classify anomalous network data(binary classification). They first train the model unsupervised, and then they describe this process:
Next, fine-tuning training (supervised) is conducted to train the last layer of
the network using labeled samples. Implementing the fine-tuning using
supervised training criterion can further optimize the whole network. We use softmax regression layer with two channels at the top
layer
Currently, I've implemented the autoencoder:
class AnomalyDetector(Model):
def __init__(self):
super(AnomalyDetector, self).__init__()
self.encoder = tf.keras.Sequential([
layers.Dense(64, activation="relu"),
layers.Dense(32, activation="relu"),
layers.Dense(16, activation="relu"),
layers.Dense(8, activation="relu")])
self.decoder = tf.keras.Sequential([
layers.Dense(16, activation="relu"),
layers.Dense(32, activation="relu"),
layers.Dense(64, activation="relu"),
layers.Dense(79, activation='relu')
])
How do you implement the softmax regression layer in TensorFlow?
I'm having trouble understanding the process, am I supposed to add another layer to the autoencoder? Am I supposed to add another function to the class?
Just in case anyone in the future visits this -
You can create a softmax layer by changing the activation. I chose a sigmoid activation in my case since sigmoid is equivalent to a two-element softmax. As per the documentation.
class AnomalyDetector(Model):
def __init__(self):
super(AnomalyDetector, self).__init__()
self.pretrained = False
self.finished_training = False
self.encoder = tf.keras.Sequential([
layers.SimpleRNN(64, activation="relu", return_sequences=True),
layers.SimpleRNN(32, activation="relu", return_sequences=True),
layers.SimpleRNN(16, activation="relu", return_sequences=True),
layers.SimpleRNN(8, activation="relu", return_sequences=True)])
self.decoder = tf.keras.Sequential([
layers.SimpleRNN(16, activation="relu", return_sequences=True),
layers.SimpleRNN(32, activation="relu", return_sequences=True),
layers.SimpleRNN(64, activation="relu", return_sequences=True),
layers.SimpleRNN(79, activation="relu"), return_sequences=True])
layers.SimpleRNN(1, activation="sigmoid")
I am doing am image similarity problem and want to save the image embeddings the model creates during training. Is there a way I can capture the embeddings before they are passed into the loss function?
Here is my model
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(filters=128, kernel_size=2, padding='same', activation='relu', input_shape=(32,32,3)),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Conv2D(filters=64, kernel_size=2, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(32, activation=None), # No activation on final dense layer
tf.keras.layers.Lambda(lambda x: tf.math.l2_normalize(x, axis=1)) # L2 normalize embeddings
])
model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tfa.losses.TripletSemiHardLoss(),
metrics = ["accuracy"])
history = model.fit(train_dataset, epochs=3, validation_data=test_dataset)
To be clear I do not want the outputs just from the final layer shown here. I want to save the final resulting vector that is output from my model.
You can create a custom callback and at the end of training step of each batch, call your model with input batch and get the output and save it.
class SaveEmbeddingCallback(tf.keras.callbacks.Callback):
def on_train_batch_end(self, batch, logs=None):
embedding = self.model.predict(batch)
# IN THIS STAGE YOU HAVE THE OUTPUT OF THE MODEL
# YOU CAN SAVE IT OR WHATEVER YOU WANT
...
model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tfa.losses.TripletSemiHardLoss(),
metrics = ["accuracy"])
history = model.fit(train_dataset,
epochs=3,
validation_data=test_dataset,
callbacks=[SaveEmbeddingCallback()])
For more information on keras custom callbacks read this TensorFlow tutorial