trying to callibrate keras model - python

I'm trying to calibrate my CNN model by Sklearn implementation CalibratedClassifierCV, tried to wrap it as KerasClassifier and to override the predict function but without success.
someone could say me what I did wrong?
this is the model code:
def create_model():
model = Sequential()
model.add(Conv2D(64, kernel_size=(3,3), activation = 'relu', input_shape=(28, 28 ,1) ))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Conv2D(64, kernel_size = (3, 3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Flatten())
model.add(Dense(128, activation = 'relu'))
model.add(Dropout(0.20))
model.add(Dense(24, activation = 'softmax'))
model.compile(loss = keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(), metrics=['accuracy'])
return model
this is me trying to calibrate it :
model = KerasClassifier(build_fn=create_model,epochs=5, batch_size=128,validation_data=(evalX_cnn, eval_y_cnn))
model.fit(trainX_cnn, train_y_cnn)
model_c = CalibratedClassifierCV(base_estimator=model, cv='prefit')
model_c.fit(valX_cnn, val_y_cnn)
the output :
-------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-19-3d3ce9ce4fca> in <module>
----> 1 model_c.fit(np.array(valX_cnn), np.array(val_y_cnn))
~\anaconda3\lib\site-packages\sklearn\calibration.py in fit(self, X, y, sample_weight)
286 pred_method, method_name = _get_prediction_method(base_estimator)
287 n_classes = len(self.classes_)
--> 288 predictions = _compute_predictions(pred_method, method_name, X, n_classes)
289
290 calibrated_classifier = _fit_calibrator(
~\anaconda3\lib\site-packages\sklearn\calibration.py in _compute_predictions(pred_method, method_name, X, n_classes)
575 (X.shape[0], 1).
576 """
--> 577 predictions = pred_method(X=X)
578
579 if method_name == "decision_function":
TypeError: predict_proba() missing 1 required positional argument: 'x'
valX_cnn and val_y_cnn are of type np.array.
tried even to override the method:
keras.models.Model.predict_proba = keras.models.Model.predict

The problem is because predict_proba from KerasClassifier requires x as input while predict_proba method from sklearn accepts X as input argument (note the difference: X is not x).
You can simply overdrive the problem wrapping KerasClassifier into a new class to correct the predict_proba method.
samples,classes = 100,3
X = np.random.uniform(0,1, (samples,28,28,1))
Y = tf.keras.utils.to_categorical(np.random.randint(0,classes, (samples)))
class MyKerasClassifier(KerasClassifier):
def predict_proba(self, X):
return self.model.predict(X)
model = MyKerasClassifier(build_fn=create_model, epochs=3, batch_size=128)
model.fit(X, Y)
model_c = CalibratedClassifierCV(base_estimator=model, cv='prefit')
model_c.fit(X, Y)

The wrappers are going to be deprecated. From tensorflow>=2.7.0 you might want to use scikeras.
pckg repo>
https://github.com/adriangb/scikeras
code example>
from sklearn.datasets import make_classification
from tensorflow import keras
from scikeras.wrappers import KerasClassifier
X, y = make_classification(1000, 20, n_informative=10, random_state=0)
X = X.astype(np.float32)
y = y.astype(np.int64)
def get_model(hidden_layer_dim, meta):
# note that meta is a special argument that will be
# handed a dict containing input metadata
n_features_in_ = meta["n_features_in_"]
X_shape_ = meta["X_shape_"]
n_classes_ = meta["n_classes_"]
model = keras.models.Sequential()
model.add(keras.layers.Dense(n_features_in_, input_shape=X_shape_[1:]))
model.add(keras.layers.Activation("relu"))
model.add(keras.layers.Dense(hidden_layer_dim))
model.add(keras.layers.Activation("relu"))
model.add(keras.layers.Dense(n_classes_))
model.add(keras.layers.Activation("softmax"))
return model
clf = KerasClassifier(
get_model,
loss="sparse_categorical_crossentropy",
hidden_layer_dim=100,
)
clf.fit(X, y)
y_proba = clf.predict_proba(X)

Related

TypeError: fit_generator() missing 1 required positional argument: 'generator'

I am trying to train a CNN to detect if an image is deepfake or not , but upon running the code I keep getting this error: TypeError: fit_generator() missing 1 required positional argument: 'generator' How do I get rid of this error? Is there an issue with my code? Im also not sure if the classifier class is necessary so i've included it but commented it out.
My code in full:
import tensorflow as tf
config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.compat.v1.Session(config=config)
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.layers import Input, Dense, Flatten, Conv2D, MaxPooling2D, BatchNormalization, Dropout, Reshape, Concatenate, LeakyReLU
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Model
from keras.callbacks import ModelCheckpoint
from keras.models import Sequential
from keras.models import Model
# Height and width refer to the size of the image
# Channels refers to the amount of color channels (red, green, blue)
image_dimensions = {'height':256, 'width':256, 'channels':3}
# Create a Classifier class
#class Classifier():
# def __init__():
# self.model = 0
#def predict(self, x):
# return self.model.predict(x)
# def fit(self, x, y):
#return self.model.train_on_batch(x, y)
# def get_accuracy(self, x, y):
#return self.model.test_on_batch(x, y)
#def load(self, path):
# self.model.load_weights(path)
class Meso4(Model):
def __init__(self, learning_rate = 0.0001):
self.model = self.init_model()
optimizer = Adam(lr = learning_rate)
self.model.compile(optimizer = optimizer,
loss = 'mean_squared_error',
metrics = ['accuracy'])
def init_model(self):
x = Input(shape = (image_dimensions['height'],
image_dimensions['width'],
image_dimensions['channels']))
x1 = Conv2D(8, (3, 3), padding='same', activation = 'relu')(x)
x1 = BatchNormalization()(x1)
x1 = MaxPooling2D(pool_size=(2, 2), padding='same')(x1)
x2 = Conv2D(8, (5, 5), padding='same', activation = 'relu')(x1)
x2 = BatchNormalization()(x2)
x2 = MaxPooling2D(pool_size=(2, 2), padding='same')(x2)
x3 = Conv2D(16, (5, 5), padding='same', activation = 'relu')(x2)
x3 = BatchNormalization()(x3)
x3 = MaxPooling2D(pool_size=(2, 2), padding='same')(x3)
x4 = Conv2D(16, (5, 5), padding='same', activation = 'relu')(x3)
x4 = BatchNormalization()(x4)
x4 = MaxPooling2D(pool_size=(4, 4), padding='same')(x4)
y = Flatten()(x4)
y = Dropout(0.5)
y = Dense(16)
y = LeakyReLU(alpha=0.1)
y = Dropout(0.5)
y = Dense(1, activation = 'sigmoid')
return Model(inputs = x, outputs = y)
bat_size = 64
input_size = 256
# initializing a train datagenerator
train_datagen = ImageDataGenerator(rescale=1./255)
# initializing a test datagenerator
test_datagen = ImageDataGenerator(rescale=1./255)
# preprocessing for trainig set
train_set = train_datagen.flow_from_directory(
'C:\\Users\\Kevin\\Desktop\\Train', # train data directory
target_size=(input_size, input_size),
batch_size=bat_size,
class_mode='categorical',
color_mode= 'rgb'
)
# preprocessing for test set
test_set = test_datagen.flow_from_directory(
'C:\\Users\\Kevin\\Desktop\\Test', # test data directory
target_size=(input_size, input_size),
batch_size=bat_size,
shuffle=False,
class_mode='categorical',
color_mode= 'rgb'
)
filepath = "FYP.hdf5"
checkpoint = ModelCheckpoint(
filepath,
monitor='val_acc',
verbose=1,
save_best_only=True,
mode='max'
)
Meso4.fit_generator(
train_set,
steps_per_epoch=1400//bat_size + 1,
epochs=25,
callbacks=[checkpoint],
validation_data=test_set,
validation_steps=600 //bat_size + 1
)
#ERROR
TypeError Traceback (most recent call last)
<ipython-input-9-00d0b295f968> in <module>
5 callbacks=[checkpoint],
6 validation_data=test_set,
----> 7 validation_steps=600 //bat_size + 1
8 )
~\Anaconda3\envs\Tf\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
89 warnings.warn('Update your `' + object_name + '` call to the ' +
90 'Keras 2 API: ' + signature, stacklevel=2)
---> 91 return func(*args, **kwargs)
92 wrapper._original_function = func
93 return wrapper
TypeError: fit_generator() missing 1 required positional argument: 'generator'
3 or 4 Mistakes i can see :
For subclassing in keras:
You need to call super(YourClass, self).__init__()
You define your model inside a call method
Check this link to learn more about keras subclassing
Also in your y part you stop using functional syntax
y = Flatten()(x4)
y = Dropout(0.5)
y = Dense(16)
it should be
y = Dropout(0.5)(y)
y = Dense(16)(y)
and you dont call class directly just instantiate a new object

KERAS TUNER: object of type 'HyperParameters' has no len()

here its my code trying to use KERAS TUNER:
datagen = ImageDataGenerator(
rescale=1.0/255.0,
zoom_range=[-2, 2],
width_shift_range=[-25, 25],
height_shift_range=[-25, 25],
rotation_range=40,
shear_range=40,
horizontal_flip=True,
vertical_flip=True,
brightness_range=[0.98,1.05],
featurewise_center=True,
samplewise_center=True,
# channel_shift_range=1.5,
#featurewise_center=True,
#featurewise_std_normalization=True,
validation_split=0.10)
mean,std=auxfunctions.getMeanStdClassification()
datagen.mean=mean
datagen.std=std
numClasses = 5
width=240 #diabetic retinopaty 120 120, drRafael 40 40, 96 96
height=240
input_shape=(width,height,3)
train_generator = datagen.flow_from_dataframe(
dataframe=trainLabels,
directory='./resized_train_cropped',
x_col="image",
y_col="level",
target_size=(240,240),
batch_size=16,
class_mode='categorical',
color_mode='rgb', #quitar o no quitar
subset='training')
validation_generator =datagen.flow_from_dataframe(
dataframe=trainLabels,
directory='./resized_train_cropped',
x_col="image",
y_col="level",
target_size=(240,240),
batch_size=16,
class_mode='categorical',
color_mode='rgb',
subset='validation')
#----------------------------------------------------------------------------------------
def createBaseNetwork(input_shape):
weight_decay = 1e-4
L2_norm = regularizers.l2(weight_decay)
input = Input(shape=input_shape)
print(input)
x = Conv2D(96, (9, 9), activation='relu', name='conv1', kernel_regularizer=L2_norm)(input)
x = MaxPooling2D((3, 3), name='pool1')(x)
x = BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001)(x)
x = Conv2D(384, (5, 5), activation='relu', name='conv2', kernel_regularizer=L2_norm)(x)
x = MaxPooling2D((3, 3), name='pool2')(x)
x = BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001)(x)
x = Conv2D(384, (3, 3), activation='relu', name='conv3')(x)
x = Conv2D(384, (3, 3), activation='relu', name='conv4')(x)
x = Conv2D(256, (3, 3), activation='relu', name='conv5')(x)
x = MaxPooling2D((3, 3), name='pool3')(x)
x = Flatten()(x)
x = Dense(4096, activation='relu', name='fc1')(x)
return Model(input, x)
# ---------------------------------------------------------------------------------
hp=HyperParameters()
baseNetwork=createBaseNetwork(input_shape)
#baseNetwork.load_weights('./ModelWeights2.h5',by_name=True)
for l in baseNetwork.layers:
l.trainable=True
input_a = Input(shape=input_shape,name='input1')
outLayers = baseNetwork(input_a)
outLayers = Dense(2048, activation='relu', name='fc3')(outLayers)
outLayers= Dropout(0.2)(outLayers)
outLayers = Dense(1024, activation='relu', name='fc4')(outLayers)
outLayers= Dropout(0.2)(outLayers)
outLayers = Dense(hp.Int('input_units',min_value=32,max_value=512), activation='relu', name='fc5')(outLayers)
classifier = Dense(numClasses, activation='softmax', name='predictions')(outLayers)
model = Model(input_a, classifier)
model.summary()
tuner = RandomSearch(
model,
objective='val_accuracy',
max_trials=1,
executions_per_trial=1,
directory='./logtunner'
)
tuner.search(
train_generator,
validation_data=validation_generator,
epochs=1,
)
For now im just trying to use it on the last Dense layer, as you can see i just want to stimate a good number of neurons with this:
hp.Int('input_units',min_value=32,max_value=512)
But i get an error like this:
ValueError: TypeError: object of type 'HyperParameters' has no len()
I dont know how to solve it, i spent hours watching videos and tutorials but no idea of what is happening.
I also realize that there is another error mesage:
This function does not handle the case of the path where all inputs are not already EagerTensors
But i dont have any idea about that too
I was having more or less of the same error.
If you pay attention to to the keras-tuner in the tensorflow website https://www.tensorflow.org/tutorials/keras/keras_tuner or in the keras website, you see the following:
tuner = kt.Hyperband(model_builder,
objective = 'val_accuracy',
max_epochs = 10,
factor = 3,
directory = 'my_dir',
project_name = 'intro_to_kt')
the first input to the tuner is the function model_builder that is declared earlier as
def model_builder(hp):
model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28, 28)))
# Tune the number of units in the first Dense layer
# Choose an optimal value between 32-512
hp_units = hp.Int('units', min_value = 32, max_value = 512, step = 32)
model.add(keras.layers.Dense(units = hp_units, activation = 'relu'))
model.add(keras.layers.Dense(10))
# Tune the learning rate for the optimizer
# Choose an optimal value from 0.01, 0.001, or 0.0001
hp_learning_rate = hp.Choice('learning_rate', values = [1e-2, 1e-3, 1e-4])
model.compile(optimizer = keras.optimizers.Adam(learning_rate = hp_learning_rate),
loss = keras.losses.SparseCategoricalCrossentropy(from_logits = True),
metrics = ['accuracy'])
return model
So, all you need is reorganize your code to follow the same structure. You need to encapsulate the keras model and keras-tuner hp inside a function.
Cheers.

'Sequential' object has no attribute '_in_multi_worker_mode'

I tried to use google colab resources to save my CNN model weights and I get this error. I tried googling it but nothing helps.
'Sequential' object has no attribute '_in_multi_worker_mode'
My code:
checkpoint_path = "training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path, save_weights_only=True, verbose=1)
cnn_model = Sequential()
cnn_model.add(Conv2D(filters = 64, kernel_size = (3,3), activation = "relu", input_shape = Input_shape ))
cnn_model.add(Conv2D(filters = 64, kernel_size = (3,3), activation = "relu"))
cnn_model.add(MaxPooling2D(2,2))
cnn_model.add(Dropout(0.4))
cnn_model = Sequential()
cnn_model.add(Conv2D(filters = 128, kernel_size = (3,3), activation = "relu"))
cnn_model.add(Conv2D(filters = 128, kernel_size = (3,3), activation = "relu"))
cnn_model.add(MaxPooling2D(2,2))
cnn_model.add(Dropout(0.3))
cnn_model.add(Flatten())
cnn_model.add(Dense(units = 512, activation = "relu"))
cnn_model.add(Dense(units = 512, activation = "relu"))
cnn_model.add(Dense(units = 10, activation = "softmax"))
history = cnn_model.fit(X_train, y_train, batch_size = 32,epochs = 1,
shuffle = True, callbacks = [cp_callback])
Stack trace:
AttributeError Traceback (most recent call last)
<ipython-input-19-35c1db9636b7> in <module>()
----> 1 history = cnn_model.fit(X_train, y_train, batch_size = 32,epochs = 1, shuffle = True, callbacks = [cp_callback])
4 frames
/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/callbacks.py in on_train_begin(self, logs)
903 def on_train_begin(self, logs=None):
904 # pylint: disable=protected-access
--> 905 if self.model._in_multi_worker_mode():
906 # MultiWorkerTrainingState is used to manage the training state needed
907 # for preemption-recovery of a worker in multi-worker training.
AttributeError: 'Sequential' object has no attribute '_in_multi_worker_mode'
I've recently faced the same issue
instead of,
from tensorflow.keras.callbacks import ModelCheckpoint
use,
from keras.callbacks import ModelCheckpoint
Check your tensorflow version. You actually only need to synchronize it. check if all your import uses
from keras import ...
or
from tensorflow.keras import ...
use only one of the above for your keras imports. using different (both) at the same time can cause collision by the libraries.
Instead of
tf.keras.callbacks.ModelCheckpoint
in your model building process, you can use
from keras.callbacks import ModelCheckpoint
in order to import ModelCheckpoint, and then just use ModelCheckpoint in the later code.
Please check if your version of tensorflow matches the latest one.In my case the error was solved when is updated it to 2.1.0.

Why does my keras custom layer fit well on training data but gives bad results on validation?

I am trying to understand how Keras custom layers works, but I am facing a problem with the validation accuracy of my model.
I tried to reproduce a simple convolutional network on MNIST dataset but with a custom layer combining the Conv2D operator and the BatchNormalisation.
First, the data I used :
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = np.array([x.reshape(28, 28, 1) for x in X_train])
X_test = np.array([x.reshape(28, 28, 1) for x in X_test])
y_train = pd.get_dummies(y_train)
y_test = pd.get_dummies(y_test)
Here is the original implementation which works well :
def get_model():
input_ = Input(shape=(28, 28, 1))
x = Conv2D(filters=64, kernel_size=3, activation="relu", input_shape=(28,28,1))(input_)
x = BatchNormalization()(x)
x = MaxPool2D(pool_size=(2,2))(x)
x = Conv2D(filters=128, kernel_size=3, activation="relu")(input_)
x = BatchNormalization()(x)
x = MaxPool2D(pool_size=(2,2))(x)
x = Conv2D(filters=256, kernel_size=3, activation="relu")(input_)
x = BatchNormalization()(x)
x = MaxPool2D(pool_size=(2,2))(x)
x = Flatten()(x)
x = Dense(128, activation="relu")(x)
x = Dense(64, activation="relu")(x)
x = Dense(10, activation="softmax")(x)
mod = Model(inputs=input_, outputs=x)
return mod
optim = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, clipvalue=K.epsilon())
model = get_model()
model.compile(optimizer=optim, loss='categorical_crossentropy', metrics=["accuracy"])
model.fit(X_train, y_train, batch_size=128, epochs=3, validation_data=(X_test, y_test))
With this initial model, after 3 epochs, I get a train accuracy of 97% and validation 97%
And here is my custom layer :
class Conv2DLayer(Layer):
def __init__(self, filters, kernel_size, dropout_ratio=None, strides=(1, 1), activation="relu", use_bn=True, *args, **kwargs):
self._filters = filters
self._kernel_size = kernel_size
self._dropout_ratio = dropout_ratio
self._strides = strides
self.use_bn = use_bn
self._activation = activation
self._args = args
self._kwargs = kwargs
super(Conv2DLayer, self).__init__(*args, **kwargs)
def build(self, input_shape):
self.conv = Conv2D(self._filters,
kernel_size=self._kernel_size,
activation=self._activation,
strides=self._strides,
input_shape=input_shape,
*self._args,
**self._kwargs)
self.conv.build(input_shape)
self.out_conv_shape = self.conv.compute_output_shape(input_shape)
self._trainable_weights = self.conv._trainable_weights
self._non_trainable_weights = self.conv._non_trainable_weights
if self.use_bn:
self.bn = BatchNormalization()
self.bn.build(self.out_conv_shape)
self._trainable_weights.extend(self.bn._trainable_weights)
self._non_trainable_weights.extend(self.bn._non_trainable_weights)
if self._dropout_ratio is not None:
self.dropout = Dropout(rate=self._dropout_ratio)
self.dropout.build(self.out_conv_shape)
self._trainable_weights.extend(self.dropout._trainable_weights)
self._non_trainable_weights.extend(self.dropout._non_trainable_weights)
super(Conv2DLayer, self).build(input_shape)
def call(self, inputs):
x = self.conv(inputs)
if self.use_bn:
x = self.bn(x)
if self._dropout_ratio is not None:
x = self.dropout(x)
return x
def compute_output_shape(self, input_shape):
return self.out_conv_shape
Finally, here is the modified model :
def get_model():
input_ = Input(shape=(28, 28, 1))
x = Conv2DLayer(filters=64, kernel_size=3, activation="relu")(input_)
x = MaxPool2D(pool_size=(2,2))(x)
x = Conv2DLayer(filters=128, kernel_size=3, activation="relu")(input_)
x = MaxPool2D(pool_size=(2,2))(x)
x = Conv2DLayer(filters=256, kernel_size=3, activation="relu")(input_)
x = MaxPool2D(pool_size=(2,2))(x)
x = Flatten()(x)
x = Dense(128, activation="relu")(x)
x = Dense(64, activation="relu")(x)
x = Dense(10, activation="softmax")(x)
mod = Model(inputs=input_, outputs=x)
return mod
For this model with custom layer, I managed to get the same train accuracy (97%), but the validation accuracy get stuck around 50%.
EDIT
Thanks to Matias Valdenegro, I achieved to solve the problem by modifying the call method :
def call(self, inputs):
training = K.learning_phase()
x = self.conv(inputs)
if self.use_bn:
x = self.bn(x, training=training)
if self._dropout_ratio is not None:
x = self.dropout(x, training=training)
return x
With K the keras.backend module.
Both Dropout and Batch Normalization behave differently during training and testing/inference, and your layer does not have any of that behavior, so its using those inner layers as training mode during inference, producing incorrect results.
I am not sure but I think you can fix this by passing the training parameter in the call function call through the layers, something like:
def call(self, inputs, training=None):
x = self.conv(inputs)
if self.use_bn:
x = self.bn(x, training=training)
if self._dropout_ratio is not None:
x = self.dropout(x, training=training)
return x
This should make the inner layers work differently during train and testing/inference phases.

keras fit_generator gives 0 accuracy

I have a large dataset of n_samples, n_features, n_classes = 346679, 10233, 86. I am trying to build a classifier on this dataset. For this, I am using a Multi-Layer Perceptron which is built using the keras sequential model.
DataGeneratorClass
class DataGeneratorKeras:
def __init__(self, num_rows, n_classes, n_samples, n_features, batch_size=1, shuffle=True):
self.num_rows = num_rows
self.n_samples = n_samples
self.n_features = n_features
self.n_classes = n_classes
self.batch_size = batch_size
self.shuffle = shuffle
self.flag = False
def __get_exploration_order(self, list_ids):
"""
Generates order of exploration
:param list_ids:
:return:
"""
# Find exploration order
indexes = np.arange(len(list_ids))
if self.shuffle:
np.random.shuffle(indexes)
return indexes
def __data_generation(self, list_ids_temp, n_classes):
"""
Generates data of batch_size samples
:param list_ids_temp:
:param n_classes:
:return:
"""
index = list_ids_temp[0]
fv = load_npz("data_file_" + str(index) + ".npz")
labels_complete = load(...) # Load labels
partial_labels = labels_complete[index]
del labels_complete
y = self.sparsify(partial_labels, n_classes)
return fv, y
#staticmethod
def sparsify(y, n_classes):
"""
:return:
"""
label_encoder = np_utils.to_categorical(y, n_classes)
return label_encoder
def generate(self, list_ids):
"""
Generates batches of samples
:param list_ids:
:return:
"""
# Infinite loop
while 1:
# Generate order of exploration of dataset
indexes = self.__get_exploration_order(list_ids)
# Generate batches
imax = int(len(indexes) / self.batch_size)
for i in range(imax):
# Find list of IDs
list_ids_temp = [list_ids[k] for k in indexes[i * self.batch_size:(i + 1) * self.batch_size]]
# Generate data
x, y = self.__data_generation(list_ids_temp, self.n_classes)
yield x.toarray(), y
The Script class
class Script:
def __init__(self, num_rows, batch_size, test_size, n_classes, n_samples, n_features):
self.batch_size = batch_size
self.num_rows = num_rows
self.test_size = test_size
self.n_classes = n_classes
self.n_samples = n_samples
self.n_features = n_features
def main(self):
validation = int(self.test_size * self.num_rows)
train = self.num_rows - validation
params = {
'num_rows': self.num_rows,
'n_samples': self.n_samples,
'n_features': self.n_features,
'n_classes': self.n_classes,
'batch_size': self.batch_size,
'shuffle': True
}
partition = {'train': range(train), 'validation': range(train, self.num_rows)}
# Generators
training_generator = DataGeneratorKeras(**params).generate(partition['train'])
validation_generator = DataGeneratorKeras(**params).generate(partition['validation'])
return training_generator, validation_generator, partition
if __name__ == "__main__":
script = Script(num_rows=347, test_size=0.25, n_classes=86, n_samples=346679, n_features=10233, batch_size=1)
training_generator, validation_generator, partition = script.main()
Building the model
def classifier_base_data(dropout, learning_rate):
model = Sequential()
model.add(Dense(2**13, input_shape=(script.n_features,), activation='relu', name="l_input"))
model.add(BatchNormalization())
model.add(Dropout(dropout))
model.add(Dense(2**12, input_dim=2**13, activation='relu', name="l_hidden_1"))
model.add(BatchNormalization())
model.add(Dropout(dropout))
model.add(Dense(2**11, input_dim=2**12, activation='relu', name="l_hidden_2"))
model.add(BatchNormalization())
model.add(Dropout(dropout))
model.add(Dense(2**10, input_dim=2**11, activation='relu', name="l_hidden_3"))
model.add(BatchNormalization())
model.add(Dropout(dropout))
model.add(Dense(2**9, input_dim=2**10, activation='relu', name="l_hidden_4"))
model.add(BatchNormalization())
model.add(Dropout(dropout))
model.add(Dense(2**8, input_dim=2**9, activation='relu', name="l_hidden_5"))
model.add(BatchNormalization())
model.add(Dropout(dropout))
model.add(Dense(2**7, input_dim=2**8, activation='relu', name="l_hidden_6"))
model.add(BatchNormalization())
model.add(Dropout(dropout))
model.add(Dense(script.n_classes, activation='softmax', name="l_output"))
optimizer = adam(lr=learning_rate)
model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
print model.summary()
return model
When I run the model using keras fit function, I am able to achieve val_acc and acc above 25%.
history = model.fit(x_train.toarray(), y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_validation.toarray(), y_validation))
Since the data is large, I am using the DataGenerator by keras following a very well written tutorial keras-datagen-tutorial. When I run the model using the fit_generator, I get 0% val_acc.
model.fit_generator(
generator = training_generator,
steps_per_epoch = len(partition['train']),
epochs = epochs,
validation_data = validation_generator,
validation_steps = len(partition['validation']),
verbose = 1
)
Is there any issue in the DataGenerator written?

Categories