Keras密集神经网络在窄范围预测中的应用

2024-09-21 04:43:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在玩Numer.ai数据,主要是为了提高我对神经网络的理解,但我遇到了一个似乎无法克服的问题。无论我的密集神经网络的配置如何,输出都在一个很小的范围内。 输入为300个按比例缩放的要素列(0到1),目标在0到1之间(值为0、0.25、0.5、0.75和1)

以下是我的完全可复制代码:

import pandas as pd
# load data
training_data = pd.read_csv("https://numerai-public-datasets.s3-us-west-2.amazonaws.com/latest_numerai_training_data.csv.xz")
tournament_data = pd.read_csv("https://numerai-public-datasets.s3-us-west-2.amazonaws.com/latest_numerai_tournament_data.csv.xz")

feature_cols = training_data.columns[training_data.columns.str.startswith('feature')]
# select those columns out of the training dataset
X_train = training_data[feature_cols].to_numpy()
# select target variables
y_train = training_data.loc[:,'target'].to_numpy()

#same thing on validation data
val_data = tournament_data[tournament_data.data_type=='validation']
X_val = val_data[feature_cols]
y_val= val_data.loc[:,'target']

我在我的神经网络中尝试了许多不同的配置(不同的优化器:adam和sgd,不同的学习率从0.01下降到0.0001,不同的神经元大小,增加了辍学率:尽管如此,我没想到这会起作用,因为使用线性、softmax和sigmoid最终层激活函数似乎存在偏差问题,而不是方差问题:softmax产生负值,所以这是一个立即否定的结果。)n-starter,不同的批量大小:小到16,大到256,添加或删除批量规范化,洗牌输入数据,并针对不同的纪元数进行训练)。最终,结果是两件事之一:

  1. 预测值都是相同的数字,通常在0.45到0.55的范围内
  2. 预测值的范围很窄,通常相差不超过0.05。因此,预测值为0.45到0.55

我不知道我需要做什么配置更改,才能让这个神经网络在0到1的范围内输出预测

from tensorflow.keras import models, layers

dropout_rate = 0.15

model = models.Sequential()
model.add(layers.Dense(512, input_shape=(X_train.shape[1],)))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(dropout_rate))

model.add(layers.Dense(1028, activation = 'relu', kernel_regularizer='l2'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(dropout_rate))

model.add(layers.Dense(1, activation='sigmoid'))

model.compile(optimizer='adam',
  loss='binary_crossentropy',metrics=['mae', 'mse'])

history = model.fit(X_train, y_train,
          validation_data=(X_val, y_val),
          batch_size=64,
          epochs=200,
          verbose=1)

# Prediction output
predictions_df = model.predict(X_val)
predictions_df = predictions_df.reshape(len(predictions_df))

pred_max = predictions_df.max()
pred_min = predictions_df.min()
pred_range = pred_max - pred_min

print(pred_max, pred_min, pred_range)
# example output: 0.51895267 0.47968164 0.039271027

Tags: csvadddfdatamodellayerstrainingtrain
1条回答
网友
1楼 · 发布于 2024-09-21 04:43:23

编辑:

当进行以下更改时,会对其产生影响(测试在512个批次上运行,次数为5,以下结果仅针对培训数据)——

  1. 丢失设置为mse,而不是binary_crossentropy
  2. 批量512(用于快速原型制作)
  3. 纪元设置为5(之后损失变平)
  4. 移除l2正则化,并增加退出
  5. 设置输出激活-
  • sigmoid->;最高:0.60,​最低:0.36
  • 未激活->;最大值:0.69,最小值:0.29
  • relu->;最大值:0.73,最小值:0.10

以下是用于测试目的的代码-

from tensorflow.keras import models, layers

dropout_rate = 0.50

model = models.Sequential()
model.add(layers.Dense(512, input_shape=(X_train.shape[1],)))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(dropout_rate))

model.add(layers.Dense(1024, activation = 'relu'))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(dropout_rate))

model.add(layers.Dense(1, activation='relu'))

model.compile(optimizer='adam',
  loss='mse',metrics=['mae'])

history = model.fit(X_train, y_train,
          #validation_data=(X_val, y_val),
          batch_size=512,
          epochs=5,
          verbose=1)

# Prediction output
predictions_df = model.predict(X_train)
predictions_df = predictions_df.reshape(len(predictions_df))

pred_max = predictions_df.max()
pred_min = predictions_df.min()
pred_range = pred_max - pred_min

print(pred_max, pred_min, pred_range)
0.73566914 0.1063129 0.62935627

建议的解决方案

您试图解决一个回归问题,即预测0到1(values of 0, 0.25, 0.5, 0.75, and 1)之间的任意值,但试图使用sigmoid激活和binary_crossentropy丢失将其作为二进制分类问题来解决

您可能想要尝试的是使用mse和/或删除任何输出激活(或者更好,按照@desertnaut的建议使用relu)。正如@xdurch0所建议的那样,您可能只是不合身。尝试使用和不使用正则化

model = models.Sequential()
model.add(layers.Dense(512, input_shape=(X_train.shape[1],)))
model.add(layers.BatchNormalization())
model.add(layers.Dropout(dropout_rate))

model.add(layers.Dense(1028, activation = 'relu')
model.add(layers.BatchNormalization())
model.add(layers.Dropout(dropout_rate))

model.add(layers.Dense(1))

model.compile(optimizer='adam', loss='mse')

检查此表以帮助您如何使用不同类型问题设置的损失和激活

enter image description here

在一个旁注中,你的因变量中的值的离散性质Y,你也可以考虑将问题重新定义为多类单标签分类问题,如果下游任务允许的话。p>

相关问题 更多 >

    热门问题