What should be the input to Convolution neural network (CNN) using keras and tensorflow? - python

I'm trying to create CNN model using keras ad tensorflow as backend.
below is code for the same..
Cannot understand what input it is expecting...
import cv2,os
import glob
import numpy as np
from sklearn.utils import shuffle
from sklearn.cross_validation import train_test_split
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Input, Convolution2D, MaxPooling2D, Dense, Dropout, Flatten
PATH = os.getcwd()
data_path = PATH + '/data1/cat/*.PNG'
files = glob.glob(data_path)
X_data = []
for myFile in files:
image = cv2.imread (myFile)
image_resize = cv2.resize(image,(128,128))
X_data.append (image_resize)
image_data = np.array(X_data)
image_data = image_data.astype('float32')
image_data /= 255
print('X_data shape:', image_data.shape)
#Class ani labels
class_num = 2
total_Images = image_data.shape[0]
labels = np.ones((total_Images),dtype='int64')
labels[0:30] = 0
labels[31:] = 1
Y = to_categorical(labels,class_num)
#print(Y);
# Shuffle the dataset
x, y = shuffle(image_data, Y, random_state=2)
# Split the dataset
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=2)
input_shape = image_data[0].shape
#print(input_shape)
model = Sequential()
conv1 = Convolution2D(32,(3,3),padding='same',activation='relu')(input_shape)
conv2 = Convolution2D(32,(3,3),padding='same',activation='relu')(conv1)
pool_1 = MaxPooling2D(pool_size=(2,2))(conv2)
drop1 = Dropout(0.5)(pool_1)
conv3 = Convolution2D(64,(3,3),padding='same',activation='relu')(drop1)
conv4 = Convolution2D(64,(3,3),padding='same',activation='relu')(conv3)
pool_2 = MaxPooling2D(pool_size=(2,2))(conv4)
drop2 = Dropout(0.5)(pool_2)
flat = Flatten()(drop2)
hidden = Dense(64,activation='relu')(flat)
drop3 = Dropout(0.5)(hidden)
out = Dense(class_num,activation='softmax')(drop3)
model.compile(loss = 'categorical_crossentropy', optimizer= 'adam', metrics=['accuracy'])
model.fit(X_train,y_train,batch_size=16,nb_epoch=20, verbose=1, validation_data=(X_test,y_test))
model.evaluate(X_test,y_test,verbose=1)
Error: ValueError: Layer conv2d_1 was called with an input that isn't a
symbolic tensor. Received type: <class 'tuple'>. Full input: [(128, 128,3)].
All inputs to the layer should be tensors.

You are attempting to use the functional API and the sequential model all at once you need to first eliminate this line
model = Sequential()
Then, from the documentation of the functional API, we add an Input(channels,rows,columns) layer, and fill in the size values from your X_train matrix.
input_shape = Input()

Related

ValueError being thrown 'This model has not been built'...for CNN Audio Spectrogram feature extraction

In the code below, I am getting the error:
raise ValueError('This model has not yet been built. ' ValueError: This model has not yet been built. Build the model first by calling ``build()`` or calling ``fit()`` with some data, or specify an ``input_shape`` argument in the first layer(s) for automatic build.
I am trying to use a spectrogram instead of the Mel feature extraction for this CNN. I think the error may be in the extraction process for the extract_features step.
Any help will be greatly appreciated in figuring out the source of this error.
Here are some sizes of arrays generated before the error:
x_test = {ndarray:(353,128)}
x_train = {ndarray:(1408,128)}
y = {ndarray:(1761,)}
y_test = {ndarray:(353,10)}
y_ttrain = {ndarray:(1408,10)}
CODE
# Sample rate conversion
import librosa
import librosa.display
from scipy.io import wavfile as wav
import numpy as np
import pandas as pd
import os
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
max_pad_len = 174
n_mels = 128
def extract_features(file_name):
try:
audio, sample_rate = librosa.core.load(file_name, res_type='kaiser_fast')
mely = librosa.feature.melspectrogram(y=audio, sr=sample_rate, n_mels=n_mels)
# pad_width = max_pad_len - mely.shape[1]
# mely = np.pad(mely, pad_width=((0, 0), (0, pad_width)), mode='constant')
melyscaled = np.mean(mely.T, axis=0)
except Exception as e:
print("Error encountered while parsing file: ", file_name)
return None
return melyscaled
features = []
# Iterate through each sound file and extract the features
from time import sleep
#from tqdm import tqdm
from alive_progress import alive_bar
items = len(metadata.index)
with alive_bar(items) as bar:
for index, row in metadata.iterrows():
bar()
file_name = os.path.join(os.path.abspath(fulldatasetpath), 'fold' + str(row["fold"]) + '/',
str(row["slice_file_name"]))
class_label = row["class_name"]
data = extract_features(file_name)
features.append([data, class_label])
# Convert into a Panda dataframe
featuresdf = pd.DataFrame(features, columns=['feature', 'class_label'])
print('Finished feature extraction from ', len(featuresdf), ' files')
from sklearn.preprocessing import LabelEncoder
from keras.utils import to_categorical
# Convert features and corresponding classification labels into numpy arrays
X = np.array(featuresdf.feature.tolist())
y = np.array(featuresdf.class_label.tolist())
# Encode the classification labels
le = LabelEncoder()
yy = to_categorical(le.fit_transform(y))
# split the dataset
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, yy, test_size=0.2, random_state = 42)
### Convolutional Neural Network (CNN) model architecture
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, Conv2D, MaxPooling2D, GlobalAveragePooling2D
from keras.optimizers import Adam
from keras.utils import np_utils
from sklearn import metrics
num_rows = 40
num_columns = 174
num_channels = 1
#
#x_train = x_train.reshape(x_train.shape[0], num_rows, num_columns, num_channels)
#x_test = x_test.reshape(x_test.shape[0], num_rows, num_columns, num_channels)
num_labels = yy.shape[1]
filter_size = 2
# Construct model
model = Sequential()
#model.add(Conv2D(filters=16, kernel_size=2, input_shape=(num_rows, num_columns, num_channels), activation='relu'))
model.add(Conv2D(filters=16, kernel_size=2, activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
model.add(Conv2D(filters=32, kernel_size=2, activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
model.add(Conv2D(filters=64, kernel_size=2, activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
model.add(Conv2D(filters=128, kernel_size=2, activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
model.add(GlobalAveragePooling2D())
model.add(Dense(num_labels, activation='softmax'))
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
# Display model architecture summary
model.summary()
You have to build your model with your input shape before calling model.summary():
model.build((128,))

I scripted a simple convLSTM for video classification but i get an error

i created a convLSTM network that classifies videos. The dataset consist of 6 classes with videos inside it.
I get the error "NameError: name 'y_pred' is not defined" and it's related to the third last line of code. You don't need to run the code because it's probably a syntax error or something like this.
Why i get this error ?
import keras
from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential, Model
from keras.layers import *
from keras.callbacks import ModelCheckpoint, LearningRateScheduler, TensorBoard, EarlyStopping
import os
import cv2
import numpy as np
from sklearn.model_selection import train_test_split
import keras_metrics as km
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
from sklearn.metrics import cohen_kappa_score
from sklearn.metrics import roc_auc_score
from sklearn.metrics import multilabel_confusion_matrix
data_dir = "video_data/"
img_height , img_width = 64, 64
seq_len = 70
classes = ["Apply Eye Makeup", "Archery", "Apply Lipstick", "Baby Crawling", "Balance Beam", "Band Marching"]
# Creating frames from videos
def frames_extraction(video_path):
frames_list = []
vidObj = cv2.VideoCapture(video_path)
# Used as counter variable
count = 1
while count <= seq_len:
success, image = vidObj.read()
if success:
image = cv2.resize(image, (img_height, img_width))
frames_list.append(image)
count += 1
else:
print("Defected frame")
break
return frames_list
def create_data(input_dir):
X = []
Y = []
classes_list = os.listdir(input_dir)
for c in classes_list:
print(c)
files_list = os.listdir(os.path.join(input_dir, c))
for f in files_list:
frames = frames_extraction(os.path.join(os.path.join(input_dir, c), f))
if len(frames) == seq_len:
X.append(frames)
y = [0]*len(classes)
y[classes.index(c)] = 1
Y.append(y)
X = np.asarray(X)
Y = np.asarray(Y)
return X, Y
X, Y = create_data(data_dir)
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.20, shuffle=True, random_state=0)
model = Sequential()
model.add(ConvLSTM2D(filters = 64, kernel_size = (3, 3), return_sequences = False, data_format = "channels_last", input_shape = (seq_len, img_height, img_width, 3)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(256, activation="relu"))
model.add(Dropout(0.3))
model.add(Dense(6, activation = "softmax"))
model.summary()
opt = keras.optimizers.SGD(lr=0.001)
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=["accuracy"])
earlystop = EarlyStopping(patience=7)
callbacks = [earlystop]
history = model.fit(x = X_train, y = y_train, epochs=40, batch_size = 8 , shuffle=True, validation_split=0.2, callbacks=callbacks)
y_pred = np.argmax(y_pred, axis = 1)
y_test = np.argmax(y_test, axis = 1)
print(classification_report(y_test, y_pred))
The error is self-explanatory from the message: y_pred is not defined...
You have to predict your data first, doing something like y_pred = model.predict(X_test) then, you can argmax, etc.
[EDIT]: to sum up, replace your three last lines with that
y_pred = model.predict(X_test)
y_pred = np.argmax(y_pred, axis = 1)
print(classification_report(y_test, y_pred))

Keras: How to get model predictions( or last layer output) in a custom generator during training?

I have made a custom generator in which I need my model's prediction, during training, to do some calculations on it, before it is trained against the true labels. Therefore, I save the model first and then call model.predict() on the current state.
from keras.models import load_model
def custom_generator(model):
while True:
state, target_labels = next(train_it)
model.save('my_model.h5')
#pause training and do some calculations on the output of the model trained so far
print(state)
print(target_labels)
model.predict(state)
#resume training
#model = load_model('my_model.h5')
yield state, target_labels
model3.fit_generator(custom_generator(model3), steps_per_epoch=1, epochs = 10)
loss = model3.evaluate_generator(test_it, steps=1)
loss
I get the following error due to calling model.predict(model) in the custom_generator()
Error:
ValueError: Tensor Tensor("dense_2/Softmax:0", shape=(?, 200),
dtype=float32) is not an element of this graph.
Kindly, help me how to get model predictions(or last layer output) in a custom generator during training.
This is my model:
#libraries
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
from matplotlib import pyplot
from keras.applications.vgg16 import VGG16
model = VGG16(include_top=False, weights='imagenet')
print(model.summary())
#add layers
z = Conv2D(1, (3, 3), activation='relu')(model.output)
z = Conv2D(1,(1,1), activation='relu')(z)
z = GlobalAveragePooling2D()(z)
predictions3 = Dense(200, activation='softmax')(z)
model3 = Model(inputs=model.input, outputs=predictions3)
for layer in model3.layers[:20]:
layer.trainable = False
for layer in model3.layers[20:]:
layer.trainable = True
model3.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')
Image data generators for loading training and testing data
from keras.preprocessing.image import ImageDataGenerator
# create a data generator
datagen = ImageDataGenerator()
# load and iterate training dataset
train_it = datagen.flow_from_directory('DATA/C_Train/', class_mode='categorical', batch_size=1)
test_it = datagen.flow_from_directory('DATA/C_Test/', class_mode='categorical', batch_size=1)
Your best bet may be to write a custom train loop via train_on_batch or fit; the former's only disadvantaged if use_multiprocessing=True, or using callbacks - which isn't the case. Below is an implementation with train_on_batch - if you use fit instead (for multiprocessing, callbacks, etc), make sure you feed only one batch at a time, and provide no validation data (use model.evaluate instead) - else the control flow breaks. (Also, a custom Callback is a valid, but involved alternative)
CUSTOM TRAIN LOOP
iters_per_epoch = len(train_it) // batch_size
num_epochs = 5
outs_store_freq = 20 # in iters
print_loss_freq = 20 # in iters
iter_num = 0
epoch_num = 0
model_outputs = []
loss_history = []
while epoch_num < num_epochs:
while iter_num < iters_per_epoch:
x_train, y_train = next(train_it)
loss_history += [model3.train_on_batch(x_train, y_train)]
x_test, y_test = next(test_it)
if iter_num % outs_store_freq == 0:
model_outputs += [model3.predict(x_test)]
if iter_num % print_loss_freq == 0:
print("Iter {} loss: {}".format(iter_num, loss_history[-1]))
iter_num += 1
print("EPOCH {} FINISHED".format(epoch_num + 1))
epoch_num += 1
iter_num = 0 # reset counter
FULL CODE
from keras.models import Sequential
from keras.layers import Dense, Conv2D, GlobalAveragePooling2D
from keras.models import Model
from keras.optimizers import SGD
from keras.applications.vgg16 import VGG16
from keras.preprocessing.image import ImageDataGenerator
model = VGG16(include_top=False, weights='imagenet')
print(model.summary())
#add layers
z = Conv2D(1, (3, 3), activation='relu')(model.output)
z = Conv2D(1,(1,1), activation='relu')(z)
z = GlobalAveragePooling2D()(z)
predictions3 = Dense(2, activation='softmax')(z)
model3 = Model(inputs=model.input, outputs=predictions3)
for layer in model3.layers[:20]:
layer.trainable = False
for layer in model3.layers[20:]:
layer.trainable = True
model3.compile(optimizer=SGD(lr=0.0001, momentum=0.9),
loss='categorical_crossentropy')
batch_size = 1
datagen = ImageDataGenerator()
train_it = datagen.flow_from_directory('DATA/C_Train/',
class_mode='categorical',
batch_size=batch_size)
test_it = datagen.flow_from_directory('DATA/C_Test/',
class_mode='categorical',
batch_size=batch_size)
[custom train loop here]
BONUS CODE: to get outputs of any layer, use below:
def get_layer_outputs(model, layer_name, input_data, learning_phase=1):
outputs = [layer.output for layer in model.layers if layer_name in layer.name]
layers_fn = K.function([model.input, K.learning_phase()], outputs)
return [layers_fn([input_data,learning_phase])][0]
outs = get_layer_outputs(model, 'dense_1', x_test, 0) # 0 == inference mode

Store images into multiply array and use it to train model

I get this error when train the model:
ValueError: Error when checking target:
expected dropout_5 to have shape (33,) but got array with shape (1,).
I want to store my images into 33 array from folder using path. I have categories the images into different folder which were 1,2,3,4,5...
I have use this code to do it but i dont know how to store it into different array. Can someone help me.
datadir = 'C:/Users/user/Desktop/RESIZE' #path of the folder
categories = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y']
img_rows, img_cols = 100, 100
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_rows,img_cols))
training_data.append([new_array,class_num])
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_rows,img_cols,1)
X = X.astype("float32")
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()
After I save the file, then I use this code to train model and I want get 33 output layer but it only can work when my output layer(Dense) set 1.
I got this error:
ValueError: Error when checking target:
expected dropout_5 to have shape (33,) but got array with shape (1,)
Here was my training code.
import tensorflow as tf
from keras import optimizers
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers import Activation
import cv2
import os
import numpy as np
import pickle
from sklearn.utils import shuffle
X = pickle.load(open("X.pickle","rb"))
y = pickle.load(open("y.pickle","rb"))
X = X/255.0
model = Sequential()
model.add(Conv2D(32,(3,3), input_shape = X.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(64,(3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(128,(3,3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.4))
model.add(Dense(128))
model.add(Activation("relu"))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(33, activation='softmax'))
model.add(Dropout(0.4))
model.compile(loss = "binary_crossentropy", optimizer = "adam", metrics = ["accuracy"])
model.fit(X, y, batch_size = 2, epochs = 1, validation_split = 0.2)
You need to change your y as one hot encoded data to do the training.
Try this for y,
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# integer encode
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(y)
print(label_encoder.classes_) # This is your classes.
print(integer_encoded.shape())
# binary encode
onehot_encoder = OneHotEncoder(sparse=False)
integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
print(onehot_encoded.shape())
And one more thing, if you want to classify for 33 class than change your loss to categorical_crossentropy.

How to match expected input shape to array shape in CNN model?

I am attempting a CNN for classification of biological data (EEG data). However, after importing and splitting the data into train/test/dev sets and building the CNN, I cannot get the input array shape to match the expected array shape.
Note: Data contains 5 trials/samples for each participant(ID's) in the study, so GSS was used to ensure data from each participant was not mixed train and test sets.
Code and error as follows:
#Load Data
def load_all_data(filename):
import numpy as np
a = np.load(filename)
d = (dict(zip(("data1{}".format(k) for k in a), (a[k] for k in a))))
return d
filename = ("dataname.npz")
X = load_all_data(filename)['array_0']
y = load_all_data(filename)['array_1']
IDs = load_all_data(filename)['array_2']
#Split Test Data with Groupshuffle Split
from sklearn.model_selection import GroupShuffleSplit
import numpy as np
test_size = 0.2
gss = GroupShuffleSplit(n_splits = 1, test_size = 0.2)
for train,test in gss.split(X, y, IDs):
X_train = X[train]
y_train = y[train]
IDs_train = IDs[train]
X_test = X[test]
y_test = y[test]
IDs_test = IDs[test]
fileoutname = 'train_test_data'
np.savez(fileoutname,X_train, y_train, X_test, y_test,IDs_train,IDs_test)
#Split Train, Test Data
gss = GroupShuffleSplit(1, test_size)
for train,test in gss.split(X, y, IDs):
X_train2 = X[train]
y_train2 = y[train]
IDs_train = IDs[train]
X_dev = X[test]
y_dev = y[test]
IDs_test = IDs[test]
#Add dimension to X and Convert y to Categorical
X_train2 = np.expand_dims(X_train2,axis=0)
y_train2 = keras.utils.to_categorical(y_train2,num_classes=2)
X_dev = np.expand_dims(X_test,axis=0)
y_dev = keras.utils.to_categorical(y_test,num_classes=2)
X = np.expand_dims(X,axis=0)
#Build the CNN
def simpleCNN(self, units = 10):
import keras
from keras.layers import Dense
from keras.layers import Conv2D
from keras.layers import Flatten
from keras.models import Model, Input
inp = Input(shape = self.shape[1:], name='inp')
#layer 1
x = Conv2D(units, kernel_size=(1,1), strides = (1,1), activation='relu', data_format='channels_last')(inp)
#layer 2
x = Conv2D(units, kernel_size=(2,2), strides = (1,1), activation='relu', data_format='channels_last')(x)
#layer 3
x = Flatten()(x)
#layer4
out = Dense(2, activation='softmax',name='out')(x)
model = Model(inputs = inp, outputs = out)
return model
#Fit the Data
model = simpleCNN(X)
from keras.optimizers import Adamax
adamax = Adamax(lr=3e-4, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0); #3e-4; 2e-3 is a default.
model.compile(optimizer=adamax, loss='categorical_crossentropy', metrics=['acc'])
model.fit(X_train2, y_train2, epochs=20, batch_size=32, verbose = 1, validation_data = (X_dev, y_dev))
ValueError: Error when checking input: expected inp to have shape (11459, 26, 60) but got array with shape (9065, 26, 60)

Categories

Resources