# How to improve my test accuracy using CNN in Tensorflow

I'm working on a Dogs vs. Cats Redux: Kernels Edition project from Kaggle and I'm new for this area. So far, I couldn't be able to improve my test rate over %50. I'm wondering what can i do to improve my test accuracy or is there something wrong about my code? By the way, below code is use tflearn library but i also tried with Tensorflow directly, still i can not go over %50.

from __future__ import division, print_function, absolute_import

import csv

from skimage import color, io
from scipy.misc import imresize
import numpy as np
from sklearn.model_selection import train_test_split
import os
from glob import glob
import tflearn
from tflearn.data_utils import shuffle, to_categorical
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.estimator import regression
from tflearn.data_preprocessing import ImagePreprocessing
from tflearn.data_augmentation import ImageAugmentation
from tflearn.metrics import Accuracy
###################################
### Import picture files
###################################

files_path = 'dataset/train'
cat_files_path = os.path.join(files_path, 'cat*.jpg')
dog_files_path = os.path.join(files_path, 'dog*.jpg')
test_files_path = os.path.join('dataset/test1', '*.jpg')

cat_files = sorted(glob(cat_files_path))
dog_files = sorted(glob(dog_files_path))
test_files = sorted(glob(test_files_path))

n_files = len(cat_files) + len(dog_files)
test_n = len(test_files)
print(test_n)
size_image = 64
allX = np.zeros((n_files, size_image, size_image,3), dtype='float64')
ally = np.zeros(n_files)
testX = np.zeros((test_n, size_image, size_image, 3), dtype='float64')
count = 0
for f in test_files:
try:
new_img = imresize(img, (size_image,size_image,3))
testX[count] = np.array(new_img)
count += 1
except:
continue
count = 0
for f in cat_files:
try:
new_img = imresize(img, (size_image,size_image,3))
allX[count] = np.array(new_img)
ally[count] = 0
count += 1
except:
continue
for f in dog_files:
try:
new_img = imresize(img, (size_image,size_image,3))
allX[count] = np.array(new_img)
ally[count] = 1
count += 1
except:
continue

###################################
# Prepare train & test samples
###################################

# test-train split
X, X_test, Y, Y_test = train_test_split(allX,ally,test_size=0.1, random_state=42)

#encode the Ys
Y = to_categorical(Y,2)
Y_test = to_categorical(Y_test, 2)

###################################
# Image transformations
###################################

# normalisation of images
img_prep = ImagePreprocessing()

# Create extra synthetic training data by flipping & rotating images
img_aug = ImageAugmentation()

###################################
# Define network architecture
###################################

# Input is a 32x32 image with 3 color channels (red, green and blue)
network = input_data(shape=[None, 64, 64, 3],
data_preprocessing=img_prep,
data_augmentation=img_aug)

# 1: Convolution layer with 32 filters, each 3x3x3
conv_1 = conv_2d(network, 32, [3,3], activation='relu', name='conv_1')

# 2: Max pooling layer
network = max_pool_2d(conv_1, [3,3])

# 3: Convolution layer with 64 filters
conv_2 = conv_2d(network, 64, [3,3], activation='relu', name='conv_2')

# 2: Max pooling layer
network = max_pool_2d(conv_2, [3,3])

# 4: Convolution layer with 64 filters
conv_3 = conv_2d(network, 32, [3,3], activation='relu', name='conv_3')

# 5: Max pooling layer
network = max_pool_2d(conv_3, [3,3])

# 5: Convolution layer with 64 filters
conv_4 = conv_2d(network, 64, [3,3], activation='relu', name='conv_4')

# 6: Max pooling layer
network = max_pool_2d(conv_4, [3,3])

# 7: Convolution layer with 64 filters
conv_5 = conv_2d(network, 32, [3,3], activation='relu', name='conv_5')

# 8: Max pooling layer
network = max_pool_2d(conv_5, [3,3])

# 9: Convolution layer with 64 filters
conv_6 = conv_2d(network, 64, [3,3], activation='relu', name='conv_6')

# 10: Max pooling layer
network = max_pool_2d(conv_6, [3,3])

# 11: Fully-connected 512 node layer
network = fully_connected(network, 1024, activation='relu')

# 12: Dropout layer to combat overfitting
network = dropout(network, 0.8)

# 13: Fully-connected layer with two outputs
network = fully_connected(network, 2, activation='softmax')

# Configure how the network will be trained
acc = Accuracy(name="Accuracy")
loss='categorical_crossentropy',
learning_rate=0.0005, metric=acc)

# Wrap the network in a model object
model = tflearn.DNN(network, checkpoint_path='model_cat_dog_6.tflearn', max_checkpoints = 3,
tensorboard_verbose = 3, tensorboard_dir='tmp/tflearn_logs/')

model.fit(X, Y, validation_set=(X_test, Y_test), batch_size=500,
n_epoch=10, run_id='cat_dog_model', show_metric=True)
model.save('cat_dog_model_final.tflearn')
# choose images & plot the first one
result = []
logloss = 0

with open('deneme.csv','wb') as cs:
writer = csv.writer(cs, delimiter=',',quoting=csv.QUOTE_NONE)
for i in range(0, len(testX)):
im = [testX[i]]
a = model.predict(im)
if a[0][0]<a[0][1]:
writer.writerow([str(i+1), 1])
else:
writer.writerow([str(i + 1), 0])


50% is no better than random. What was your training score?

You have 6 max pooling layers with 3x3 size for a 64 x 64 image:

• After 1st: size is 21 x 21 x 32
• After 2nd: size is 7 x 7 x 64
• After 3rd: size is 2 x 2 x 32
• After 4th: size is 1 x 1 x 64 (?)

Then there is two more conv/pool layers after that. It is too much pooling.

Instead, try 3 5x5 conv layers, max pool in 2x2 blocks, then dropout before the fully connected layer. Each time there is [2,2] max pool, the depth of the conv layer doubles.

# Input is a 64x64 image with 3 color channels (red, green and blue)
network = input_data(shape=[None, 64, 64, 3],
data_preprocessing=img_prep,
data_augmentation=img_aug)

# 1: Convolution layer with 32 filters, each 5x5
conv_1 = conv_2d(network, 32, [5,5], activation='relu', name='conv_1')
# 2: Max pooling layer, out size is 32x32x32
network = max_pool_2d(conv_1, [2,2])
# 3: Convolution layer with 64 filters
conv_2 = conv_2d(network, 64, [5,5], activation='relu', name='conv_2')
# 2: Max pooling layer, out size is 16x16x64
network = max_pool_2d(conv_2, [2,2])
# 4: Convolution layer with 128 filters
conv_3 = conv_2d(network, 128, [5,5], activation='relu', name='conv_3')
# 5: Max pooling layer, out size is 8x8x128
network = max_pool_2d(conv_3, [2,2])
# 12: Dropout layer to combat overfitting
network = dropout(network, 0.5)
# 11: Fully-connected 1024 node layer
network = fully_connected(network, 1024, activation='relu')
# 13: Fully-connected layer with two outputs
network = fully_connected(network, 2, activation='softmax')


Finally, you might have to turn dropout off before testing if tflearn doesn't do this automatically. In vanilla Tensorflow this is done by using a placeholder for the dropout keep probability and feeding 1.0 to it when testing.

• I already tried with you mentioned above but result didn't changed. My training accuracy is %96 Why u didn't recommend tflearn? – aysebilgegunduz Jul 4 '17 at 11:48
• @cybseccrypt Could be I'm wrong too, I'm only relatively new to the field. ;) At the time I tried both and found Tensoylayer better, but now I see tflearn has more layer types added in. Might have to change. (Removing comment) – geometrikal Jul 4 '17 at 20:00

I am not familiar with tensorflow, but I can tell you what I know from your question. To start off, the problem is most likely how you're training, not your model itself.

There are two possible problems you may have:

1 - You are overfitting to the train data

2 - You haven't trained your model enough

I suggest that you either use a pretrained model and finetune it to achieve better results or train your existing model on more data before going back to cats and dogs. Furthermore, it helps to augment your data so your network has more images to train on. A few more things that help would be using dropout, batchnorm, and regularization (more helpful if you are overfitting). If none of these things work, then you may have a problematic model and may need to change it.

I really hope this helps you in the future.

(If you're a beginner to ML, I recommend you start of with Fast.AI's MOOC on machine learning and learn with the libraries they use, keras and theano. Although, they may seem much simpler, they are definitely good enough to achieve incredible results on a number of things.)

• Thanks for your comment, at least now, i know what i look for. – aysebilgegunduz Jul 4 '17 at 7:22