def show_images_diff()

in utils.py [0:0]


def show_images_diff(image, adv_image, adv_label=None, class_names=None, cmap=None):
    adv_image = tensor_to_imgarray(adv_image, floating_point=True)
    image = tensor_to_imgarray(image, floating_point=True)

    fig, (ax0, ax1, ax2) = plt.subplots(ncols=3, figsize=(12, 4))

    ax0.imshow(image)
    ax0.set_title('Original')
    ax0.set_axis_off()

    ax1.imshow(adv_image)
    if adv_label is None:
        ax1.set_title('Adversarial image')
    else:
        ax1.set_title(f'Model prediction: {class_names[adv_label] if class_names else adv_label}')
    ax1.set_axis_off()

    difference = adv_image - image

    # If colormapping, convert RGB to single lightness channel:
    if cmap is not None and 3 in difference.shape:
        channeldim = difference.shape.index(3)
        rgbindices = [
            tuple(rgb if dim == channeldim else slice(None) for dim in range(len(difference.shape)))
            for rgb in range(3)
        ]
        # RGB->lightness function per PIL docs, but no need to import the lib just for this:
        # https://pillow.readthedocs.io/en/3.2.x/reference/Image.html#PIL.Image.Image.convert
        # L = R * 299/1000 + G * 587/1000 + B * 114/1000
        difference = (
            difference[rgbindices[0]] * 0.299
            + difference[rgbindices[1]] * 0.587
            + difference[rgbindices[2]] * 0.114
        )

    # Scale to a symmetric range around max absolute difference (which we print out), and map that to 0-1
    # for imshow. (When colormapping we could just use vmin/vmax, but this way we keep same path for both).
    maxdiff = abs(difference).max()
    difference = difference / (maxdiff * 2.0) + 0.5
    ax2.imshow(difference, cmap=cmap, vmin=0., vmax=1.)
    ax2.set_title(f'Diff ({-maxdiff:.4f} to {maxdiff:.4f})')
    ax2.set_axis_off()
    plt.tight_layout()
    plt.show()