1
$\begingroup$

I wanted to use the CNN as feature extractor for my images and then fed these features to some machine learning classifiers such as SVM, decision tree and KNN. However when I was trying with SVM I got this error message:

File "C:\Users\Afef-\Anaconda3\lib\site-packages\sklearn\svm\base.py", line 521, in _validate_targets " class" % len(cls)) ValueError: The number of classes has to be greater than one; got 1 class

This is my code :

import os
import numpy as np
from sklearn.metrics import confusion_matrix
from plot_metrics import plot_accuracy, plot_loss, plot_roc_curve
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')
np.random.seed(15)  


"""
Using Theano backend and Theano image_dim_ordering:
(# channels, # images, # rows, # cols)
(1, 3040, 513, 125)
"""

def preprocess(X_train, X_test):
    """
    Convert from float64 to float32 and normalize normalize to decibels
    relative to full scale (dBFS) for the 4 sec clip.
    """
    X_train = X_train.astype('float32')
    X_test = X_test.astype('float32')

    X_train = np.array([(X - X.min()) / (X.max() - X.min()) for X in X_train])
    X_test = np.array([(X - X.min()) / (X.max() - X.min()) for X in X_test])
    return X_train, X_test


def prep_train_test(X_train, y_train1, X_test, y_test1, nb_classes):
    """
    Prep samples ands labels for Keras input by noramalzing and converting
    labels to a categorical representation.
    """
    print('Train on {} samples, validate on {}'.format(X_train.shape[0],
                                                       X_test.shape[0]))

    # normalize to dBfS
    X_train, X_test = preprocess(X_train, X_test)

    # Convert class vectors to binary class matrices
    Y_train1 = np_utils.to_categorical(y_train, nb_classes)
    Y_test1 = np_utils.to_categorical(y_test, nb_classes)

    return X_train, X_test, Y_train1, Y_test1


def keras_img_prep(X_train, X_test, img_dep, img_rows, img_cols):
    """
    Reshape feature matrices for Keras' expexcted input dimensions.
    For 'th' (Theano) dim_order, the model expects dimensions:
    (# channels, # images, # rows, # cols).
    """
    if K.image_dim_ordering() == 'th':
        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:
        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)
    return X_train, X_test, input_shape


def cnn(X_train, y_train1, X_test, y_test1, batch_size,
        nb_classes, epochs, input_shape):
    """
    The Convolutional Neural Net architecture for classifying the audio clips
    as normal (0) or depressed (1).
    """
    model = Sequential()

    model.add(Conv2D(32, (3, 3), padding='valid', strides=1,
                     input_shape=input_shape, activation='relu'))

    model.add(MaxPooling2D(pool_size=(4, 3), strides=(1, 3)))

    model.add(Conv2D(32, (1, 3), padding='valid', strides=1,
              input_shape=input_shape, activation='relu'))

    model.add(MaxPooling2D(pool_size=(1, 3), strides=(1, 3)))

    model.add(Flatten())
    model.add(Dense(512, activation='relu'))
    model.add(Dense(512, activation='relu'))
    model.add(Dropout(0.5))

    model.add(Dense(nb_classes))
    model.add(Activation('softmax'))

    model.compile(loss='categorical_crossentropy',
                  optimizer='adadelta',
                  metrics=['accuracy'])

    history = model.fit(X_train, y_train1, batch_size=batch_size, epochs=epochs,
                        verbose=1, validation_data=(X_test, y_test1))


    # Evaluate accuracy on test and train sets
    score_train = model.evaluate(X_train, y_train1, verbose=0)
    print('Train accuracy:', score_train[1])
    score_test = model.evaluate(X_test, y_test1, verbose=0)
    print('Test accuracy:', score_test[1])
#    print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
    return model, history



if __name__ == '__main__':


    print('Retrieving locally')
    X_train = np.load('E:/depression detection/data/processed/train_samples.npz')
    y_train = np.load('E:/depression detection/data/processed/train_labels.npz')
    X_test = np.load('E:/depression detection/data/processed/test_samples.npz')
    y_test = np.load('E:/depression detection/data/processed/test_labels.npz')

    X_train, y_train, X_test, y_test = \
        X_train['arr_0'], y_train['arr_0'], X_test['arr_0'], y_test['arr_0']

    # CNN parameters
    batch_size = 32
    nb_classes = 2
    epochs = 7

    # normalalize data and prep for Keras
    print('Processing images for Keras...')
    X_train, X_test, y_train1, y_test1 = prep_train_test(X_train, y_train,
                                                       X_test, y_test,
                                                       nb_classes=nb_classes)

    # 513x125x1 for spectrogram with crop size of 125 pixels
    img_rows, img_cols, img_depth = X_train.shape[1], X_train.shape[2], 1

    # reshape image input for Keras
    # used Theano dim_ordering (th), (# chans, # images, # rows, # cols)
    X_train, X_test, input_shape = keras_img_prep(X_train, X_test, img_depth,
                                                  img_rows, img_cols)


    # run CNN
    print('Fitting model...')
    model, history = cnn(X_train, y_train1, X_test, y_test1, batch_size,
                         nb_classes, epochs, input_shape)



    for l in range(len(model.layers)):
      print(l, model.layers[l])

     # feature extraction layer
    getFeature = K.function([model.layers[0].input, K.learning_phase()],
                       [model.layers[7].output])
# classification layer
    getPrediction = K.function([model.layers[8].input, K.learning_phase()],
                           [model.layers[9].output])

    exTrain = getFeature([X_train[:30], 0])[0]
    exTest = getFeature([X_test[:30], 0])[0]
    y_train00 = y_train[:30]
    y_test00 = y_test[:30]
    from sklearn.svm import SVC
    clf = SVC(gamma='auto')
    clf.fit(exTrain, y_train00)
$\endgroup$

1 Answer 1

0
$\begingroup$

Check y_test[:30] contains more than one class.

$\endgroup$
4
  • $\begingroup$ Ok, I have checked and I found that it contains only one class. So I think I should add more input for the train and test. I Hope it works !! $\endgroup$
    – root
    Aug 8, 2019 at 8:49
  • $\begingroup$ That is the issue, to classify you need more than one category/class. $\endgroup$ Aug 8, 2019 at 8:50
  • $\begingroup$ Yes, but i thought it was a problem of shape .The inputs shape of SVM classifier are : exTrain.shape: (30, 512), exTest.shape: (30, 512), y_train00.shape : (30,) and y_test00.shape) :(30,). The inputs shape of CNN are : X_train.shape: (2480, 1, 513, 125), X_test.shape: (560, 1, 513, 125) , y_train1.shape : (2480, 2) and y_test1.shape) :(560, 2) $\endgroup$
    – root
    Aug 8, 2019 at 9:07
  • 1
    $\begingroup$ can you please explain the comment. i didn't mention shape issue, number of categories is 1 which means first 30 values are from same class( y_test[:30]). if you have classes A and B, y_test[:30] is giving you all 30 A values. so there is no B class for the classifier to classify $\endgroup$ Aug 8, 2019 at 9:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.