1

I was trying to to use the combination of SVM with my CNN code, so I used this code. However, I got some problems in the part of reshaping the target to fit SVM.

The orignal X_train.shape, X_test.shape, y_train.shape, y_test.shape are correspondingly :

(2480, 1, 513, 125)
(560, 1, 513, 125) 
(2480, 2) 
(560, 2)

After that when I tried this :

exTrain = getFeature([X_train[:50], 0])[0]
exTest = getFeature([X_test[:10], 0])[0]
y_train = y_train[:50].reshape(y_train[:50].shape[0],)

I got this error message :

ValueError: cannot reshape array of size 100 into shape (50,)

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) 

"""
CNN used to classify spectrograms of normal participants (0) or depressed
participants (1). 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_train, X_test, y_test, 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_train = np_utils.to_categorical(y_train, nb_classes)
    Y_test = np_utils.to_categorical(y_test, nb_classes)

    return X_train, X_test, Y_train, Y_test


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_train, X_test, y_test, 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_train, batch_size=batch_size, epochs=epochs,
                        verbose=1, validation_data=(X_test, y_test))

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


def model_performance(model, X_train, X_test, y_train, y_test):
    """
    Evaluation metrics for network performance.
    """
    y_test_pred = model.predict_classes(X_test)
    y_train_pred = model.predict_classes(X_train)

    y_test_pred_proba = model.predict_proba(X_test)
    y_train_pred_proba = model.predict_proba(X_train)

    # Converting y_test back to 1-D array for confusion matrix computation
    y_test_1d = y_test[:, 1]

    # Computing confusion matrix for test dataset
    conf_matrix = standard_confusion_matrix(y_test_1d, y_test_pred)
    print("Confusion Matrix:")
    print(conf_matrix)

    return y_train_pred, y_test_pred, y_train_pred_proba, \
        y_test_pred_proba, conf_matrix


def standard_confusion_matrix(y_test, y_test_pred):
    """
    Make confusion matrix with format:
                  -----------
                  | TP | FP |
                  -----------
                  | FN | TN |
                  -----------
    Parameters
    ----------
    y_true : ndarray - 1D
    y_pred : ndarray - 1D

    Returns
    -------
    ndarray - 2D
    """
    [[tn, fp], [fn, tp]] = confusion_matrix(y_test, y_test_pred)
    return np.array([[tp, fp], [fn, tn]])


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 = 1

    # normalalize data and prep for Keras
    print('Processing images for Keras...')
    X_train, X_test, y_train, y_test = 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_train, X_test, y_test, batch_size,
                         nb_classes, epochs, input_shape)

    # evaluate model
    print('Evaluating model...')
    y_train_pred, y_test_pred, y_train_pred_proba, y_test_pred_proba, \
        conf_matrix = model_performance(model, X_train, X_test, y_train, y_test)

    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[:50], 0])[0]
    exTest = getFeature([X_test[:10], 0])[0]
    y_train = y_train[:50].reshape(y_train[:50].shape[0],)
    y_test = y_test[:10]
    print(exTrain.shape, exTest.shape, y_train.shape, y_test.shape)
    from sklearn.svm import SVC
    clf = SVC(gamma='auto')
    clf.fit(exTrain, y_train)
    score_train = model.evaluate(exTrain, y_train, verbose=0)
    print('Train accuracy:', score_train[1])
    score_test = model.evaluate(exTest, y_test, verbose=0)
    print('Test accuracy:', score_test[1])

I don't know how to fix this problem.

root
  • 59
  • 1
  • 7
  • you are missing the dimension `2` of y_train. You have a length of 50 x 2. – razimbres Jul 30 '19 at 12:42
  • So should i just right it like this y_train = y_train[:50] – root Jul 30 '19 at 12:57
  • Probably `y_train = y_train[:50]` is enough, given that y_train shape is already `(2480, 2)` – razimbres Jul 30 '19 at 13:03
  • I have tried it but when I train the SVM model with these inputs, I got this error message"ValueError: bad input shape (50, 2)" – root Jul 30 '19 at 13:23
  • Yes, you have to change the one-hot encoding `(2480,2)` back to `(2480,)`. Check this link: https://stackoverflow.com/questions/38334296/reversing-one-hot-encoding-in-pandas – razimbres Jul 30 '19 at 13:31
  • As you can see my code below. I have checked the shape of y_train is (2480,). – root Jul 30 '19 at 16:29

0 Answers0