|
50 | 50 | 'sequence_last_step',
|
51 | 51 | 'dropout',
|
52 | 52 | 'split',
|
| 53 | + 'block_expand', |
53 | 54 | ]
|
54 | 55 |
|
55 | 56 |
|
@@ -1547,13 +1548,13 @@ def split(input, num_or_sections, dim=-1):
|
1547 | 1548 |
|
1548 | 1549 | Args:
|
1549 | 1550 | input (Variable): The input variable which is a Tensor or LoDTensor.
|
1550 |
| - num_or_sections (int|list): If :attr:`num_or_sections` is an integer, |
1551 |
| - then the integer indicates the number of equal sized sub-tensors |
1552 |
| - that the tensor will be divided into. If :attr:`num_or_sections` |
1553 |
| - is a list of integers, the length of list indicates the number of |
1554 |
| - sub-tensors and the integers indicate the sizes of sub-tensors' |
| 1551 | + num_or_sections (int|list): If :attr:`num_or_sections` is an integer, |
| 1552 | + then the integer indicates the number of equal sized sub-tensors |
| 1553 | + that the tensor will be divided into. If :attr:`num_or_sections` |
| 1554 | + is a list of integers, the length of list indicates the number of |
| 1555 | + sub-tensors and the integers indicate the sizes of sub-tensors' |
1555 | 1556 | :attr:`dim` dimension orderly.
|
1556 |
| - dim (int): The dimension along which to split. If :math:`dim < 0`, the |
| 1557 | + dim (int): The dimension along which to split. If :math:`dim < 0`, the |
1557 | 1558 | dimension to split along is :math:`rank(input) + dim`.
|
1558 | 1559 |
|
1559 | 1560 | Returns:
|
@@ -1597,3 +1598,119 @@ def split(input, num_or_sections, dim=-1):
|
1597 | 1598 | 'axis': dim
|
1598 | 1599 | })
|
1599 | 1600 | return outs
|
| 1601 | + |
| 1602 | + |
| 1603 | +def block_expand(input, |
| 1604 | + block_x=1, |
| 1605 | + block_y=1, |
| 1606 | + stride_x=1, |
| 1607 | + stride_y=1, |
| 1608 | + padding_x=0, |
| 1609 | + padding_y=0, |
| 1610 | + name=None, |
| 1611 | + layer_attr=None): |
| 1612 | + """ |
| 1613 | + This op use block to scan images and convert these images to sequences. |
| 1614 | + After expanding, the number of time step are output_height * output_width |
| 1615 | + for an image, in which output_height and output_width are calculated |
| 1616 | + by below equation: |
| 1617 | +
|
| 1618 | + .. math:: |
| 1619 | +
|
| 1620 | + output\_size = 1 + \ |
| 1621 | + (2 * padding + img\_size - block\_size + stride - 1) / stride |
| 1622 | +
|
| 1623 | + And the dimension of each time step is block_y * block_x * input.channels. |
| 1624 | +
|
| 1625 | +
|
| 1626 | +
|
| 1627 | + Args: |
| 1628 | + input (Variable): The input should be a tensor in NCHW format. |
| 1629 | + block_x (int): The width of sub block. |
| 1630 | + block_y (int): The width of sub block. |
| 1631 | + stride_x (int): The stride size in horizontal direction. |
| 1632 | + stride_y (int): The stride size in vertical direction. |
| 1633 | + padding_x (int): The padding size in horizontal direction. |
| 1634 | + padding_y (int): The padding size in vertical direction. |
| 1635 | + name (int): The name of this layer. It is optional. |
| 1636 | +
|
| 1637 | + Returns: |
| 1638 | + output: The output is a LoDTensor woth shape |
| 1639 | + {input.batch_size * output_y * x, |
| 1640 | + block_y * block_x * input.channels}. |
| 1641 | + If we regard output as matrix, each row of this matrix is a step of sequence. |
| 1642 | +
|
| 1643 | + Examples: |
| 1644 | +
|
| 1645 | + As an example: |
| 1646 | +
|
| 1647 | + .. code-block:: text |
| 1648 | +
|
| 1649 | + Given: |
| 1650 | +
|
| 1651 | + x = [[[[ 6. 2. 1.] |
| 1652 | + [ 8. 3. 5.] |
| 1653 | + [ 0. 2. 6.]] |
| 1654 | +
|
| 1655 | + [[ 2. 4. 4.] |
| 1656 | + [ 6. 3. 0.] |
| 1657 | + [ 6. 4. 7.]]] |
| 1658 | +
|
| 1659 | + [[[ 6. 7. 1.] |
| 1660 | + [ 5. 7. 9.] |
| 1661 | + [ 2. 4. 8.]] |
| 1662 | +
|
| 1663 | + [[ 1. 2. 1.] |
| 1664 | + [ 1. 3. 5.] |
| 1665 | + [ 9. 0. 8.]]]] |
| 1666 | +
|
| 1667 | + x.dims = {2, 2, 3, 3} |
| 1668 | +
|
| 1669 | + And: |
| 1670 | +
|
| 1671 | + block_height = 2 |
| 1672 | + block_width = 2 |
| 1673 | + stride_height = 1 |
| 1674 | + stride_width = 1 |
| 1675 | + padding_height = 0 |
| 1676 | + padding_width = 0 |
| 1677 | +
|
| 1678 | + Then: |
| 1679 | +
|
| 1680 | + output.data = [[ 6. 2. 8. 3. 2. 4. 6. 3.] |
| 1681 | + [ 2. 1. 3. 5. 4. 4. 3. 0.] |
| 1682 | + [ 8. 3. 0. 2. 6. 3. 6. 4.] |
| 1683 | + [ 3. 5. 2. 6. 3. 0. 4. 7.] |
| 1684 | + [ 6. 7. 5. 7. 1. 2. 1. 3.] |
| 1685 | + [ 7. 1. 7. 9. 2. 1. 3. 5.] |
| 1686 | + [ 5. 7. 2. 4. 1. 3. 9. 0.] |
| 1687 | + [ 7. 9. 4. 8. 3. 5. 0. 8.]] |
| 1688 | +
|
| 1689 | + output.dims = {8, 9} |
| 1690 | +
|
| 1691 | + output.lod = [[0, 4, 8]] |
| 1692 | +
|
| 1693 | +
|
| 1694 | +
|
| 1695 | + The simple usage is: |
| 1696 | +
|
| 1697 | + .. code-block:: python |
| 1698 | +
|
| 1699 | + output = fluid.layers.block_expand(input=layer, stride_x=1, stride_y=1, block_x=2, block_y=2) |
| 1700 | +
|
| 1701 | + """ |
| 1702 | + helper = LayerHelper('block_expand', **locals()) |
| 1703 | + out = helper.create_tmp_variable(dtype=helper.input_dtype()) |
| 1704 | + helper.append_op( |
| 1705 | + type='block_expand', |
| 1706 | + inputs={'X': input}, |
| 1707 | + outputs={'Out': out}, |
| 1708 | + attrs={ |
| 1709 | + 'block_height': block_y, |
| 1710 | + 'block_width': block_x, |
| 1711 | + 'stride_height': stride_y, |
| 1712 | + 'stride_width': stride_x, |
| 1713 | + 'padding_height': padding_y, |
| 1714 | + 'padding_width': padding_x |
| 1715 | + }) |
| 1716 | + return out |
0 commit comments