提交 fa9cbfb7 编写于 作者: Y Yu Yang

Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into...

Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into feature/polish_reshape_and_lod_tensor_blocking_queue
...@@ -1768,3 +1768,11 @@ reverse ...@@ -1768,3 +1768,11 @@ reverse
.. autofunction:: paddle.fluid.layers.reverse .. autofunction:: paddle.fluid.layers.reverse
:noindex: :noindex:
.. _api_fluid_layers_rank_loss:
rank_loss
-------
.. autofunction:: paddle.fluid.layers.rank_loss
:noindex:
...@@ -110,6 +110,7 @@ __all__ = [ ...@@ -110,6 +110,7 @@ __all__ = [
'relu', 'relu',
'log', 'log',
'crop', 'crop',
'rank_loss',
] ]
...@@ -5282,3 +5283,74 @@ def crop(x, shape=None, offsets=None, name=None): ...@@ -5282,3 +5283,74 @@ def crop(x, shape=None, offsets=None, name=None):
outputs={'Out': out}, outputs={'Out': out},
attrs=None if len(attrs) == 0 else attrs) attrs=None if len(attrs) == 0 else attrs)
return out return out
def rank_loss(label, left, right, name=None):
"""
**Rank loss layer for RankNet**
RankNet(http://icml.cc/2015/wp-content/uploads/2015/06/icml_ranking.pdf)
is a pairwise ranking model with a training sample consisting of a pair
of documents, A and B. Label P indicates whether A is ranked higher than B
or not:
P = {0, 1} or {0, 0.5, 1}, where 0.5 means that there is no information
about the rank of the input pair.
Rank loss layer takes three inputs: left (o_i), right (o_j) and
label (P_{i,j}). The inputs respectively represent RankNet's output scores
for documents A and B and the value of label P. The following equation
computes rank loss C_{i,j} from the inputs:
$$
C_{i,j} = -\tilde{P_{ij}} * o_{i,j} + \log(1 + e^{o_{i,j}}) \\
o_{i,j} = o_i - o_j \\
\tilde{P_{i,j}} = \left \{0, 0.5, 1 \right \} \ or \ \left \{0, 1 \right \}
$$
Rank loss layer takes batch inputs with size batch_size (batch_size >= 1).
Args:
label (Variable): Indicats whether A ranked higher than B or not.
left (Variable): RankNet's output score for doc A.
right (Variable): RankNet's output score for doc B.
name(str|None): A name for this layer(optional). If set None, the layer
will be named automatically.
Returns:
list: The value of rank loss.
Raises:
ValueError: Any of label, left, and right is not a variable.
Examples:
.. code-block:: python
label = fluid.layers.data(name="label", shape=[4, 1], dtype="float32")
left = fluid.layers.data(name="left", shape=[4, 1], dtype="float32")
right = fluid.layers.data(name="right", shape=[4, 1], dtype="float32")
out = fluid.layers.rank_loss(label, left, right)
"""
helper = LayerHelper('rank_loss', **locals())
if not (isinstance(label, Variable)):
raise ValueError("The label should be a Variable")
if not (isinstance(left, Variable)):
raise ValueError("The left should be a Variable")
if not (isinstance(right, Variable)):
raise ValueError("The right should be a Variable")
out = helper.create_tmp_variable("float32")
helper.append_op(
type='rank_loss',
inputs={"Label": label,
"Left": left,
"Right": right},
outputs={'Out': out})
return out
...@@ -443,6 +443,28 @@ class TestBook(unittest.TestCase): ...@@ -443,6 +443,28 @@ class TestBook(unittest.TestCase):
self.assertIsNotNone(ids) self.assertIsNotNone(ids)
print(str(program)) print(str(program))
def test_rank_loss(self):
program = Program()
with program_guard(program):
label = layers.data(
name='label',
append_batch_size=False,
shape=[16, 1],
dtype="float32")
left = layers.data(
name='left',
append_batch_size=False,
shape=[16, 1],
dtype="float32")
right = layers.data(
name='right',
append_batch_size=False,
shape=[16, 1],
dtype="float32")
out = layers.rank_loss(label, left, right, name="rank_loss")
self.assertIsNotNone(out)
print(str(program))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册