如何在TensorFlow二分类中为部分正样本设置权重
我来帮你搞定这个问题!你需要给下单样本单独设置更高的权重,核心思路是先构造每个样本的权重张量,再用它去加权交叉熵损失。下面是具体的修改步骤和代码:
解决方案步骤
1. 调整训练输入,传入下单标记特征
首先要把下单样本的标记作为特征传入模型,这样模型能识别哪些是需要加权的样本。修改你的训练input_fn,把data_train_order合并到训练数据的特征中:
# 先把下单标记加入训练特征 data_train['is_order'] = data_train_order # 修改input_fn,确保x包含is_order特征 train_input_fn = tf.estimator.inputs.pandas_input_fn( x=data_train, y=data_train_click, batch_size=1024, num_epochs=1, shuffle=False )
2. 修改模型中的损失计算逻辑
在my_model函数里,我们需要先从features中取出下单标记,然后构造每个样本的权重,再计算加权后的交叉熵损失:
def my_model(features, labels, mode, params): net = tf.feature_column.input_layer(features, params['feature_columns']) for units in params['hidden_units']: net = tf.layers.dense(net, units=units, activation=params["activation"]) logits = tf.layers.dense(net, params['n_classes'], activation=None) predicted_classes = tf.argmax(logits, 1) if mode == tf.estimator.ModeKeys.PREDICT: predictions = { 'class_ids': predicted_classes, 'probabilities': tf.nn.softmax(logits), 'logits': logits, } return tf.estimator.EstimatorSpec(mode, predictions=predictions) # ------------------- 关键修改:构造样本权重并计算加权损失 ------------------- # 取出下单标记特征 is_order = features['is_order'] # 构造权重:下单样本(label=1且is_order=1)权重10,其他样本权重1 weights = tf.where( tf.logical_and(tf.equal(labels, 1), tf.equal(is_order, 1)), tf.ones_like(labels, dtype=tf.float32) * 10.0, tf.ones_like(labels, dtype=tf.float32) ) # 计算每个样本的交叉熵损失(不做归约) per_sample_loss = tf.losses.sparse_softmax_cross_entropy( labels=labels, logits=logits, reduction=tf.losses.Reduction.NONE ) # 加权后求平均得到总损失 loss = tf.reduce_mean(per_sample_loss * weights) # ------------------------------------------------------------------------- metrics = {'auc': tf.metrics.auc(labels=labels, predictions=tf.nn.softmax(logits)[:,1])} if mode == tf.estimator.ModeKeys.EVAL: return tf.estimator.EstimatorSpec(mode, loss=loss, eval_metric_ops=metrics) assert mode == tf.estimator.ModeKeys.TRAIN optimizer = tf.train.AdagradOptimizer(learning_rate=0.1) train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step()) return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
3. 确保特征列包含is_order
别忘了在你的params['feature_columns']里加入is_order的特征列,比如:
feature_columns = [ # 你的其他特征列... tf.feature_column.numeric_column('is_order') ]
这样修改后,模型在训练时就会给下单样本(同时满足点击标记为1、下单标记为1)赋予10倍的权重,普通点击和未点击样本权重保持为1,完全符合你的需求。
内容的提问来源于stack exchange,提问作者user3151261
相关产品推荐
相关产品推荐

