Flower Type Recognition CNN (Tensorflow) [on hold]











up vote
1
down vote

favorite












I have created a CNN for image recognition (Flower types - 5 classes) and am now considering model parameter changes to improve accuracy. The model (5 3*3conv + 2*2max pooling layers) attains ~59% accuracy on the test set over 20 epochs and appears to be outperformed by this 1 conv + max pooling layer Keras implementation (https://www.kaggle.com/jagadeeshkotra/flower-recognition-classification-with-keras). What factors might affect the relative underperformance of my model vs the one layer implementation? Code shown below.



I also implemented the 1 layer Keras implementation in vanilla Tensorflow using the same model parameters (but AdamOptimizer instead of AdaDeltaOptimizer) and attained ~44% accuracy so the issues may be related.



Dataset: https://www.kaggle.com/alxmamaev/flowers-recognition



'''
Multi class classification of flower types using CNN
'''
import os
import numpy as np
import tensorflow as tf

# image_folders_dir is location of folders containing images of various flower types
image_folders_dir = 'C:\UserssquirDropboxML ProjectsKaggleFlowers Recognition\flowers'

IMG_SIZE = 128 # resize image to this height and width
num_classes = 5
batch_size = 32
lr = 0.01 # learning rate
dropout_keep_rate = 0.95
epochs = 20 # number of times model sees full data

MODEL_NAME = 'flowers-{}-{}.model'.format(lr, 'conv-basic')

print('Load pre-existing preprocessed data for training (L) or preprocess data (P)?')
decision1 = input()
if decision1 == 'P':
from preprocessing import create_data
train_data, test_data = create_data(image_folders_dir, IMG_SIZE)
elif decision1 == 'L':
if os.path.exists('train_data.npy'):
train_data = np.load('train_data.npy')
test_data = np.load('test_data.npy')
else:
raise Exception('No preprocessed data exists in path, please preprocess some.')
else:
raise Exception('Please retry and type L or P')

# data is comprised of a list containing: [0]: image data, [1]: class label
# image data = IMG_SIZE * IMG_SIZE * 3 array
# either rgb or bgr? not sure it matters
'''
4321 (3889train, 432test) images are now:
IMG_SIZE*IMG_SIZE RGB attached to one hot class label flower type and ordered randomly
'''
# derive image and label data from new data sets
train_data_imgs = [item[0] for item in train_data]
train_data_lbls = [item[1] for item in train_data]
test_data_imgs = [item[0] for item in test_data]
test_data_lbls = [item[1] for item in test_data]
# create arrays for us in models
X_train = np.array(train_data_imgs).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
Y_train = train_data_lbls
x_valid = np.array(test_data_imgs).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
y_valid = test_data_lbls

# GAN Image Augmentation here

# need to normalise?

''' Model execution (training or loading) '''
x = tf.placeholder('float', [None, IMG_SIZE, IMG_SIZE, 3])
y = tf.placeholder('float')


def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')


def maxpool2D(x):
# 2*2 pool (ksize), stride 2 so non overlapping
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


def conv_NN_model(x, num_classes, img_size, keep_rate):
# 5 by 5 kernel, 3 input depth (RGB image), 32 output depth (convolutions)
weights = { 'W_conv1': tf.Variable(tf.random_normal([3, 3, 3, 32])),
'W_conv2': tf.Variable(tf.random_normal([3, 3, 32, 64])),
'W_conv3': tf.Variable(tf.random_normal([3, 3, 64, 128])),
'W_conv4': tf.Variable(tf.random_normal([3, 3, 128, 256])),
'W_conv5': tf.Variable(tf.random_normal([3, 3, 256, 512])),
'W_fc': tf.Variable(tf.random_normal([4 * 4 * 512, 1024])), # conv output layer size, num neurons in fc
'out': tf.Variable(tf.random_normal([1024, num_classes]))}

biases = { 'b_conv1': tf.Variable(tf.random_normal([32])),
'b_conv2': tf.Variable(tf.random_normal([64])),
'b_conv3': tf.Variable(tf.random_normal([128])),
'b_conv4': tf.Variable(tf.random_normal([256])),
'b_conv5': tf.Variable(tf.random_normal([512])),
'b_fc': tf.Variable(tf.random_normal([1024])), # conv output layer size, num neurons in fc
'out': tf.Variable(tf.random_normal([num_classes]))}

x = tf.reshape(x, shape=[-1, img_size, img_size, 3])
# does tf.reshape(x, shape=[28,28]) have the same effect?

conv1 = conv2d(x, weights['W_conv1'])
conv1 = maxpool2D(conv1)

conv2 = conv2d(conv1, weights['W_conv2'])
conv2 = maxpool2D(conv2)

conv3 = conv2d(conv2, weights['W_conv3'])
conv3 = maxpool2D(conv3)

conv4 = conv2d(conv3, weights['W_conv4'])
conv4 = maxpool2D(conv4)

conv5 = conv2d(conv4, weights['W_conv5'])
conv5 = maxpool2D(conv5)

fc = tf.reshape(conv5, [-1, 4 * 4 * 512])
fc = tf.matmul(fc, weights['W_fc']) + biases['b_fc']
fc = tf.nn.relu(fc)

fc = tf.nn.dropout(fc, keep_prob=keep_rate)

output = tf.matmul(fc, weights['out']) + biases['out']

return output


def next_batch(num, data, labels):
'''
Return a total of `num` random samples and labels.
'''
idx = np.arange(0, len(data))
np.random.shuffle(idx)
idx = idx[:num]
data_shuffle = [data[i] for i in idx]
labels_shuffle = [labels[i] for i in idx]

return np.asarray(data_shuffle), np.asarray(labels_shuffle)


def train_neural_network(x, num_epochs, train_data, batch_size, train_imgs, train_lbls, test_imgs, test_lbls):
prediction = conv_NN_model(x=x,
num_classes=num_classes,
img_size=IMG_SIZE,
keep_rate=dropout_keep_rate)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=prediction, labels=y))

optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)
#optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(cost)

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())

for epoch in range(num_epochs):
epoch_loss = 0
for _ in range(int(len(train_data)/batch_size)):
epoch_x, epoch_y = next_batch(batch_size, train_imgs, train_lbls)
_, c = sess.run([optimizer, cost], feed_dict={x: epoch_x, y: epoch_y})
epoch_loss += c

print('Epoch', epoch, 'completed out of', num_epochs, 'loss:', epoch_loss)

correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))

accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
print('Accuracy:', accuracy.eval({x: test_imgs, y: test_lbls}))


train_neural_network(x=x,
num_epochs=epochs,
train_data=train_data,
batch_size=batch_size,
train_imgs=train_data_imgs,
train_lbls=train_data_lbls,
test_imgs=test_data_imgs,
test_lbls=test_data_lbls)



''' PREPROCESSING MODULE
Data presented in 5 different folders, one for each class ~800 images per folderA
task = create two .npy files containing image data and labels with roughly even distribution of flower types in each
train = 90%, test = 10%
combine into single list containing 2 arrays. [0] = image data, [1] = one hot encoded class label
'''
import os
import cv2
import numpy as np
from tqdm import tqdm
from random import shuffle


def create_data(folders_dir, img_size):
data = # create full data with (numerical) labels
for fold in os.listdir(folders_dir):
# one hot encoding class labels
if fold == 'daisy': label = [1, 0, 0, 0, 0]
elif fold == 'dandelion': label = [0, 1, 0, 0, 0]
elif fold == 'rose': label = [0, 0, 1, 0, 0]
elif fold == 'sunflower': label = [0, 0, 0, 1, 0]
elif fold == 'tulip': label = [0, 0, 0, 0, 1]
for img in tqdm(os.listdir(os.path.join(folders_dir, str(fold)))):
path = os.path.join(folders_dir, fold, img)
img = cv2.resize(cv2.imread(path, 1), (img_size, img_size))
data.append([np.array(img), label])
shuffle(data)
training_data = data[:4105]
testing_data = data[4105:]
np.save('train_data.npy', training_data)
np.save('test_data.npy', testing_data)
return training_data, testing_data









share|improve this question













put on hold as off-topic by πάντα ῥεῖ, t3chb0t, Toby Speight, Graipher, IEatBagels 14 hours ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – πάντα ῥεῖ, t3chb0t, Toby Speight, Graipher, IEatBagels

If this question can be reworded to fit the rules in the help center, please edit the question.









  • 3




    Hi! You might be interested into reading the related meta question. Given your accuracies and the nature of the question, this is maybe not the site you’re looking for.
    – Mathias Ettinger
    yesterday






  • 1




    @MathiasEttinger thanks for the link, will go to crossvalidated
    – Seb Squire
    yesterday















up vote
1
down vote

favorite












I have created a CNN for image recognition (Flower types - 5 classes) and am now considering model parameter changes to improve accuracy. The model (5 3*3conv + 2*2max pooling layers) attains ~59% accuracy on the test set over 20 epochs and appears to be outperformed by this 1 conv + max pooling layer Keras implementation (https://www.kaggle.com/jagadeeshkotra/flower-recognition-classification-with-keras). What factors might affect the relative underperformance of my model vs the one layer implementation? Code shown below.



I also implemented the 1 layer Keras implementation in vanilla Tensorflow using the same model parameters (but AdamOptimizer instead of AdaDeltaOptimizer) and attained ~44% accuracy so the issues may be related.



Dataset: https://www.kaggle.com/alxmamaev/flowers-recognition



'''
Multi class classification of flower types using CNN
'''
import os
import numpy as np
import tensorflow as tf

# image_folders_dir is location of folders containing images of various flower types
image_folders_dir = 'C:\UserssquirDropboxML ProjectsKaggleFlowers Recognition\flowers'

IMG_SIZE = 128 # resize image to this height and width
num_classes = 5
batch_size = 32
lr = 0.01 # learning rate
dropout_keep_rate = 0.95
epochs = 20 # number of times model sees full data

MODEL_NAME = 'flowers-{}-{}.model'.format(lr, 'conv-basic')

print('Load pre-existing preprocessed data for training (L) or preprocess data (P)?')
decision1 = input()
if decision1 == 'P':
from preprocessing import create_data
train_data, test_data = create_data(image_folders_dir, IMG_SIZE)
elif decision1 == 'L':
if os.path.exists('train_data.npy'):
train_data = np.load('train_data.npy')
test_data = np.load('test_data.npy')
else:
raise Exception('No preprocessed data exists in path, please preprocess some.')
else:
raise Exception('Please retry and type L or P')

# data is comprised of a list containing: [0]: image data, [1]: class label
# image data = IMG_SIZE * IMG_SIZE * 3 array
# either rgb or bgr? not sure it matters
'''
4321 (3889train, 432test) images are now:
IMG_SIZE*IMG_SIZE RGB attached to one hot class label flower type and ordered randomly
'''
# derive image and label data from new data sets
train_data_imgs = [item[0] for item in train_data]
train_data_lbls = [item[1] for item in train_data]
test_data_imgs = [item[0] for item in test_data]
test_data_lbls = [item[1] for item in test_data]
# create arrays for us in models
X_train = np.array(train_data_imgs).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
Y_train = train_data_lbls
x_valid = np.array(test_data_imgs).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
y_valid = test_data_lbls

# GAN Image Augmentation here

# need to normalise?

''' Model execution (training or loading) '''
x = tf.placeholder('float', [None, IMG_SIZE, IMG_SIZE, 3])
y = tf.placeholder('float')


def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')


def maxpool2D(x):
# 2*2 pool (ksize), stride 2 so non overlapping
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


def conv_NN_model(x, num_classes, img_size, keep_rate):
# 5 by 5 kernel, 3 input depth (RGB image), 32 output depth (convolutions)
weights = { 'W_conv1': tf.Variable(tf.random_normal([3, 3, 3, 32])),
'W_conv2': tf.Variable(tf.random_normal([3, 3, 32, 64])),
'W_conv3': tf.Variable(tf.random_normal([3, 3, 64, 128])),
'W_conv4': tf.Variable(tf.random_normal([3, 3, 128, 256])),
'W_conv5': tf.Variable(tf.random_normal([3, 3, 256, 512])),
'W_fc': tf.Variable(tf.random_normal([4 * 4 * 512, 1024])), # conv output layer size, num neurons in fc
'out': tf.Variable(tf.random_normal([1024, num_classes]))}

biases = { 'b_conv1': tf.Variable(tf.random_normal([32])),
'b_conv2': tf.Variable(tf.random_normal([64])),
'b_conv3': tf.Variable(tf.random_normal([128])),
'b_conv4': tf.Variable(tf.random_normal([256])),
'b_conv5': tf.Variable(tf.random_normal([512])),
'b_fc': tf.Variable(tf.random_normal([1024])), # conv output layer size, num neurons in fc
'out': tf.Variable(tf.random_normal([num_classes]))}

x = tf.reshape(x, shape=[-1, img_size, img_size, 3])
# does tf.reshape(x, shape=[28,28]) have the same effect?

conv1 = conv2d(x, weights['W_conv1'])
conv1 = maxpool2D(conv1)

conv2 = conv2d(conv1, weights['W_conv2'])
conv2 = maxpool2D(conv2)

conv3 = conv2d(conv2, weights['W_conv3'])
conv3 = maxpool2D(conv3)

conv4 = conv2d(conv3, weights['W_conv4'])
conv4 = maxpool2D(conv4)

conv5 = conv2d(conv4, weights['W_conv5'])
conv5 = maxpool2D(conv5)

fc = tf.reshape(conv5, [-1, 4 * 4 * 512])
fc = tf.matmul(fc, weights['W_fc']) + biases['b_fc']
fc = tf.nn.relu(fc)

fc = tf.nn.dropout(fc, keep_prob=keep_rate)

output = tf.matmul(fc, weights['out']) + biases['out']

return output


def next_batch(num, data, labels):
'''
Return a total of `num` random samples and labels.
'''
idx = np.arange(0, len(data))
np.random.shuffle(idx)
idx = idx[:num]
data_shuffle = [data[i] for i in idx]
labels_shuffle = [labels[i] for i in idx]

return np.asarray(data_shuffle), np.asarray(labels_shuffle)


def train_neural_network(x, num_epochs, train_data, batch_size, train_imgs, train_lbls, test_imgs, test_lbls):
prediction = conv_NN_model(x=x,
num_classes=num_classes,
img_size=IMG_SIZE,
keep_rate=dropout_keep_rate)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=prediction, labels=y))

optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)
#optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(cost)

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())

for epoch in range(num_epochs):
epoch_loss = 0
for _ in range(int(len(train_data)/batch_size)):
epoch_x, epoch_y = next_batch(batch_size, train_imgs, train_lbls)
_, c = sess.run([optimizer, cost], feed_dict={x: epoch_x, y: epoch_y})
epoch_loss += c

print('Epoch', epoch, 'completed out of', num_epochs, 'loss:', epoch_loss)

correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))

accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
print('Accuracy:', accuracy.eval({x: test_imgs, y: test_lbls}))


train_neural_network(x=x,
num_epochs=epochs,
train_data=train_data,
batch_size=batch_size,
train_imgs=train_data_imgs,
train_lbls=train_data_lbls,
test_imgs=test_data_imgs,
test_lbls=test_data_lbls)



''' PREPROCESSING MODULE
Data presented in 5 different folders, one for each class ~800 images per folderA
task = create two .npy files containing image data and labels with roughly even distribution of flower types in each
train = 90%, test = 10%
combine into single list containing 2 arrays. [0] = image data, [1] = one hot encoded class label
'''
import os
import cv2
import numpy as np
from tqdm import tqdm
from random import shuffle


def create_data(folders_dir, img_size):
data = # create full data with (numerical) labels
for fold in os.listdir(folders_dir):
# one hot encoding class labels
if fold == 'daisy': label = [1, 0, 0, 0, 0]
elif fold == 'dandelion': label = [0, 1, 0, 0, 0]
elif fold == 'rose': label = [0, 0, 1, 0, 0]
elif fold == 'sunflower': label = [0, 0, 0, 1, 0]
elif fold == 'tulip': label = [0, 0, 0, 0, 1]
for img in tqdm(os.listdir(os.path.join(folders_dir, str(fold)))):
path = os.path.join(folders_dir, fold, img)
img = cv2.resize(cv2.imread(path, 1), (img_size, img_size))
data.append([np.array(img), label])
shuffle(data)
training_data = data[:4105]
testing_data = data[4105:]
np.save('train_data.npy', training_data)
np.save('test_data.npy', testing_data)
return training_data, testing_data









share|improve this question













put on hold as off-topic by πάντα ῥεῖ, t3chb0t, Toby Speight, Graipher, IEatBagels 14 hours ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – πάντα ῥεῖ, t3chb0t, Toby Speight, Graipher, IEatBagels

If this question can be reworded to fit the rules in the help center, please edit the question.









  • 3




    Hi! You might be interested into reading the related meta question. Given your accuracies and the nature of the question, this is maybe not the site you’re looking for.
    – Mathias Ettinger
    yesterday






  • 1




    @MathiasEttinger thanks for the link, will go to crossvalidated
    – Seb Squire
    yesterday













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have created a CNN for image recognition (Flower types - 5 classes) and am now considering model parameter changes to improve accuracy. The model (5 3*3conv + 2*2max pooling layers) attains ~59% accuracy on the test set over 20 epochs and appears to be outperformed by this 1 conv + max pooling layer Keras implementation (https://www.kaggle.com/jagadeeshkotra/flower-recognition-classification-with-keras). What factors might affect the relative underperformance of my model vs the one layer implementation? Code shown below.



I also implemented the 1 layer Keras implementation in vanilla Tensorflow using the same model parameters (but AdamOptimizer instead of AdaDeltaOptimizer) and attained ~44% accuracy so the issues may be related.



Dataset: https://www.kaggle.com/alxmamaev/flowers-recognition



'''
Multi class classification of flower types using CNN
'''
import os
import numpy as np
import tensorflow as tf

# image_folders_dir is location of folders containing images of various flower types
image_folders_dir = 'C:\UserssquirDropboxML ProjectsKaggleFlowers Recognition\flowers'

IMG_SIZE = 128 # resize image to this height and width
num_classes = 5
batch_size = 32
lr = 0.01 # learning rate
dropout_keep_rate = 0.95
epochs = 20 # number of times model sees full data

MODEL_NAME = 'flowers-{}-{}.model'.format(lr, 'conv-basic')

print('Load pre-existing preprocessed data for training (L) or preprocess data (P)?')
decision1 = input()
if decision1 == 'P':
from preprocessing import create_data
train_data, test_data = create_data(image_folders_dir, IMG_SIZE)
elif decision1 == 'L':
if os.path.exists('train_data.npy'):
train_data = np.load('train_data.npy')
test_data = np.load('test_data.npy')
else:
raise Exception('No preprocessed data exists in path, please preprocess some.')
else:
raise Exception('Please retry and type L or P')

# data is comprised of a list containing: [0]: image data, [1]: class label
# image data = IMG_SIZE * IMG_SIZE * 3 array
# either rgb or bgr? not sure it matters
'''
4321 (3889train, 432test) images are now:
IMG_SIZE*IMG_SIZE RGB attached to one hot class label flower type and ordered randomly
'''
# derive image and label data from new data sets
train_data_imgs = [item[0] for item in train_data]
train_data_lbls = [item[1] for item in train_data]
test_data_imgs = [item[0] for item in test_data]
test_data_lbls = [item[1] for item in test_data]
# create arrays for us in models
X_train = np.array(train_data_imgs).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
Y_train = train_data_lbls
x_valid = np.array(test_data_imgs).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
y_valid = test_data_lbls

# GAN Image Augmentation here

# need to normalise?

''' Model execution (training or loading) '''
x = tf.placeholder('float', [None, IMG_SIZE, IMG_SIZE, 3])
y = tf.placeholder('float')


def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')


def maxpool2D(x):
# 2*2 pool (ksize), stride 2 so non overlapping
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


def conv_NN_model(x, num_classes, img_size, keep_rate):
# 5 by 5 kernel, 3 input depth (RGB image), 32 output depth (convolutions)
weights = { 'W_conv1': tf.Variable(tf.random_normal([3, 3, 3, 32])),
'W_conv2': tf.Variable(tf.random_normal([3, 3, 32, 64])),
'W_conv3': tf.Variable(tf.random_normal([3, 3, 64, 128])),
'W_conv4': tf.Variable(tf.random_normal([3, 3, 128, 256])),
'W_conv5': tf.Variable(tf.random_normal([3, 3, 256, 512])),
'W_fc': tf.Variable(tf.random_normal([4 * 4 * 512, 1024])), # conv output layer size, num neurons in fc
'out': tf.Variable(tf.random_normal([1024, num_classes]))}

biases = { 'b_conv1': tf.Variable(tf.random_normal([32])),
'b_conv2': tf.Variable(tf.random_normal([64])),
'b_conv3': tf.Variable(tf.random_normal([128])),
'b_conv4': tf.Variable(tf.random_normal([256])),
'b_conv5': tf.Variable(tf.random_normal([512])),
'b_fc': tf.Variable(tf.random_normal([1024])), # conv output layer size, num neurons in fc
'out': tf.Variable(tf.random_normal([num_classes]))}

x = tf.reshape(x, shape=[-1, img_size, img_size, 3])
# does tf.reshape(x, shape=[28,28]) have the same effect?

conv1 = conv2d(x, weights['W_conv1'])
conv1 = maxpool2D(conv1)

conv2 = conv2d(conv1, weights['W_conv2'])
conv2 = maxpool2D(conv2)

conv3 = conv2d(conv2, weights['W_conv3'])
conv3 = maxpool2D(conv3)

conv4 = conv2d(conv3, weights['W_conv4'])
conv4 = maxpool2D(conv4)

conv5 = conv2d(conv4, weights['W_conv5'])
conv5 = maxpool2D(conv5)

fc = tf.reshape(conv5, [-1, 4 * 4 * 512])
fc = tf.matmul(fc, weights['W_fc']) + biases['b_fc']
fc = tf.nn.relu(fc)

fc = tf.nn.dropout(fc, keep_prob=keep_rate)

output = tf.matmul(fc, weights['out']) + biases['out']

return output


def next_batch(num, data, labels):
'''
Return a total of `num` random samples and labels.
'''
idx = np.arange(0, len(data))
np.random.shuffle(idx)
idx = idx[:num]
data_shuffle = [data[i] for i in idx]
labels_shuffle = [labels[i] for i in idx]

return np.asarray(data_shuffle), np.asarray(labels_shuffle)


def train_neural_network(x, num_epochs, train_data, batch_size, train_imgs, train_lbls, test_imgs, test_lbls):
prediction = conv_NN_model(x=x,
num_classes=num_classes,
img_size=IMG_SIZE,
keep_rate=dropout_keep_rate)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=prediction, labels=y))

optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)
#optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(cost)

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())

for epoch in range(num_epochs):
epoch_loss = 0
for _ in range(int(len(train_data)/batch_size)):
epoch_x, epoch_y = next_batch(batch_size, train_imgs, train_lbls)
_, c = sess.run([optimizer, cost], feed_dict={x: epoch_x, y: epoch_y})
epoch_loss += c

print('Epoch', epoch, 'completed out of', num_epochs, 'loss:', epoch_loss)

correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))

accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
print('Accuracy:', accuracy.eval({x: test_imgs, y: test_lbls}))


train_neural_network(x=x,
num_epochs=epochs,
train_data=train_data,
batch_size=batch_size,
train_imgs=train_data_imgs,
train_lbls=train_data_lbls,
test_imgs=test_data_imgs,
test_lbls=test_data_lbls)



''' PREPROCESSING MODULE
Data presented in 5 different folders, one for each class ~800 images per folderA
task = create two .npy files containing image data and labels with roughly even distribution of flower types in each
train = 90%, test = 10%
combine into single list containing 2 arrays. [0] = image data, [1] = one hot encoded class label
'''
import os
import cv2
import numpy as np
from tqdm import tqdm
from random import shuffle


def create_data(folders_dir, img_size):
data = # create full data with (numerical) labels
for fold in os.listdir(folders_dir):
# one hot encoding class labels
if fold == 'daisy': label = [1, 0, 0, 0, 0]
elif fold == 'dandelion': label = [0, 1, 0, 0, 0]
elif fold == 'rose': label = [0, 0, 1, 0, 0]
elif fold == 'sunflower': label = [0, 0, 0, 1, 0]
elif fold == 'tulip': label = [0, 0, 0, 0, 1]
for img in tqdm(os.listdir(os.path.join(folders_dir, str(fold)))):
path = os.path.join(folders_dir, fold, img)
img = cv2.resize(cv2.imread(path, 1), (img_size, img_size))
data.append([np.array(img), label])
shuffle(data)
training_data = data[:4105]
testing_data = data[4105:]
np.save('train_data.npy', training_data)
np.save('test_data.npy', testing_data)
return training_data, testing_data









share|improve this question













I have created a CNN for image recognition (Flower types - 5 classes) and am now considering model parameter changes to improve accuracy. The model (5 3*3conv + 2*2max pooling layers) attains ~59% accuracy on the test set over 20 epochs and appears to be outperformed by this 1 conv + max pooling layer Keras implementation (https://www.kaggle.com/jagadeeshkotra/flower-recognition-classification-with-keras). What factors might affect the relative underperformance of my model vs the one layer implementation? Code shown below.



I also implemented the 1 layer Keras implementation in vanilla Tensorflow using the same model parameters (but AdamOptimizer instead of AdaDeltaOptimizer) and attained ~44% accuracy so the issues may be related.



Dataset: https://www.kaggle.com/alxmamaev/flowers-recognition



'''
Multi class classification of flower types using CNN
'''
import os
import numpy as np
import tensorflow as tf

# image_folders_dir is location of folders containing images of various flower types
image_folders_dir = 'C:\UserssquirDropboxML ProjectsKaggleFlowers Recognition\flowers'

IMG_SIZE = 128 # resize image to this height and width
num_classes = 5
batch_size = 32
lr = 0.01 # learning rate
dropout_keep_rate = 0.95
epochs = 20 # number of times model sees full data

MODEL_NAME = 'flowers-{}-{}.model'.format(lr, 'conv-basic')

print('Load pre-existing preprocessed data for training (L) or preprocess data (P)?')
decision1 = input()
if decision1 == 'P':
from preprocessing import create_data
train_data, test_data = create_data(image_folders_dir, IMG_SIZE)
elif decision1 == 'L':
if os.path.exists('train_data.npy'):
train_data = np.load('train_data.npy')
test_data = np.load('test_data.npy')
else:
raise Exception('No preprocessed data exists in path, please preprocess some.')
else:
raise Exception('Please retry and type L or P')

# data is comprised of a list containing: [0]: image data, [1]: class label
# image data = IMG_SIZE * IMG_SIZE * 3 array
# either rgb or bgr? not sure it matters
'''
4321 (3889train, 432test) images are now:
IMG_SIZE*IMG_SIZE RGB attached to one hot class label flower type and ordered randomly
'''
# derive image and label data from new data sets
train_data_imgs = [item[0] for item in train_data]
train_data_lbls = [item[1] for item in train_data]
test_data_imgs = [item[0] for item in test_data]
test_data_lbls = [item[1] for item in test_data]
# create arrays for us in models
X_train = np.array(train_data_imgs).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
Y_train = train_data_lbls
x_valid = np.array(test_data_imgs).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
y_valid = test_data_lbls

# GAN Image Augmentation here

# need to normalise?

''' Model execution (training or loading) '''
x = tf.placeholder('float', [None, IMG_SIZE, IMG_SIZE, 3])
y = tf.placeholder('float')


def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')


def maxpool2D(x):
# 2*2 pool (ksize), stride 2 so non overlapping
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


def conv_NN_model(x, num_classes, img_size, keep_rate):
# 5 by 5 kernel, 3 input depth (RGB image), 32 output depth (convolutions)
weights = { 'W_conv1': tf.Variable(tf.random_normal([3, 3, 3, 32])),
'W_conv2': tf.Variable(tf.random_normal([3, 3, 32, 64])),
'W_conv3': tf.Variable(tf.random_normal([3, 3, 64, 128])),
'W_conv4': tf.Variable(tf.random_normal([3, 3, 128, 256])),
'W_conv5': tf.Variable(tf.random_normal([3, 3, 256, 512])),
'W_fc': tf.Variable(tf.random_normal([4 * 4 * 512, 1024])), # conv output layer size, num neurons in fc
'out': tf.Variable(tf.random_normal([1024, num_classes]))}

biases = { 'b_conv1': tf.Variable(tf.random_normal([32])),
'b_conv2': tf.Variable(tf.random_normal([64])),
'b_conv3': tf.Variable(tf.random_normal([128])),
'b_conv4': tf.Variable(tf.random_normal([256])),
'b_conv5': tf.Variable(tf.random_normal([512])),
'b_fc': tf.Variable(tf.random_normal([1024])), # conv output layer size, num neurons in fc
'out': tf.Variable(tf.random_normal([num_classes]))}

x = tf.reshape(x, shape=[-1, img_size, img_size, 3])
# does tf.reshape(x, shape=[28,28]) have the same effect?

conv1 = conv2d(x, weights['W_conv1'])
conv1 = maxpool2D(conv1)

conv2 = conv2d(conv1, weights['W_conv2'])
conv2 = maxpool2D(conv2)

conv3 = conv2d(conv2, weights['W_conv3'])
conv3 = maxpool2D(conv3)

conv4 = conv2d(conv3, weights['W_conv4'])
conv4 = maxpool2D(conv4)

conv5 = conv2d(conv4, weights['W_conv5'])
conv5 = maxpool2D(conv5)

fc = tf.reshape(conv5, [-1, 4 * 4 * 512])
fc = tf.matmul(fc, weights['W_fc']) + biases['b_fc']
fc = tf.nn.relu(fc)

fc = tf.nn.dropout(fc, keep_prob=keep_rate)

output = tf.matmul(fc, weights['out']) + biases['out']

return output


def next_batch(num, data, labels):
'''
Return a total of `num` random samples and labels.
'''
idx = np.arange(0, len(data))
np.random.shuffle(idx)
idx = idx[:num]
data_shuffle = [data[i] for i in idx]
labels_shuffle = [labels[i] for i in idx]

return np.asarray(data_shuffle), np.asarray(labels_shuffle)


def train_neural_network(x, num_epochs, train_data, batch_size, train_imgs, train_lbls, test_imgs, test_lbls):
prediction = conv_NN_model(x=x,
num_classes=num_classes,
img_size=IMG_SIZE,
keep_rate=dropout_keep_rate)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=prediction, labels=y))

optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost)
#optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(cost)

with tf.Session() as sess:
sess.run(tf.global_variables_initializer())

for epoch in range(num_epochs):
epoch_loss = 0
for _ in range(int(len(train_data)/batch_size)):
epoch_x, epoch_y = next_batch(batch_size, train_imgs, train_lbls)
_, c = sess.run([optimizer, cost], feed_dict={x: epoch_x, y: epoch_y})
epoch_loss += c

print('Epoch', epoch, 'completed out of', num_epochs, 'loss:', epoch_loss)

correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))

accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
print('Accuracy:', accuracy.eval({x: test_imgs, y: test_lbls}))


train_neural_network(x=x,
num_epochs=epochs,
train_data=train_data,
batch_size=batch_size,
train_imgs=train_data_imgs,
train_lbls=train_data_lbls,
test_imgs=test_data_imgs,
test_lbls=test_data_lbls)



''' PREPROCESSING MODULE
Data presented in 5 different folders, one for each class ~800 images per folderA
task = create two .npy files containing image data and labels with roughly even distribution of flower types in each
train = 90%, test = 10%
combine into single list containing 2 arrays. [0] = image data, [1] = one hot encoded class label
'''
import os
import cv2
import numpy as np
from tqdm import tqdm
from random import shuffle


def create_data(folders_dir, img_size):
data = # create full data with (numerical) labels
for fold in os.listdir(folders_dir):
# one hot encoding class labels
if fold == 'daisy': label = [1, 0, 0, 0, 0]
elif fold == 'dandelion': label = [0, 1, 0, 0, 0]
elif fold == 'rose': label = [0, 0, 1, 0, 0]
elif fold == 'sunflower': label = [0, 0, 0, 1, 0]
elif fold == 'tulip': label = [0, 0, 0, 0, 1]
for img in tqdm(os.listdir(os.path.join(folders_dir, str(fold)))):
path = os.path.join(folders_dir, fold, img)
img = cv2.resize(cv2.imread(path, 1), (img_size, img_size))
data.append([np.array(img), label])
shuffle(data)
training_data = data[:4105]
testing_data = data[4105:]
np.save('train_data.npy', training_data)
np.save('test_data.npy', testing_data)
return training_data, testing_data






python image machine-learning tensorflow






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 days ago









Seb Squire

141




141




put on hold as off-topic by πάντα ῥεῖ, t3chb0t, Toby Speight, Graipher, IEatBagels 14 hours ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – πάντα ῥεῖ, t3chb0t, Toby Speight, Graipher, IEatBagels

If this question can be reworded to fit the rules in the help center, please edit the question.




put on hold as off-topic by πάντα ῥεῖ, t3chb0t, Toby Speight, Graipher, IEatBagels 14 hours ago


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – πάντα ῥεῖ, t3chb0t, Toby Speight, Graipher, IEatBagels

If this question can be reworded to fit the rules in the help center, please edit the question.








  • 3




    Hi! You might be interested into reading the related meta question. Given your accuracies and the nature of the question, this is maybe not the site you’re looking for.
    – Mathias Ettinger
    yesterday






  • 1




    @MathiasEttinger thanks for the link, will go to crossvalidated
    – Seb Squire
    yesterday














  • 3




    Hi! You might be interested into reading the related meta question. Given your accuracies and the nature of the question, this is maybe not the site you’re looking for.
    – Mathias Ettinger
    yesterday






  • 1




    @MathiasEttinger thanks for the link, will go to crossvalidated
    – Seb Squire
    yesterday








3




3




Hi! You might be interested into reading the related meta question. Given your accuracies and the nature of the question, this is maybe not the site you’re looking for.
– Mathias Ettinger
yesterday




Hi! You might be interested into reading the related meta question. Given your accuracies and the nature of the question, this is maybe not the site you’re looking for.
– Mathias Ettinger
yesterday




1




1




@MathiasEttinger thanks for the link, will go to crossvalidated
– Seb Squire
yesterday




@MathiasEttinger thanks for the link, will go to crossvalidated
– Seb Squire
yesterday















active

oldest

votes






















active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes

Popular posts from this blog

Morgemoulin

Scott Moir

Souastre