o
    NeA.  ã                   @   sl   d dl mZ ddlmZ ddlmZ ddlmZ g d¢ZG dd	„ d	eƒZ	G d
d„ deƒZ
G dd„ deƒZdS )é    )ÚOrderedDicté   )Ú	Parameteré   )ÚLayer)Úparam_guard)Ú
SequentialÚParameterListÚ	LayerListc                       sH   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	‡  Z
S )r   a®  Sequential container.
    Sub layers will be added to this container in the order of argument in the constructor.
    The argument passed to the constructor can be iterable Layers or iterable name Layer pairs.

    Parameters:
        layers(Layer|list|tuple): Layer or list/tuple of iterable name Layer pair.

    Examples:
        .. code-block:: python

            import paddle
            import numpy as np

            data = np.random.uniform(-1, 1, [30, 10]).astype('float32')
            data = paddle.to_tensor(data)
            # create Sequential with iterable Layers
            model1 = paddle.nn.Sequential(
                paddle.nn.Linear(10, 1), paddle.nn.Linear(1, 2)
            )
            model1[0]  # access the first layer
            res1 = model1(data)  # sequential execution

            # create Sequential with name Layer pairs
            model2 = paddle.nn.Sequential(
                ('l1', paddle.nn.Linear(10, 2)),
                ('l2', paddle.nn.Linear(2, 3))
            )
            model2['l1']  # access l1 layer
            model2.add_sublayer('l3', paddle.nn.Linear(3, 3))  # add sublayer
            res2 = model2(data)  # sequential execution

    c                    sp   t t| ƒ ¡  t|ƒdkr%t|d ttfƒr%|D ]
\}}|  ||¡ qd S t|ƒD ]\}}|  t	|ƒ|¡ q)d S )Nr   )
Úsuperr   Ú__init__ÚlenÚ
isinstanceÚlistÚtupleÚadd_sublayerÚ	enumerateÚstr)ÚselfÚlayersÚnameÚlayerÚidx©Ú	__class__© úND:\Projects\ConvertPro\env\Lib\site-packages\paddle/fluid/dygraph/container.pyr   =   s   ÿÿzSequential.__init__c                 C   sª   t |tƒr| jt| j ¡ ƒ| Ž S t |tƒr| j| S |t| jƒkr)td 	|¡ƒ‚|dk r=|t| jƒ kr=|t| jƒ7 }n|t| jƒ k rLtd 	|¡ƒ‚t| j ¡ ƒ| S )Nzindex {} is out of ranger   )
r   Úslicer   r   Ú_sub_layersÚvaluesr   r   Ú
IndexErrorÚformat©r   r   r   r   r   Ú__getitem__F   s   


zSequential.__getitem__c                 C   ó"   t |tƒsJ ‚t| t|ƒ|ƒ d S ©N)r   r   Úsetattrr   )r   r   r   r   r   r   Ú__setitem__T   ó   zSequential.__setitem__c                 C   s"   t |ƒ}|| jv sJ ‚| j|= d S r%   )r   r   r"   r   r   r   Ú__delitem__X   s   zSequential.__delitem__c                 C   ó
   t | jƒS r%   ©r   r   ©r   r   r   r   Ú__len__]   ó   
zSequential.__len__c                 C   s   | j  ¡ D ]}||ƒ}q|S r%   )r   r   )r   Úinputr   r   r   r   Úforward`   s   
zSequential.forward)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r#   r'   r)   r-   r0   Ú__classcell__r   r   r   r   r      s    !	r   c                       sJ   e Zd ZdZd‡ fdd„	Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	‡  Z
S )r	   a  ParameterList Container.

    This container acts like a Python list, but parameters it contains will be properly added.

    Parameters:
        parameters (iterable, optional): Iterable Parameters to be added

    Examples:
        .. code-block:: python

            import paddle
            import numpy as np

            class MyLayer(paddle.nn.Layer):
                def __init__(self, num_stacked_param):
                    super(MyLayer, self).__init__()
                    # create ParameterList with iterable Parameters
                    self.params = paddle.nn.ParameterList(
                        [paddle.create_parameter(
                            shape=[2, 2], dtype='float32')] * num_stacked_param)

                def forward(self, x):
                    for i, p in enumerate(self.params):
                        tmp = self._helper.create_variable_for_type_inference('float32')
                        self._helper.append_op(
                            type="mul",
                            inputs={"X": x,
                                    "Y": p},
                            outputs={"Out": tmp},
                            attrs={"x_num_col_dims": 1,
                                    "y_num_col_dims": 1})
                        x = tmp
                    return x

            data_np = np.random.uniform(-1, 1, [5, 2]).astype('float32')
            x = paddle.to_tensor(data_np)
            num_stacked_param = 4
            model = MyLayer(num_stacked_param)
            print(len(model.params))  # 4
            res = model(x)
            print(res.shape)  # [5, 2]

            replaced_param = paddle.create_parameter(shape=[2, 3], dtype='float32')
            model.params[num_stacked_param - 1] = replaced_param  # replace last param
            res = model(x)
            print(res.shape)  # [5, 3]
            model.params.append(paddle.create_parameter(shape=[3, 4], dtype='float32'))  # append param
            print(len(model.params))  # 5
            res = model(x)
            print(res.shape)  # [5, 4]
    Nc                    sN   t t| ƒ ¡  |d ur#t|ƒD ]\}}t|tƒsJ ‚|  t|ƒ|¡ qd S d S r%   )r   r	   r   r   r   r   Úadd_parameterr   )r   Ú
parametersr   Úparamr   r   r   r   ›   s   ýzParameterList.__init__c                 C   s<   t | jƒ | jt|ƒ W  d   ƒ S 1 sw   Y  d S r%   )r   Ú_parametersr   ©r   r   r   r   r   r#   ¢   ó   $ÿzParameterList.__getitem__c                 C   r$   r%   )r   r   r&   r   )r   r   r8   r   r   r   r'   ¦   r(   zParameterList.__setitem__c                 C   r*   r%   )r   r9   r,   r   r   r   r-   ª   r.   zParameterList.__len__c                 C   s<   t | jƒ t| j ¡ ƒW  d   ƒ S 1 sw   Y  d S r%   )r   r9   Úiterr   r,   r   r   r   Ú__iter__­   r;   zParameterList.__iter__c                 C   s   t | jƒ}|  t|ƒ|¡ | S )z†Appends a given parameter at the end of the list.

        Parameters:
            parameter (Parameter): parameter to append
        )r   r9   r6   r   )r   Z	parameterr   r   r   r   Úappend±   s   
zParameterList.appendr%   )r1   r2   r3   r4   r   r#   r'   r-   r=   r>   r5   r   r   r   r   r	   f   s    4r	   c                       sj   e Zd ZdZd‡ fdd„	Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Z‡  ZS )r
   a`  
    LayerList holds sublayers, and sublayers it contains are properly registered.
    Holded sublayers can be indexed like a regular python list.

    Parameters:
        sublayers (iterable of Layer, optional): sublayers to hold

    Examples:
        .. code-block:: python

            import paddle
            import numpy as np

            class MyLayer(paddle.nn.Layer):
                def __init__(self):
                    super(MyLayer, self).__init__()
                    self.linears = paddle.nn.LayerList(
                        [paddle.nn.Linear(10, 10) for i in range(10)])

                def forward(self, x):
                    # LayerList can act as an iterable, or be indexed using ints
                    for i, l in enumerate(self.linears):
                        x = self.linears[i // 2](x) + l(x)
                    return x
    Nc                    s@   t t| ƒ ¡  |d urt|ƒD ]\}}|  t|ƒ|¡ qd S d S r%   )r   r
   r   r   r   r   )r   Ú	sublayersr   r   r   r   r   r   ×   s   þzLayerList.__init__c                 C   s^   t |tƒr-t| ƒ |  krt| ƒk s#n td |t| ƒ t| ƒ¡ƒ‚|dk r-|t| ƒ7 }|S )Nz@index {} is out of range, should be an integer in range [{}, {})r   )r   Úintr   r    r!   r:   r   r   r   Ú_get_abs_idxÝ   s   
 þzLayerList._get_abs_idxc                 C   s:   t |tƒr|  t| j ¡ ƒ| ¡S |  |¡}| jt|ƒ S r%   )r   r   r   r   r   r   rA   r   r:   r   r   r   r#   ç   s   

zLayerList.__getitem__c                 C   s   |   |¡}t| t|ƒ|ƒS r%   )rA   r&   r   )r   r   Úsublayerr   r   r   r'   î   s   
zLayerList.__setitem__c                 C   s€   t |tƒrtt| jƒƒ| D ]	}t| t|ƒƒ qn|  |¡}t| t|ƒƒ dd„ tt| jƒƒD ƒ}tt	t
|| j ¡ ƒƒƒ| _d S )Nc                 S   s   g | ]}t |ƒ‘qS r   )r   )Ú.0Úir   r   r   Ú
<listcomp>ù   s    z)LayerList.__delitem__.<locals>.<listcomp>)r   r   Úranger   r   Údelattrr   rA   r   r   Úzipr   )r   r   ÚkZstr_indicesr   r   r   r)   ò   s   
ÿ

ÿzLayerList.__delitem__c                 C   r*   r%   r+   r,   r   r   r   r-   ý   r.   zLayerList.__len__c                 C   s   t | j ¡ ƒS r%   )r<   r   r   r,   r   r   r   r=      s   zLayerList.__iter__c                 C   s   |   tt| ƒƒ|¡ | S )aº  
        Appends a sublayer to the end of the list.

        Parameters:
            sublayer (Layer): sublayer to append

        Examples:
            .. code-block:: python

                import paddle

                linears = paddle.nn.LayerList([paddle.nn.Linear(10, 10) for i in range(10)])
                another = paddle.nn.Linear(10, 10)
                linears.append(another)
                print(len(linears))  # 11
        )r   r   r   )r   rB   r   r   r   r>     s   zLayerList.appendc                 C   s˜   t |tƒrt| jƒ |  krt| jƒk s$n J d t| ƒ t| ƒ¡ƒ‚|  |¡}tt| jƒ|dƒD ]}| jt|d ƒ | jt|ƒ< q2|| jt|ƒ< dS )a  
        Insert a sublayer before a given index in the list.

        Parameters:
            index (int): index to insert.
            sublayer (Layer): sublayer to insert

        Examples:
            .. code-block:: python

                import paddle

                linears = paddle.nn.LayerList([paddle.nn.Linear(10, 10) for i in range(10)])
                another = paddle.nn.Linear(10, 10)
                linears.insert(3, another)
                print(linears[3] is another)  # True
                another = paddle.nn.Linear(10, 10)
                linears.insert(-1, another)
                print(linears[-2] is another) # True
        z,index should be an integer in range [{}, {})éÿÿÿÿr   N)r   r@   r   r   r!   rA   rF   r   )r   ÚindexrB   rD   r   r   r   Úinsert  s   
&ÿ
zLayerList.insertc                 C   s6   t | ƒ}t|ƒD ]\}}t|| ƒ}|  ||¡ q| S )aD  
        Appends sublayers to the end of the list.

        Parameters:
            sublayers (iterable of Layer): iterable of sublayers to append

        Examples:
            .. code-block:: python

                import paddle

                linears = paddle.nn.LayerList([paddle.nn.Linear(10, 10) for i in range(10)])
                another_list = paddle.nn.LayerList([paddle.nn.Linear(10, 10) for i in range(5)])
                linears.extend(another_list)
                print(len(linears))  # 15
                print(another_list[0] is linears[10])  # True
        )r   r   r   r   )r   r?   ÚoffsetrD   rB   r   r   r   r   Úextend5  s
   zLayerList.extendr%   )r1   r2   r3   r4   r   rA   r#   r'   r)   r-   r=   r>   rL   rN   r5   r   r   r   r   r
   ¼   s    
r
   N)Úcollectionsr   Z	frameworkr   r   r   Úbaser   Ú__all__r   r	   r
   r   r   r   r   Ú<module>   s   KV