|
110 | 110 | 'relu',
|
111 | 111 | 'log',
|
112 | 112 | 'crop',
|
| 113 | + 'rank_loss', |
113 | 114 | ]
|
114 | 115 |
|
115 | 116 |
|
@@ -5282,3 +5283,74 @@ def crop(x, shape=None, offsets=None, name=None):
|
5282 | 5283 | outputs={'Out': out},
|
5283 | 5284 | attrs=None if len(attrs) == 0 else attrs)
|
5284 | 5285 | return out
|
| 5286 | + |
| 5287 | + |
| 5288 | +def rank_loss(label, left, right, name=None): |
| 5289 | + """ |
| 5290 | + **Rank loss layer for RankNet** |
| 5291 | +
|
| 5292 | + RankNet(http://icml.cc/2015/wp-content/uploads/2015/06/icml_ranking.pdf) |
| 5293 | + is a pairwise ranking model with a training sample consisting of a pair |
| 5294 | + of documents, A and B. Label P indicates whether A is ranked higher than B |
| 5295 | + or not: |
| 5296 | + |
| 5297 | + P = {0, 1} or {0, 0.5, 1}, where 0.5 means that there is no information |
| 5298 | + about the rank of the input pair. |
| 5299 | + |
| 5300 | + Rank loss layer takes three inputs: left (o_i), right (o_j) and |
| 5301 | + label (P_{i,j}). The inputs respectively represent RankNet's output scores |
| 5302 | + for documents A and B and the value of label P. The following equation |
| 5303 | + computes rank loss C_{i,j} from the inputs: |
| 5304 | + |
| 5305 | + $$ |
| 5306 | + C_{i,j} = -\tilde{P_{ij}} * o_{i,j} + \log(1 + e^{o_{i,j}}) \\ |
| 5307 | + o_{i,j} = o_i - o_j \\ |
| 5308 | + \tilde{P_{i,j}} = \left \{0, 0.5, 1 \right \} \ or \ \left \{0, 1 \right \} |
| 5309 | + $$ |
| 5310 | + |
| 5311 | + Rank loss layer takes batch inputs with size batch_size (batch_size >= 1). |
| 5312 | + |
| 5313 | + Args: |
| 5314 | + label (Variable): Indicats whether A ranked higher than B or not. |
| 5315 | + left (Variable): RankNet's output score for doc A. |
| 5316 | + right (Variable): RankNet's output score for doc B. |
| 5317 | + name(str|None): A name for this layer(optional). If set None, the layer |
| 5318 | + will be named automatically. |
| 5319 | +
|
| 5320 | + Returns: |
| 5321 | + list: The value of rank loss. |
| 5322 | +
|
| 5323 | + Raises: |
| 5324 | + ValueError: Any of label, left, and right is not a variable. |
| 5325 | +
|
| 5326 | + Examples: |
| 5327 | +
|
| 5328 | + .. code-block:: python |
| 5329 | +
|
| 5330 | + label = fluid.layers.data(name="label", shape=[4, 1], dtype="float32") |
| 5331 | + left = fluid.layers.data(name="left", shape=[4, 1], dtype="float32") |
| 5332 | + right = fluid.layers.data(name="right", shape=[4, 1], dtype="float32") |
| 5333 | + out = fluid.layers.rank_loss(label, left, right) |
| 5334 | +
|
| 5335 | +
|
| 5336 | + """ |
| 5337 | + helper = LayerHelper('rank_loss', **locals()) |
| 5338 | + |
| 5339 | + if not (isinstance(label, Variable)): |
| 5340 | + raise ValueError("The label should be a Variable") |
| 5341 | + |
| 5342 | + if not (isinstance(left, Variable)): |
| 5343 | + raise ValueError("The left should be a Variable") |
| 5344 | + |
| 5345 | + if not (isinstance(right, Variable)): |
| 5346 | + raise ValueError("The right should be a Variable") |
| 5347 | + |
| 5348 | + out = helper.create_tmp_variable("float32") |
| 5349 | + |
| 5350 | + helper.append_op( |
| 5351 | + type='rank_loss', |
| 5352 | + inputs={"Label": label, |
| 5353 | + "Left": left, |
| 5354 | + "Right": right}, |
| 5355 | + outputs={'Out': out}) |
| 5356 | + return out |
0 commit comments