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.
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.
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())