我正在在线学习机器学习课程,我们在DNN模型中使用以下评分函数进行回归:
def r_squared(y_true, y_pred):
# 1 - ((y_i - y_hat_i)^2 / (y_i - y_sum)^2)
numerator = tf.reduce_sum(tf.square(tf.subtract(y_true, y_pred)))
denominator = tf.reduce_sum(tf.square(tf.subtract(y_pred, tf.reduce_mean(y_true))))
r2 = tf.clip_by_value(tf.subtract(1.0, tf.div(numerator, denominator)), clip_value_min = 0.0, clip_value_max = 1.0)
return r2
... later ...
model.compile(loss = "mse", # mean-square-error,
optimizer = optimizer(lr = learning_rate),
metrics = [r_squared])
现在,当模型和所有模型正常工作时,我想进行一次网格搜索,以确定适合我模型的最佳参数。但是,当尝试将r_squared
函数与gridsearch一起用作记分器时,会出现一些错误:
grid = GridSearchCV(estimator = estimator,
param_grid = param_grid,
n_jobs = 1,
verbose = 1,
cv = folds,
scoring = make_scorer(FeedForward.r_squared, greater_is_better=True))
导致:
TypeError: Input 'y' of 'Sub' Op has type float64 that does not match type float32 of argument 'x'.
在这里:
r2 = tf.clip_by_value(tf.subtract(1.0, tf.div(numerator, denominator)), clip_value_min = 0.0, clip_value_max = 1.0)
因此,我将行更改如下:
r2 = tf.clip_by_value(tf.subtract(1.0, tf.div(tf.cast(numerator, tf.float32), tf.cast(denominator, tf.float32))), clip_value_min = 0.0, clip_value_max = 1.0)
然后将导致:
ValueError: scoring must return a number, got Tensor("mul:0", shape=(), dtype=float32) (<class 'tensorflow.python.framework.ops.Tensor'>) instead. (scorer=score)
虽然我理解了该错误并可以在调试器中确认该错误,但是即使使用Google搜索错误也无法解决该问题。可能是由于-无需多说-蜜蜂对tensorflow不够熟悉。
那么如何从张量中获取值?我什至在这里做正确的事,还是其他错误?
答案 0 :(得分:0)
问题在于混合使用TensorFlow / Keras和scikit-learn。 Keras指标需要使用keras.backend
函数来实现,但是scikit-learn函数不是符号性的,必须使用numpy来实现。
幸运的是,scikit-learn已将R ^ 2得分实现为sklearn.metrics.r2_score
,因此您可以像这样使用它:
from sklearn.metrics import r2_score
grid = GridSearchCV(estimator = estimator,
param_grid = param_grid,
n_jobs = 1,
verbose = 1,
cv = folds,
scoring = make_scorer(r2_score, greater_is_better=True))
您的Keras度量标准无需更改,您必须保留该度量标准的两个实现,这有点奇怪,但是就是这样。