Python 如何在keras上进行OHEM(在线硬示例挖掘)

Python 如何在keras上进行OHEM(在线硬示例挖掘),python,keras,Python,Keras,最近,我试着用keras做OHEM。有人在凯拉斯身上做过这件事吗?我的想法如下: step1 : get the losses of 100 samples each batch during the FP(forward propagation) stage. step2 : sort the losses of 100 samples by desc step3 : use top-k losses during the BP(Backpropagation) stage. 但是,我找不

最近,我试着用keras做OHEM。有人在凯拉斯身上做过这件事吗?我的想法如下:

step1 : get the losses of 100 samples each batch during the FP(forward propagation) stage.
step2 : sort the losses of 100 samples by desc
step3 : use top-k losses during the BP(Backpropagation) stage. 
但是,我找不到api,所以我查看了源代码并找到了一些相关代码,如下所示。 -代码位置在888行的keras/engine/training.py中

       # Compute total loss.
        total_loss = None
        for i in range(len(self.outputs)):
            if i in skip_indices:
                continue
            y_true = self.targets[i]
            y_pred = self.outputs[i]
            weighted_loss = weighted_losses[i]
            sample_weight = sample_weights[i]
            mask = masks[i]
            loss_weight = loss_weights_list[i]
            output_loss = weighted_loss(y_true, y_pred,
                                        sample_weight, mask)
            if len(self.outputs) > 1:
                self.metrics_tensors.append(output_loss)
                self.metrics_names.append(self.output_names[i] + '_loss')
            if total_loss is None:
                total_loss = loss_weight * output_loss
            else:
                total_loss += loss_weight * output_loss
        if total_loss is None:
            if not self.losses:
                raise RuntimeError('The model cannot be compiled '
                                   'because it has no loss to optimize.')
            else:
                total_loss = 0.
总损耗是一个包含所有样本损耗的张量。KERA使用总损耗的train_函数来训练和更新参数。其代码为keras/engine/training.py,1003行

    def _make_train_function(self):
        if not hasattr(self, 'train_function'):
            raise RuntimeError('You must compile your model before using it.')
        if self.train_function is None:
            inputs = self._feed_inputs + self._feed_targets + self._feed_sample_weights
            if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
                inputs += [K.learning_phase()]

            training_updates = self.optimizer.get_updates(
                self._collected_trainable_weights,
                self.constraints,
                self.total_loss)
            updates = self.updates + training_updates
            # Gets loss and metrics. Updates weights at each call.
            self.train_function = K.function(inputs,
                                             [self.total_loss] + self.metrics_tensors,
                                             updates=updates,
                                             **self._function_kwargs)
所以我只是用top-k损耗替换总损耗。这可能有用。所以我在总损耗后面加了两行代码

import tensorflow as tf
total_loss = tf.nn.top_k(total_loss, k=40)
整个代码如下所示

# Compute total loss.
total_loss = None
for i in range(len(self.outputs)):
    if i in skip_indices:
        continue
    y_true = self.targets[i]
    y_pred = self.outputs[i]
    weighted_loss = weighted_losses[i]
    sample_weight = sample_weights[i]
    mask = masks[i]
    loss_weight = loss_weights_list[i]
    output_loss = weighted_loss(y_true, y_pred,
                                sample_weight, mask)
    if len(self.outputs) > 1:
        self.metrics_tensors.append(output_loss)
        self.metrics_names.append(self.output_names[i] + '_loss')
    if total_loss is None:
        total_loss = loss_weight * output_loss
    else:
        total_loss += loss_weight * output_loss
if total_loss is None:
    if not self.losses:
        raise RuntimeError('The model cannot be compiled '
                           'because it has no loss to optimize.')
    else:
        total_loss = 0.
#total_loss = 0.
# Add regularization penalties
# and other layer-specific losses.
for loss_tensor in self.losses:
    total_loss += loss_tensor
# modify by cxt get top-k loss
import tensorflow as tf
total_loss = tf.nn.top_k(total_loss, k=40)
但是,它显示如下错误。原因是代码在model.compile阶段运行。没有数据。我怎样才能得到top-k损失

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/keras/engine/training.py", line 921, in compile
    total_loss = tf.nn.top_k(total_loss, k=40)

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/nn_ops.py", line 1998, in top_k
    return gen_nn_ops._top_kv2(input, k=k, sorted=sorted, name=name)

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/gen_nn_ops.py", line 2502, in _top_kv2
    name=name)

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py", line 768, in apply_op
    op_def=op_def)

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 2338, in create_op
    set_shapes_for_outputs(ret)

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1719, in set_shapes_for_outputs
    shapes = shape_func(op)

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1669, in call_with_requiring
    return call_cpp_shape_fn(op, require_shape_fn=True)

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py", line 610, in call_cpp_shape_fn
    debug_python_shape_fn, require_shape_fn)

  File "/home/cxt/softwares/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/common_shapes.py", line 676, in _call_cpp_shape_fn_impl
    raise ValueError(err.message)

ValueError: Shape must be at least rank 1 but is rank 0 for 'TopKV2' (op: 'TopKV2') with input shapes: [], [].

我以前用于OHEM的方法是编写自己的数据生成器。该生成器首先生成样本,并使用当前模型选择损失最大的top-k样本。生成器的代码如下所示

def generate_topk(model):
   all_samples = get_samples() 
   all_samples_prediction= model.predict(all_samples)
   losses = loss(all_samples_prediction, all_samples_groundtruth)
   topk_samples = get_topk(all_samples, losses)
   yield topk_samples, topk_samples_groundtruth

我以前用于OHEM的方法是编写自己的数据生成器。该生成器首先生成样本,并使用当前模型选择损失最大的top-k样本。生成器的代码如下所示

def generate_topk(model):
   all_samples = get_samples() 
   all_samples_prediction= model.predict(all_samples)
   losses = loss(all_samples_prediction, all_samples_groundtruth)
   topk_samples = get_topk(all_samples, losses)
   yield topk_samples, topk_samples_groundtruth

你是如何调用
model.compile
你的代码的?我在开始时创建了一个模型。下面是我的名字model=Sequential()model.add(…)、model.compile(loss='classifical_crossentropy',optimizer='sgd',metrics=['mse',accurity'])@Anthony KongHow你调用了
model.compile
你的代码吗?我从一开始就创建了一个模型。下面是我的名字model=Sequential()model.add(…),model.compile(loss='classifical_crossentropy',optimizer='sgd',metrics=['mse','accurity'])@Anthony Kong