o
    Ne,                     @   s   d dl mZ d dl mZ d dl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ddZG dd de	ZdS )    )print_function)divisionN   )core)SamplerSequenceSamplerRandomSamplerWeightedRandomSamplerc                   @   s"   e Zd ZdZdddZdd ZdS )r   a  
    An abstract class to encapsulate methods and behaviors of samplers.

    All sampler used by :code:`paddle.io.BatchSampler` should be a subclass
    of :code:`paddle.io.Sampler`, BatchSampler subclasses should
    implement following methods:

    :code:`__iter__`: return sample index iterably, which iterate over indices
    of dataset elements

    :code:`__len__`: the number of sample in :attr:`data_source`


    Args:
        data_source(Dataset, optional): this could be an instance of
                :code:`paddle.io.Dataset` other Python object which
                implemented :code:`__len__` for Sampler to get indices
                as the range of :attr:`dataset` length. Default None.

    Returns:
        Sampler: an iterable object for sample indices iterating

    Examples:
        
        .. code-block:: python
            
            from paddle.io import Dataset, Sampler

            class RandomDataset(Dataset):
                def __init__(self, num_samples):
                    self.num_samples = num_samples
            
                def __getitem__(self, idx):
                    image = np.random.random([784]).astype('float32')
                    label = np.random.randint(0, 9, (1, )).astype('int64')
                    return image, label
                
                def __len__(self):
                    return self.num_samples

            class MySampler(Sampler):
                def __init__(self, data_source):
                    self.data_source = data_source

                def __iter__(self):
                    return iter(range(len(self.data_source)))

                def __len__(self):
                    return len(self.data_source)
            
            sampler = MySampler(data_source=RandomDataset(100))

            for index in sampler:
                print(index)

    see `paddle.io.BatchSampler`
    see `paddle.io.DataLoader`

    Nc                 C   
   || _ d S Ndata_sourceselfr    r   OD:\Projects\ConvertPro\env\Lib\site-packages\paddle/fluid/dataloader/sampler.py__init__W      
zSampler.__init__c                 C   s   t r   )NotImplementedErrorr   r   r   r   __iter__Z   s   zSampler.__iter__r   )__name__
__module____qualname____doc__r   r   r   r   r   r   r      s    
<r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   au  
    Iterate samples sequentially, yield :code:`0, 1, 2, ..., len(data_source) -1`
    generally,

    Args:
        data_source(Dataset): dataset to sample, this could be an
                instance of :code:`paddle.io.Dataset` other Python
                object which implemented :code:`__len__`.

    Returns:
        Sampler: a Sampler yield sample index sequentially

    Examples:

        .. code-block:: python
            
            from paddle.io import Dataset, SequenceSampler

            class RandomDataset(Dataset):
                def __init__(self, num_samples):
                    self.num_samples = num_samples
            
                def __getitem__(self, idx):
                    image = np.random.random([784]).astype('float32')
                    label = np.random.randint(0, 9, (1, )).astype('int64')
                    return image, label
                
                def __len__(self):
                    return self.num_samples

            sampler = SequenceSampler(data_source=RandomDataset(100))

            for index in sampler:
                print(index)

    see `paddle.io.Sampler`
    c                 C   r
   r   r   r   r   r   r   r      r   zSequenceSampler.__init__c                 C   s   t tt| jS r   )iterrangelenr   r   r   r   r   r      s   zSequenceSampler.__iter__c                 C   s
   t | jS r   )r   r   r   r   r   r   __len__   r   zSequenceSampler.__len__Nr   r   r   r   r   r   r   r   r   r   r   r   a   s
    &r   c                   @   s<   e Zd ZdZ			dddZedd Zdd	 Zd
d ZdS )r   ah  
    Iterate samples randomly, yield shuffled indices, if :attr:`replacement=False`,
    yield shuffled indices of the whole data souce, if :attr:`replacement=True`,
    :attr:`num_samples` can set to specify the sample number to draw.

    Args:
        data_source(Dataset): dataset to sample, this could be an
                instance of :code:`paddle.io.Dataset` other Python
                object which implemented :code:`__len__`.
        replacement(bool): If False, sample the whole dataset, If False,
                set :attr:`num_samples` for how many sample to draw. Default False.
        num_samples(int): set sample number to draw if :attr:`replacement`
                is True. Default None.
        generator(Generator): specify a generator to sample the data source. Default None
        
    Returns:
        Sampler: a Sampler yield sample index randomly

    Examples:

        .. code-block:: python
            
            from paddle.io import Dataset, RandomSampler

            class RandomDataset(Dataset):
                def __init__(self, num_samples):
                    self.num_samples = num_samples
            
                def __getitem__(self, idx):
                    image = np.random.random([784]).astype('float32')
                    label = np.random.randint(0, 9, (1, )).astype('int64')
                    return image, label
                
                def __len__(self):
                    return self.num_samples

            sampler = RandomSampler(data_source=RandomDataset(100))

            for index in sampler:
                print(index)

    see `paddle.io.Sampler`
    FNc                 C   st   || _ || _|| _|| _t| jtstd| j| jd ur%|s%tdt| j	t
r0| j	dkr8td| j	d S )Nz<expect boolean value for replacement, but got replacement={}z>num_samples should not be specified while replacement is Falser   z@num_samples should be a positive integer, but got num_samples={})r   replacement_num_samples	generator
isinstancebool	TypeErrorformat
ValueErrornum_samplesint)r   r   r    r(   r"   r   r   r   r      s"   zRandomSampler.__init__c                 C   s   | j d u r
t| jS | j S r   )r!   r   r   r   r   r   r   r(      s   

zRandomSampler.num_samplesc              	   c   s    t | j}| jr)t| jD ]}zt| j}W n ty"   Y  d S w |V  qd S | jrCtj	j
t|| jdd D ]}|V  q;d S tj	j
t||dd D ]}|V  qQd S )NT)replaceF)r   r   r"   r   r(   nextStopIterationr    nprandomchoiceZarangetolist)r   niindexr   r   r   r      s6   
zRandomSampler.__iter__c                 C   s   | j S r   )r(   r   r   r   r   r      s   zRandomSampler.__len__)FNN)	r   r   r   r   r   propertyr(   r   r   r   r   r   r   r      s    .

r   Tc                 C   sJ  t | tjr
|  } t | ttfrt| } t | tjs J dt	| j
dks+J d| d| j
d f} t| dks@J dt| tjkrLJ dt| tjkrXJ dtj| dkd	d
}t|dkslJ d|syt||ksyJ d| | jd	d
 } g }t| j
d D ]}tj| j
d	 ||| | }|| qt|S )Nz=weights should be paddle.Tensor, numpy.ndarray, list or tupler   z$weights should be a 1-D or 2-D arrayg        z weights should be positive valuezweights shoule not be INFzweights shoule not be NaN   )Zaxisr   z#weights should have positive valueszUweights positive value number should not less than num_samples when replacement=False)r#   r   Z	LoDTensornumpylisttupler-   arrayZndarrayr   shapereshapeallanyinfnansumr   r.   r/   append)weightsr(   r    Z	non_zerosZretsr2   retr   r   r   _weighted_sample   sH   

rE   c                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )r	   a  
    Random sample with given weights (probabilities), sampe index will be in range
    [0, len(weights) - 1], if :attr:`replacement` is True, index can be sampled
    multiple times.

    Args:
        weights(numpy.ndarray|paddle.Tensor|list|tuple): sequence of weights,
                should be numpy array, paddle.Tensor, list or tuple
        num_samples(int): set sample number to draw from sampler.
        replacement(bool): Whether to draw sample with replacements, default True
        
    Returns:
        Sampler: a Sampler yield sample index randomly by given weights

    Examples:

        .. code-block:: python
            
            from paddle.io import WeightedRandomSampler

            sampler = WeightedRandomSampler(weights=[0.1, 0.3, 0.5, 0.7, 0.2],
                                            num_samples=5,
                                            replacement=True)

            for index in sampler:
                print(index)
    Tc                 C   sB   t |tr	|dkrtdt |tstd|| _|| _|| _d S )Nr   z(num_samples should be a positive integerz%replacement should be a boolean value)r#   r)   r'   r$   rC   r(   r    )r   rC   r(   r    r   r   r   r   3  s   

zWeightedRandomSampler.__init__c                 C   s$   t | j| j| j}t|d S Nr5   )rE   rC   r(   r    r   r<   r0   )r   Zidxsr   r   r   r   <  s   
zWeightedRandomSampler.__iter__c                 C   s$   t | jj| jjd  }| j| S rF   )r-   prodrC   r;   r(   )r   mulr   r   r   r   A  s   
zWeightedRandomSampler.__len__NTr   r   r   r   r   r	     s
    
	r	   rI   )
__future__r   r   r7   r-    r   __all__objectr   r   r   rE   r	   r   r   r   r   <module>   s   G1
b"