3

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])
  • What is your question? I read your whole post, but it isn't clear to me what you are asking for someone else to help with. – Anton Codes Mar 29 '19 at 18:23
  • My Model isn´t solving the task because accuracy is not good enough. So I am thinking about tuning the Hyperparametres in the code, but I failed by doing it. Im looking for tips to improve my classification model. Most of the things I find online I couldn't make work in my code. e.g. I tried to implement a grid search to find the right best amount of epochs and batch_size: – John Robertus Mar 29 '19 at 18:31
  • Your issue may be because you are trying to use 'binary_crossentropy' and metric='accuracy'. As described in https://stackoverflow.com/questions/42081257/keras-binary-crossentropy-vs-categorical-crossentropy-performance , when using 'binary_crossentropy', you should probably use metrics=[categorical_accuracy] – Anton Codes Mar 29 '19 at 19:06
  • I have a problem with the grid search. it gives me: ValueError: Error when checking input: expected dense_1_input to have 2 dimensions, but got array with shape (21, 224, 224, 3) I gave him: grid_result = grid.fit(x_train, label_batch) as is shown in the code my x_train are my Image_batches and label_batch I loaded them: Found 633 images belonging to 2 classes. Image batch shape: (32, 224, 224, 3) Labe batch shape: (32, 2) But he can't use the shapes for grid search. how can I convert them to the right shape. So he gives me the best Parameters – John Robertus Mar 30 '19 at 19:14

1 Answers1

1

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))
halfer
  • 19,824
  • 17
  • 99
  • 186