如何确定 Keras 的 Dense 方法中的层大小?

Posted

技术标签:

【中文标题】如何确定 Keras 的 Dense 方法中的层大小?【英文标题】:How to decide the size of layers in Keras' Dense method? 【发布时间】:2016-08-25 07:50:17 【问题描述】:

以下是多类分类任务的简单示例 虹膜数据。

import seaborn as sns
import numpy as np
from sklearn.cross_validation import train_test_split
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.regularizers import l2
from keras.utils import np_utils


#np.random.seed(1335)

# Prepare data
iris = sns.load_dataset("iris")
iris.head()
X = iris.values[:, 0:4]
y = iris.values[:, 4]


# Make test and train set
train_X, test_X, train_y, test_y = train_test_split(X, y, train_size=0.5, random_state=0)


################################
# Evaluate Keras Neural Network
################################


# Make ONE-HOT
def one_hot_encode_object_array(arr):
    '''One hot encode a numpy array of objects (e.g. strings)'''
    uniques, ids = np.unique(arr, return_inverse=True)
    return np_utils.to_categorical(ids, len(uniques))

train_y_ohe = one_hot_encode_object_array(train_y)
test_y_ohe = one_hot_encode_object_array(test_y)


model = Sequential()
model.add(Dense(16, input_shape=(4,),
      activation="tanh",
      W_regularizer=l2(0.001)))
model.add(Dropout(0.5))
model.add(Dense(3, activation='sigmoid'))
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')


# Actual modelling
# If you increase the epoch the accuracy will increase until it drop at
# certain point. Epoch 50 accuracy 0.99, and after that drop to 0.977, with
# epoch 70 
hist = model.fit(train_X, train_y_ohe, verbose=0,   nb_epoch=100,  batch_size=1)


score, accuracy = model.evaluate(test_X, test_y_ohe, batch_size=16, verbose=0)
print("Test fraction correct (NN-Score) = :.2f".format(score))
print("Test fraction correct (NN-Accuracy) = :.2f".format(accuracy))

我的问题是人们通常如何决定层的大小? 例如基于上面的代码,我们有:

model.add(Dense(16, input_shape=(4,),
      activation="tanh",
      W_regularizer=l2(0.001)))
model.add(Dense(3, activation='sigmoid'))

Dense 的第一个参数是 16,第二个是 3。

为什么两个层使用两个不同的 Dense 值? 我们如何选择 Dense 的最佳价值?

【问题讨论】:

【参考方案1】:

基本上这只是反复试验。这些称为超参数,应在验证集上进行调整(从原始数据拆分为训练/验证/测试)。

调整只是意味着尝试不同的参数组合,并根据问题在验证集上保留具有最低损失值或更好准确度的参数组合。

有两种基本方法:

网格搜索:对于每个参数,确定一个范围并进入该范围,例如 8 到 64 个神经元,以 2 的幂 (8, 16, 32, 64) 为单位,并尝试每个参数组合。这显然需要大量的模型进行训练和测试,并且需要大量时间。

随机搜索:执行相同操作,但只需为每个参数定义一个范围并尝试从每个范围上的均匀分布中抽取的随机参数集。您可以尝试尽可能多的参数集,只要您可以。这只是一个有根据的随机猜测。

不幸的是,没有其他方法可以调整这些参数。关于具有不同数量神经元的层,这可能来自调整过程,或者您也可以将其视为降维,就像前一层的压缩版本。

【讨论】:

【参考方案2】:

没有已知的方法来确定评估输入或输出数量的良好网络结构。它依赖于训练示例的数量、批量大小、时期的数量,基本上,在每个重要的网络参数。

此外,大量单元可能会引入过度拟合和梯度爆炸等问题。另一方面,较少的单元数会导致模型具有高偏差和低准确度值。再次强调,这取决于用于训练的数据大小。

遗憾的是,它正在尝试一些不同的值来为您提供最佳调整。如上一篇文章所述,您可以选择为您的数据集提供最低损失和验证损失值以及最佳准确度的组合。

你可以对你的单位价值做一些比例,比如:

# Build the model
model = Sequential()
model.add(Dense(num_classes * 8, input_shape=(shape_value,),  activation = 'relu' )) 
model.add(Dropout(0.5))

model.add(Dense(num_classes * 4, activation = 'relu'))
model.add(Dropout(0.2))

model.add(Dense(num_classes * 2, activation = 'relu'))
model.add(Dropout(0.2))

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

上面的模型显示了分类 AI 系统的示例。 num_classes 是系统必须选择的不同类别的数量。例如,在 Keras 的 iris 数据集中,我们有:

鸢尾花 鸢尾花 弗吉尼亚鸢尾

num_classes = 3

但是,这可能会导致比使用其他随机值更差的结果。我们需要通过一些不同的尝试来调整训练数据集的参数,然后分析结果以寻求最佳的参数组合。

【讨论】:

【参考方案3】:

我的建议是使用EarlyStopping()。然后用测试损失检查 epoch 数和准确率。

from  tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping
rlp = lrd = ReduceLROnPlateau(monitor = 'val_loss',patience = 2,verbose = 1,factor = 0.8, min_lr = 1e-6)
es = EarlyStopping(verbose=1, patience=2)
his = classifier.fit(X_train, y_train, epochs=500, batch_size = 128, validation_split=0.1, verbose = 1, callbacks=[lrd,es])

【讨论】:

以上是关于如何确定 Keras 的 Dense 方法中的层大小?的主要内容,如果未能解决你的问题,请参考以下文章

深度学习-Keras-层及损失函数

深度学习-Keras-层及损失函数

CNN——全连接层 dense/FC

Keras开发一个神经网络

如何向Keras的层喂入数据

keras中双向LSTM流程的验证