Как заставить Keras использовать поле group_id для пакетов - PullRequest
0 голосов
/ 25 февраля 2020

Я строю модель для прогнозирования стартовой позиции (PG / PF / SG / SF / C) для каждого из пяти стартовых игроков команды в баскетбольном матче, используя их игровую статистику (например, очки, рикошеты, блоки, кражи и т. д. c). Я хочу убедиться, что сеть учится предсказывать только одного человека на каждой позиции для каждой игры. Для этого я хочу сделать batch_size = 5 и убедиться, что партии формируются с использованием поля game_id в кадре данных. Я создал функцию custom_loss, когда добавляет штраф для игр, где сумма вероятностей для каждого класса отличается от фактической суммы; см. ниже:

import tensorflow.keras.backend as K

def custom_loss(y_true, y_pred):
    logloss = K.categorical_crossentropy(y_true, y_pred)
    constraint = 10*(K.sum(y_pred, axis=-1) - K.sum(y_true, axis=-1))
    return(logloss+constraint)

Однако мне кажется, что эта пользовательская функция потерь будет работать лучше, если каждая партия представляет одну команду за игру, и модель узнает, что она должна прогнозировать точно одного из пяти игроков на каждой позиции. Например, нет смысла говорить, что вероятность того, что Леброн Джеймс будет Lakers SF, составляет 85%, а Дэнни Грина - 35%, но это возможный прогноз, если пользовательские потери не применяются к партиям, представляющим одну команду в одной игре. .

Я погуглил проблему и не нашел информации об определении пакетов с помощью поля group_id (в данном случае game_id).

Полный код приведен ниже, любая помощь очень ценится!

# import packages
import pandas as pd
import numpy as np
import tensorflow.keras.backend as K
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.utils import to_categorical
from tensorflow.keras import regularizers
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.layers import LeakyReLU
from tensorflow.keras.layers import Dropout
from tensorflow.keras.optimizers import Adam

# define custom loss function
def custom_loss(y_true, y_pred):
    logloss = K.categorical_crossentropy(y_true, y_pred)
    constraint = 10*(K.sum(y_pred, axis=-1) - K.sum(y_true, axis=-1))
    return(logloss+constraint)

# create data
n, k = 1000, 25
game_ids = np.repeat(range(int(n/5)), 5)   
xtrain, xtest = pd.DataFrame(np.random.rand(n, k), columns=list(range(k))), pd.DataFrame(np.random.rand(n, k), columns=list(range(k)))
ytrain, ytest = pd.DataFrame(np.random.randint(low=0, high=4, size=n), columns=['y_var']), pd.DataFrame(np.random.randint(low=0, high=4, size=n), columns=['y_var'])
ytrain1H, ytest1H = to_categorical(ytrain), to_categorical(ytest)

# define keras model
model = Sequential()
model.add(Dense(25, input_shape=(xtrain.shape[1],), kernel_regularizer=regularizers.l1(0.002)))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
model.add(Dropout(0.05))
model.add(Dense(8))
model.add(LeakyReLU(alpha=0.1))
model.add(Dense(ytrain1H.shape[1], activation='softmax'))
adam = Adam(lr=0.001)
model.compile(optimizer=adam, loss=custom_loss, metrics=['categorical_accuracy'])
earlystop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=5, verbose=1, mode='auto', restore_best_weights=True)
model.fit(xtrain, ytrain1H, epochs=50, batch_size=5, validation_data=(xtest, ytest1H), callbacks = [earlystop])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...