<jupyter_start><jupyter_text>DataWe assume that data has already been downloaded in via notebook [1_data.ipynb](1_data.ipynb).  In general, training data (for input `X` with associated labels `Y`) can be provided via lists of numpy arrays, where each image can have a different size. Alternatively, a single numpy array can also be used if all images have the same size.  Input images can either be two-dimensional (single-channel) or three-dimensional (multi-channel) arrays, where the channel axis comes last. Label images need to be integer-valued.<jupyter_code>X = sorted(glob('data/dsb2018/train/images/*.tif'))
Y = sorted(glob('data/dsb2018/train/masks/*.tif'))
assert all(Path(x).name==Path(y).name for x,y in zip(X,Y))
X = list(map(imread,X))
Y = list(map(imread,Y))
n_channel = 1 if X[0].ndim == 2 else X[0].shape[-1]<jupyter_output><empty_output><jupyter_text>Normalize images and fill small label holes.<jupyter_code>axis_norm = (0,1)   # normalize channels independently
# axis_norm = (0,1,2) # normalize channels jointly
if n_channel > 1:
    print("Normalizing image channels %s." % ('jointly' if axis_norm is None or 2 in axis_norm else 'independently'))
    sys.stdout.flush()

X = [normalize(x,1,99.8,axis=axis_norm) for x in tqdm(X)]
Y = [fill_label_holes(y) for y in tqdm(Y)]
rng = np.random.RandomState(42)
ind = rng.permutation(len(X))
n_val = int(round(0.15 * len(X)))
ind_train, ind_val = ind[:-n_val], ind[-n_val:]
X_val, Y_val = [X[i][:256,:256,np.newaxis] for i in ind_val]  , [Y[i][:256,:256,np.newaxis] for i in ind_val]
X_trn, Y_trn = [X[i][:256,:256,np.newaxis] for i in ind_train], [Y[i][:256,:256,np.newaxis] for i in ind_train] 
print('number of images: %3d' % len(X))
print('- training:       %3d' % len(X_trn))
print('- validation:     %3d' % len(X_val))


#https://segmentation-models.readthedocs.io/en/latest/tutorial.html
from segmentation_models import Unet
from segmentation_models.backbones import get_preprocessing
from segmentation_models.losses import bce_jaccard_loss
from segmentation_models.metrics import iou_score
from keras.layers import Input, Conv2D
from keras.models import Model
from keras.utils import multi_gpu_model

BACKBONE = 'resnet34'
preprocess_input = get_preprocessing(BACKBONE)

# load your data
x_train = np.stack(X_trn,axis=0)
y_train = np.stack(Y_trn,axis=0)
x_val = np.stack(X_val,axis=0)
y_val = np.stack(Y_val,axis=0)
# preprocess input
x_train = preprocess_input(x_train)
x_val = preprocess_input(x_val)

# define model
#base_model = Unet(BACKBONE, encoder_weights='imagenet')

# mitigating greyscale images
#inp = Input(shape=(None, None, 1))
#l1 = Conv2D(3, (1, 1))(inp) # map 1 channel onto 3 channels through a conv with 1x1 and 3 filters
#out = base_model(l1)

#kmodel = Model(inp, out, name=base_model.name)
#kmodel = multi_gpu_model(model, gpus=2)
kmodel = Unet(BACKBONE, encoder_weights=None, input_shape=(None, None, 1))

kmodel.compile('Adam', loss=bce_jaccard_loss, metrics=[iou_score])
print(kmodel.output)
# fit model
# if you use data generator use model.fit_generator(...) instead of model.fit(...)
# more about `fit_generator` here: https://keras.io/models/sequential/#fit_generator
kmodel.fit(
    x=x_train,
    y=y_train,
    batch_size=16,
    epochs=100,
    validation_data=(x_val, y_val),
)
inim = X[42][:256,:256]
print(inim.shape,inim.dtype,np.min(inim),np.max(inim))
img=X[42][np.newaxis,:256,:256,np.newaxis]
pred = kmodel.predict(img)[0,:,:,0]
print(pred.shape)

fig, ax = plt.subplots(1,2, figsize=(12,6))

for a,d,cm,s in zip(ax.flat, [inim,pred], ['gray','magma'],
                    ['Input image','Predicted object probability']):
    a.imshow(d,cmap=cm)
    a.set_title(s)
    a.axis('off')
plt.tight_layout()
None;
from foolbox.models import KerasModel


fmodel = KerasModel(kmodel,bounds=(-1., 2.))


from foolbox.criteria import Criterion 
import math

class Missegmentation(Criterion):
    """Defines adversarials as inputs for which the predicted class
    is not the original class.
    See Also
    --------
    :class:`TopKMisclassification`
    Notes
    -----
    Uses `numpy.argmax` to break ties.
    """
    def __init__(self, cut=1e-5):
        super(Missegmentation, self).__init__()
        assert cut > 0
        self.t = cut
        
    def name(self):
        return 'Top1Missegmentation'

    #def is_adversarial(self, predictions, label):
    #    top1 = np.argmax(predictions)
    #    return top1 != label
    def is_adversarial(self, predictions, label):
        l2 = np.sum((pred-label)**2)
        return math.sqrt(l2) > self.t
    
#base_model.summary()
kmodel.summary()
from foolbox.adversarial import Adversarial
from foolbox.attacks import SinglePixelAttack
from IPython.core.debugger import set_trace

#lab = Y[42][np.newaxis,:256,:256,np.newaxis]
inp = x_val[42]
lab = y_val[42]
print(lab.shape,inp.shape)
print("+"*50)

attack = SinglePixelAttack()
criterion = Missegmentation()
set_trace()
adversarial = Adversarial(fmodel, criterion, inp, lab)

fpred = attack(adversarial)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13894945490584737, 'fraction_numerical': 0.02616451932606541, 'mean_word_length': 4.753705815279361, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 12, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '322234', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1956, 'n_tokens_neox': 1851, 'n_words': 446, 'path': 'resources/stardist/2_training-other-segmentations.ipynb', 'repo_name': 'psteinb/adversarial-medical-imaging-imbdd', 'size': '5045'}