Indeed, the dice of the batch is not the same as the mean of the batch of each image. This comes from the fact that the size of your positive regions is not the same in each image (I assume).
For both your loss and evaluation, you could actually use the same function:
def dice_score(input: torch.Tensor, target: torch.Tensor, eps: float=1e-8) -> torch.Tensor:
    """input and target should be FloatTensor where the first dimension is the batch."""
    intersection = (input * target).flatten(1).sum(1)
    sum_both = input.flatten(1).sum(1) + target.flatten(1).sum(1)
    return (2 * intersection + eps) / (sum_both + eps)

This works only if you consider one class.