Повышение точности GRU, keras

#python #tensorflow #keras

#python #тензорный поток #keras

Вопрос:

Я пытаюсь предсказать следующую ноту пианино, используя ранее сыгранные ноты. Входные и целевые данные (значения из классических файлов piano .mid) форматируются как

 x_train=[ [[1,2,3,4,5],[0,0,0,0,0],[0,0,0,0,0]], [[1,2,3,4,5],[4,5,6,7,8],[0,0,0,0,0]] ]
#notes not played yet are [0,0,0,0,0]
#y_train is the next note played
y_train= [ [[4,5,6,7,8]], [[10,11,12,13,14]] ]
  

Проблема: моя точность низкая (~ 45%), и следующая предсказанная нота всегда одинакова (или в конечном итоге становится одинаковой)

Обучение-

 (x_train,y_train)=create_data()

x_train=np.array(x_train)
y_train=np.array(y_train)

x_train=x_train.astype("int")
y_train=y_train.astype("int")

x_train=x_train[:500]
y_train=y_train[:500]

model=keras.Sequential()
model.add(keras.Input(shape=(500,5)))
model.add(keras.layers.GRU(5,activation='linear'))
model.add(keras.layers.Dense(1*5))

model.compile(
        loss=keras.losses.MeanAbsoluteError(),
        optimizer=keras.optimizers.Adam(lr=0.001),
        metrics=["accuracy"]
    )

model.fit(x_train,y_train)
  

Создание песни с первой нотой, взятой из x_train:

 currentNote=x_train[0].tolist()

i=0
while i<499:
    feed=[currentNote]
    feed=np.array(feed)
    output=model.predict(feed)
    output=np.absolute(output)
    output=output[0].astype("int").tolist()
    print(output)                       # printing next note predicted
    currentNote[i 1]=output
    i =1
  

Ответ №1:

Прежде всего, вы используете неправильную потерю. Вы должны использовать categorical_crossentropy or sparse_categorical_crossentropy , потому что это проблема классификации. Кроме того, ваша окончательная функция активации (которую вы не указали) должна быть 'softmax' .

Кроме того, вы должны выбирать из выходных вероятностей, а не брать самую высокую вероятность. Существует учебное пособие по Tensorflow, которое охватывает это.

Примечание: Важно выполнять выборку из этого дистрибутива, поскольку использование argmax дистрибутива может легко привести к тому, что модель застрянет в цикле.

Примерно так вы можете это сделать:

 example_batch_predictions = model(X_test)

sampled_indices = tf.random.categorical(example_batch_predictions[0], 
                                        num_samples=1)
sampled_indices = tf.squeeze(sampled_indices,axis=-1).numpy()
  
 array([41, 60,  3, 31, 47, 21, 61,  6, 56, 42, 39, 40, 52, 60, 37, 37, 27,
       11,  6, 56, 64, 62, 43, 42,  6, 34,  1, 30, 16, 45, 46, 11, 17,  8,
       26,  8,  1, 46, 37, 21, 37, 53, 34, 49,  5, 58, 11,  9, 42, 62, 14,
       56, 56, 30, 31, 32, 63, 53, 10, 23, 35,  5, 19, 19, 46,  3, 23, 63,
       61, 11, 57,  0, 35, 48, 32,  4, 37,  7, 48, 23, 39, 30, 20, 26,  1,
       52, 57, 23, 46, 56, 11, 22,  7, 47, 16, 27, 38, 51, 55, 28])