I have xtrain.shape as
(60000, 28, 28)
It means 60000 channels with image size 28 * 28
I want to make a keras Sequential model.
specifying the model shape
model = Sequential()
model.add(Convolution2D(32,3,activation='relu',input_shape=(????)))
model.add(Dense(10, activation='relu'))
model.summary()
what input_shape should looks like?
model = Sequential()
model.add(Dense(64,input_shape=(1,28,28)))
when I put this I got an following error
Error when checking input: expected dense_31_input to have 4 dimensions, but got array with shape (60000, 28, 28)
why this required 4 dimensions? and how to fix it form code?
I have xtrain.shape as
(60000, 28, 28)
It means 60000 channels with image size 28 * 28
Well, it certainly does not mean that; it means 60000 samples, not channels (MNIST is a single-channel dataset).
No need to re-invent the wheel in such cases - have a look at the MNIST CNN example in Keras:
from keras import backend as K
# input image dimensions
img_rows, img_cols = 28, 28
# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()
if K.image_data_format() == 'channels_first': # Theano backend
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else: # Tensorflow backend
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
# normalise:
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
# your model:
model = Sequential()
model.add(Convolution2D(32,3,activation='relu',input_shape=input_shape))
model.add(Dense(10, activation='softmax')) # change to softmax in the final layer
where you should also change the activation of the final layer to softmax (and most probably add some pooling and flatten layers before the final dense one).
Try to reshape data to (60000, 28, 28, 1) or (60000, 1, 28, 28).
First one,
model = Sequential()
model.add(Convolution2D(32,3,activation='relu',input_shape=(60000,28,28)))
model.add(Dense(10, activation='relu'))
model.summary()
Second one,
model = Sequential()
model.add(Dense(64,input_shape=(None,60000,28,28)))
Related
This question is in line with the question posted here but with a slight nuance of the CNN. Using the feature extraction definition:
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')
except Exception as e:
print("Error encountered while parsing file: ", file_name)
return None
return mely
How do you go about getting the correct dimension of the num_rows, num_columns and num_channels to be input to the train and test data?
In constructing the CNN Model, how to determine the correct shape to input?
model = Sequential()
model.add(Conv2D(filters=16, kernel_size=2, input_shape=(num_rows, num_columns, num_channels), activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
I dont know if it is exactly your problem but I also have to use a MEL as an input to a CNN.
Short answer:
input_shape = (x_train.shape[1], x_train.shape[2], 1)
x_train = x_train.reshape(x_train.shape[0], x_train.shape[1], x_train.shape[2], 1)
or
x_train = x_train.reshape(x_train.shape[0], x_train.shape[1], x_train.shape[2], 1)
input_shape = x_train.shape[1:]
Long answer
In my case I have a DataFrame with speakers_id and mel spectrograms (previously calculated with librosa).
The Keras CNN models are prepared for images with width, height and channels of colors (grayscale - RGB)
The Mel Spectrograms given by librosa are image-like arrays with width and height, so you need to do a reshape to add the channel dimension.
Define the input and expected output
# It looks stupid but that way i could convert the panda.Series to a np.array
x = np.array(list(df.mel))
y = df.speaker_id
print('X shape:', x.shape)
X shape: (2204, 128, 24)
2204 Mels, 128x24
Split in train-test
x_train, x_test, y_train, y_test = train_test_split(x, y)
print(f'Train: {len(x_train)}', f'Test: {len(x_test)}')
Train: 1653 Test: 551
Reshape to add the extra dimension
x_train = x_train.reshape(x_train.shape[0], x_train.shape[1], x_train.shape[2], 1)
x_test = x_test.reshape(x_test.shape[0], x_test.shape[1], x_test.shape[2], 1)
print('Shapes:', x_train.shape, x_test.shape)
Shapes: (1653, 128, 24, 1) (551, 128, 24, 1)
Set input_shape
# The input shape is independent of the amount of inputs
input_shape = x_train.shape[1:]
print('Input shape:', input_shape)
Input shape: (128, 24, 1)
Put it into the model
model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))
model.add(MaxPooling2D())
# More layers...
model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['accuracy'])
Run model
model.fit(x_train, y_train, epochs=20, validation_data=(x_test, y_test))
Hope this is helpfull
I created a CNN model for predicting fashions using the mnist fashion dataset. After the model has been trained, I tried predicting one of the test images that are loaded from Keras and another image that is identical but imported from my PC onto my Google Colab notebook, and it turns out, the prediction results are not the same. How can I solve this problem?
This is how I imported the dataset:
import tensorflow as tf
from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
Data manipulation:
from keras.utils import to_categorical
yTest = to_categorical(y_test)
yTrain = to_categorical(y_train)
xTrain = x_train.reshape((60000, 28, 28, 1))
xTest = x_test.reshape(10000, 28, 28, 1)
Model Setup:
from keras.layers import Dense, Flatten, Conv2D, Dropout, MaxPool2D, BatchNormalization
from keras.callbacks import ModelCheckpoint
model = keras.Sequential()
#Adding the convolutional layer
model.add(Conv2D(50, kernel_size=3, activation='relu',padding = 'same', input_shape = (28, 28, 1)))
model.add(MaxPool2D(pool_size = (2, 2), strides = 1, padding = 'valid'))
model.add(Dropout(0.5))
model.add(Conv2D(40, kernel_size = 3, activation = 'relu', padding = 'same'))
model.add(MaxPool2D(pool_size = (2, 2), strides = 1, padding = 'valid'))
model.add(Dropout(0.5))
model.add(Conv2D(30, kernel_size = 3, activation = 'relu', padding = 'same'))
model.add(MaxPool2D(pool_size = (2, 2), strides = 2, padding = 'valid'))
model.add(Dropout(0.5))
model.add(Conv2D(10, kernel_size = 3, activation = 'relu', padding = 'same'))
model.add(Dropout(0.5))
#Connecting the CNN layers to the ANN
model.add(Flatten())
model.add(Dense(60, activation='relu'))
model.add(Dense(40, activation='relu'))
model.add(Dense(40, activation = 'relu'))
model.add(Dense(10, activation = 'softmax'))
model.load_weights('mnist_fashion.h5')
# Compiling the model
opt = tf.keras.optimizers.Adam(learning_rate=0.0001)
model.compile(optimizer=opt, loss = 'categorical_crossentropy', metrics = ['accuracy']
The model for training:
model = keras.Sequential()
#Adding the convolutional layer
model.add(Conv2D(50, kernel_size=3, activation='relu',padding = 'same', input_shape = (28, 28, 1)))
model.add(MaxPool2D(pool_size = (2, 2), strides = 1, padding = 'valid'))
model.add(Dropout(0.5))
model.add(Conv2D(40, kernel_size = 3, activation = 'relu', padding = 'same'))
model.add(MaxPool2D(pool_size = (2, 2), strides = 1, padding = 'valid'))
model.add(Dropout(0.5))
model.add(Conv2D(30, kernel_size = 3, activation = 'relu', padding = 'same'))
model.add(MaxPool2D(pool_size = (2, 2), strides = 2, padding = 'valid'))
model.add(Dropout(0.5))
model.add(Conv2D(10, kernel_size = 3, activation = 'relu', padding = 'same'))
model.add(Dropout(0.5))
#Connecting the CNN layers to the ANN
model.add(Flatten())
model.add(Dense(60, activation='relu'))
model.add(Dense(40, activation='relu'))
model.add(Dense(40, activation = 'relu'))
model.add(Dense(10, activation = 'softmax'))
The model's Performance:
precision recall f1-score support
0 0.89 0.88 0.88 1000
1 0.99 0.99 0.99 1000
2 0.88 0.89 0.89 1000
3 0.93 0.93 0.93 1000
4 0.87 0.89 0.88 1000
5 0.99 0.98 0.99 1000
6 0.79 0.78 0.78 1000
7 0.97 0.98 0.97 1000
8 0.99 0.98 0.99 1000
9 0.97 0.97 0.97 1000
accuracy 0.93 10000
macro avg 0.93 0.93 0.93 10000
weighted avg 0.93 0.93 0.93 10000
Picture from dataset prediction
#From the dataset
import numpy as np
image = xTrain[0].reshape(1, 28, 28, 1)
prd = model.predict(image)
new_prd = np.argmax(prd, axis = 1)
print(f"Prediction = {new_prd}")
print(f"Full Prediction = {prd}")
print(f"Label = {y_train[0]}")
Dataset Result
Prediction = [9]
Full Prediction = [[1.6268513e-07 2.3548612e-08 1.5456487e-07 8.6898848e-07 1.9692785e-09
4.4544859e-04 6.6932116e-06 1.4004705e-02 4.1784686e-05 9.8550016e-01]]
Label = 9
Imported picture prediction
imported_img = plt.imread("mnist fashion sample.png")
yolo = imported_img.reshape(1, 28, 28, 1)
super_prd = model.predict(yolo)
prediction = np.argmax(super_prd, axis = 1)
print(f"Prediction = {prediction}")
print(f"Full Prediction = {super_prd}")
print(f"Label = {y_train[0]}")
Imported picture prediction result
Prediction = [8]
Full Prediction = [[2.49403762e-04 1.69450897e-04 4.47237398e-04 3.05729372e-05
1.10463676e-04 4.34053177e-03 5.16198808e-04 8.16224664e-02
8.73587310e-01 3.89263593e-02]]
Label = 9
I solved the problem!
What I did wrong was that I did not normalize the pictures before training. This may cause an error because the data pixel range can be too complex for the relu activation function to calculate or predict.
Thank you!!!
I want to predict the kind of 2 diseases but I get results as binary (like 1.0 and 0.0). How can I get accuracy of these (like 0.7213)?
Training code:
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
# Intialising the CNN
classifier = Sequential()
# Step 1 - Convolution
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Adding a second convolutional layer
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
# Step 3 - Flattening
classifier.add(Flatten())
# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
# Part 2 - Fitting the CNN to the images
import h5py
from keras.preprocessing.image import ImageDataGenerator
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('training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
test_set = test_datagen.flow_from_directory('test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
classifier.fit_generator(training_set,
steps_per_epoch = 100,
epochs = 1,
validation_data = test_set,
validation_steps = 100)
Single prediction code:
import numpy as np
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img,image
test_image = image.load_img('path_to_image', target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = classifier.predict(test_image)
print(result[0][0]) # Prints 1.0 or 0.0
# I want accuracy rate for this prediction like 0.7213
The file structures is like:
test_set
benigne
benigne_images
melignant
melignant_images
training set
Training set structure is also the same as test set.
Update: As you clarified in the comments, you are looking for the probabilities of each class given one single test sample. Therefore you can use predict method. However, note that you must first preprocess the image the same way you have done in the training phase:
test_image /= 255.0
result = classifier.predict(test_image)
The result would be the probability of the given image belonging to class one (i.e. positive class).
If you have a generator for test data, then you can use evaluate_generator() to get the loss as well as the accuracy (or any other metric you have set) of the model on the test data.
For example, right after fitting the model, i.e. using fit_generator, you can use evaluate_generator on your test data generator, i.e. test_set:
loss, acc = evaluate_generator(test_set)
I'm working on a classification of one dimensional data. I presented the data in the form of 549 arrays, each contains 600 samples. I've made a multi-layer perceptron, which showed an efficiency of about 80%. Now I'm trying to do CNN but for some reason it's accuracy doesn't exceed 31%. What can be wrong?
My model:
model = Sequential()
model.add(Conv1D(filters=20, kernel_size=4,activation='relu',padding='same',input_shape=(600,1)))
model.add(MaxPooling1D(pool_size = 2))
model.add(Dropout(0.3))
model.add(Flatten())
model.add(Dense(50, activation='relu', input_dim = 600))
model.add(Dense(1, activation='softmax'))
model.compile(loss="binary_crossentropy", optimizer="nadam", metrics=['accuracy'])
model.fit(np.array(X), np.array(Y), epochs = 100, batch_size=8, verbose=1, validation_data=(np.array(X1),np.array(Y1)))
scores = model.evaluate(np.array(X1), np.array(Y1), verbose=0)
Input data:
X1 = X[:90]
X = X[91:]
Y1 = Y[:90]
Y = Y[91:]
X = np.expand_dims(X, axis=2)
X1 =np.expand_dims(X1, axis=2)
print(np.array(X).shape)
Get the dimension (458, 600, 1) can there be something wrong with the dimensions?
change
model.add(Dense(1, activation='softmax'))
to
model.add(Dense(1, activation='sigmoid'))
I am trying to feed 1-D signal(1,2000) which has 22 features(22,2000) into LSTM.
(1-D signal is taken by 10 seconds with 200 hz sampling rate)
And I have 808 batches. (808, 22, 2000)
I saw that the LSTM receives 3D tensor shape of (batch_size, timestep, input_dim).
So is it right that my input shape as?
: (batch_size = 808, timestep = 2000, input_dim = 3)
here is my sample of code.
# data shape check
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
(727, 22, 2000)
(81, 22, 2000)
(727, 2)
(81, 2)
# Model Config
inputshape = (808,2000,2) # 22 chanel, 2000 samples
lstm_1_cell_num = 20
lstm_2_cell_num = 20
inputdrop_ratio = 0.2
celldrop_ratio = 0.2
# define model
model = Sequential()
model.add(LSTM(lstm_1_cell_num, input_shape=inputshape, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(20))
model.add(LSTM(lstm_2_cell_num, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(2, activation='sigmoid'))
print(model.summary())
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
First input shape must be (22,2000) and batch size should be given in the fit function. So try this
inputshape = (22,2000)
model.fit(X_train, y_train,
batch_size=808,
epochs=epochs,
validation_data=(X_test,y_test),
shuffle=True)