jujuking 266
jujuking 266

Reputation: 13

Keras : Value Error | Shape Miss-match while transfer the pretrained model weight

I have pre-trained a model and save.Now I want to use it for train - test purpose of another dataset. Kind of like transfer learning.

My model architecture is given below.

 model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv1d_1 (Conv1D)            (None, 298, 32)           128       
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 149, 32)           0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 4768)              0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 4768)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 128)               610432    
_________________________________________________________________
dense_2 (Dense)              (None, 4)                 516       
=================================================================
Total params: 611,076
Trainable params: 611,076
Non-trainable params: 0
_________________________________________________________________

So, now when i load this model to train-test another model, I am getting some error. I am not sure about it. I am giving my program below.

# -*- coding: utf-8 -*-
"""Created on Mon Dec 18 23:18:36 2017
@author: Md Junayed Hasan
"""

# PART 1 - Data preprocessing
import numpy as np 
import pandas as pd 

# importing the dataset
# Description: Dataset has row : 5969 and Column : 301
dataset = pd.read_csv('dataset.csv')
# Independent Variables
# In x taking cloumn till 300
x = dataset.iloc[:, :-1].values
# Dependent Variables
y = dataset.iloc[:, 300:301].values 


# Encoding categorical data
from sklearn.preprocessing import LabelEncoder
labelencoder = LabelEncoder()
y[:, 0] = labelencoder.fit_transform(y[:, 0])
classes = list(labelencoder.classes_)


# split train data into train and validation
from sklearn.cross_validation import train_test_split
x_train,x_valid, y_train, y_valid = train_test_split(x,y, test_size=0.8, random_state=23) 


# Feature Scaling / Normalization / Standardization
from sklearn.preprocessing import StandardScaler
sc_x = StandardScaler()
x_train = sc_x.fit_transform(x_train)
x_valid = sc_x.fit_transform(x_valid)


# Initializers
nb_filters = 32 # number of feature detector
nb_kernel_size = 3
nb_strides_conv = 1
nb_features = len(np.transpose(x_train)) # sample size
nb_total_samples = len(x_train) # sample number
nb_pool_size = 2
nb_strides_pool = 2
nb_dropout = 0.1
nb_labels = len(classes)
nb_epochs = 2 # for example
nb_batch_size = 15
nb_channels = 1


# 1 D CNN converting DATA into 3D tensor is must

x_train_r=  np.reshape(x_train,(len(x_train),nb_features,nb_channels))
x_valid_r=  np.reshape(x_valid,(len(x_valid),nb_features,nb_channels))


# CNN Func
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD 
from keras.models import load_model

def CNN_1D(nb_channels,nb_labels,x,y,x_valid_r,y_valid):
    model = Sequential()
    model.add(Dense(128,input_dim =4768, activation = 'relu')) 
    model.add(Dense(32, activation = 'relu' ))
    model.add(Dense(nb_labels, activation = 'softmax'))
    model.load_weights('Scenario1- WC1-2 - WEIGHTS.h5')

    sgd = SGD(lr=0.01, nesterov=True, decay=1e-6, momentum=0.9)

    model.compile(loss='sparse_categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])
    

    y_pred = model.predict(x)
    y_pred = (y_pred > 0.5)
    

    from sklearn.metrics import confusion_matrix
    cm = confusion_matrix(y_valid, y_pred)
    
    print("FINISHED")
    pass

# PART 3 - 1D CNN Function Call
CNN_1D(nb_channels,nb_labels,x,y,x_valid_r,y_valid)

while getting output, I am getting this error.

ValueError: Shapes must be equal rank, but are 2 and 3 for 'Assign' (op: 'Assign') with input shapes: [4768,128], [3,1,32].

I put my details network architecture and dataset architecture also. Please help me to figure it out.

Upvotes: 1

Views: 1191

Answers (1)

Daniel Möller
Daniel Möller

Reputation: 86640

Both models you describe are completely different.

While your model has convolutional layers, pooling layers, etc., you're trying to transfer the weights to a model made only of Dense layers.

This is simply not possible.


The only model that can receive those weights is:

model = Sequential()
model.add(Conv1D(32,
                 kernel_size,
                 input_shape=(inputLength,inputChannels), 
                 activation = any
                 padding=validOrSame)) 
model.add(MaxPooling1D())
model.add(Flatten())
model.add(Dense(128, activation = any))
model.add(Dense(4, activation = any))

model.load_weights('Scenario1- WC1-2 - WEIGHTS.h5')

By the calculations in the summary you can have these combinations:

  • kernel_size=3; inputChannels=1
  • kernel_size=1; inputChannels=3

Only one of the above options will work.

And:

  • nputLength=300; validOrSame='valid'
  • inputLength=298; validOrSame='same'

Only you may know what your original model was to decide about those vars.

Transfering part of the weights

If you create a model compatible with the weights and call it oldModel:

oldModel.load_weights('Scenario1- WC1-2 - WEIGHTS.h5')

Then you create the new model changing the last Dense layer from 4 to 6 units and call it newModel.

After having both models, you transfer the weights:

for i in range(len(oldModel.layers)-1): #loop excluding the last layer
    newModel.layers[i].set_weights(oldModel.layers[i].get_weights())

Upvotes: 1

Related Questions