nets.py 6.0 KB
Newer Older
1
import layers
F
fengjiayi 已提交
2

3 4 5
__all__ = [
    "simple_img_conv_pool",
    "sequence_conv_pool",
6
    "glu",
7
    "",
8
]
D
dzhwinter 已提交
9

F
fengjiayi 已提交
10 11 12

def simple_img_conv_pool(input,
                         num_filters,
D
dzhwinter 已提交
13
                         filter_size,
F
fengjiayi 已提交
14 15 16
                         pool_size,
                         pool_stride,
                         act,
F
fengjiayi 已提交
17
                         param_attr=None,
18
                         pool_type='max'):
F
fengjiayi 已提交
19 20 21 22
    conv_out = layers.conv2d(
        input=input,
        num_filters=num_filters,
        filter_size=filter_size,
F
fengjiayi 已提交
23
        param_attr=param_attr,
24
        act=act)
F
fengjiayi 已提交
25 26 27 28

    pool_out = layers.pool2d(
        input=conv_out,
        pool_size=pool_size,
Q
Qiao Longfei 已提交
29
        pool_type=pool_type,
30
        pool_stride=pool_stride)
Q
Qiao Longfei 已提交
31 32 33 34 35 36 37 38 39
    return pool_out


def img_conv_group(input,
                   conv_num_filter,
                   pool_size,
                   conv_padding=1,
                   conv_filter_size=3,
                   conv_act=None,
F
fengjiayi 已提交
40
                   param_attr=None,
Q
Qiao Longfei 已提交
41 42 43
                   conv_with_batchnorm=False,
                   conv_batchnorm_drop_rate=None,
                   pool_stride=1,
44
                   pool_type=None):
Q
Qiao Longfei 已提交
45 46 47 48 49
    """
    Image Convolution Group, Used for vgg net.
    """
    tmp = input
    assert isinstance(conv_num_filter, list) or \
50
        isinstance(conv_num_filter, tuple)
Q
Qiao Longfei 已提交
51 52 53 54 55 56 57 58 59

    def __extend_list__(obj):
        if not hasattr(obj, '__len__'):
            return [obj] * len(conv_num_filter)
        else:
            return obj

    conv_padding = __extend_list__(conv_padding)
    conv_filter_size = __extend_list__(conv_filter_size)
F
fengjiayi 已提交
60
    param_attr = __extend_list__(param_attr)
Q
Qiao Longfei 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73
    conv_with_batchnorm = __extend_list__(conv_with_batchnorm)
    conv_batchnorm_drop_rate = __extend_list__(conv_batchnorm_drop_rate)

    for i in xrange(len(conv_num_filter)):
        local_conv_act = conv_act
        if conv_with_batchnorm[i]:
            local_conv_act = None

        tmp = layers.conv2d(
            input=tmp,
            num_filters=conv_num_filter[i],
            filter_size=conv_filter_size[i],
            padding=conv_padding[i],
F
fengjiayi 已提交
74
            param_attr=param_attr[i],
75
            act=local_conv_act)
Q
Qiao Longfei 已提交
76 77

        if conv_with_batchnorm[i]:
78
            tmp = layers.batch_norm(input=tmp, act=conv_act)
Q
Qiao Longfei 已提交
79 80
            drop_rate = conv_batchnorm_drop_rate[i]
            if abs(drop_rate) > 1e-5:
81
                tmp = layers.dropout(x=tmp, dropout_prob=drop_rate)
Q
Qiao Longfei 已提交
82 83 84 85 86

    pool_out = layers.pool2d(
        input=tmp,
        pool_size=pool_size,
        pool_type=pool_type,
87
        pool_stride=pool_stride)
F
fengjiayi 已提交
88
    return pool_out
D
dzhwinter 已提交
89 90 91 92 93


def sequence_conv_pool(input,
                       num_filters,
                       filter_size,
F
fengjiayi 已提交
94
                       param_attr=None,
95
                       act="sigmoid",
96
                       pool_type="max"):
D
dzhwinter 已提交
97 98 99 100
    conv_out = layers.sequence_conv(
        input=input,
        num_filters=num_filters,
        filter_size=filter_size,
F
fengjiayi 已提交
101
        param_attr=param_attr,
102
        act=act)
D
dzhwinter 已提交
103

104
    pool_out = layers.sequence_pool(input=conv_out, pool_type=pool_type)
D
dzhwinter 已提交
105
    return pool_out
G
guosheng 已提交
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132


def glu(input, dim=-1):
    """
    The gated linear unit composed by split and elementwise multiplication. 
    Specifically, Split the input into two equal sized parts :math:`a` and 
    :math:`b` along the given dimension and then compute as following:

        .. math::

            {GLU}(a, b)= a \otimes \sigma(b)

    Refer to `Language Modeling with Gated Convolutional Networks 
    <https://arxiv.org/pdf/1612.08083.pdf>`_.
    
    Args:
        input (Variable): The input variable which is a Tensor or LoDTensor.
        dim (int): The dimension along which to split. If :math:`dim < 0`, the 
            dimension to split along is :math:`rank(input) + dim`.

    Returns:
        Variable: The Tensor variable with half the size of input.

    Examples:
        .. code-block:: python

            # x is a Tensor variable with shape [3, 6, 9]
133
            fluid.nets.glu(input=x, dim=1)  # shape of output: [3, 3, 9]
G
guosheng 已提交
134 135 136 137 138
    """

    a, b = layers.split(input, num_or_sections=2, dim=dim)
    out = layers.elementwise_mul(x=a, y=b)
    return out
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190


def dot_product_attention(querys, keys, values):
    """
    The dot-product attention.

    Attention mechanism can be seen as mapping a query and a set of key-value 
    pairs to an output. The output is computed as a weighted sum of the values, 
    where the weight assigned to each value is computed by a compatibility 
    function (dot-product here) of the query with the corresponding key.
    
    The dot-product attention can be implemented through (batch) matrix 
    multipication as follows:

        .. math::

            Attention(Q, K, V)= softmax(QK^\mathrm{T})V

    Refer to `Attention Is All You Need 
    <https://arxiv.org/pdf/1706.03762.pdf>`_.

    Note that batch data containing sequences with different lengths is not 
    supported by this because of the (batch) matrix multipication.
    
    Args:
        query (Variable): The input variable which is a Tensor or LoDTensor.
        key (Variable): The input variable which is a Tensor or LoDTensor.
        value (Variable): The input variable which is a Tensor or LoDTensor.

    Returns:
        tuple: The Tensor variables representing the output and attention scores.

    Examples:
        .. code-block:: python

            # Suppose q, k, v are tensor variables with the following shape:
            # q: [3, 5, 9], k: [3, 6, 9], v: [3, 6, 10]
            out, attn_scores = fluid.nets.dot_product_attention(q, k, v)
            out.shape  # [3, 5, 10]
            attn_scores.shape  # [3, 5, 6]
    """
    assert keys.shape[-2] == values.shape[
        -2], 'The shapes of keys and values mismatch.'
    assert querys.shape[-1] == keys.shape[
        -1], 'The shapes of querys and keys mismatch.'
    product = layers.matmul(x=querys, y=keys, transpose_y=True)
    attn_scores = layers.reshape(
        x=layers.reshape(
            x=product, shape=[-1, product.shape[-1]], act='softmax'),
        shape=product.shape)
    out = layers.matmul(attn_scores, values)
    return out, attn_scores