leondgarse / keras_cv_attention_models

Keras beit,caformer,CMT,CoAtNet,convnext,davit,dino,efficientdet,edgenext,efficientformer,efficientnet,eva,fasternet,fastervit,fastvit,flexivit,gcvit,ghostnet,gpvit,hornet,hiera,iformer,inceptionnext,lcnet,levit,maxvit,mobilevit,moganet,nat,nfnets,pvt,swin,tinynet,tinyvit,uniformer,volo,vanillanet,yolor,yolov7,yolov8,yolox,gpt2,llama2, alias kecam
MIT License
595 stars 95 forks source link

Training pretrained models with new input_shape #87

Closed ErenCaldiran closed 1 year ago

ErenCaldiran commented 1 year ago

Hi, How can I change the input shape of a model while preserving weights of layers and finetune?

I have tried methods that I've found online such as changing config files, but the input shape does not change.

Here is what I've tried:

model = #load some model

config = model.layers[0].get_config() #Get Input layer of pretrained model.

config['batch_input_shape'] = (None, 640, 384, 3) #default (None, 260, 260, 3)

print(config) #Prints {'batch_input_shape': (None, 640, 384, 3), 'dtype': 'float32', 'sparse': False, 'ragged': False, 'name': 'input_3'}

model.layers[0] = model.layers[0].from_config(config)

print(model.layers[0].get_config()) #Prints {'batch_input_shape': (None, 260, 260, 3), 'dtype': 'float32', 'sparse': False, 'ragged': False, 'name': 'input_3'}

If I use somename = model.layers[0].from_config(config) and print, input_shape changes correctly but now I have to attach all other layers to "somename" and build a new model, which will lose the weights.

Then to save the weights I use:

new_model = tf.keras.models.model_from_json(model.to_json())

for layer in new_model.layers: layer.set_weights(model.get_layer(name=layer.name).get_weights())

At the end I have new_model, which is exactly the same as the pretrained model with its weights.

What to do at this point to be able to change input_size of a model and finetune with initially saved weights preserved.

leondgarse commented 1 year ago

Just create model with a new input_shape, it will auto reload the pretrained weights if any.

from keras_cv_attention_models import coatnet
mm = coatnet.CoAtNet0(input_shape=(114, 227, 3))
# >>>> Load pretrained from: /home/leondgarse/.keras/models/coatnet0_224_imagenet.h5

Also, if it's a model like efficientnet not care about input_shape, model_surgery.change_model_input_shape will do the job:

from keras_cv_attention_models import efficientnet, model_surgery
mm = efficientnet.EfficientNetV2B3(pretrained='imagenet21k', num_classes=21843)
print(mm.input_shape)
# (None, 300, 300, 3)
dd = model_surgery.change_model_input_shape(mm, [256, 256, 3])
# >>>> Changed model input shape from (None, 300, 300, 3) to (None, 256, 256, 3)
print(dd.input_shape)
# (None, 256, 256, 3)
ErenCaldiran commented 1 year ago

Thank you, I will try your suggestions and close the issue.