我正在以两种不同的方式( A 和 B )使用交叉验证来评估神经网络模型,我认为这两种方式是等效的。
- 评估类型 A: 对于每个交叉验证循环,都会对模型进行实例化和拟合。
- 评估类型 B: 我将模型实例化一次,然后将该实例化模型拟合到交叉验证过程的每个循环中。
我正在使用度量平均绝对误差(MAE)。
问题:为什么在使用 B 类评估而不是使用 A 类评估时,交叉验证循环中的MAE会持续下降?
代码和细节
首先我生成合成数据:
from sklearn.datasets import make_regression
X , y = make_regression( n_samples = 1000 , n_features = 10 , n_informative = 5 , n_targets = 1 , random_state = 2 )
然后我定义一个函数来获取模型(神经网络):
from keras.models import Sequential
from keras.layers import Dense
def get_model( n_nodes_hidden_layer , n_inputs , n_outputs ) :
model = Sequential()
model.add( Dense( n_nodes_hidden_layer , input_dim = n_inputs , kernel_initializer = 'he_uniform' , activation = 'relu' ) )
model.add( Dense( n_outputs ) )
model.compile( loss = 'mae' , optimizer = 'adam' )
return model
之后,我使用以下方法定义了 2 个评估函数:
from sklearn.model_selection import RepeatedKFold
from sklearn.metrics import mean_absolute_error
A类评价函数:
def evaluate_model_A( X , y ) :
results = list()
cv = RepeatedKFold( n_splits = 10 , n_repeats = 1 , random_state = 999 )
for train_ix, test_ix in cv.split( X ) :
X_train, X_test = X[ train_ix ] , X[ test_ix ]
y_train, y_test = y[ train_ix ] , y[ test_ix ]
model = get_model( 20 , 10 , 1 )
model.fit( X_train , y_train , epochs = 100 , verbose = 0 )
y_test_pred = model.predict( X_test )
mae = mean_absolute_error( y_test , y_test_pred )
results.append( mae )
print( f'mae : {mae}' )
return results
B类评价函数:
def evaluate_model_B( model , X , y ) :
results = list()
cv = RepeatedKFold( n_splits = 10 , n_repeats = 1 , random_state = 999 )
for train_ix, test_ix in cv.split( X ) :
X_train, X_test = X[ train_ix ] , X[ test_ix ]
y_train, y_test = y[ train_ix ] , y[ test_ix ]
model.fit( X_train , y_train , epochs = 100 , verbose = 0 )
y_test_pred = model.predict( X_test )
mae = mean_absolute_error( y_test , y_test_pred )
results.append( mae )
print( f'mae : {mae}' )
return results
在使用 B 型评估函数之前,我需要实例化模型,因为它是函数的参数:
model = get_model( 20 , 10 , 1 )
我不明白的是,在使用 B 型评估函数时,每个交叉验证循环的 MAE 都在减少,而 A 型评估函数并非如此。
这是特定于神经网络的吗?
注意:当我使用 a 时RandomForestRegressor()没有出现这种现象。