Multiple images input to the same CNN using Conv3d in keras - python

I want to enter 8 images at the same time to the same CNN structure using conv3d. my CNN model is as following:
def build(sample, frame, height, width, channels, classes):
model = Sequential()
inputShape = (sample, frame, height, width, channels)
chanDim = -1
if K.image_data_format() == "channels_first":
inputShape = (sample, frame, channels, height, width)
chanDim = 1
model.add(Conv3D(32, (3, 3, 3), padding="same", input_shape=inputShape))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding="same", data_format="channels_last"))
model.add(Dropout(0.25))
model.add(Conv3D(64, (3, 3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding="same", data_format="channels_last"))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128)) #(Dense(1024))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))
# softmax classifier
model.add(Dense(classes))
model.add(Activation("softmax")
The training of model is as follow:
IMAGE_DIMS = (57, 8, 60, 60, 3) # since I have 460 images so 57 sample with 8 image each
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)
# binarize the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
# note: data is a list of all dataset images
(trainX, testX, trainY, testY) train_test_split(data, labels, test_size=0.2, random_state=42)
aug = ImageDataGenerator(rotation_range=25, width_shift_range=0.1, height_shift_range=0.1, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode="nearest")
# initialize the model
model = CNN_Network.build(sample= IMAGE_DIMS[0], frame=IMAGE_DIMS[1],
height = IMAGE_DIMS[2], width=IMAGE_DIMS[3],
channels=IMAGE_DIMS[4], classes=len(lb.classes_))
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="categorical_crossentropy", optimizer= opt, metrics=["accuracy"])
# train the network
model.fit_generator(
aug.flow(trainX, trainY, batch_size=BS),
validation_data=(testX, testY),
steps_per_epoch=len(trainX) // BS,
epochs=EPOCHS, verbose=1)
I have confused with the input_shape, I know Conv3D require 5D input, the input is 4D with batch added from keras, but I have the following error:
ValueError: Error when checking input: expected conv3d_1_input to have 5 dimensions, but got array with shape (92, 60, 60, 3)
Can anyone please help me what can I do? what is the 92 resulted, I determine input_shape with (57, 8, 60, 60, 3). And what is my input_shape should become to get 8 colored images input to the same model at the same time.

** Edit: updated the link
Here is a custom imagedatagenerator for 5D input to Conv3D nets. Hope it helps. Here is an example on how to use it:
from tweaked_ImageGenerator_v2 import ImageDataGenerator
datagen = ImageDataGenerator()
train_data=datagen.flow_from_directory('path/to/data', target_size=(x, y), batch_size=32, frames_per_step=4)
OR
You can build your own 5D tensor:
frames_folder = 'path/to/folder'
X_data = []
y_data = []
list_of_sent = os.listdir(frames_folder)
print (list_of_sent)
class_num = 0
time_steps = 0
frames = []
for i in list_of_sent:
classes_folder = str(frames_folder + '/' + i) #path to each class
print (classes_folder)
list_of_frames = os.listdir(classes_folder)
time_steps= 0
frames = []
for filename in sorted(list_of_frames):
if ( time_steps == 8 ):
X_data.append(frames) #appending each tensor of 8 frames resized to 110,110
y_data.append(class_num) #appending a class label to the set of 8 frames
j = 0
frames = []
else:
time_steps+=1
filename = cv2.imread(vid + '/' + filename)
filename = cv2.resize(filename,(110, 110),interpolation=cv2.INTER_AREA)
frames.append(filename)
class_num+=1
X_data = np.array(X_data)
y_data = np.array(y_data)
For the snippet above, the folder structure must be like that:
data/
class0/
img001.jpg
img002.jpg
...
class1/
img001.jpg
img002.jpg
...

input shape must be without sample, so instead of
inputShape = (sample, frame, height, width, channels)
try:
inputShape = (frame, height, width, channels)

Related

smile detection when running the code of NN

I have an error when I launch the training of the model indicating the existence of more than one element is ambiguous
I try to detect the smile of faces from RGB images by CNN using python and KERAS
from google.colab import drive
drive.mount('/content/drive')
rom imutils import paths
import cv2
from tensorflow.keras.utils import img_to_array
data = []
labels = []
imagePaths = list(paths.list_images("/content/drive/MyDrive/dataset/SMILEs"))
for imagePath in sorted(list(paths.list_images("/content/drive/MyDrive/dataset/SMILEs"))):
# load the image, pre-process it, and store it in the data list
image = cv2.imread(imagePath)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = imutils.resize(image, width=28)
image = img_to_array(image)
data.append(image)
# extract the class label from the image path and update the labels list
label = imagePath.split(os.path.sep)[-3]
label = "smiling" if label == "positives" else "not_smiling"
labels.append(label)
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)
le = LabelEncoder().fit(labels)
labels = np_utils.to_categorical(le.transform(labels), 2)
classTotals = labels.sum(axis=0)
classWeight = classTotals.max() / classTotals
(trainX, testX, trainY, testY) = train_test_split(data,labels, test_size=0.20, stratify=labels, random_state=42)
class LeNet:
def build(width, height, depth, classes):
model = Sequential()
inputShape = (height, width, depth)
#if K.image_data_format() == "channels_first":
#inputShape = (depth, height, width)
# premiere couche de CONV==>RELU==>POOL:
model.add(Conv2D(20, (5, 5), padding="same",input_shape=inputShape))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
# Deuxieme couche CONV==>RELU==>POOL:
model.add(Conv2D(50, (5, 5), padding="same"))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
# La couche fully connected et d'applatissement:
model.add(Flatten())
model.add(Dense(500))
model.add(Activation("relu"))
model.add(Dense(classes))
model.add(Activation("softmax"))
return model
model = LeNet.build(28, 28, 1,2)
from tensorflow import keras
print("[INFO] compiling model...")
model.compile(loss="categorical_crossentropy",optimizer="adam",metrics=['accuracy'])
print("[INFO] training network...")
H = model.fit(trainX, trainY, validation_data=(testX, testY),class_weight=classWeight, batch_size=64, epochs=15, verbose=1)
and here is the error displayed
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

ValueError: Error when checking target: expected activation_1 to have shape (158,) but got array with shape (121,)

Got the following error when training my CNN:
Traceback (most recent call last):
File "train_and_test.py", line 66, in
H = model.fit(trainX, trainY, validation_data=(testX, testY), batch_size=32, epochs=100, verbose=1)
File "/usr/local/lib/python3.6/dist-packages/keras/engine/training.py", line 972, in fit
batch_size=batch_size)
File "/usr/local/lib/python3.6/dist-packages/keras/engine/training.py", line 789, in _standardize_user_data
exception_prefix='target')
File "/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py", line 138, in standardize_input_data
str(data_shape))
ValueError: Error when checking target: expected activation_1 to have shape (158,) but got array with shape (121,)
Activation_1 is the Last layer of my network, it should have an array of size 158 as input, because my problem has 158 classes. I build the model like this:
model = DeepIrisNet_A.build(width=128, height=128, depth=1, classes=158)
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
Now there's the Strange thing: if I put a number X in classes argument that is different from 158, the error says:
ValueError: Error when checking target: expected activation_1 to have shape (X,) but got array with shape (158,)
So the input array has the right dimensions! But everytime I use the correct value the input array has never (158,) shape.
Where am I wrong? Any suggestions?
EDIT - Here's some of my code:
This is for training and testing the CNN
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from datasets import UtirisLoader
from models import DeepIrisNet_A
from utilities import ResizerPreprocessor
from utilities import ConvertColorSpacePreprocessor
from keras.optimizers import SGD
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import tensorflow as tf
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True, help="path to input dataset")
ap.add_argument("-o", "--output", required=True, help="path to the output loss/accuracy plot")
args = vars(ap.parse_args())
# grab the list of images that we’ll be describing
print("[INFO] loading images...")
imagePaths = list(paths.list_images(args["dataset"]))
# initialize the image preprocessor
rp = ResizerPreprocessor(128, 128)
ccsp = ConvertColorSpacePreprocessor()
# load the dataset from disk then scale the raw pixel intensities to the range [0, 1]
utiris = UtirisLoader(preprocessors=[rp, ccsp])
(data, labels) = utiris.load_infrared(imagePaths, verbose=100)
# print some infos
print("DATA LENGTH: {}".format(len(data)))
print("LABELS LENGTH: {}".format(len(labels)))
unique = np.unique(labels, return_counts=False)
print("LABELS COUNT: {}".format(len(unique)))
# convert data to float
data = data.astype("float") / 255.0
# partition the data into training and testing splits using 75% of the data for training
# and the remaining 25% for testing
(trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.25, random_state=42)
#trainX = np.resize(trainX, (-1, 128, 128, 1))
trainX = trainX.reshape((trainX.shape[0], 128, 128, 1))
testX = testX.reshape((testX.shape[0], 128, 128, 1))
# convert the labels from integers to vectors
trainY = LabelBinarizer().fit_transform(trainY)
testY = LabelBinarizer().fit_transform(testY)
print("trainY: {}".format(trainY))
# initialize the optimizer and model_selection
print("[INFO] compiling model...")
opt = SGD(lr=0.01, momentum=0.9)
model = DeepIrisNet_A.build(width=128, height=128, depth=1, classes=158)
model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
#train the network
print("[INFO] training network...")
H = model.fit(trainX, trainY, validation_data=(testX, testY), batch_size=32, epochs=100, verbose=1)
# evaluate the network
print("[INFO] evaluating network...")
predictions = model.predict(testX, batch_size=32)
print(classification_report(testY.argmax(axis=1), predictions.argmax(axis=1), target_names=["cat", "dog", "panda"]))
# plot the training loss and accuracy
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, 100), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, 100), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, 100), H.history["acc"], label="train_acc")
plt.plot(np.arange(0, 100), H.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.savefig(args["output"])
This is the structure of the CNN
from keras.models import Sequential
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dropout
from keras.layers.core import Dense
from keras import backend as K
class DeepIrisNet_A:
#staticmethod
def build(width, height, depth, classes):
# initialize the models along with the input shape to be "channels last" and the channels dimension itself
model = Sequential()
inputShape = (height, width, depth)
chanDim = -1 # the index of the channel dimension, needed for batch normalization. -1 indicates that channels is the last dimension in the input shape
# if we are using "channel first", update the input shape
if K.image_data_format() == "channels_first":
inputShape = (depth, height, width)
chanDim = 1
# CONV 1
model.add(Conv2D(32,(5,5), strides=(1,1), padding="same", input_shape=inputShape))
# BN 1
model.add(BatchNormalization(axis=chanDim))
# CONV 2
model.add(Conv2D(64, (3,3), strides=(1,1), padding ="valid"))
# POOL 1
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
# BN 2
model.add(BatchNormalization(axis=chanDim))
# CONV 3
model.add(Conv2D(128, (3,3), strides=(1,1), padding ="valid"))
# BN 3
model.add(BatchNormalization(axis=chanDim))
# CONV 4
model.add(Conv2D(192, (3,3), strides=(1,1), padding ="same"))
# POOL 2
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
# BN 4
model.add(BatchNormalization(axis=chanDim))
# CONV 5
model.add(Conv2D(256, (3,3), strides=(1,1), padding ="valid"))
# BN 5
model.add(BatchNormalization(axis=chanDim))
# CONV 6
model.add(Conv2D(320, (3,3), strides=(1,1), padding ="valid"))
# POOL 3
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
# BN 6
model.add(BatchNormalization(axis=chanDim))
# CONV 7
model.add(Conv2D(480, (3,3), strides=(1,1), padding ="valid"))
# BN 7
model.add(BatchNormalization(axis=chanDim))
# CONV 8
model.add(Conv2D(512, (3,3), strides=(1,1), padding ="valid"))
# POOL 4
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
# BN 8
model.add(BatchNormalization(axis=chanDim))
# FC 9
model.add(Flatten())
model.add(Dense(4096))
# DROP 10
model.add(Dropout(0.5))
# FC 11
model.add(Dense(4096))
# DROP 12
model.add(Dropout(0.5))
# FC 13
model.add(Dense(classes))
# COST 14
model.add(Activation("softmax"))
# return the constructed network architecture
return model
I didn't try to run the code but i might have figured your problem.
Be aware that LabelBinarizeronly gives you as many columns as there are different classes. For example:
from sklearn import preprocessing
y = [1, 2, 6, 4, 2]
lb = preprocessing.LabelBinarizer()
lb.fit(y)
lb.transform(y)
will give you:
>>> array([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0]])
Since there are only 4 unique classes.
You might have 158 different classes but maybe you dont have a sample for each one so you only get 121 columns in trainYin the end.

Input shape for 3d-CNN in python

I want to enter 8 images at the same time to the same CNN structure using conv3d. my CNN model is as following:
def build(sample, frame, height, width, channels, classes):
model = Sequential()
inputShape = (sample, frame, height, width, channels)
chanDim = -1
if K.image_data_format() == "channels_first":
inputShape = (sample, frame, channels, height, width)
chanDim = 1
model.add(Conv3D(32, (3, 3, 3), padding="same", input_shape=inputShape))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding="same", data_format="channels_last"))
model.add(Dropout(0.25))
model.add(Conv3D(64, (3, 3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding="same", data_format="channels_last"))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128)) #(Dense(1024))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))
# softmax classifier
model.add(Dense(classes))
model.add(Activation("softmax")
The training of model is as follow:
IMAGE_DIMS = (57, 8, 60, 60, 3) # since I have 460 images so 57 sample with 8 image each
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)
# binarize the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
# note: data is a list of all dataset images
(trainX, testX, trainY, testY) train_test_split(data, labels, test_size=0.2, random_state=42)
aug = ImageDataGenerator(rotation_range=25, width_shift_range=0.1, height_shift_range=0.1, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode="nearest")
# initialize the model
model = CNN_Network.build(sample= IMAGE_DIMS[0], frame=IMAGE_DIMS[1],
height = IMAGE_DIMS[2], width=IMAGE_DIMS[3],
channels=IMAGE_DIMS[4], classes=len(lb.classes_))
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="categorical_crossentropy", optimizer= opt, metrics=["accuracy"])
# train the network
model.fit_generator(
aug.flow(trainX, trainY, batch_size=BS),
validation_data=(testX, testY),
steps_per_epoch=len(trainX) // BS,
epochs=EPOCHS, verbose=1)
I have confused with the input_shape, I know Conv3D require 5D input, the input is 4D with batch added from keras, but I have the following error:
ValueError: Error when checking input: expected conv3d_1_input to have 5 dimensions, but got array with shape (92, 60, 60, 3)
Can anyone please help me what can I do? what is the 92 resulted, I determine input_shape with (57, 8, 60, 60, 3). And what is my input_shape should become to get 8 colored images input to the same model at the same time.
In Keras Python 3, the input shape can be as follows:
input_shape = (8, 64, 64, 1)
Where:
Value 1 (8) is the number of frames
Value 2 (64) is the width
Value 3 (64) is the height
Value 4 (1) is the number of channels

Create 5-dimension input shape to 3d-CNN in python [duplicate]

This question already has answers here:
Multiple images input to the same CNN using Conv3d in keras
(2 answers)
Closed 3 years ago.
I have a dataset of 15 class with 460 images all. I want to enter every 8 sequences of images at the same time to the same CNN structure. I use conv3d to do that, but I'm confusing with input shape, it returns error.
This is my model:
IMAGE_DIMS = (8, 460, 60, 60, 3)
data = []
labels = []
# loading images...
imagePaths = "dataset\\path"
listing = os.listdir(imagePaths)
for imagePath in listing:
image_fold = os.listdir(imagePaths + "\\" + imagePath)
for file in image_fold:
im = (imagePaths + "\\" + imagePath + "\\" + file)
image = cv2.imread(im)
image = cv2.resize(image, (IMAGE_DIMS[2], IMAGE_DIMS[3]))
image = img_to_array(image)
data.append(image)
label= imagePath.split(os.path.sep)[-1]
labels.append(label)
# scale the raw pixel intensities to the range [0, 1]
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)
# binarize the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
(trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.2, random_state=42)
model = Sequential()
sample= IMAGE_DIMS[0]
frame=IMAGE_DIMS[1]
height = IMAGE_DIMS[2]
width=IMAGE_DIMS[3]
channels=IMAGE_DIMS[4]
classes=len(lb.classes_)
inputShape = (sample, frame, height, width, channels)
chanDim = -1
if K.image_data_format() == "channels_first":
inputShape = (sample, frame, channels, height, width)
chanDim = 1
model.add(Conv3D(32, (3, 3, 3), padding="same", batch_input_shape=inputShape))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding="same", data_format="channels_last"))
model.add(Dropout(0.25))
model.add(Conv3D(64, (3, 3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling3D(pool_size=(2, 2, 2), padding="same", data_format="channels_last"))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))
# softmax classifier
model.add(Dense(classes))
model.add(Activation("softmax"))
model.summary()
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="categorical_crossentropy", optimizer= opt, metrics=["accuracy"])
H = model.fit(trainX, trainY, batch_size=BS, epochs=EPOCHS, verbose=1,validation_data (testX,testY))
and this is my model summary:
But I get the following error:
ValueError: Error when checking input: expected conv3d_1_input to have 5 dimensions, but got array with shape (368, 60, 60, 3)
How can I fix the error, can anyone please help me, I will be thankful for any help. I know the problem with the input shape, the compiler refer to the model.fit step. I thing trainX, testX, trainY, testY must be in 5-dim, but I cannot able to that.
If I understand correctly, you would like to fit your model with 8 images which is called actually batch. So when you call the method model.fit() set batch_size = 8. Another point that, I think, you confused is about the input shape. If you would like to fit images to the network, your input shape is the height x width of the image and the number of channels which is in your case RGB. So, the set input_shape = (3, 60, 60). Please be aware of that the network structure does not includes the total number of images in it. Because the NN structure does not need to know what is the training number. When you fit the training images to the network it will just take a batch of it and does the training job. Lastly, Instead of using 3D convolution layer, you need to use 2D. Think it as a 2D frame that moves over the training image and it does the movement for each channel. Therefore, the frame size need to has a 2D shape, set it (x, x). This frame is called kernel in documents.
The following code just an sample and has not been tested. I hope it helps to understand the structure:
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(3, 60, 60)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(number_of_classes))
model.add(Activation('softmax'))

Is there a python way for reducing the training time of convolution neural network?

I'm building a keras model of convolution neural network for predicting the correct class and classify the tested objects. the model have the conv2D, activation, maxpooling, dropout, flatten, dense layers. after that I training the network on large dataset, but it take a very long time for training, it may reach to 3,4 days, What I need is to reduce the time required to training the network, Is there any way to do that in python?
I have tried to optimize the learning rate by using the LR_Finder class as follow:
from LR_Finder import LRFinder
lr_finder = LRFinder(min_lr=1e-5,max_lr=1e-2, steps_per_epoch=np.ceil(len(trainX) // BS), epochs=100)
But this also did not give me any reduction about the time required.
This is the code of my model:
class SmallerVGGNet:
#staticmethod
def build(width, height, depth, classes):
# initialize the model along with the input shape to be
# "channels last" and the channels dimension itself
model = Sequential()
inputShape = (height, width, depth)
chanDim = -1
# if we are using "channels first", update the input shape
# and channels dimension
if K.image_data_format() == "channels_first":
inputShape = (depth, height, width)
chanDim = 1
# CONV => RELU => POOL
model.add(Conv2D(32, (3, 3), padding="same",
input_shape=inputShape))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(3, 3)))
model.add(Dropout(0.25))
# (CONV => RELU) * 2 => POOL
model.add(Conv2D(64, (3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(64, (3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
# (CONV => RELU) * 2 => POOL
model.add(Conv2D(128, (3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(128, (3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
# first (and only) set of FC => RELU layers
model.add(Flatten())
model.add(Dense(1024))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))
# softmax classifier
model.add(Dense(classes))
model.add(Activation("softmax"))
# return the constructed network architecture
return model
and after that I trained the model as following code:
EPOCHS = 100
INIT_LR = 1e-3
BS = 32
IMAGE_DIMS = (96, 96, 3)
data = []
labels = []
# grab the image paths and randomly shuffle them
imagePaths = sorted(list(paths.list_images("Dataset")))
random.seed(42)
random.shuffle(imagePaths)
# loop over the input images
for imagePath in imagePaths:
# load the image, pre-process it, and store it in the data list
image = cv2.imread(imagePath)
image = cv2.resize(image, (IMAGE_DIMS[1], IMAGE_DIMS[0]))
image = img_to_array(image)
data.append(image)
label = imagePath.split(os.path.sep)[-2]
labels.append(label)
# scale the raw pixel intensities to the range [0, 1]
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)
print("[INFO] data matrix: {:.2f}MB".format(data.nbytes / (1024 * 1000.0)))
# binarize the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
# partition the data into training and testing splits using 80% of
# the data for training and the remaining 20% for testing
(trainX, testX, trainY, testY) = train_test_split(data,
labels, test_size=0.2, random_state=42)
# construct the image generator for data augmentation
aug = ImageDataGenerator(rotation_range=25, width_shift_range=0.1,
height_shift_range=0.1, shear_range=0.2, zoom_range=0.2,
horizontal_flip=True, fill_mode="nearest")
# initialize the model
model = SmallerVGGNet.build(width=IMAGE_DIMS[1], height=IMAGE_DIMS[0],
depth=IMAGE_DIMS[2], classes=len(lb.classes_))
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="categorical_crossentropy", optimizer= opt,
metrics=["accuracy"])
print("model compiled in few minutes successfully ^_^")
# train the network
H = model.fit_generator(aug.flow(trainX, trainY, batch_size=BS),
validation_data=(testX, testY), steps_per_epoch=len(trainX) // BS,
epochs=EPOCHS, verbose=1)
According to this code,I expected the output required some minutes or may be a few hours, but when it reach to training in model.fit_generator step, the actual time required is about many hours for every epoch and it requires some days to train all the network or it may be crash and stop working. Is there any way to reduce the training time?
set use_multiprocessing=True and workers>1 when you call fit_generator because the default is to execute the generator on the main thread only

Categories

Resources