CNN using TFlearn - The accuracy is very poor - tensorflow

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 15 23:46:38 2017
#author: Aprameyo
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from scipy.misc import imresize
import os
import urllib
import tensorflow as tf
import cv2 as cv2
import numpy as np
import tflearn
from tflearn.data_utils import image_preloader
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.normalization import local_response_normalization
from tflearn.layers.estimator import regression
Tensor = np.zeros((112,92,280))
Tensor_V = np.zeros((112,92,120))
K = 0
for x in range(1, 41):
directory = "s%d"%x
os.chdir(directory)
for y in range(1,8):
image = "%d.pgm"%y
Tensor[:,:,K] = (cv2.imread(image,-1))
K = K+1
os.chdir("../")
#Tensor_Fin = tf.convert_to_tensor(Tensor, dtype=tf.float32)
T =0
Targets = np.zeros((280,40))
for x in range(0,40):
for y in range(0,7):
Targets[T,x] = 1
T = T+1
K1 = 0
for x in range(1, 41):
directory = "s%d"%x
os.chdir(directory)
for y in range(8,11):
image = "%d.pgm"%y
Tensor_V[:,:,K1] = (cv2.imread(image,-1))
K1 = K1+1
os.chdir("../")
#Tensor_Fin = tf.convert_to_tensor(Tensor, dtype=tf.float32)
T1 =0
Targets_V = np.zeros((120,40))
for x in range(0,40):
for y in range(0,3):
Targets_V[T1,x] = 1
T1 = T1+1
Tensor_Train = Tensor
Targets_Train = Targets
Tensor_Vali = Tensor_V
Targets_Vali = Targets_V
Tensor_Train = Tensor_Train.reshape([-1, 112, 92, 1])
Tensor_Vali = Tensor_Vali.reshape([-1, 112, 92, 1])
network = input_data(shape=[None, 112, 92, 1], name='input')
network = conv_2d(network, 32, 3, activation='relu', regularizer="L2")
network = max_pool_2d(network, 2)
network = local_response_normalization(network)
network = conv_2d(network, 64, 3, activation='relu', regularizer="L2")
network = max_pool_2d(network, 2)
network = local_response_normalization(network)
network = fully_connected(network, 128, activation='sigmoid')
network = dropout(network, 0.8)
network = fully_connected(network, 256, activation='sigmoid')
network = dropout(network, 0.8)
network = fully_connected(network, 40, activation='softmax')
network = regression(network, optimizer='adam', learning_rate=0.01,
loss='categorical_crossentropy', name='target')
# Training
model = tflearn.DNN(network, tensorboard_verbose=0)
model.fit({'input': Tensor_Train}, {'target': Targets_Train},n_epoch=20,
validation_set=({'input': Tensor_Vali}, {'target':Targets_Vali}),
snapshot_step=100, show_metric=True, run_id='convnet_mnist')
I implemented this code by keeping it in a directory called att_faces which contains 10 images of a person and there are 40 such persons, the training set includes 7 of them and the test includes 3 of them. I can't figure out why the accuracy is so abominable.

Related

Detect digit on a live video camera using OpenCV and TensorFlow

I tried the code provided below to detect digit in the video camera and put a contour around it then classify it using the H5 model but it's giving me bad results, just the camera is open and I can see neither detection nor classification. I'm not sure what I need to change or work on.
I use python2.7
OpenCV 4.2.0 and TensorFlow 1.5.0
The code I'm working with:
from statistics import mode
import cv2, time
from keras.models import load_model
from keras.datasets import mnist
import tensorflow as tf
import numpy as np
import vision_definitions
from PIL import Image
import numpy as np
import sys, os
from utils.inference import detect_digits
from utils.inference import draw_text
from utils.inference import draw_bounding_box
from utils.inference import apply_offsets
from utils.inference import load_detection_model
from utils.preprocessor import preprocess_input
# parameters for loading data and images
detection_model_path = '../trained_models/detection_models/model.sav'
class_model_path = '../trained_models/class_models/Num.h5'
# hyper-parameters for bounding boxes shape
frame_window = 10
class_offsets = (20, 40)
# loading models
digit_detection = load_detection_model(detection_model_path)
class_classifier = load_model(class_model_path)
# getting input model shapes for inference
class_target_size = class_classifier.input_shape[1:3]
class_window = []
class_window1 = []
# starting video streaming
cameraIndex = 0
resolution = vision_definitions.kVGA
colorSpace = vision_definitions.kRGBColorSpace
resolution = 2
colorSpace = 3
cv2.namedWindow('window_frame')
video_capture = cv2.VideoCapture(0)
if video_capture.isOpened():
frame = video_capture.read()
else:
rval = False
while True:
rval, frame = video_capture.read()
gray_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
digits = detect_digits(digit_detection, gray_image)
frame = cv2.resize(frame, (640, 480))
key = cv2.waitKey(1)
b,g,r = cv2.split(frame) # get b,g,r
rgb_img = cv2.merge([r,g,b]) # switch it to rgb
for digit_coordinates in digits:
x1, x2, y1, y2 = apply_offsets(digit_coordinates, class_offsets)
gray_digit = gray_image[y1:y2, x1:x2]
try:
gray_digit = cv2.resize(gray_digit, (class_target_size))
except:
continue
gray_digit = preprocess_input(gray_digit, True)
gray_digit = np.expand_dims(gray_digit, 0)
gray_digit = np.expand_dims(gray_digit, -1)
class_prediction = class_classifier.predict(gray_digit)
class_probability = np.max(class_prediction)
class_label_arg = np.argmax(class_prediction)
color = color.astype(int)
color = color.tolist()
draw_bounding_box(digit_coordinates, rgb_image, color)
draw_text(digit_coordinates, rgb_image, class_mode,
color, 0, -45, 1, 1)
frame = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)
cv2.imshow('window_frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
I spend sometimes since there is no CV2.imshow() on Windows except C++ but there it is ...
[ Sample ]:
import cv2
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import tensorflow as tf
import os
from os.path import exists
import time
def f1( picture ):
return np.asarray( picture )
fig = plt.figure()
image = plt.imread( "C:\\Users\\Jirayu Kaewprateep\\Pictures\\Cats\\samples\\03.png" )
im = plt.imshow( image )
global video_capture_0
video_capture_0 = cv2.VideoCapture(0)
video_capture_1 = cv2.VideoCapture(1)
def animate(i ):
ret0, frame0 = video_capture_0.read()
if (ret0):
picture = np.concatenate( ( np.reshape(frame0[:,:,2:3], ( 480, 640, 1 )),
np.reshape(frame0[:,:,1:2], ( 480, 640, 1 )),
np.reshape(frame0[:,:,0:1], ( 480, 640, 1 ))),
axis=2 )
im.set_array( f1( picture ) )
return im,
while True:
# Capture frame-by-frame
ret0, frame0 = video_capture_0.read()
ani = animation.FuncAnimation(fig, animate, interval=50, blit=True)
plt.show()
# When everything is done, release the capture
video_capture_0.release()
cv2.destroyAllWindows()
[ Model ]:
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Model Initialize
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
model = tf.keras.models.Sequential([
tf.keras.layers.InputLayer(input_shape=( 29, 39, 3 )),
# tf.keras.layers.Reshape(( 29, 39 * 3 )),
# tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(128, return_sequences=True, return_state=False)),
tf.keras.layers.RandomFlip("horizontal_and_vertical"),
tf.keras.layers.RandomRotation(0.2),
tf.keras.layers.RandomZoom(.5, .2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.Dense(64),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.Dense(64),
])
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(64))
model.add(tf.keras.layers.Dense(2))
model.summary()
[ Output ]:

CNN Model Predicting Only First Class

I am working on a fine-grained classification to classify car models. So I have used transfer learning ResNet50. As per my knowledge it is performing fine while training. But when I try new images it is always predicting a single class. Below is my code.
For training:
from tensorflow.keras.layers import Input, Lambda, Dense, Flatten
from tensorflow.keras.models import Model
from tensorflow.keras.applications.resnet50 import ResNet50
from keras.applications.vgg16 import VGG16
from tensorflow.keras.applications.resnet50 import preprocess_input
from tensorflow.keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator,load_img
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
import numpy as np
from glob import glob
IMAGE_SIZE = [224, 224]
train_path = 'Datasets/train'
valid_path = 'Datasets/test'
resnet = ResNet50(input_shape = IMAGE_SIZE + [3], weights='imagenet', include_top = False)
for layer in resnet.layers:
layer.trainable = False
folders = glob('Datasets/train/*') #training folders
x = Flatten()(resnet.output)
prediction = Dense(len(folders), activation='softmax') (x)
model = Model(inputs = resnet.input, outputs = prediction)
model.compile(
loss = 'categorical_crossentropy',
optimizer = 'adam',
metrics = ['accuracy']
)
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('Datasets/train',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical')
test_set = test_datagen.flow_from_directory('Datasets/test',
target_size = (224, 224),
batch_size = 32,
class_mode = 'categorical')
r = model.fit_generator(
training_set,
validation_data=test_set,
epochs=200,
steps_per_epoch=len(training_set),
validation_steps=len(test_set)
)
from tensorflow.keras.models import load_model
model.save('model_updateV1.h5')
y_pred = model.predict(test_set)
import numpy as np
y_pred = np.argmax(y_pred, axis=1)
For Trying New Images:
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
import numpy as np
from tensorflow.keras.applications.resnet50 import preprocess_input
model = load_model('model_updateV1.h5')
img = image.load_img('Datasets/test/mercedes/45.jpg', target_size=(224,224))
x = image.img_to_array(img)
x = x/255.
x = np.expand_dims(x, axis = 0)
img_data = preprocess_input(x)
img_data.shape
model.predict(img_data)
a = np.argmax(model.predict(img_data), axis=1)
a
I think your problem is that you are rescaling the images twice. You have code
x=x/255
then you expand the dimensions which is fine. However you then have code
img_data = preprocess_input(x)
The preprocess_input functon I believe rescales the pixel values between -1 and +1 with the code
x=x/127.5-1.
So now your pixel value have been scaled down twice. So just delete the code
x=x/255

What format do these lists have to be in to be accepted by Keras Tuners Search function?

This Code reads in a set of testing and training guitar jpg images for the neural net to learn and test from.
import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
import random
DATADIR = "C:/Users/TheKid/Data/DataMiningProject/DataSet"
CATEGORIES = ["Fender_Jazzmaster", "Gibson_ES"]
CATEGORIES2 = ["Test"]
for category in CATEGORIES:
path = os.path.join(DATADIR,category)
for img in os.listdir(path):
img_array = cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)
IMG_SIZE = 70
new_array = cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
training_data = []
def create_training_data():
for category in CATEGORIES:
path = os.path.join(DATADIR,category)
class_num = CATEGORIES.index(category)
for img in os.listdir(path):
img_array = cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
training_data.append([new_array,class_num])
create_training_data()
print(len(training_data))
random.shuffle(training_data)
X = []
y = []
for features, label in training_data:
X.append(features)
y.append(label)
X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
for category in CATEGORIES2:
path2 = os.path.join(DATADIR,category)
for img in os.listdir(path2):
img_array2 = cv2.imread(os.path.join(path2,img),cv2.IMREAD_GRAYSCALE)
IMG_SIZE = 70
new_array2 = cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
testing_data = []
def create_testing_data():
for category in CATEGORIES2:
path2 = os.path.join(DATADIR,category)
class_num2 = CATEGORIES2.index(category)
for img in os.listdir(path2):
img_array2 = cv2.imread(os.path.join(path2,img),cv2.IMREAD_GRAYSCALE)
new_array2 = cv2.resize(img_array2,(IMG_SIZE,IMG_SIZE))
testing_data.append([new_array2,class_num2])
create_testing_data()
print(len(testing_data))
random.shuffle(testing_data)
X2 = []
y2 = []
for features, label in testing_data:
X2.append(features)
y2.append(label)
X2 = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
import pickle
pickle_out = open("X.pickle" , "wb")
pickle.dump(X, pickle_out)
pickle_out.close()
pickle_out = open("y.pickle" , "wb")
pickle.dump(y, pickle_out)
pickle_out.close()
pickle_in = open("X.pickle", "rb")
X = pickle.load(pickle_in)
pickle_out = open("X2.pickle" , "wb")
pickle.dump(X2, pickle_out)
pickle_out.close()
pickle_out = open("y2.pickle" , "wb")
pickle.dump(y2, pickle_out)
pickle_out.close()
pickle_in = open("X2.pickle", "rb")
X = pickle.load(pickle_in)
This next bit of code takes in the pickle file saved in previous code and is supposed to use Keras tuners search function to run different variants of the neural net with different amounts of conv layer ,layer sizes etc so I can choose the most efficient version. But when run this error gets thrown:
ValueError: Data cardinality is ambiguous:
x sizes: 1312
y sizes: 12
Please provide data which shares the same first dimension.
The Shapes of all the variables are:
(x_train = (1312, 70, 70, 1)
y_train =(1312,)
x_test = (1312, 70, 70, 1)
y_test =(12,)
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.callbacks import TensorBoard
import numpy as np
import time
import pickle
import matplotlib.pyplot as plt
from tensorflow import keras
from kerastuner.tuners import RandomSearch
from kerastuner.engine.hyperparameters import HyperParameters
pickle_in = open("X.pickle","rb")
x_train = pickle.load(pickle_in)
pickle_in = open("y.pickle","rb")
y_train = pickle.load(pickle_in)
pickle_in = open("X2.pickle","rb")
x_test = pickle.load(pickle_in)
pickle_in = open("y2.pickle","rb")
y_test = pickle.load(pickle_in)
x_train=np.array(x_train/255.0)
y_train=np.array(y_train)
x_test=np.array(x_test/255.0)
y_test=np.array(y_test)
LOG_DIR = f"{int(time.time())}"
def build_model(hp):
model = keras.models.Sequential()
model.add(Conv2D(hp.Int("input_units",32, 256, 32 ), (3, 3), input_shape=x_train.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
for i in range(hp.Int("n_layers", 1, 4)):
model.add(Conv2D(hp.Int(f"conv-{i}_units",32, 256, 32 ), (3, 3)))
model.add(Activation('relu'))
model.add(Flatten()) # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(10))
model.add(Activation("softmax"))
model.compile(optimizer="adam",
loss="binary_crossentropy",
metrics=["accuracy"])
return model
tuner = RandomSearch(
build_model,
objective = "val_accuracy",
max_trials = 1,
executions_per_trial = 1,
directory = LOG_DIR)
tuner.search(x=x_train,
y=y_train,
epochs=1,
batch_size=64,
validation_data=(x_test,y_test))
with open(f"tuner_{int(time.time())}.pkl", "wb") as f:
pickle.dump(tuner, f)
tuner = pickle.load(open(""))
print(tuner.get_best_hyperparameters()[0].values)
How would I go about resolving this error? It's seems like a matrix formatting issue to me but I have little experience in dealing with a problem like this.
As the error message and shape of the data (x_test and y_test) clearly suggests, you have 1312 rows in x_test and 12 rows in y_test. You are feeding this data to validation_data=(x_test,y_test).
Kindly pass the same dimension or same rows of data for x_test and y_test in validation_data and this should fix your error.

Error loading keras model in Deeplearning4j - java

I trained my model in python keras.
I am trying to load that in java code but getting following error
How to fix this problem.
Ref:
https://towardsdatascience.com/deploying-keras-deep-learning-models-with-java-62d80464f34a
https://deeplearning4j.konduit.ai/keras-import/overview
Exception in thread "main" org.deeplearning4j.nn.modelimport.keras.exceptions.InvalidKerasConfigurationException: Model class name must be Sequential (found Model). For more information, see http://deeplearning4j.org/docs/latest/keras-import-overview
at org.deeplearning4j.nn.modelimport.keras.KerasSequentialModel.<init>(KerasSequentialModel.java:90)
at org.deeplearning4j.nn.modelimport.keras.KerasSequentialModel.<init>(KerasSequentialModel.java:57)
at org.deeplearning4j.nn.modelimport.keras.utils.KerasModelBuilder.buildSequential(KerasModelBuilder.java:322)
at org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasSequentialModelAndWeights(KerasModelImport.java:223)
at Jktes.jk(Jktes.java:24)
at Jktes.main(Jktes.java:13)
code:
public static void jk()
throws IOException, InvalidKerasConfigurationException, UnsupportedKerasConfigurationException {
String simpleMlp = new ClassPathResource(
"randomjk.h5").getFile().getPath();
MultiLayerNetwork model = KerasModelImport.
importKerasSequentialModelAndWeights(simpleMlp);
}
dependency :
<dependency>
<groupId>org.nd4j</groupId>
<artifactId>nd4j-native-platform</artifactId>
<version>1.0.0-beta6</version>
</dependency>
<dependency>
<groupId>org.deeplearning4j</groupId>
<artifactId>deeplearning4j-modelimport</artifactId>
<version>1.0.0-beta6</version>
</dependency>
<dependency>
<groupId>org.deeplearning4j</groupId>
<artifactId>deeplearning4j-core</artifactId>
<version>0.9.1</version>
</dependency>
My python-3.6 imports:
import datetime
import keras.backend as K
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import statistics
import sys
import tensorflow as tf
import uuid
from IPython.display import display, FileLink
from keras.layers import Activation, BatchNormalization, Conv2D, Dense, Dropout, Flatten, Input, Lambda, MaxPooling2D
from keras.models import Model, Sequential, load_model
from keras.optimizers import Adam, SGD
How i saved in python:
model_name_jk = "model_name_jk"
hyper['uuid'] = model_name_jk
stamp('%.1f%% (%.1f%% training) %s' % (test_accuracy, train_accuracy, hyper))
model.save('saved_models/%s.h5' % hyper['uuid'])
How did I created model in python:
hyper['dropout'] = 0.5
model_size = 'L'
if model_size == 'S':
hyper['conv_filters'] = [32, 64]
hyper['pool_size'] = (8, 8)
elif model_size == 'M':
hyper['conv_filters'] = [32, 64, 128]
hyper['pool_size'] = (4, 4)
else:
hyper['conv_filters'] = [32, 64, 128, 256, 512]
hyper['pool_size'] = (2, 2)
hyper['batch_normalization'] = True
hyper['dense_units'] = [6144]
hyper['share_per_character_weights'] = False
hyper['post_shared_dense'] = False
hyper['batch_normalization'] = True
def create_per_character_model(activation):
inputs = Input(shape=(hyper['charset_len'],))
x = Dense(hyper['charset_len'], activation='softmax')(inputs)
return Model(inputs, x, name='char_model')
def create_model():
x = Input(shape=(hyper['image_height'], hyper['image_width'], 1), name='input')
image_input = x
# Shared convolutional layers
for layer, filters in enumerate(hyper['conv_filters']):
if hyper['batch_normalization']:
x = BatchNormalization()(x)
x = Conv2D(filters, (3, 3), strides=(1, 1), padding='same', name=f'conv_{layer}', activation='relu')(x)
x = MaxPooling2D(pool_size=hyper['pool_size'], padding='same', name=f'maxpool_{layer}')(x)
x = Dropout(hyper['dropout'], name=f'conv_dropout_{layer}')(x)
# Shared dense layers
x = Flatten()(x)
for layer, units in enumerate(hyper['dense_units']):
x = Dense(units, activation='relu', name=f'dense_{layer}')(x)
x = Dropout(hyper['dropout'], name=f'dense_dropout_{layer}')(x)
x = Dense(hyper['max_len'] * hyper['charset_len'], name='wide_output', activation='linear')(x)
# Per-character output layers
split = Lambda(lambda whole: tf.split(whole, num_or_size_splits=hyper['max_len'], axis=1))(x)
if hyper['share_per_character_weights']:
per_character_model = create_per_character_model(activation='relu' if hyper['post_shared_dense'] else 'softmax')
if hyper['post_shared_dense']:
outputs = [Dense(hyper['charset_len'], name='output_char_%d' % ii, activation='softmax')(per_character_model(split[ii])) for ii in range(hyper['max_len'])]
else:
outputs = [per_character_model(split[ii]) for ii in range(hyper['max_len'])]
else:
outputs = [Dense(hyper['charset_len'], name='output_char_%d' % ii, activation='softmax')(split[ii]) for ii in range(hyper['max_len'])]
model = Model(inputs=[image_input], outputs=outputs)
model.summary()
return model
model = create_model()
You are using the functionality for the sequential model import, but are creating the model using a functional API.
To import models created with the functional API you need to use a different importer.
https://deeplearning4j.konduit.ai/keras-import/model-functional shows how to do that.
The TL;DR of it is that you have to use
KerasModelImport.importKerasModelAndWeights(simpleMlp);
instead of
KerasModelImport.importKerasSequentialModelAndWeights(simpleMlp);

Keras Inception V3 predict image not working

Learnt from Jerry Kurata on Pluralsight, I'm trying to recognize birds:
my dataset structure is:
My model training code is:
import glob
import matplotlib.pyplot as plt
from keras import backend as K
import tensorflow as tf
with K.tf.device("/device:GPU:0"):
config = tf.ConfigProto(intra_op_parallelism_threads=4,
inter_op_parallelism_threads=4, allow_soft_placement=True,
device_count = {'CPU' : 1, 'GPU' : 1})
session = tf.Session(config=config)
K.set_session(session)
from keras.callbacks import EarlyStopping
from keras.applications.inception_v3 import InceptionV3, preprocess_input
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
# "/device:GPU:0"
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
def get_num_files(path):
if not os.path.exists(path):
return 0
return sum([len(files) for r, d, files in os.walk(path)])
def get_num_subfolders(path):
if not os.path.exists(path):
return 0
return sum([len(d) for r, d, files in os.walk(path)])
def create_img_generator():
return ImageDataGenerator(
preprocessing_function=preprocess_input,
rotation_range=30,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True
)
Image_width, Image_height = 299, 299
Training_Epochs = 1
Batch_Size = 32
Number_FC_Neurons = 1024
train_dir = '.../birds/train'
validate_dir = '.../birds/validation'
num_train_samples = get_num_files(train_dir)
num_classes = get_num_subfolders(train_dir)
num_validate_samples = get_num_files(validate_dir)
num_epoch = Training_Epochs
batch_size = Batch_Size
train_image_gen = create_img_generator()
test_image_gen = create_img_generator()
train_generator = train_image_gen.flow_from_directory(
train_dir,
target_size=(Image_width, Image_height),
batch_size = batch_size,
seed = 42
)
validation_generator = test_image_gen.flow_from_directory(
validate_dir,
target_size=(Image_width, Image_height),
batch_size=batch_size,
seed=42
)
Inceptionv3_model = InceptionV3(weights='imagenet', include_top=False)
print('Inception v3 model without last FC loaded')
x = Inceptionv3_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(Number_FC_Neurons, activation='relu')(x)
predictions = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=Inceptionv3_model.input, outputs=predictions)
print(model.summary())
print('\nFine tuning existing model')
Layers_To_Freeze = 172
for layer in model.layers[:Layers_To_Freeze]:
layer.trainable = False
for layer in model.layers[Layers_To_Freeze:]:
layer.trainable = True
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='binary_crossentropy', metrics=['accuracy'])
cbk_early_stopping = EarlyStopping(monitor='val_acc', mode='max')
history_transfer_learning = model.fit_generator(
train_generator,
steps_per_epoch = num_train_samples,
epochs=num_epoch,
validation_data=validation_generator,
validation_steps = num_validate_samples,
class_weight='auto',
callbacks=[cbk_early_stopping]
)
model.save('incepv3_transfer.h5', overwrite=True, include_optimizer=True)
My detector is
from keras.models import load_model
from keras.optimizers import SGD
from keras.preprocessing import image
from keras.applications.inception_v3 import preprocess_input
import matplotlib.pyplot as plt
import numpy as np
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
class Detector:
def __init__(self, model_path):
self.model = load_model(model_path)
print('input shape') # output is always (None, None, None, 3), this should be wrong
print(self.model.layers[0].input_shape)
# self.model.summary()
# self.model.compile(loss='binary_crossentropy', optimizer=SGD(lr=0.0001, momentum=0.9), metrics=['accuracy'])
def preprocess_input(self, x):
y = np.copy(x)
y /= 255.
y -= 0.5
y *= 2.
return y
def load_image(self, img_path, show=False):
img = image.load_img(img_path, target_size=(299,299))
img_tensor = image.img_to_array(img) # (height, width, channels)
img_tensor = np.expand_dims(img, axis=0) # (1, height, width, channels), add a dimension because the model expects this shape: (batch_size, height, width, channels)
# img_tensor /= 255. # imshow expects values in the range [0, 1]
img_tensor = preprocess_input(img_tensor)
if show:
plt.imshow(img_tensor[0])
plt.axis('off')
plt.show()
return img_tensor
def detect(self, img_path):
img = self.load_image(img_path, True)
classes = self.model.predict(img)
return classes
from this link
And here is how I use them to predict whether an image has a bird or not:
from keras.models import Model
from detector import Detector
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
model_path = 'incepv3_transfer.h5'
detective = Detector(model_path)
bird_img = 'b1.jpeg'
classes = detective.detect(bird_img)
print(classes)
bird_img = 'dog1.jpg'
classes = detective.detect(bird_img)
print(classes)
the output is always:
[[1.]]