tf.keras。顺序二分类模型预测[0.5,0.5]或接近

时间:2019-09-10 08:44:24

标签: python tensorflow keras deep-learning tf.keras

我目前正在尝试根据主队,客队和比赛联赛,使用tf.keras.Sequential基于主队,客队和比赛联赛来建立一个模型,对给定足球比赛的结果是否高于或低于2.5个目标进行分类TensorFlow 2.0RC中的模型。

我遇到的问题是,使用[0.5,0.5]方法时,我的softmax结果收敛于model.predict。奇怪的是,经过1000次训练后,我的验证和测试准确性和损失分别约为0.94和0.12,否则我会把它归结为过拟合问题。我知道1000个纪元极有可能过拟合,但是,我想了解为什么我的精度会提高到大约800个纪元。我的损失在300个纪元之前趋于平坦。

我试图改变层数,每层中的单元数,激活函数,优化器和损失函数,时期数和学习率,但似乎只能增加损失。

无论如何,结果似乎仍趋于[0.5,0.5]

完整的代码可以在https://github.com/AhmUgEk/tensorflow_football_predictions处查看,但是下面是显示模型组成的摘录。

# Create Keras Sequential model:
model = keras.Sequential()

model.add(feature_layer)  # Input processing layer.

model.add(Dense(units=32, activation='relu'))  # Hidden Layer 1.
model.add(Dropout(rate=0.4))
model.add(BatchNormalization())

model.add(Dense(units=32, activation='relu'))  # Hidden Layer 2.
model.add(Dropout(rate=0.4))
model.add(BatchNormalization())

model.add(Dense(units=2, activation='softmax'))  # Output layer.

# Compile the model:
model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.0001),
    loss=keras.losses.MeanSquaredLogarithmicError(),
    metrics=['accuracy']
)

# Compile the model:
model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.0001),
    loss=keras.losses.MeanSquaredLogarithmicError(),
    metrics=['accuracy']
)

# Fit the model to the training dataset and validate against the 
validation dataset between epochs:
model.fit(
    train_dataset,
    validation_data=val_dataset,
    epochs=1000,
    callbacks=[tensorboard_callback]
)

例如,我希望收到输入[0.282, 0.718]的结果:

model.predict_classes([np.array(['E0'], dtype='object'),
    np.array(['Liverpool'], dtype='object'),
    np.array(['Newcastle'], dtype='object')])[0]

但根据上述内容,收到说[0.5, 0.5]的结果。

我在这里缺少明显的东西吗?

1 个答案:

答案 0 :(得分:0)

我对模型做了一些小的更改。现在,我得到的准确度不是[0.5,0.5]。

结果:

[[0.61482537 0.3851746 ]
 [0.5121426  0.48785746]
 [0.48058605 0.51941395]
 [0.48913187 0.51086813]
 [0.45480043 0.5451996 ]
 [0.48933673 0.5106633 ]
 [0.43431875 0.5656812 ]
 [0.55314165 0.4468583 ]
 [0.5365097  0.4634903 ]
 [0.54371756 0.45628244]]

实施:

import datetime
import os
import numpy as np
import pandas as pd
import tensorflow as tf

from gpu_limiter import limit_gpu
from pipe_functions import csv_to_df, dataframe_to_dataset
from sklearn.model_selection import train_test_split
from tensorflow import keras
from tensorflow.keras.layers import BatchNormalization, Dense, DenseFeatures, Dropout, Input
from tensorflow.keras.callbacks import TensorBoard, ModelCheckpoint
import tensorflow.keras.backend as K
from tensorflow.data import Dataset


# Test GPU availability and instantiate memory growth limitation if True:
if tf.test.is_gpu_available():
    print('GPU Available\n')
    limit_gpu()
else:
    print('Running on CPU')

df = csv_to_df("./csv_files")

# Format & organise imported data, making the "Date" column the new index:
df['Date'] = pd.to_datetime(df['Date'])
df = df[['Date', 'Div', 'HomeTeam', 'AwayTeam', 'FTHG', 'FTAG']].dropna().set_index('Date').sort_index()
df['Over_2.5'] = (df['FTHG'] + df['FTAG'] > 2.5).astype(int)
df = df.drop(['FTHG', 'FTAG'], axis=1)


# Split data into training, validation and testing data:
# Note: random_state variable set to ensure reproducibility.
train, test = train_test_split(df, test_size=0.05, random_state=42)
train, val = train_test_split(train, test_size=0.05, random_state=42)

# print(df['Over_2.5'].value_counts())  # Check that data is balanced.


# Create datasets from train, val & test dataframes:
target_col = 'Over_2.5'
batch_size = 32

def df_to_dataset(features: np.ndarray, labels: np.ndarray, shuffle=True, batch_size=8) -> Dataset:
    ds = Dataset.from_tensor_slices(({"feature": features}, {"target": labels}))
    if shuffle:
        ds = ds.shuffle(buffer_size=len(features))
    ds = ds.batch(batch_size)
    return ds

def get_feature_transform() -> DenseFeatures:
    # Format features into feature columns to ensure data is in the correct format for feeding into the model:
    feature_cols = []
    for column in filter(lambda x: x != target_col, df.columns):
        feature_cols.append(tf.feature_column.embedding_column(tf.feature_column.categorical_column_with_vocabulary_list(
            key=column, vocabulary_list=df[column].unique()), dimension=5))
    return DenseFeatures(feature_cols)

# Transforms all features into dense tensors.
feature_transform = get_feature_transform()
train_features = feature_transform(dict(train)).numpy()
val_features = feature_transform(dict(val)).numpy()
test_features = feature_transform(dict(test)).numpy()

train_dataset = df_to_dataset(train_features, train[target_col].values, shuffle=True, batch_size=batch_size)
val_dataset = df_to_dataset(val_features, val[target_col].values, shuffle=True, batch_size=batch_size)  # Shuffle not required to validation data.
test_dataset = df_to_dataset(test_features, test[target_col].values, shuffle=True, batch_size=batch_size)  # Shuffle not required to test data.

# Create Keras Functional API:
# Create a feature layer from the feature columns, to be placed at the input layer of the model:

def build_model(input_shape: tuple) -> keras.Model:

    input_layer = keras.Input(shape=input_shape, name='feature')

    model = Dense(units=1028, activation='relu', kernel_initializer='normal', name='dense0')(input_layer)  # Hidden Layer 1.
    model = BatchNormalization(name='bc0')(model)

    model = Dense(units=1028, activation='relu', kernel_initializer='normal', name='dense1')(model)  # Hidden Layer 2.
    model = Dropout(rate=0.1)(model)
    model = BatchNormalization(name='bc1')(model)

    model = Dense(units=100, activation='relu', kernel_initializer='normal', name='dense2')(model)  # Hidden Layer 3.
    model = Dropout(rate=0.25)(model)
    model = BatchNormalization(name='bc2')(model)

    model = Dense(units=50, activation='relu', kernel_initializer='normal', name='dense3')(model)  # Hidden Layer 4.
    model = Dropout(rate=0.4)(model)
    model = BatchNormalization(name='bc3')(model)

    output_layer = Dense(units=2, activation='softmax', kernel_initializer='normal', name='target')(model)  # Output layer.

    model = keras.Model(inputs=input_layer, outputs=output_layer, name='better-than-chance')

    # Compile the model:
    model.compile(
        optimizer=keras.optimizers.Adam(learning_rate=0.001),
        loss='mse',
        metrics=['accuracy']
    )
    return model

# # Create a TensorBoard log file (time appended) directory for every run of the model:
# directory = ".\\logs\\" + str(datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
# os.mkdir(directory)

# # Create a TensorBoard callback to log a record of model performance for every 1 epoch:
# tensorboard_callback = TensorBoard(log_dir=directory, histogram_freq=1, write_graph=True, write_images=True)

# Run "tensorboard --logdir .\logs" in anaconda prompt to review & compare logged results.
# Note: Make sure that the correct environment is activated before running.

model = build_model((train_features.shape[1],))
model.summary()

# checkpoint = ModelCheckpoint('model-{epoch:03d}.h5', verbose=1, monitor='val_loss',save_best_only=True, mode='auto')  

# Fit the model to the training dataset and validate against the validation dataset between epochs:
model.fit(
    train_dataset,
    validation_data=val_dataset,
    epochs=10)
    # callbacks=[checkpoint]

# Saves and reloads model.
# model.save("./model.h5")
# model_from_saved = keras.models.load_model("./model.h5")

# Evaluate model accuracy against test dataset:
# scores, accuracy = model.evaluate(train_dataset)
# print('Accuracy:', accuracy)

##############
## OPTIONAL ##
##############

# DUBUGGING
# inp = model.input                                           # input placeholder
# outputs = [layer.output for layer in model.layers]          # all layer outputs
# functors = [K.function([inp], [out]) for out in outputs]    # evaluation functions

# # Testing
# layer_outs = [func([test_features]) for func in functors]
# print(layer_outs)


# # # Form a prediction based on inputs:
prediction = model.predict({"feature": test_features[:10]})
print(prediction)
  1. 您可以做的一件事就是尝试一些整体学习方法,例如 RandomForestXGBoost 并比较结果。

  2. 您应该尝试的是在其中添加其他关键绩效指标(KPI) 您的数据,然后尝试拟合模型。