For the sake of reproducibility, the training and validations datasets I am using are shared here
The validation_dataset.csv is the ground truth of training_dataset.csv.
What I am doing below is feeding the datasets into a simple CNN layer that extracts the useful features of the images and feed that as 1D into the LSTM network for classification.
from keras.models import Sequential
from keras.layers import Dense, Flatten, Activation
from keras.layers.convolutional import Conv1D
from keras.layers import LSTM
from keras.layers.convolutional import MaxPooling1D
from keras.layers import TimeDistributed
from keras.layers import Dropout
from keras import optimizers
from keras.callbacks import EarlyStopping
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score
from confusion_matrix import plot_confusion_matrix
import scikitplot as skplt
from numpy import genfromtxt
train_set = genfromtxt('data/train/training_dataset.csv', delimiter=',')
validation_set = genfromtxt('data/validation/validation_dataset.csv', delimiter=',')
train_set = train_set[..., None]
validation_set = validation_set[..., None]
X_train, X_test, y_train, y_test = train_test_split(train_set, validation_set, test_size=0.30, random_state=0)
batch_size=16
epochs=5
# Create the model
model = Sequential()
model.add(Conv1D(filters=5, kernel_size=3, activation='relu', padding='same'))
model.add(MaxPooling1D(pool_size=2))
model.add(LSTM(50, return_sequences=True))
model.add(Dropout(0.5))
model.add(LSTM(10))
model.add(Dense(1,kernel_initializer='random_normal'))
model.add(Activation('relu'))
adam = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0)
sgd = optimizers.SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=adam, loss='mean_squared_error', metrics=['mae', 'mape', 'mean_squared_error', 'acc'])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs)
print(model.summary())
# Evaluate the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))
skplt.metrics.plot_confusion_matrix(y_test, scores, x_tick_rotation=50, title=' ', normalize=True)
Finally, I want to plot the confusion matrix of the model using
skplt.metrics.plot_confusion_matrix(y_test, scores, x_tick_rotation=50, title=' ', normalize=True)
However, it is raising an error ValueError: Found input variables with inconsistent numbers of samples: [5394, 5].
How can we fix this error?
The second argument to skplt.metrics.plot_confusion_matrix must be the predicted labels (see https://scikit-plot.readthedocs.io/en/stable/metrics.html). But, you pass scores, which does not contain the predicted labels.
The fix would be to do:
y_pred = model.predict(X_test)
skplt.metrics.plot_confusion_matrix(y_test,
y_pred,
x_tick_rotation=50,
title=' ',
normalize=True)
I was working on SVM few days ago and when i tried to plot confusion matrix the following lines of code worked for me.
predicted=model.predict(X_test) #predicted output
cm=metrics.confusion_matrix(y_test, predicted)
df_cm = pd.DataFrame(cm, range(2), range(2))
sns.set(font_scale=1.4)
sns.heatmap(df_cm, annot=True, annot_kws={"size": 16})
plt.title('CONFUSION MATRIX ',fontdict={'fontsize': 14, 'fontweight': 'bold'})
plt.show()
Related
The training and validations datasets I am using are shared here for the sake of reproducibility.
The validation_dataset.csv is the ground truth of training_dataset.csv.
What I am doing below is feeding the datasets into a simple CNN layer that extracts the useful features of the images and feed that as 1D into the LSTM network for classification.
from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.layers.convolutional import Conv1D
from keras.layers import LSTM
from keras.layers.convolutional import MaxPooling1D
from keras.layers import TimeDistributed
from keras.layers import Dropout
from keras import optimizers
from keras.callbacks import EarlyStopping
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from numpy import genfromtxt
df_train = genfromtxt('data/train/training_dataset.csv', delimiter=',')
df_validation = genfromtxt('data/validation/validation_dataset.csv', delimiter=',')
#train,test = train_test_split(df_train, test_size=0.20, random_state=0)
df_train = df_train[..., None]
df_validation = df_validation[..., None]
batch_size=8
epochs=5
model = Sequential()
model.add(Conv1D(filters=5, kernel_size=3, activation='relu', padding='same'))
model.add(MaxPooling1D(pool_size=2))
#model.add(TimeDistributed(Flatten()))
model.add(LSTM(50, return_sequences=True, recurrent_dropout=0.2))
model.add(Dropout(0.2))
model.add(LSTM(10))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))
adam = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0)
model.compile(optimizer="rmsprop", loss='mse', metrics=['accuracy'])
callbacks = [EarlyStopping('val_loss', patience=3)]
model.fit(df_train, df_validation, batch_size=batch_size)
print(model.summary())
scores = model.evaluate(df_train, df_validation, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))
I want to split the training and validation dataset into (X_train, y_train), (X_test, y_test) so that I can use both datasets for training and testing. I tried the split function of the Scikit-learn library -train,test = train_test_split(df_train, test_size=0.20, random_state=0) but it is giving me the following error after we invoke the model.fit() function.
ValueError: Data cardinality is ambiguous:
x sizes: 14384
y sizes: 3596
Please provide data which shares the same first dimension.
How can we split the dataset into (X_train, y_train), (X_test, y_test) sharing the same dimension?
One way is to have X and Y sets. Here, I assume the column name for Y is 'target'.
target = df_train['target']
df_train = df_train.drop(columns=['target'])
X_train, X_test, y_train, y_test = train_test_split(df_train, target, test_size=0.20, random_state=0)
--
It seems that I had initially misunderstood your problem, and "validation_dataset.csv" is your label data. I apologize for not reading correctly.
In this case, you do not need a "target" variable, as that is what df_validation would be. Therefore, I think the following may work:
X_train, X_test, y_train, y_test = train_test_split(df_train, df_validation, test_size=0.20, random_state=0)
I have a folder called train and in that I have three separate folders for "Covid", "Pneumonia", "Healthy". I have created VGG19 model using transfer learning. I want help with creating confusion matrix for my test data. I have split my train data as 75%,25%. I have tried everything to create confusion matrix and calculate F-1 score. It would be really great if someone provides me the code, since I am new to this.
#import needed packages
import numpy as np
import tensorflow as tf
import keras
from keras import backend as K
from keras.optimizers import Adam
from keras.metrics import categorical_crossentropy
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Model
from keras.layers import Dense,GlobalAveragePooling2D,Dropout,SeparableConv2D,BatchNormalization, Activation, Dense
from keras.applications.vgg19 import VGG19
from keras.applications.resnet import ResNet101
from keras.optimizers import Adam
from keras.layers import Input, Lambda, Dense, Flatten
import matplotlib.pyplot as plt
# dataset has 3 classes
num_class = 3
# Base model without Fully connected Layers
base_model = VGG19(include_top=False, weights='imagenet', input_shape=(224,224,3))
# don't train existing weights
for layer in base_model.layers:
layer.trainable = False
x=base_model.output
x = Flatten()(base_model.output)
##3 classes ,COVID, PNEUNOMIA, NORMAL
preds=Dense(num_class, activation='softmax')(x) #final layer with softmax activation
model=Model(inputs=base_model.input,outputs=preds)
##check the model
model.summary()
# tell the model what cost and optimization method to use
model.compile(
loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
##Preparing Data
train_datagen=ImageDataGenerator(preprocessing_function=keras.applications.vgg16.preprocess_input,
validation_split=0.25)
train_generator=train_datagen.flow_from_directory('C:/Users/prani/OneDrive/Desktop/Masters project/chest_xray/Train-250/',
target_size=(224,224),
batch_size=64,
class_mode='categorical',
subset='training')
validation_generator = train_datagen.flow_from_directory(
'C:/Users/prani/OneDrive/Desktop/Masters project/chest_xray/Train-250/', # same directory as training data
target_size=(224,224),
batch_size=64,
class_mode='categorical',
subset='validation') # set as validation data
##Training
##SEtting hyper parameter
epochs = 50
learning_rate = 0.0005
decay_rate = learning_rate / epochs
opt = Adam(lr=learning_rate, beta_1=0.9, beta_2=0.999, decay=decay_rate, amsgrad=False)
model.compile(optimizer=opt,loss='categorical_crossentropy',metrics=['accuracy'])
##Train
step_size_train = train_generator.n/train_generator.batch_size
step_size_val = validation_generator.samples // validation_generator.batch_size
r = model.fit_generator(generator=train_generator,
steps_per_epoch=step_size_train,
validation_data = validation_generator,
validation_steps =step_size_val,
epochs=50)
##Confusion Matrix (Sample code for confusion matrix but this is not working, it doesn't produce error neither results)
from sklearn.metrics import classification_report, confusion_matrix
batch_size=64
Y_pred = model.predict_generator(validation_generator,186)
y_pred = np.argmax(Y_pred, axis=1)
print('Confusion Matrix')
print(confusion_matrix(validation_generator.classes, y_pred))
print('Classification Report')
target_names = ['COVID','NORMAL','PNEUMONIA']
print(classification_report(validation_generator.classes, y_pred, target_names=target_names))
You could look at this page for information on how to code a confusion matrix and other metrics:
https://www.tensorflow.org/tutorials/structured_data/imbalanced_data
I have to perform a simple FSGM attack to a convolutional neural network. The code for the CNN works correctly, and the model is saved without a problem, but when i try to perform the attack an error is shown.
HERE'S THE CODE FOR THE CNN
from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten, MaxPooling2D
import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.utils import to_categorical
import json
import tensorflow as tf
#Using TensorFlow backend.
#download mnist data and split into train and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()
#plot the first image in the dataset
plt.imshow(X_train[0])
#check image shape
X_train[0].shape
#reshape data to fit model
X_train = X_train.reshape(60000,28,28,1)
X_test = X_test.reshape(10000,28,28,1)
#one-hot encode target column
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
y_train[0]
#create model
model = Sequential()
#add model layers
model.add(Conv2D(32, kernel_size=(5,5), activation='relu', input_shape= (28,28,1)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, kernel_size=(5,5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(10, activation='softmax'))
#compile model using accuracy as a measure of model performance
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics= ['accuracy'])
#train model
model.fit(X_train, y_train,validation_data=(X_test, y_test), epochs=5)
json.dump({'model':model.to_json()},open("model.json", "w"))
model.save_weights("model_weights.h5")
THEN I TRY TO PERFORM THE ATTACK WITH THE FOLLOWING CODE:
import json
import foolbox
import keras
import numpy as np
from keras import backend
from keras.models import load_model
from keras.datasets import mnist
from keras.utils import np_utils
from foolbox.attacks import FGSM
from foolbox.criteria import Misclassification
from foolbox.distances import MeanSquaredDistance
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense, Flatten, Conv2D, MaxPooling2D
import numpy as np
import tensorflow as tf
from keras.models import model_from_json
import os
############## Loading the model and preprocessing #####################
backend.set_learning_phase(False)
model = tf.keras.models.model_from_json(json.load(open("model.json"))["model"],custom_objects={})
model.load_weights("model_weights.h5")
fmodel = foolbox.models.KerasModel(model, bounds=(0,1))
_,(images, labels) = mnist.load_data()
images = images.reshape(10000,28,28)
images= images.astype('float32')
images /= 255
######################### Attacking the model ##########################
attack=foolbox.attacks.FGSM(fmodel, criterion=Misclassification())
adversarial=attack(images[12],labels[12]) # for single image
adversarial_all=attack(images,labels) # for all the images
adversarial =adversarial.reshape(1,28,28,1) #reshaping it for model prediction
model_predictions = model.predict(adversarial)
print(model_predictions)
########################## Visualization ################################
images=images.reshape(10000,28,28)
adversarial =adversarial.reshape(28,28)
plt.figure()
plt.subplot(1,3,1)
plt.title('Original')
plt.imshow(images[12])
plt.axis('off')
plt.subplot(1, 3, 2)
plt.title('Adversarial')
plt.imshow(adversarial)
plt.axis('off')
plt.subplot(1, 3, 3)
plt.title('Difference')
difference = adversarial - images[124]
plt.imshow(difference / abs(difference).max() * 0.2 + 0.5)
plt.axis('off')
plt.show()
this error is shown when the adversarial examples are generated:
c_api.TF_GetCode(self.status.status))
InvalidArgumentError: Matrix size-incompatible: In[0]: [1,639232], In[1]: [1024,10]
[[{{node dense_4_5/MatMul}}]]
[[{{node dense_4_5/BiasAdd}}]]
What could it be?
here is my solution.
First of all modify the model code as follows
import tensorflow as tf
import json
# download mnist data and split into train and test sets
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()
# reshape data to fit model
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)
X_train, X_test = X_train/255, X_test/255
# one-hot encode target column
y_train = tf.keras.utils.to_categorical(y_train)
y_test = tf.keras.utils.to_categorical(y_test)
# create model
model = tf.keras.models.Sequential()
# add model layers
model.add(tf.keras.layers.Conv2D(32, kernel_size=(5, 5),
activation='relu', input_shape=(28, 28, 1)))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Conv2D(64, kernel_size=(5, 5), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(10, activation='softmax'))
# compile model using accuracy as a measure of model performance
model.compile(optimizer='adam', loss='categorical_crossentropy',
metrics=['accuracy'])
# train model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=5)
json.dump({'model': model.to_json()}, open("model.json", "w"))
model.save_weights("model_weights.h5")
You just forgot to divide each pixel by the maximum value of RGB (255)
As for the attacker code
import json
import foolbox
from foolbox.attacks import FGSM
from foolbox.criteria import Misclassification
import numpy as np
import tensorflow as tf
############## Loading the model and preprocessing #####################
tf.enable_eager_execution()
tf.keras.backend.set_learning_phase(False)
model = tf.keras.models.model_from_json(
json.load(open("model.json"))["model"], custom_objects={})
model.load_weights("model_weights.h5")
model.compile(optimizer='adam', loss='categorical_crossentropy',
metrics=['accuracy'])
_, (images, labels) = tf.keras.datasets.mnist.load_data()
images = images.reshape(images.shape[0], 28, 28, 1)
images = images/255
images = images.astype(np.float32)
fmodel = foolbox.models.TensorFlowEagerModel(model, bounds=(0, 1))
######################### Attacking the model ##########################
attack = foolbox.attacks.FGSM(fmodel, criterion=Misclassification())
adversarial = np.array([attack(images[0], label=labels[0])])
model_predictions = model.predict(adversarial)
print('real label: {}, label prediction; {}'.format(
labels[0], np.argmax(model_predictions)))
I used TensorFlowEagerModel instead of KerasModel for simplicty. The error you were encountering was due to the fact that model.predict expects a 4d matrix while you were passing a 3d matrix, so I just wrapped up the attack to the image example into a numpy array to make it 4d.
Hope it helps
I'm trying to train a baseline ANN model for a binary classification with Keras (tensorflow backend) and Jupyter notebooks.
The code is the following:
array=df6.values
X= array[:,0:384]
Y = array[:,385]
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
seed = 7
np.random.seed(seed)
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)
def create_baseline():
model = Sequential()
model.add(Dense(60, input_dim=60, kernel_initializer='normal', activation='relu'))
model.add(Dense(10, kernel_initializer='normal', activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
estimator = KerasClassifier(build_fn=create_baseline, epochs=100, batch_size=5, verbose=0)
kfold = StratifiedKFold(n_splits=2, shuffle=True, random_state=seed)
results = cross_val_score(estimator, X, encoded_Y, cv=kfold)
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
Finally the error is the following:
ValueError: Error when checking input: expected dense_5_input to have shape (None, 60) but got array with shape (8, 384)
Also my dataset has 18 rows and 385 columns
I would like to know how to reshape correctly for a correct estimation of results. Thank you so much!
input_dim = 384
This argument refers to the shape of your input, which is X.
I train the KDD CUP Dataset using Keras, RNN.
When I train, I have this error.
"ValueError: ('Bad input argument to theano function with name
"/usr/local/lib/python2.7/dist-packages/Keras-1.0.5-py2.7.egg/keras/backend/theano_backend.py:527"
at index 0 (0-based)', "invalid literal for long() with base 10: 'SF'")"
This is my code:
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
import keras
from keras.preprocessing import sequence
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Embedding
from keras.layers import LSTM, SimpleRNN, GRU
import pandas as pd
max_features = 5000000
maxlen = 50 # cut texts after this number of words (among top max_features most common words)
batch_size = 32
nb_epoch = 100
print('Loading data...')
train_data=pd.read_csv('./data.csv')
labels = (train_data.ix[:,41:42].values)
train = (train_data.ix[:,0:41].values)
#labels = np_utils.to_categorical(labels)
test_data=pd.read_csv('./testdata.csv')
test = (test_data.ix[:,0:41].values)
'''
print('labels')
print(labels)
print('train')
print(train)
print('test')
print(test)
'''
print(train_data.shape[1])
print(train.shape)
print(labels.shape)
print('Build model...')
model = Sequential()
model.add(Embedding(max_features, 128, dropout=0.2))
model.add(LSTM(128, dropout_W=0.2, dropout_U=0.2)) # try using a GRU instead, for fun
model.add(Dense(1))
model.add(Activation('sigmoid'))
# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
print('Train...')
model.fit(train, labels, batch_size=batch_size, nb_epoch=nb_epoch, validation_split=0.25, verbose=1, shuffle=True)
store = model.predict(test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])