Librosa Keras Нейронная сеть для анализа музыки Python: ошибка входного значения

Недавно я попытался провести эксперимент, в котором нейронная сеть, написанная в Python IDE IDLE с использованием Keras, используется для анализа набора данных песен GTZAN. Я пытаюсь изменить слои, чтобы увидеть, не влияет ли это на производительность. Я основываю свой эксперимент на конкретной статье, подробно описывающей основу этого проекта:

https://medium.com/@navdeepsingh_2336/identifying-the-genre-of-a-song-with-neural-networks-851db89c42f0

Код, представленный в статье, вместе формирует эту программу:

import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.utils.np_utils import to_categorical

def display_mfcc(song):
    y, _ = librosa.load(song)
    mfcc = librosa.feature.mfcc(y)

    plt.figure(figsize=(10, 4))
    librosa.display.specshow(mfcc, x_axis='time', y_axis='mel')
    plt.colorbar()
    plt.title(song)
    plt.tight_layout()
    plt.show()


def extract_features_song(f):
    y, _ = librosa.load(f)

    mfcc = librosa.feature.mfcc(y)
    mfcc /= np.amax(np.absolute(mfcc))

    return np.ndarray.flatten(mfcc)[:25000]

def generate_features_and_labels():
    all_features = []
    all_labels = []
    genres = ['blues', 'classical', 'country', 'disco', 'hiphop',
    'jazz', 'metal', 'pop', 'reggae', 'rock']

    for genre in genres:
        sound_files = glob.glob('genres/'+genre+'/*.au')
        print('Processing %d songs in %s genre...' % 
        (len(sound_files), genre))
        for f in sound_files:
            features = extract_features_song(f)
            all_features.append(features)
            all_labels.append(genre)

    label_uniq_ids, label_row_ids = np.unique(all_labels,   
    (len(sound_files), genre))
    label_row_ids = label_row_ids.astype(np.int32, copy=False)
    onehot_labels = to_categorical(label_row_ids, 
    len(label_uniq_ids))

    return np.stack(all_features), onehot_labels


features, labels = generate_features_and_labels()

print(np.shape(features))
print(np.shape(labels))

training_split = 0.8

alldata = np.column_stack((features, labels))

np.random.shuffle(alldata)
splitidx = int(len(alldata) * training_split)
train, test = alldata[:splitidx,:], alldata[splitidx:,:]

print(np.shape(train))
print(np.shape(test))

train_input = test[:,:-10]
train_labels = train[:,-10:]

test_input = test[:,:-10]
test_labels = test[:,-10:]

print(np.shape(train_input))
print(np.shape(train_labels))

model = Sequential([
    Dense(100, input_dim=np.shape(train_input)[1]),
    Activation('relu'),
    Dense(10),
    Activation('softmax'),
    ])


model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
print(model.summary())

model.fit(train_input, train_labels, epochs=10, batch_size=32,
          validation_split=0.2) 
loss, acc = model.evaluate(test_input, test_labels, batch_size=32)

print('Done!')
print('Loss: %.4f, accuracy: %.4f' % (loss, acc))

Затем я получил ожидаемый результат:

Using TensorFlow backend.
Processing 100 songs in blues genre...
Processing 100 songs in classical genre...
Processing 100 songs in country genre...
Processing 100 songs in disco genre...
Processing 100 songs in hiphop genre...
Processing 100 songs in jazz genre...
Processing 100 songs in metal genre...
Processing 100 songs in pop genre...
Processing 100 songs in reggae genre...
Processing 100 songs in rock genre...
(1000, 25000)
(1000, 10)
(800, 25010)
(200, 25010)
(200, 25000)
(800, 10)
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 100)               2500100   
_________________________________________________________________
activation_1 (Activation)    (None, 100)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 10)                1010      
_________________________________________________________________
activation_2 (Activation)    (None, 10)                0         
=================================================================
Total params: 2,501,110
Trainable params: 2,501,110
Non-trainable params: 0

None

После чего я получил это сообщение об ошибке:

   Traceback (most recent call last):
  File "/Users/surengrigorian/Documents/Stage1.py", line 88, in <module>
validation_split=0.2)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 952, in fit
batch_size=batch_size)
  File   "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training.py", line 804, in _standardize_user_data
check_array_length_consistency(x, y, sample_weights)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/keras/engine/training_utils.py", line 237, in check_array_length_consistency
    'and ' + str(list(set_y)[0]) + ' target samples.')
ValueError: Input arrays should have the same number of samples as      target arrays. Found 200 input samples and 800 target samples.

В статье о разделе сказано следующее:

Всего у вас около 2,5 миллионов параметров или весов. Затем выполните подгонку. Он принимает входные данные обучения и метки обучения и берет желаемое количество эпох. Вам нужно 10, так что это 10 повторов для обученного ввода. Требуется размер пакета, который сообщает вам количество, в данном случае песен, которые нужно пройти перед обновлением весов; а validation_split 0,2 говорит о том, что нужно взять 20% этого обученного ввода, разделить его, на самом деле не обучаться этому и использовать это для оценки того, насколько хорошо он работает после каждой эпохи. На самом деле он никогда не тренируется на валидационном сплите, но валидационный сплит позволяет вам следить за ходом выполнения.

Спасибо за любую помощь, которую вы можете оказать.


person Suren Grig    schedule 20.01.2019    source источник
comment
Это выглядит неправильно: train_input = test [:,: - 10]   -  person Dr. Snoopy    schedule 21.01.2019


Ответы (1)


Лучше использовать методы разделения из scikit

from sklearn.model_selection import train_test_split, StratifiedShuffleSplit, StratifiedKFold

# apply Scikit stratified sampling
sss = StratifiedShuffleSplit(n_splits=1, test_size=0.20, random_state=random_state)
for train_index, test_index in sss.split(X, y):
  X_train, X_test = X[train_index], X[test_index]
  y_train, y_test = y[train_index], y[test_index]
person Samer Ayoub    schedule 21.01.2019
comment
Где бы я разместил этот фрагмент кода? Спасибо. - person Suren Grig; 21.01.2019
comment
замените эти 3 строки: np.random.shuffle (alldata) splitidx = int (len (alldata) * training_split) train, test = alldata [: splitidx ,:], alldata [splitidx:,:], удалите импорт в начало, и попробуйте чередовать 3 метода train_test_split, StratifiedShuffleSplit, StratifiedKFold .. чтобы узнать, что вам подходит - person Samer Ayoub; 21.01.2019
comment
Привет. Я ценю вашу помощь. Однако терминал Python выдал сообщение об ошибке следующего вида: Traceback (последний вызов последний): File /Users/surengrigorian/Documents/Stage1.py, строка 59, в ‹module› sss = StratifiedShuffleSplit (n_splits = 1, test_size = 0.20, random_state = random_state) NameError: имя 'random_state' не определено - person Suren Grig; 23.01.2019
comment
random_state = 37 или любое число ... для раздачи - person Samer Ayoub; 23.01.2019