How to retrain Inception V4 model by unsupervised learning? - python

I was trying to retrain Inception-V4 with an image set to unsupervised learning.
First, I have read the pre-trained weights file for the Inception-V4.
out = Dense(output_dim=nb_classes, activation='softmax')(x)
model = Model(init, out, name='Inception-v4')
if load_weights == True:
weights = checkpoint_custom_path
model.load_weights(weights, by_name=True)
print("Model weights loaded.")
return model
And I removed final full connection layer and dense layer to make the feature extractor.
Next, i added a new convolution layer to get special dimension feature vector form model.
And I saved a model and read again.
model = create_inception_v4(load_weights=check)
model.summary()
model.layers.pop()
model.layers.pop()
model.summary()
x = conv_block(model.layers[-1].output, 512, 1, 1)
x = Flatten()(x)
out = Dense(output_dim=500, activation='softmax')(x)
out = Activation('sigmoid', name='loss')(out)
model2 = Model(input=model.input, output=[out])
model2.summary()
model2.save(checkpoint_custom_path)
model = create_custormized_inception_v4(nb_classes=500, load_weights=check_custom)
model.summary()
The problem is to retrain this model with my image data set.
But I don't know the label for each images.
So, I have to retrain the model by unsupervised learning.
The size of image data set is over 130K.
How can I do retrain the model by unsupervised learning?

Related

Validation Accuracy and training accuracy not improving after applying Transfer learning

I am working on a project in which i am trying to implement transfer learning to classify ECG signals (1-Dimentional). I have a pretrained model with pretty good accuracy, but the model was trained on a different dataset which have an input shape of (4096,12) and output shape (6). I want to fine tune this pre-trained model on my data which have an input shape of (350,5).
To do so, i have added some layers before the input of the pretrained model in order to get the shape (4096,12) and added an output dense layer with shape (5). the code of my model is as below:
from tensorflow.keras.layers import Dense,Input,Conv1D, BatchNormalization,
Activation,Flatten,Reshape,Dropout
from tensorflow.keras.models import Model
#layer to get the desired shape for pre-trained model
new_inp = Input(shape=(300,5))
net = Flatten()(new_inp)
net = Dense(1000, activation='relu')(net)
net = Dropout(0.3)(net)
net = Dense(4096, activation='relu')(net)
net = Dropout(0.3)(net)
net = Reshape([4096,1])(net)
net = Conv1D (filters = 64, kernel_size = 11, strides = 1, padding = 'same')(net)
net = BatchNormalization()(net)
net = Activation('relu')(net)
net = Conv1D (filters = 12, kernel_size = 9, strides = 1, padding = 'same')(net)
net = BatchNormalization()(net)
net = Activation('relu')(net)
# pre-trained model
net = mod(net)
# output layer
ll = Dense(4,activation="softmax")(net)
newModel = Model(new_inp, ll)
my training and validation accuracy is not improving... it improved upto 55%. any idea about the problem.
Thank you.
The idea behind transfer learning is that you concatenate new trainable layers to the end of a pre-trained model, freeze the pre-trained layers, and train the new layers. When you add these new layers to the beginning of the pre-trained model and training the whole network, you are essentially overwriting the pre-trained coefficients.
It is possible to add preprocessing layers (or any layer that does not require back-propagation) to the beginning, but you have added a whole DNN.

If I pass layers to two Keras models and Train only one ,will both the model share weights after the former is trained

I tried to build a simple Autoencoder using Keras for this I started with a single fully-connected neural layer as an encoder and as a decoder.
> input_img = Input(shape=(784,))
>encoded = Dense(encoding_dim,activation='relu')(input_img)
>decoded = Dense(784, activation='sigmoid')(encoded)
>autoencoder =Model(input_img, decoded)
I also created a separate encoder module with the help of
encoder = Model(input_img, encoded)
As well as the decoder model:
encoded_input = Input(shape=(32,))
# retrieve the last layer of the autoencoder model
decoder_layer = autoencoder.layers[-1]
# create the decoder model
decoder = Model(encoded_input, decoder_layer(encoded_input))
Then I trained the model
autoencoder.fit(x_train, x_train,
epochs=50,
batch_size=256,
shuffle=True,
validation_data=(x_test, x_test))
but even if i didn't train my encoder and decoder, Those are sharing the weights of autoencoder even if I passed the layers before training. I trained only the encoder but both encoder and decoder are getting trained.
encoded_imgs = encoder.predict(x_test)
decoded_imgs = decoder.predict(encoded_imgs)
I should have been more careful while reading the text.
If two Keras models are sharing some layers, when you train the first model, the weights from the shared layers will be updated automatically in the other model.
https://keras.io/getting-started/functional-api-guide/
This blog illustrates the use of shared layers nicely.
https://blog.keras.io/building-autoencoders-in-keras.html/

Train with custom weights

Currently I am using transfer learning to train a neural network.
I am using the ResNet50 pretrained model provided by keras.
base_model=ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
# function to finetune model
def build_finetune_model(base_model, dropout, fc_layers, num_classes):
for layer in base_model.layers:
layer.trainable = False
x = base_model.output
x = Flatten()(x)
for fc in fc_layers:
# New FC layer, random init
x = Dense(fc, use_bias=False)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Dropout(dropout)(x)
# New softmax layer
x = Dense(num_classes, use_bias=False)(x)
x = BatchNormalization()(x)
predictions = Activation('softmax')(x)
finetune_model = Model(inputs=base_model.input, outputs=predictions)
return finetune_model
FC_LAYERS = [1024, 512]
dropout = 0.5
model = build_finetune_model(base_model, dropout=dropout, fc_layers=FC_LAYERS,num_classes=len(categories))
Now I wanted to see whether or not using Resnet50 1by2 (amongst others) would increase my accuracy. These models are provided as caffe models. I used the Caffe weight converter to convert these models to a keras h5 file.
The problem now is that these files do not contain a model that can be trained, only the weights.
How can I use the weights to train a model in keras?
If you only have saved weights, you can only load those weights into a network with the same architecture. Assuming the weights you have match the architecture of the Keras Applications model, you can:
base_model = ResNet50(...,weights=None)
base_model.load_weights('my_weights_file.h5')
for layer in base_model.layers:
layer.training = False

Changing input layer size in Keras pertained model

I'm using Inception model in Keras with the pre-trained weights of image net.
The problem is that default input size for this model is 299x299 as per Keras documentation. While my images are 230 * 350 and I don't want to resize them as it will distort the image. So I am trying to find a method to change input layer size.
Below is code is what I tried so far, however I am doubting that the image net weights are being preserved as I thing the architecture will change when I change input size.
Any ideas ..
input = Input(shape=(230, 350, 3), name='image_input')
base_model = InceptionV3(weights='imagenet', include_top=False, input_tensor=input)
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(64, activation='relu')(x)
predictions = Dense(1, activation='sigmoid')(x)
model = Model(inputs=input, outputs=predictions)
for layer in base_model.layers:
layer.trainable = True
model.compile(loss='binary_crossentropy',
optimizer=Adam(lr=0.0001),
metrics=['accuracy'])
Inception V3 is a fully convolutional model. You use the global pooling on the top of convolutional encoder, so slight deviation from the 299x299 should not be a big deal. If you do not have error messages with your code, it must be absolutely fine to use it like this.

Combining CNN with LSTM using Tensorflow Keras

I'm using pre-trained ResNet-50 model and want to feed the outputs of the penultimate layer to a LSTM Network. Here is my sample code containing only CNN (ResNet-50):
N = NUMBER_OF_CLASSES
#img_size = (224,224,3)....same as that of ImageNet
base_model = ResNet50(include_top=False, weights='imagenet',pooling=None)
x = base_model.output
x = GlobalAveragePooling2D()(x)
predictions = Dense(1024, activation='relu')(x)
model = Model(inputs=base_model.input, outputs=predictions)
Next, I want to feed it to a LSTM network, as follows...
final_model = Sequential()
final_model.add((model))
final_model.add(LSTM(64, return_sequences=True, stateful=True))
final_model.add(Dense(N, activation='softmax'))
But I'm confused how to reshape the output to the LSTM input. My original input is (224*224*3) to CNN.
Also, should I use TimeDistributed?
Any kind of help is appreciated.
Adding an LSTM after a CNN does not make a lot of sense, as LSTM is mostly used for temporal/sequence information, whereas your data seems to be only spatial, however if you still like to use it just use
x = Reshape((1024,1))(x)
This would convert it to a sequence of 1024 samples, with 1 feature
If you are talking of spatio-temporal data, Use Timedistributed on the Resnet Layer and then you can use convlstm2d
Example of using pretrained network with LSTM:
inputs = Input(shape=(config.N_FRAMES_IN_SEQUENCE, config.IMAGE_H, config.IMAGE_W, config.N_CHANNELS))
cnn = VGG16(include_top=False, weights='imagenet', input_shape=(config.IMAGE_H, config.IMAGE_W, config.N_CHANNELS))
x = TimeDistributed(cnn)(inputs)
x = TimeDistributed(Flatten())(x)
x = LSTM(256)(x)

Categories