U Ph@sRddlmZddlZddlmZddlZddlmZddl m Z GdddZ dS)) annotationsN)Any)NdarrayOrTensorc@sdeZdZdZddddZddddZdd d d d d Zdd d d ddZdddddddZdS)CumulativeAveragea A utility class to keep track of average values. For example during training/validation loop, we need to accumulate the per-batch metrics and calculate the final average value for the whole dataset. When training in multi-gpu environment, with DistributedDataParallel, it will average across the processes. Example: .. code-block:: python from monai.metrics import CumulativeAverage run_avg = CumulativeAverage() batch_size = 8 for i in range(len(train_set)): ... val = calc_metric(x,y) #some metric value run_avg.append(val, count=batch_size) val_avg = run_avg.aggregate() #average value None)returncCs |dS)N)resetselfr U/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/metrics/cumulative_average.py__init__.szCumulativeAverage.__init__cCs@d|_tjdtjd|_tjdtjd|_to8t|_ dS)z" Reset all stats Nrdtype) valtorchtensorfloatsumcountdist is_availableis_initializedis_distributedr r r r r1szCumulativeAverage.resetTboolr)to_numpyrcCsX|jdkrdS|j}d|t|<|jrD|t}t||rT| }|S)z returns the most recent value (averaged across processes) Args: to_numpy: whether to convert to numpy array. Defaults to True Nr) rclonerisfiniterrget_world_size all_reducecpunumpy)r rrr r r get_current:s     zCumulativeAverage.get_currentcCs~|jdkrdS|j}|j}|jrT|j|jdd}|j|jdd}t|t|t|dk|||}|rz| }|S)z returns the total average value (averaged across processes) Args: to_numpy: whether to convert to numpy array. Defaults to True NrT)copy) rrrrtorrrwherer r!)r rrrrr r r aggregatePs    zCumulativeAverage.aggregaterz Any | None)rrrcCstj|tjd|_|jjr*|j|_tj|tjdd}|jdkrn|j|jjkrnt d|d|j ||j }t |}t |st d|d|t||t|}t||t|}|j||_|j||_d S) a Append with a new value, and an optional count. Any data type is supported that is convertable with torch.as_tensor() e.g. number, list, numpy array, or Tensor. Args: val: value (e.g. number, list, numpy array or Tensor) to keep track of count: count (e.g. number, list, numpy array or Tensor), to update the contribution count For example: # a simple constant tracking avg = CumulativeAverage() avg.append(0.6) avg.append(0.8) print(avg.aggregate()) #prints 0.7 # an array tracking, e.g. metrics from 3 classes avg= CumulativeAverage() avg.append([0.2, 0.4, 0.4]) avg.append([0.4, 0.6, 0.4]) print(avg.aggregate()) #prints [0.3, 0.5. 0.4] # different contributions / counts avg= CumulativeAverage() avg.append(1, count=4) #avg metric 1 coming from a batch of 4 avg.append(2, count=6) #avg metric 2 coming from a batch of 6 print(avg.aggregate()) #prints 1.6 == (1*4 +2*6)/(4+6) # different contributions / counts avg= CumulativeAverage() avg.append([0.5, 0.5, 0], count=[1, 1, 0]) # last elements count is zero to ignore it avg.append([0.5, 0.5, 0.5], count=[1, 1, 1]) # print(avg.aggregate()) #prints [0.5, 0.5, 0,5] == ([0.5, 0.5, 0] + [0.5, 0.5, 0.5]) / ([1, 1, 0] + [1, 1, 1]) rr )rdevicerzCCount shape must match val shape, unless count is a single number: z val z!non-finite inputs received: val: z , count: N)r as_tensorrr requires_graddetachrndimshape ValueErrorr rallwarningswarnr% zeros_likerr)r rrZnfinr r r appendis #   zCumulativeAverage.appendN)T)T)r') __name__ __module__ __qualname____doc__r rr"r&r3r r r r rs  r) __future__rr0typingrrtorch.distributed distributedr monai.configrrr r r r  s