John Robertus
John Robertus

Reputation: 31

Hyperparameter-Tuning for pretrained NN from TensorFlow

I am starting to learn Python and trying create a neural network, which detects and localizes anomalious parts of images. I am using a pretrained CNN from TensorFlow. The code works so far as it learns my images and classifies them. But when I give him the same amount (around 100) of images for each class. the accuracy is around 50% which is random for two classes. So I am looking for a solution for it right now. The localization Problem I solving by slicing my images in to multiple parts. The anomaly is being split from non-anomalous region while every image has an reference of its location in its name. So when the image is classified as a certain class one also finds out about its location by its name.

first option: I have to find for a way to extent the amount of my images to look if it improves my accuracy.I didn't work on that yet. second option: trying to tune the hyper parameters of the CNN, maybe put my images in some earlier layers. I watched a couple tutorials and tried to implement them, but they all failed mostly due to the shape of the arrays or inconsistent numbers.


# Use scikit-learn to grid search the batch size and epochs
import numpy
from sklearn.model_selection import GridSearchCV
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
# Function to create model, required for KerasClassifier
def create_model():
    # create model
    model = Sequential()
    model.add(Dense(12, input_dim=8, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    # Compile model
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load dataset
# create model
model = KerasClassifier(build_fn=create_model, verbose=0)
# define the grid search parameters
batch_size = [10, 20, 40, 60, 80, 100]
epochs = [10, 50, 100]
param_grid = dict(batch_size=batch_size, epochs=epochs)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
grid_result = grid.fit(x_train, label_batch)
# summarize results
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
    print("%f (%f) with: %r" % (mean, stdev, param))

init = tf.global_variables_initializer()
sess.run(init)

result = model.predict(image_batch)
result.shape

model.compile(
  optimizer=tf.train.AdamOptimizer(), 
  loss='categorical_crossentropy',
  metrics=['accuracy'])

class CollectBatchStats(tf.keras.callbacks.Callback):
  def __init__(self):
    self.batch_losses = []
    self.batch_acc = []

  def on_batch_end(self, batch, logs=None):
    self.batch_losses.append(logs['loss'])
    self.batch_acc.append(logs['acc'])

steps_per_epoch = image_data.samples//image_data.batch_size
batch_stats = CollectBatchStats()
model.fit((item for item in image_data), epochs=1, 
                    steps_per_epoch=steps_per_epoch,
                    callbacks = [batch_stats])

Upvotes: 3

Views: 617

Answers (1)

user11530462
user11530462

Reputation:

From what you mentioned in the comments you are facing the below error.

ValueError: Error when checking input: expected dense_1_input to have 2 dimensions, but got array with shape (21, 224, 224, 3)

If you are using CNN, why is the First Layer a Dense Layer (I understand it from the name, dense_1_input), instead of a Convolutional Layer.

With the First Layer being the Convolutional Layer, you should pass (224,224,3) for the argument, input_shape

Complete code for Fine Tuning Batch_Size and Number of Epochs for Fashion_MNIST Dataset using CNN is shown below:

# To support both python 2 and python 3
from __future__ import division, print_function, unicode_literals
from io import open

# Common imports
import numpy as np
import os
import tensorflow as tf
from keras.layers import Input, Conv2D, MaxPool2D, Dense, Dropout, Flatten
from keras.models import Sequential
from keras.optimizers import Adam
import matplotlib.pyplot as plt
from keras.regularizers import l1_l2
from matplotlib.pyplot import axis as ax
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV


X = tf.placeholder(tf.float32, shape=[None, 784], name="X")
X_reshaped = tf.reshape(X, shape=[-1, 28, 28, 1])
y = tf.placeholder(tf.int32, shape=[None], name="y")

def create_model():

    # instantiate regularizer
    Regularizer = l1_l2(0.001)

    cnn_model = Sequential()

    cnn_model.add(Conv2D(filters = 64,kernel_size = 3, strides=(1, 1), input_shape = (28,28,1), 
                         activation='relu', data_format='channels_last', activity_regularizer=Regularizer))

    cnn_model.add(MaxPool2D(pool_size = (2, 2)))

    cnn_model.add(Dropout(0.25))

    cnn_model.add(Flatten())

    cnn_model.add(Dense(units = 32, activation = 'relu', activity_regularizer=Regularizer))

    cnn_model.add(Dense(units = 10, activation = 'sigmoid', activity_regularizer=Regularizer))

    cnn_model.compile(loss ='sparse_categorical_crossentropy', optimizer=Adam(lr=0.001),metrics =['accuracy'])
    return cnn_model

model = KerasClassifier(build_fn=create_model, verbose=0)

(X_train, y_train), (X_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
X_train = X_train.astype(np.float32).reshape(-1, 28*28) / 255.0
X_train_reshaped = np.reshape(X_train, newshape=[-1, 28, 28, 1])

X_test = X_test.astype(np.float32).reshape(-1, 28*28) / 255.0
X_test_reshaped = np.reshape(X_test, newshape=[-1, 28, 28, 1])

y_train = y_train.astype(int)
y_test = y_test.astype(int)


batch_size = [20, 40]
epochs = [10, 50]
param_grid = dict(batch_size=batch_size, epochs=epochs)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=1, cv=3)
grid_result = grid.fit(X_train_reshaped, y_train)
# summarize results
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
    print("%f (%f) with: %r" % (mean, stdev, param))

Upvotes: 1

Related Questions