Kaggle competition: APTOS 2019 Blindness Detection
<SOS> metric: QuadraticWeightedKappa Kaggle data source: aptos-2019-blindness-detection<load_from_csv>
seed = 5
np.random.seed(seed)
 tf.set_random_seed(seed )
if os.path.exists(TEST_IMAGES_PATH):
TEST_DF = pd.read_csv(TEST_CSV_PATH)
 else:
TEST_DF = pd.read_csv(TRAIN_CSV_PATH)[:32]
TEST_DF['opt_angle'] = -1<load_pretrained>
print(os.listdir('.. /input'))
%matplotlib inline
IMG_SIZE=256
BATCH_SIZE = 16
def load_model_state(model, checkpoint_path):
device = torch.device('cpu')
 state_dict = torch.load(checkpoint_path, map_location=device)
 model.load_state_dict(non_parallel_state_dict(state_dict['model_state_dict']))
def non_parallel_state_dict(state_dict):
new_state_dict = OrderedDict()
for k, v in state_dict.items() :
k = k[k.startswith('module.')and len('module.'):]
new_state_dict[k] = v
return new_state_dict 
<normalization>

 MEAN_RGB = [0.485 * 255, 0.456 * 255, 0.406 * 255]
STDDEV_RGB = [0.229 * 255, 0.224 * 255, 0.225 * 255]
MAP_INTERPOLATION_TO_ORDER = {
"nearest": 0,
"bilinear": 1,
"biquadratic": 2,
"bicubic": 3,
}
def center_crop_and_resize(image, image_size, crop_padding=32, interpolation="bicubic"):
assert image.ndim in {2, 3}
assert interpolation in MAP_INTERPOLATION_TO_ORDER.keys()
h, w = image.shape[:2]
padded_center_crop_size = int(
(image_size /(image_size + crop_padding)) * min(h, w)
)
 offset_height =(( h - padded_center_crop_size)+ 1)// 2
offset_width =(( w - padded_center_crop_size)+ 1)// 2
image_crop = image[
offset_height : padded_center_crop_size + offset_height,
offset_width : padded_center_crop_size + offset_width,
]
resized_image = resize(
 image_crop, 
(image_size, image_size),
order=MAP_INTERPOLATION_TO_ORDER[interpolation],
preserve_range=True, 
)
 return resized_image
def preprocess_input(x):
assert x.ndim in(3, 4)
 assert x.shape[-1] == 3
x = x - np.array(MEAN_RGB)
 x = x / np.array(STDDEV_RGB)
 return x
class EfficientConv2DKernelInitializer(Initializer):

 def __call__(self, shape, dtype=K.floatx() , **kwargs):
kernel_height, kernel_width, _, out_filters = shape
fan_out = int(kernel_height * kernel_width * out_filters)
 return tf.random_normal(
 shape, mean=0.0, stddev=np.sqrt(2.0 / fan_out), dtype=dtype 
)
 class EfficientDenseKernelInitializer(Initializer):

 def __call__(self, shape, dtype=K.floatx() , **kwargs):

 init_range = 1.0 / np.sqrt(shape[1])
 return tf.random_uniform(shape, -init_range, init_range, dtype=dtype)
 conv_kernel_initializer = EfficientConv2DKernelInitializer()
dense_kernel_initializer = EfficientDenseKernelInitializer()
get_custom_objects().update(
 {
"EfficientDenseKernelInitializer": EfficientDenseKernelInitializer,
"EfficientConv2DKernelInitializer": EfficientConv2DKernelInitializer,
} 
)
 class Swish(KL.Layer):
def call(self, inputs):
return tf.nn.swish(inputs)
 class DropConnect(KL.Layer):
def __init__(self, drop_connect_rate=0.0, **kwargs):
super().__init__(**kwargs)
 self.drop_connect_rate = drop_connect_rate
def call(self, inputs, training=None):
def drop_connect() :
keep_prob = 1.0 - self.drop_connect_rate
batch_size = tf.shape(inputs)[0]
random_tensor = keep_prob
random_tensor += tf.random_uniform(
 [batch_size, 1, 1, 1], dtype=inputs.dtype 
)
 binary_tensor = tf.floor(random_tensor)
 output = tf.div(inputs, keep_prob)* binary_tensor
return output
return K.in_train_phase(drop_connect, inputs, training=training)
 def get_config(self):
config = super().get_config()
config["drop_connect_rate"] = self.drop_connect_rate
return config
get_custom_objects().update({"DropConnect": DropConnect, "Swish": Swish})
 IMAGENET_WEIGHTS = {
"efficientnet-b0": {
"name": "efficientnet-b0_imagenet_1000.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b0_imagenet_1000.h5",
"md5": "bca04d16b1b8a7c607b1152fe9261af7",
},
"efficientnet-b0-notop": {
"name": "efficientnet-b0_imagenet_1000_notop.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b0_imagenet_1000_notop.h5",
"md5": "45d2f3b6330c2401ef66da3961cad769",
},
"efficientnet-b1": {
"name": "efficientnet-b1_imagenet_1000.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b1_imagenet_1000.h5",
"md5": "bd4a2b82f6f6bada74fc754553c464fc",
},
"efficientnet-b1-notop": {
"name": "efficientnet-b1_imagenet_1000_notop.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b1_imagenet_1000_notop.h5",
"md5": "884aed586c2d8ca8dd15a605ec42f564",
},
"efficientnet-b2": {
"name": "efficientnet-b2_imagenet_1000.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b2_imagenet_1000.h5",
"md5": "45b28b26f15958bac270ab527a376999",
},
"efficientnet-b2-notop": {
"name": "efficientnet-b2_imagenet_1000_notop.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b2_imagenet_1000_notop.h5",
"md5": "42fb9f2d9243d461d62b4555d3a53b7b",
},
"efficientnet-b3": {
"name": "efficientnet-b3_imagenet_1000.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b3_imagenet_1000.h5",
"md5": "decd2c8a23971734f9d3f6b4053bf424",
},
"efficientnet-b3-notop": {
"name": "efficientnet-b3_imagenet_1000_notop.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b3_imagenet_1000_notop.h5",
"md5": "1f7d9a8c2469d2e3d3b97680d45df1e1",
},
"efficientnet-b4": {
"name": "efficientnet-b4_imagenet_1000.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b4_imagenet_1000.h5",
"md5": "01df77157a86609530aeb4f1f9527949",
},
"efficientnet-b4-notop": {
"name": "efficientnet-b4_imagenet_1000_notop.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b4_imagenet_1000_notop.h5",
"md5": "e7c3b780f050f8f49c800f23703f285c",
},
"efficientnet-b5": {
"name": "efficientnet-b5_imagenet_1000.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b5_imagenet_1000.h5",
"md5": "c31311a1a38b5111e14457145fccdf32",
},
"efficientnet-b5-notop": {
"name": "efficientnet-b5_imagenet_1000_notop.h5",
"url": "https://github.com/qubvel/efficientnet/releases/download/v0.0.1/efficientnet-b5_imagenet_1000_notop.h5",
"md5": "a09b36129b41196e0bb659fd84fbdd5f",
},
}
GlobalParams = collections.namedtuple(
 "GlobalParams",
[
"batch_norm_momentum",
"batch_norm_epsilon",
"dropout_rate",
"data_format",
"num_classes",
"width_coefficient",
"depth_coefficient",
"depth_divisor",
"min_depth",
"drop_connect_rate",
], 
)
 GlobalParams.__new__.__defaults__ =(None,)* len(GlobalParams._fields)
 BlockArgs = collections.namedtuple(
 "BlockArgs",
[
"kernel_size",
"num_repeat",
"input_filters",
"output_filters",
"expand_ratio",
"id_skip",
"strides",
"se_ratio",
], 
)
 BlockArgs.__new__.__defaults__ =(None,)* len(BlockArgs._fields)
 def efficientnet_params(model_name):

 params_dict = {
"efficientnet-b0":(1.0, 1.0, 224, 0.2),
"efficientnet-b1":(1.0, 1.1, 240, 0.2),
"efficientnet-b2":(1.1, 1.2, 260, 0.3),
"efficientnet-b3":(1.2, 1.4, 300, 0.3),
"efficientnet-b4":(1.4, 1.8, 380, 0.4),
"efficientnet-b5":(1.6, 2.2, 456, 0.4),
"efficientnet-b6":(1.8, 2.6, 528, 0.5),
"efficientnet-b7":(2.0, 3.1, 600, 0.5),
}
return params_dict[model_name]
class BlockDecoder(object):

 def _decode_block_string(self, block_string):

 assert isinstance(block_string, str)
 ops = block_string.split("_")
 options = {}
for op in ops:
splits = re.split(r"(\d.*)", op)
 if len(splits)>= 2:
key, value = splits[:2]
options[key] = value
if "s" not in options or len(options["s"])!= 2:
raise ValueError("Strides options should be a pair of integers.")
 return BlockArgs(
 kernel_size=int(options["k"]),
num_repeat=int(options["r"]),
input_filters=int(options["i"]),
output_filters=int(options["o"]),
expand_ratio=int(options["e"]),
id_skip=("noskip" not in block_string),
se_ratio=float(options["se"])if "se" in options else None,
strides=[int(options["s"][0]), int(options["s"][1])], 
)
 def _encode_block_string(self, block):

 args = [
"r%d" % block.num_repeat,
"k%d" % block.kernel_size,
"s%d%d" %(block.strides[0], block.strides[1]),
"e%s" % block.expand_ratio,
"i%d" % block.input_filters,
"o%d" % block.output_filters,
]
if block.se_ratio > 0 and block.se_ratio <= 1:
args.append("se%s" % block.se_ratio)
 if block.id_skip is False:
args.append("noskip")
 return "_".join(args)
 def decode(self, string_list):

 assert isinstance(string_list, list)
 blocks_args = []
for block_string in string_list:
blocks_args.append(self._decode_block_string(block_string))
return blocks_args
def encode(self, blocks_args):

 block_strings = []
for block in blocks_args:
block_strings.append(self._encode_block_string(block))
return block_strings
def efficientnet(
 width_coefficient=None,
depth_coefficient=None,
dropout_rate=0.2,
drop_connect_rate=0.2, 
):

 blocks_args = [
"r1_k3_s11_e1_i32_o16_se0.25",
"r2_k3_s22_e6_i16_o24_se0.25",
"r2_k5_s22_e6_i24_o40_se0.25",
"r3_k3_s22_e6_i40_o80_se0.25",
"r3_k5_s11_e6_i80_o112_se0.25",
"r4_k5_s22_e6_i112_o192_se0.25",
"r1_k3_s11_e6_i192_o320_se0.25",
]
global_params = GlobalParams(
 batch_norm_momentum=0.99,
batch_norm_epsilon=1e-3,
dropout_rate=dropout_rate,
drop_connect_rate=drop_connect_rate,
data_format="channels_last",
num_classes=1000,
width_coefficient=width_coefficient,
depth_coefficient=depth_coefficient,
depth_divisor=8,
min_depth=None, 
)
 decoder = BlockDecoder()
return decoder.decode(blocks_args), global_params
def get_model_params(model_name, override_params=None):

 if model_name.startswith("efficientnet"):
width_coefficient, depth_coefficient, input_shape, dropout_rate = efficientnet_params(
 model_name 
)
 blocks_args, global_params = efficientnet(
 width_coefficient, depth_coefficient, dropout_rate 
)
 else:
raise NotImplementedError("model name is not pre-defined: %s" % model_name)
 if override_params:
global_params = global_params._replace(**override_params)
 return blocks_args, global_params, input_shape
__all__ = [
"EfficientNet",
"EfficientNetB0",
"EfficientNetB1",
"EfficientNetB2",
"EfficientNetB3",
"EfficientNetB4",
"EfficientNetB5",
"EfficientNetB6",
"EfficientNetB7",
]
def round_filters(filters, global_params):

 orig_f = filters
multiplier = global_params.width_coefficient
divisor = global_params.depth_divisor
min_depth = global_params.min_depth
if not multiplier:
return filters
filters *= multiplier
min_depth = min_depth or divisor
new_filters = max(min_depth, int(filters + divisor / 2)// divisor * divisor)
 if new_filters < 0.9 * filters:
new_filters += divisor
return int(new_filters)
 def round_repeats(repeats, global_params):

 multiplier = global_params.depth_coefficient
if not multiplier:
return repeats
return int(math.ceil(multiplier * repeats))
def SEBlock(block_args, global_params):
num_reduced_filters = max(1, int(block_args.input_filters * block_args.se_ratio))
filters = block_args.input_filters * block_args.expand_ratio
if global_params.data_format == "channels_first":
channel_axis = 1
spatial_dims = [2, 3]
else:
channel_axis = -1
spatial_dims = [1, 2]
def block(inputs):
x = inputs
x = KL.Lambda(lambda a: K.mean(a, axis=spatial_dims, keepdims=True))(x)
 x = KL.Conv2D(
 num_reduced_filters,
kernel_size=[1, 1],
strides=[1, 1],
kernel_initializer=conv_kernel_initializer,
padding="same",
use_bias=True,
)(x)
 x = Swish()(x)
 x = KL.Conv2D(
 filters,
kernel_size=[1, 1],
strides=[1, 1],
kernel_initializer=conv_kernel_initializer,
padding="same",
use_bias=True,
)(x)
 x = KL.Activation("sigmoid" )(x)
 out = KL.Multiply()([x, inputs])
 return out
return block
def MBConvBlock(block_args, global_params, drop_connect_rate=None):
batch_norm_momentum = global_params.batch_norm_momentum
batch_norm_epsilon = global_params.batch_norm_epsilon
if global_params.data_format == "channels_first":
channel_axis = 1
spatial_dims = [2, 3]
else:
channel_axis = -1
spatial_dims = [1, 2]
has_se =(
(block_args.se_ratio is not None)
 and(block_args.se_ratio > 0)
 and(block_args.se_ratio <= 1)
)
 filters = block_args.input_filters * block_args.expand_ratio
kernel_size = block_args.kernel_size
def block(inputs):
if block_args.expand_ratio != 1:
x = KL.Conv2D(
 filters,
kernel_size=[1, 1],
strides=[1, 1],
kernel_initializer=conv_kernel_initializer,
padding="same",
use_bias=False,
)(inputs)
 x = KL.BatchNormalization(
 axis=channel_axis,
momentum=batch_norm_momentum,
epsilon=batch_norm_epsilon,
)(x)
 x = Swish()(x)
 else:
x = inputs
x = KL.DepthwiseConv2D(
 [kernel_size, kernel_size],
strides=block_args.strides,
depthwise_initializer=conv_kernel_initializer,
padding="same",
use_bias=False,
)(x)
 x = KL.BatchNormalization(
 axis=channel_axis, momentum=batch_norm_momentum, epsilon=batch_norm_epsilon
)(x)
 x = Swish()(x)
 if has_se:
x = SEBlock(block_args, global_params )(x)
 x = KL.Conv2D(
 block_args.output_filters,
kernel_size=[1, 1],
strides=[1, 1],
kernel_initializer=conv_kernel_initializer,
padding="same",
use_bias=False,
)(x)
 x = KL.BatchNormalization(
 axis=channel_axis, momentum=batch_norm_momentum, epsilon=batch_norm_epsilon
)(x)
 if block_args.id_skip:
if(
 all(s == 1 for s in block_args.strides)
 and block_args.input_filters == block_args.output_filters 
):
if drop_connect_rate:
x = DropConnect(drop_connect_rate )(x)
 x = KL.Add()([x, inputs])
 return x
return block
def EfficientNet(
 input_shape, block_args_list, global_params, input_tensor=None, include_top=True, pooling=None 
):
batch_norm_momentum = global_params.batch_norm_momentum
batch_norm_epsilon = global_params.batch_norm_epsilon
if global_params.data_format == "channels_first":
channel_axis = 1
else:
channel_axis = -1
if input_tensor is None:
inputs = KL.Input(shape=input_shape)
 else:
if not K.is_keras_tensor(input_tensor):
inputs = KL.Input(tensor=input_tensor, shape=input_shape)
 else:
inputs = input_tensor
x = inputs
x = KL.Conv2D(
 filters=round_filters(32, global_params),
kernel_size=[3, 3],
strides=[2, 2],
kernel_initializer=conv_kernel_initializer,
padding="same",
use_bias=False,
)(x)
 x = KL.BatchNormalization(
 axis=channel_axis, momentum=batch_norm_momentum, epsilon=batch_norm_epsilon
)(x)
 x = Swish()(x)
 block_idx = 1
n_blocks = sum([block_args.num_repeat for block_args in block_args_list])
 drop_rate = global_params.drop_connect_rate or 0
drop_rate_dx = drop_rate / n_blocks
for block_args in block_args_list:
assert block_args.num_repeat > 0
block_args = block_args._replace(
 input_filters=round_filters(block_args.input_filters, global_params),
output_filters=round_filters(block_args.output_filters, global_params),
num_repeat=round_repeats(block_args.num_repeat, global_params), 
)
 x = MBConvBlock(
 block_args, global_params, drop_connect_rate=drop_rate_dx * block_idx
)(x)
 block_idx += 1
if block_args.num_repeat > 1:
block_args = block_args._replace(
 input_filters=block_args.output_filters, strides=[1, 1] 
)
 for _ in xrange(block_args.num_repeat - 1):
x = MBConvBlock(
 block_args, global_params, drop_connect_rate=drop_rate_dx * block_idx
)(x)
 block_idx += 1
x = KL.Conv2D(
 filters=round_filters(1280, global_params),
kernel_size=[1, 1],
strides=[1, 1],
kernel_initializer=conv_kernel_initializer,
padding="same",
use_bias=False,
)(x)
 x = KL.BatchNormalization(
 axis=channel_axis, momentum=batch_norm_momentum, epsilon=batch_norm_epsilon
)(x)
 x = Swish()(x)
 if include_top:
x = KL.GlobalAveragePooling2D(data_format=global_params.data_format )(x)
 if global_params.dropout_rate > 0:
x = KL.Dropout(global_params.dropout_rate )(x)
 x = KL.Dense(
 global_params.num_classes, kernel_initializer=dense_kernel_initializer
)(x)
 x = KL.Activation("softmax" )(x)
 else:
if pooling == "avg":
x = KL.GlobalAveragePooling2D(data_format=global_params.data_format )(x)
 elif pooling == "max":
x = KL.GlobalMaxPooling2D(data_format=global_params.data_format )(x)
 outputs = x
model = KM.Model(inputs, outputs)
 return model
def _get_model_by_name(
 model_name,
input_shape=None,
input_tensor=None,
include_top=True,
weights=None,
classes=1000,
pooling=None 
):

 if weights not in {None, "imagenet"}:
raise ValueError('Parameter `weights` should be one of [None, "imagenet"]')
 if weights == "imagenet" and model_name not in IMAGENET_WEIGHTS:
raise ValueError(
 "There are not pretrained weights for {} model.".format(model_name)
)
 if weights == "imagenet" and include_top and classes != 1000:
raise ValueError(
 "If using `weights` and `include_top`" " `classes` should be 1000" 
)
 block_agrs_list, global_params, default_input_shape = get_model_params(
 model_name, override_params={"num_classes": classes} 
)
 if input_shape is None:
input_shape =(default_input_shape, default_input_shape, 3)
 model = EfficientNet(
 input_shape,
block_agrs_list,
global_params,
input_tensor=input_tensor,
include_top=include_top,
pooling=pooling, 
)
 model.name = model_name
if weights:
if not include_top:
weights_name = model_name + "-notop"
else:
weights_name = model_name
weights = IMAGENET_WEIGHTS[weights_name]
weights_path = get_file(
 weights["name"],
weights["url"],
cache_subdir="models",
md5_hash=weights["md5"], 
)
 model.load_weights(weights_path)
 return model
def EfficientNetB0(
 include_top=True, input_shape=None, input_tensor=None, weights=None, classes=1000, pooling=None 
):
return _get_model_by_name(
 "efficientnet-b0",
include_top=include_top,
input_shape=input_shape,
input_tensor=input_tensor,
weights=weights,
classes=classes,
pooling=pooling, 
)
 def EfficientNetB1(
 include_top=True, input_shape=None, input_tensor=None, weights=None, classes=1000, pooling=None 
):
return _get_model_by_name(
 "efficientnet-b1",
include_top=include_top,
input_shape=input_shape,
input_tensor=input_tensor,
weights=weights,
classes=classes,
pooling=pooling, 
)
 def EfficientNetB2(
 include_top=True, input_shape=None, input_tensor=None, weights=None, classes=1000, pooling=None 
):
return _get_model_by_name(
 "efficientnet-b2",
include_top=include_top,
input_shape=input_shape,
input_tensor=input_tensor,
weights=weights,
classes=classes,
pooling=pooling, 
)
 def EfficientNetB3(
 include_top=True, input_shape=None, input_tensor=None, weights=None, classes=1000, pooling=None 
):
return _get_model_by_name(
 "efficientnet-b3",
include_top=include_top,
input_shape=input_shape,
input_tensor=input_tensor,
weights=weights,
classes=classes,
pooling=pooling, 
)
 def EfficientNetB4(
 include_top=True, input_shape=None, input_tensor=None, weights=None, classes=1000, pooling=None 
):
return _get_model_by_name(
 "efficientnet-b4",
include_top=include_top,
input_shape=input_shape,
input_tensor=input_tensor,
weights=weights,
classes=classes,
pooling=pooling, 
)
 def EfficientNetB5(
 include_top=True, input_shape=None, input_tensor=None, weights=None, classes=1000, pooling=None 
):
return _get_model_by_name(
 "efficientnet-b5",
include_top=include_top,
input_shape=input_shape,
input_tensor=input_tensor,
weights=weights,
classes=classes,
pooling=pooling, 
)
 def EfficientNetB6(
 include_top=True, input_shape=None, input_tensor=None, weights=None, classes=1000, pooling=None 
):
return _get_model_by_name(
 "efficientnet-b6",
include_top=include_top,
input_shape=input_shape,
input_tensor=input_tensor,
weights=weights,
classes=classes,
pooling=pooling, 
)
 def EfficientNetB7(
 include_top=True, input_shape=None, input_tensor=None, weights=None, classes=1000, pooling=None 
):
return _get_model_by_name(
 "efficientnet-b7",
include_top=include_top,
input_shape=input_shape,
input_tensor=input_tensor,
weights=weights,
classes=classes,
pooling=pooling, 
)
 EfficientNetB0.__doc__ = _get_model_by_name.__doc__
EfficientNetB1.__doc__ = _get_model_by_name.__doc__
EfficientNetB2.__doc__ = _get_model_by_name.__doc__
EfficientNetB3.__doc__ = _get_model_by_name.__doc__
EfficientNetB4.__doc__ = _get_model_by_name.__doc__
EfficientNetB5.__doc__ = _get_model_by_name.__doc__
EfficientNetB6.__doc__ = _get_model_by_name.__doc__
EfficientNetB7.__doc__ = _get_model_by_name.__doc__
class L_Conv2d(nn.Conv2d):
def __init__(self, in_channels, out_channels, kernel_size, stride=1,
padding=0, dilation=1, groups=1, bias=True):
super(L_Conv2d, self ).__init__(in_channels, out_channels, kernel_size, stride,
padding, dilation, groups, bias)
 def forward(self, x):
weight = self.weight
weight_mean = weight.mean(dim=1, keepdim=True ).mean(dim=2,
keepdim=True ).mean(dim=3, keepdim=True)
 weight = weight - weight_mean
std = weight.view(weight.size(0), -1 ).std(dim=1 ).view(-1, 1, 1, 1)+ 1e-5
weight = weight / std.expand_as(weight)
 return F.conv2d(x, weight, self.bias, self.stride,
self.padding, self.dilation, self.groups)
 def L_BatchNorm2d(num_features):
return nn.GroupNorm(num_channels=num_features, num_groups=32 )<import_modules>
train_df = pd.read_csv('.. /input/aptos2019-blindness-detection/train.csv')
 test_df = pd.read_csv('.. /input/aptos2019-blindness-detection/test.csv' )
class Bottleneck(nn.Module):

 expansion = 4
def __init__(self, inplanes, planes, baseWidth, cardinality, stride=1, downsample=None):

 super(Bottleneck, self ).__init__()
D = int(math.floor(planes *(baseWidth / 64)))
 C = cardinality
self.conv1 = L_Conv2d(inplanes, D * C, kernel_size=1, stride=1, padding=0, bias=False)
 self.bn1 = L_BatchNorm2d(D * C)
 self.conv2 = L_Conv2d(D * C, D * C, kernel_size=3, stride=stride, padding=1, groups=C, bias=False)
 self.bn2 = L_BatchNorm2d(D * C)
 self.conv3 = L_Conv2d(D * C, planes * 4, kernel_size=1, stride=1, padding=0, bias=False)
 self.bn3 = L_BatchNorm2d(planes * 4)
 self.relu = nn.ReLU(inplace=True)
 self.downsample = downsample
def forward(self, x):
residual = x
out = self.conv1(x)
 out = self.bn1(out)
 out = self.relu(out)
 out = self.conv2(out)
 out = self.bn2(out)
 out = self.relu(out)
 out = self.conv3(out)
 out = self.bn3(out)
 if self.downsample is not None:
residual = self.downsample(x)
 out += residual
out = self.relu(out)
 return out
class ResNeXt(nn.Module):

 def __init__(self, baseWidth, cardinality, layers, num_classes):

 super(ResNeXt, self ).__init__()
block = Bottleneck
self.cardinality = cardinality
self.baseWidth = baseWidth
self.num_classes = num_classes
self.inplanes = 64
self.output_size = 64
self.conv1 = L_Conv2d(3, 64, 7, 2, 3, bias=False)
 self.bn1 = L_BatchNorm2d(64)
 self.relu = nn.ReLU(inplace=True)
 self.maxpool1 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
 self.layer1 = self._make_layer(block, 64, layers[0])
 self.layer2 = self._make_layer(block, 128, layers[1], 2)
 self.layer3 = self._make_layer(block, 256, layers[2], 2)
 self.layer4 = self._make_layer(block, 512, layers[3], 2)
 self.avgpool = nn.AdaptiveAvgPool2d(1)
 self.fc = nn.Linear(512 * block.expansion, num_classes)
 self.multiple_devices = False
for m in self.modules() :
if isinstance(m, nn.Conv2d):
n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
m.weight.data.normal_(0, math.sqrt(2./ n))
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1)
 m.bias.data.zero_()
def place_on_multiple_devices(self, device_0, device_1):
self.conv1.to(device_0)
 self.bn1.to(device_0)
 self.relu.to(device_0)
 self.maxpool1.to(device_0)
 self.layer1.to(device_0)
 self.layer2.to(device_1)
 self.layer3.to(device_1)
 self.layer4.to(device_1)
 self.avgpool.to(device_1)
 self.fc.to(device_1)
 self.multiple_devices = True
def load_pretrained_weights(self, state_dict):
state_dict.pop('fc.weight')
 state_dict.pop('fc.bias')
 res = self.load_state_dict(state_dict, strict=False)
 assert set(res.missing_keys)== set(['fc.weight', 'fc.bias']), 'issue loading pretrained weights'
print('Loaded pretrained weights for ResNeXt')
 def _make_layer(self, block, planes, blocks, stride=1):

 downsample = None
if stride != 1 or self.inplanes != planes * block.expansion:
downsample = nn.Sequential(
 L_Conv2d(self.inplanes, planes * block.expansion,
kernel_size=1, stride=stride, bias=False),
L_BatchNorm2d(planes * block.expansion), 
)
 layers = []
layers.append(block(self.inplanes, planes, self.baseWidth, self.cardinality, stride, downsample))
self.inplanes = planes * block.expansion
for i in range(1, blocks):
layers.append(block(self.inplanes, planes, self.baseWidth, self.cardinality))
return nn.Sequential(*layers)
 def forward(self, x):
x = self.conv1(x)
 x = self.bn1(x)
 x = self.relu(x)
 x = self.maxpool1(x)
 x = self.layer1(x)
 if self.multiple_devices:
x = x.to(next(self.layer2.parameters() ).device)
 x = self.layer2(x)
 x = self.layer3(x)
 x = self.layer4(x)
 x = self.avgpool(x)
 x = x.view(x.size(0), -1)
 x = self.fc(x)
 if self.multiple_devices:
x = x.to(next(self.conv1.parameters() ).device)
 return x
def l_resnext50(baseWidth=4, cardinality=32):

 model = ResNeXt(baseWidth, cardinality, [3, 4, 6, 3], 5)
 return model
def l_resnext101(baseWidth=4, cardinality=32):

 model = ResNeXt(baseWidth, cardinality, [3, 4, 23, 3], 5)
 return model 
<find_best_params>
train_df['diagnosis'].value_counts()
model = l_resnext50()<compute_test_metric>
N = train_df.shape[0]
x_train = np.empty(( N, IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8)
 for i, image_id in enumerate(tqdm(train_df['id_code'])) :
x_train[i, :, :, :] = preprocess_image(
 f'.. /input/aptos2019-blindness-detection/train_images/{image_id}.png'
)
def quadratic_weighted_kappa(y_pred, y_true):
max_rat = 5
y_true = np.asarray(y_true, dtype=int)
 y_pred = np.asarray(y_pred, dtype=int)
 hist1 = np.zeros(( max_rat + 1,))
hist2 = np.zeros(( max_rat + 1,))
o = 0
for k in range(len(y_true)) :
i, j = y_true[k], y_pred[k]
hist1[i] += 1
hist2[j] += 1
o +=(i - j)*(i - j)
 e = 0
for i in range(max_rat + 1):
for j in range(max_rat + 1):
e += hist1[i] * hist2[j] *(i - j)*(i - j)
 e = e / y_true.shape[0]
return 1 - o / e<normalization>
y_train = pd.get_dummies(train_df['diagnosis'] ).values
print(y_train.shape)
def rotate_bound(image, angle): 
(h, w)= image.shape[:2] 
(cX, cY)=(w / 2, h / 2)
 M = cv2.getRotationMatrix2D(( cX, cY), -angle, 1.0)
 cos = np.abs(M[0, 0])
 sin = np.abs(M[0, 1])
 nW = int(( h * sin)+(w * cos))
nH = int(( h * cos)+(w * sin))
M[0, 2] +=(nW / 2)- cX
M[1, 2] +=(nH / 2)- cY
try:
return cv2.warpAffine(image, M,(nW, nH), borderValue=(255, 255, 255))
except Exception:
return image
def find_best_rounding(image):
volume = image.shape[0] * image.shape[1]
opt_angle = 0
for angle in range(-45, 45, 10):
rot_image = rotate_bound(image, angle + 2)
 rot_image = cut_image(rot_image)
 rot_volume = rot_image.shape[0] * rot_image.shape[1]
if rot_volume < volume:
volume = rot_volume
opt_angle = angle
del rot_image
gc.collect()
return opt_angle
def get_corners(image):
image_mask =(( 255 - image ).sum(axis=-1)!= 0 ).astype(np.uint8)
 rows = np.any(image_mask, axis=1)
 cols = np.any(image_mask, axis=0)
 x_min, x_max = np.where(rows)[0][[0, -1]]
y_min, y_max = np.where(cols)[0][[0, -1]]
return x_min, x_max, y_min, y_max
def cut_image(image):
x_min, x_max, y_min, y_max = get_corners(image)
 image = image[x_min:x_max, y_min:y_max]
h, w, c = image.shape
if w > h:
image = np.transpose(image, [1, 0, 2])
 return image
def get_image_mask(image):
image_mask =(( 255 - image ).sum(axis=-1)!= 0 ).astype(np.uint8)
 return image_mask<categorify>
y_train_multi = np.empty(y_train.shape, dtype=y_train.dtype)
 y_train_multi[:, 4] = y_train[:, 4]
for i in range(3, -1, -1):
y_train_multi[:, i] = np.logical_or(y_train[:, i], y_train_multi[:, i+1])
 print("Original y_train:", y_train.sum(axis=0))
print("Multilabel version:", y_train_multi.sum(axis=0))
def extract_tiles_from_image(img, tile_size=256, n_tiles=36, mode=0):
h, w, c = img.shape
pad_h =(tile_size - h % tile_size)% tile_size +(( tile_size * mode)// 2)
 pad_w =(tile_size - w % tile_size)% tile_size +(( tile_size * mode)// 2)
 img2 = np.pad(img, [[pad_h // 2, pad_h - pad_h // 2], [pad_w // 2, pad_w - pad_w // 2], [0, 0]],
constant_values=255)
 img3 = img2.reshape(
 img2.shape[0] // tile_size,
tile_size,
img2.shape[1] // tile_size,
tile_size,
3 
)
 img3 = img3.transpose(0, 2, 1, 3, 4 ).reshape(-1, tile_size, tile_size, 3)
 n_relevant_tiles =(img3.reshape(img3.shape[0], -1 ).sum(1)< tile_size ** 2 * 3 * 255 ).sum()
idxs = np.argsort(img3.reshape(img3.shape[0], -1 ).sum(-1)) [:int(np.minimum(n_relevant_tiles, n_tiles)) ]
img3 = img3[idxs]
del img2
del img
gc.collect()
return img3
def get_tiles(image_folder, image_id, tile_size=256, n_tiles=49):
tiff_file = os.path.join(image_folder, f'{image_id}.tiff')
 image_base = skimage.io.MultiImage(tiff_file)
 image = image_base[1]
if TEST_DF[TEST_DF.image_id == image_id].opt_angle.iloc[0] == -1:
low_res_image = image_base[-1]
low_res_image = cv2.resize(low_res_image,(low_res_image.shape[1] // 8,
low_res_image.shape[0] // 8))
opt_angle = find_best_rounding(low_res_image)
 else:
opt_angle = TEST_DF[TEST_DF.image_id == image_id].opt_angle.iloc[0]
image = cut_image(image)
 image = rotate_bound(image, opt_angle)
 image = cut_image(image)
 tiles = extract_tiles_from_image(image, tile_size, n_tiles)
 del image
gc.collect()
return tiles
def assemble_image(image_tiles, image_processing_func, tile_processing_func, num_tiles, tile_size):
num_row_tiles = int(np.sqrt(num_tiles))
image_tiles = [tile_processing_func(image=tile)['image'] for tile in image_tiles]
image_tiles = np.array(image_tiles)
 if len(image_tiles)== 0:
image_tiles =(255 * np.ones(( 1, tile_size, tile_size, 3)) ).astype(np.int8)
 if len(image_tiles)< num_tiles:
image_tiles = np.pad(image_tiles,
[[0, num_tiles - len(image_tiles)], [0, 0], [0, 0], [0, 0]], constant_values=255)
 joined_image = np.zeros(( tile_size * num_row_tiles, tile_size * num_row_tiles, 3))
for h in range(num_row_tiles):
for w in range(num_row_tiles):
i = h * num_row_tiles + w
h1 = h * tile_size
w1 = w * tile_size
tile_in_place = image_tiles[i]
joined_image[h1:h1 + tile_size, w1:w1 + tile_size] = tile_in_place
del image_tiles
gc.collect()
return image_processing_func(image=joined_image.astype(np.uint8)) ['image']<normalization>
x_train, x_val, y_train, y_val = train_test_split(
 x_train, y_train_multi,
test_size=0.15,
random_state=2019
)
def identity_processing() :
def identity(image):
return {'image': image}
return identity
def simple_image_processing() :
transformations = albu.Compose([
albu.Transpose(p=0.5),
albu.VerticalFlip(p=0.5),
albu.HorizontalFlip(p=0.5),
])
 return albu.Compose(transformations)
 def spacial_image_processing() :
transformations = [albu.Flip() ,
albu.Transpose() ,
albu.ShiftScaleRotate(rotate_limit=360, shift_limit=0, scale_limit=0.125),
albu.GridDistortion() ]
return albu.Compose(transformations)
 def distributional_image_processing() :
transformations = [
albu.OneOf([albu.RandomSnow() ,
albu.RandomBrightnessContrast() ,
albu.CLAHE() ]),
albu.OneOf([albu.CoarseDropout(max_holes=36 * 16, fill_value=0, max_height=32, max_width=32),
albu.CoarseDropout(max_holes=36 * 8, fill_value=0, max_height=32, max_width=32),
albu.GridDropout() ])
 ]
return albu.Compose(transformations)
 def scaling_image_processing() :
return albu.Normalize(mean=[0.90949707, 0.8188697, 0.87795304],
std=[0.36357649, 0.49984502, 0.40477625] )<import_modules>
x_val=x_val/255
class PandaDataset(Dataset):
def __init__(self, images_df, num_tta,
tile_augmentation=None,
image_augmentation=None,
num_tiles=49,
tile_size=256):
super().__init__()
self.images_df = images_df
self.tile_augmentation = identity_processing() if tile_augmentation is None else tile_augmentation
self.image_augmentation = identity_processing() if image_augmentation is None else image_augmentation
self.image_scaling = scaling_image_processing()
self.num_tiles = num_tiles
self.tile_size = tile_size
self.num_tta = num_tta
def __getitem__(self, item):
df_item = self.images_df.iloc[item]
image = self._get_image(df_item.image_id)
 image = np.transpose(image, [0, 3, 1, 2])
 return torch.tensor(image)
 def __len__(self):
return len(self.images_df)
 def _get_image(self, image_id):
if os.path.exists(TEST_IMAGES_PATH):
images_folder = TEST_IMAGES_PATH
else:
images_folder = TRAIN_IMAGES_PATH
image_tile_list = get_tiles(images_folder, image_id)
 images = []
for j in range(self.num_tta):
image = assemble_image(image_tile_list, self.image_augmentation, self.tile_augmentation,
num_tiles=self.num_tiles, tile_size=self.tile_size)
 image = self.image_scaling(image=image)['image']
images.append(image)
 return np.array(images )<predict_on_test>
train_df['diagnosis']=train_df['diagnosis'].astype(str )
def get_preds(loader, model, device):
model.eval()
y_pred = []
for image_tta_batch in tqdm(loader, total=len(loader)) :
image_tta_batch = torch.transpose(image_tta_batch, 0, 1)
 tta_preds = []
for image in image_tta_batch:
image = image.to(device)
 with torch.no_grad() :
predictions = model(image ).sigmoid().detach().cpu().numpy()
del image
gc.collect()
isup_pred = predictions.sum(axis=1)
 tta_preds.append(isup_pred)
 tta_preds = np.array(tta_preds)
 isup_pred = tta_preds.mean(axis=0)
 y_pred.extend(isup_pred)
 return np.array(y_pred )<load_from_csv>
datagen = ImageDataGenerator(
 zoom_range=0.6,
fill_mode='constant',
cval=0.,
horizontal_flip=True,
vertical_flip=True,
rotation_range=360,
width_shift_range=0.1,
height_shift_range=0.1,
rescale=1./255
)
gc.collect()
sub_df = pd.read_csv(SAMPLE_CSV_PATH)
 device = torch.device('cuda')
 model.to(device)
 num_folds = 5
if os.path.exists(TEST_IMAGES_PATH):
num_tta = 1
test_dataset = PandaDataset(images_df=TEST_DF, num_tta=num_tta,
tile_augmentation=simple_image_processing())
 test_loader = DataLoader(dataset=test_dataset, batch_size=5,
sampler=SequentialSampler(test_dataset), num_workers=2)
 y_pred_per_fold = []
for fold in range(num_folds):
load_model_state(model, MODEL_WEIGHTS_PATH.format(fold=fold))
y_pred = get_preds(test_loader, model, device)
 y_pred_per_fold.append(y_pred)
 y_pred = np.mean(y_pred_per_fold, axis=0)
 rounder = OptimizedRounder()
y_pred = rounder.predict(y_pred, coefficients=[0.5, 1.5, 2.5, 3.5, 4.5])
 sub_df = pd.DataFrame({'image_id': TEST_DF.image_id,
'isup_grade': y_pred})
 else:
num_tta = 1
y_pred_per_fold = []
for fold in range(num_folds):
test_dataset = PandaDataset(images_df=TEST_DF, num_tta=num_tta,
tile_augmentation=simple_image_processing())
 test_loader = DataLoader(dataset=test_dataset, batch_size=5,
sampler=SequentialSampler(test_dataset), num_workers=2)
 load_model_state(model, MODEL_WEIGHTS_PATH.format(fold=fold))
y_pred = get_preds(test_loader, model, device)
 y_pred_per_fold.append(y_pred)
 del test_dataset
del test_loader
gc.collect()
y_pred = np.mean(y_pred_per_fold, axis=0)
 rounder = OptimizedRounder()
y_pred = rounder.predict(y_pred, coefficients=[0.5, 1.5, 2.5, 3.5, 4.5])
 sub_df = pd.DataFrame({'image_id': TEST_DF.image_id,
'isup_grade': y_pred})
<save_to_csv>
data_generator = datagen.flow(x_train, y_train, batch_size=BATCH_SIZE, seed=2019 )
sub_df.to_csv('submission.csv', index=False )<install_modules>
true_labels = np.array([1, 0, 1, 1, 0, 1])
 pred_labels = np.array([1, 0, 0, 0, 0, 1] )
!pip install /kaggle/input/resnest/resnest-0.0.4b20200606-py3-none-any.whl<install_modules>
accuracy_score(true_labels, pred_labels )
!pip install /kaggle/input/maskslic/maskslic-0.3.3<define_variables>
cohen_kappa_score(true_labels, pred_labels )
DATA = '.. /input/prostate-cancer-grade-assessment/test_images'
TEST = '.. /input/prostate-cancer-grade-assessment/test.csv'
SAMPLE = '.. /input/prostate-cancer-grade-assessment/sample_submission.csv'
bs = 2
nworkers = 2
coef = [0.5, 1.5, 2.5, 3.5, 4.5]<define_search_space>
class Metrics(Callback):
def on_train_begin(self, logs={}):
self.val_kappas = []
def on_epoch_end(self, epoch, logs={}):
X_val, y_val = self.validation_data[:2]
y_val = y_val.sum(axis=1)- 1
y_pred = self.model.predict(X_val)> 0.5
y_pred = y_pred.astype(int ).sum(axis=1)- 1
_val_kappa = cohen_kappa_score(
 y_val,
y_pred,
weights='quadratic' 
)
 self.val_kappas.append(_val_kappa)
 print(f"val_kappa: {_val_kappa:.4f}")
 if _val_kappa == max(self.val_kappas):
print("Validation Kappa has improved.Saving model.")
 model.save_weights('model.h5')
 model_json = model.to_json()
with open('model.json', "w")as json_file:
json_file.write(model_json)
 json_file.close()
return
model_dirs = ['.. /input/jj20200629', '.. /input/jj20200701/', '.. /input/jj20200703/', '.. /input/jj20200706']
model_weights = np.array([3,4,2,1])
 use_models = [[True,True,False,False], [True,True,False,False], [True,True,False,False], [True,False,False,False]]
tile_size = [384,256,256,299]
level=[1,1,1,1]
mosaic_grid = [(4,6),(6,6),(6,6),(5,5)]
tissue_th =(0.2,0.7)
 seed = 123
sampling_method=['skeleton','skeleton','skeleton','skeleton']<load_pretrained>
efficient = EfficientNetB5(
 weights=None,
include_top=False,
input_shape=(IMG_SIZE,IMG_SIZE,3)
 )
config = [ModelConfig.fromDir(model_dir)for model_dir in model_dirs]
models = [load_models_from_dir(model_dir, tile_list_input=False)for model_dir in model_dirs]
cms = [[np.load(os.path.join(model_dir, f'cm_fold-{i}.npy')) for i in range(len(models[0])) ] for model_dir in model_dirs]
models = [[model for model, use_model in zip(_models,_use_models)if use_model] for _models,_use_models in zip(models,use_models)]
cms = [[cm for cm, use_model in zip(_cms,_use_models)if use_model] for _cms,_use_models in zip(cms,use_models)]
sz = [_config.getField('sz')for _config in config]
N = [_config.getField('N')for _config in config]
is_ordinal = [_config.getMetaField('is_ordinal')==True for _config in config]
model_name = [_config.getField('model_name')for _config in config]
regr = ["regr" in _model_name for _model_name in model_name]
mean = [torch.tensor(np.array(_config.getField('mean')).astype(np.float32)) for _config in config]
std = [torch.tensor(np.array(_config.getField('std')).astype(np.float32)) for _config in config]
for i, _models in enumerate(models):
print("Loaded {0} {1} models".format(len(_models), model_name[i]))
print(f'Mean {mean[i]} and std {std[i]}')
 print(f'regression = {regr[i]}')
 print(f'ordinal regression = {is_ordinal[i]}' )<import_modules>
efficient.load_weights('.. /input/efficientnet-keras-weights-b0b5/efficientnet-b5_imagenet_1000_notop.h5' )
VALID_SLIDE_EXTENSIONS = {'.tiff', '.mrmx', '.svs'}
def generateMetaDF(data_dir, meta_fn:str='train.csv'):

 all_files = [path.resolve() for path in Path(data_dir ).rglob("*.*")]
slide_paths = [path for path in all_files if path.suffix in VALID_SLIDE_EXTENSIONS]
if len(slide_paths)==0:
raise ValueError('No slides in `data_dir`=%s'%data_dir)
 data_df = pd.DataFrame({'slide_path':slide_paths})
 data_df['image_id'] = data_df.slide_path.apply(lambda x: x.stem)
 slides = data_df[~data_df.image_id.str.contains("mask")]
masks = data_df[data_df.image_id.str.contains("mask")]
masks['image_id'] = masks.image_id.str.replace("_mask", "")
 masks.columns = ['mask_path', 'image_id']
data_df = slides.merge(masks, on='image_id', how='left')
 data_df['slide_path'] = data_df.slide_path.apply(lambda x: str(x)if not pd.isna(x)else None)
 data_df['mask_path'] = data_df.mask_path.apply(lambda x: str(x)if not pd.isna(x)else None)
 meta_csv = [file for file in all_files if file.name==meta_fn]
if meta_csv:
meta_df = pd.read_csv(str(meta_csv[0]))
data_df = data_df.merge(meta_df, on='image_id')
 return data_df
def tileClassification(tile, provider:str):

 if provider == "karolinska":

 classes = {0:0, 1:1, 2:2}
elif provider == "radboud":

 classes = {0:0, 1:1, 2:1, 3:2, 4:2, 5:2}
tile = np.int32(tile)
 counts = np.bincount(tile.reshape(-1,1)[:,0])
 if len(counts)==1:
return 0
max_annotation = np.argmax(counts[1:])
 return classes[max_annotation+1]
def getTopLeftCorners(dims, tile_size:int):

 cols, rows = np.ceil(dims/tile_size ).astype(int)
 top_left_corners = []
for i in range(cols):
for j in range(rows):
top_left_corners.append(( i*tile_size, j*tile_size))
return np.array(top_left_corners)
 def makeTissueMask(img):

 hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
 lower_red = np.array([120,20,180])
 upper_red = np.array([190,220,255])
 tissue_mask = cv2.inRange(hsv, lower_red, upper_red)
 tissue_mask = cv2.dilate(tissue_mask, None, iterations=2)
 tissue_mask = cv2.morphologyEx(tissue_mask, cv2.MORPH_CLOSE, None)
 tissue_mask = cv2.medianBlur(tissue_mask, 21)
 return tissue_mask
def fillTissueMask(tissue_mask):

 new_tm = tissue_mask.copy()
contours,_ = cv2.findContours(new_tm,0,cv2.CHAIN_APPROX_SIMPLE)
 cv2.drawContours(new_tm,contours,-1,255,-1)
 return new_tm
def estimateWithCircles(arch, radius:int=64):
arch = arch.squeeze()
circle_centers=[arch[0]]
for point in arch:
if np.all(np.linalg.norm(point-np.array(circle_centers),axis=-1)>radius):
circle_centers.append(point)
 return np.array(circle_centers)
 def getTissuePercentages(tissue_mask, level_offset:int, tile_size:int, top_left_corners):

 ds_rate = 4**level_offset
tissue_pcts = np.array([tissue_mask[j//ds_rate:(j+tile_size)//ds_rate,
i//ds_rate:(i+tile_size)//ds_rate].sum()
for(i,j)in top_left_corners])/(255*(tile_size/ds_rate)**2)
 return tissue_pcts
def padIfNeeded(img, tgt_width:int=128, tgt_height:int=128, border_color:int=255):

 h,w = img.shape[0:2]
if w<tgt_width or h<tgt_height:
padded = np.ones(( tgt_height,tgt_width,3), dtype='uint8')*border_color
padded[:h,:w] = img
return padded
return img
def distributeIntToChunks(available:int, weights):

 distributed_amounts = []
total_weights = sum(weights)
 for weight in weights:
weight = float(weight)
 p = weight / total_weights
distributed_amount = round(p * available)
 distributed_amounts.append(distributed_amount)
 total_weights -= weight
available -= distributed_amount
return np.int32(distributed_amounts)
 class Slide:
def __init__(self,slide_fn, level=2, tile_size=128, mask_fn=None, data_provider=None):
self.slide_fn = slide_fn
self.level = level
self.tile_size = tile_size
self.img = MultiImage(self.slide_fn)[self.level].copy()
self.dims = np.array(self.img.shape[:2][::-1])
 self.ds_img = MultiImage(self.slide_fn)[2].copy()
self.tissue_mask = makeTissueMask(self.ds_img)
 self.mask_fn = mask_fn
self.data_provider = data_provider
if not(self.mask_fn==None or self.data_provider==None):
self.mask = MultiImage(mask_fn)[level].sum(axis=-1)
 self.tile_coords = None
def getTileCoords(self, num_tiles:int, sampling_method='skeleton', tissue_th:tuple=(0.2, 0.7), seed=None,):

 assert sampling_method in {'skeleton', 'tissue_pct', 'slic'}
"`sampling_method` should be one of 'skeleton', 'tissue_pct' or 'slic'"
level_offset = 2 - self.level
if sampling_method == 'skeleton':
filled_tissue_mask = fillTissueMask(self.tissue_mask.copy())
 filled_tissue_mask = filled_tissue_mask // 255
skeleton = skeletonize(filled_tissue_mask, method='lee')
 self.skeleton = np.uint8(np.where(skeleton != 0, 255, 0))
skeleton = cv2.dilate(self.skeleton, None)
 contours, _ = cv2.findContours(skeleton, 0, cv2.CHAIN_APPROX_NONE)
 arch_lens = []
valid_indices = []
radius=int(self.tile_size /(4 ** level_offset))
for idx, arch in enumerate(contours):
c = cv2.arcLength(arch, False)
 c = c / 2
if c < radius / 3:
continue
valid_indices.append(idx)
 arch_lens.append(c)
 if not np.array(valid_indices ).size == 0:
contours = np.array(contours)[valid_indices]
weights = np.array(arch_lens)/ np.sum(arch_lens)
 points_per_arch = distributeIntToChunks(num_tiles, weights)
 for idx, arch in enumerate(contours):
num_indices = points_per_arch[idx]
output = np.zeros_like(skeleton)
 cv2.drawContours(output, [arch], -1, 1, 1)
 y_, x_ = np.where(output)
 arch = np.dstack([x_, y_])
 cps = estimateWithCircles(arch, radius)
 cx, cy = cps[..., 0], cps[..., 1]
if len(cx)> num_indices:
if not seed == None:
np.random.seed(seed)
 indices = sorted(np.random.choice(len(cx), points_per_arch[idx], replace=False))
np.random.seed(None)
 cx, cy = cx[indices], cy[indices]
if idx == 0:
intermediate_coords = np.dstack([cx, cy])
 else:
intermediate_coords = np.hstack([intermediate_coords, np.dstack([cx, cy])])
 final_coords = intermediate_coords.squeeze() *4**level_offset
final_coords = final_coords - np.array([self.tile_size//2,self.tile_size//2])
 self.tile_coords = final_coords.copy()
elif sampling_method == 'tissue_pct':
self.top_left_corners = getTopLeftCorners(self.dims, self.tile_size)
 self.tissue_pcts = getTissuePercentages(self.tissue_mask, level_offset=level_offset,
tile_size=self.tile_size,
top_left_corners=self.top_left_corners)
 tth_min, tth = tissue_th
while len(np.where(self.tissue_pcts > tth)[0])< num_tiles:
if tth <= tth_min:
break
tth -= 0.05
indices = np.where(self.tissue_pcts > tth)[0]
if len(indices)>num_tiles:
if not seed == None:
np.random.seed(seed)
 indices = sorted(np.random.choice(indices, num_tiles, replace=False))
np.random.seed(None)
 self.tile_coords = self.top_left_corners[indices].copy()
elif sampling_method == 'slic':
filled_tissue_mask = fillTissueMask(self.tissue_mask.copy())
 filled_tissue_mask = filled_tissue_mask // 255
segments = seg.slic(self.ds_img, compactness=10, seed_type='nplace', mask=filled_tissue_mask, n_segments=num_tiles,
multichannel=True, recompute_seeds=True, enforce_connectivity=True)
 indices = [k for k in np.unique(segments)if not k==-1]
if len(indices)>num_tiles:
if not seed == None:
np.random.seed(seed)
 indices = sorted(np.random.choice(indices, num_tiles, replace=False))
np.random.seed(None)
 for i in indices:
contours, _ = cv2.findContours(np.uint8(np.where(segments==i, 255, 0)) , 0, 1)
 contours = sorted(contours, key=lambda x: cv2.contourArea(x)) [::-1]
M = cv2.moments(contours[0])
 cx = np.int32(M['m10'] / M['m00'])
 cy = np.int32(M['m01'] / M['m00'])
 if i==0:
intermediate_coords = np.dstack([cx, cy])
 else:
intermediate_coords = np.hstack([intermediate_coords, np.dstack([cx, cy])])
 if len(indices)<num_tiles:
enough_tiles = False
for i in indices:
contours, _ = cv2.findContours(np.uint8(np.where(segments==i, 255, 0)) , 0, 1)
 contours = sorted(contours, key=lambda x: cv2.contourArea(x)) [::-1]
for j, cnt in enumerate(contours):
if j!=0 and cv2.contourArea(cnt)>(0.05 * self.tile_size /(4**level_offset)) **2:
M = cv2.moments(cnt)
 cx = np.int32(M['m10'] / M['m00'])
 cy = np.int32(M['m01'] / M['m00'])
 intermediate_coords = np.hstack([intermediate_coords, np.dstack([cx, cy])])
 if intermediate_coords.shape[1] == 12:
enough_tiles = True
break
if enough_tiles:
break
final_coords = intermediate_coords.squeeze() * 4 ** level_offset
final_coords = final_coords - np.array([self.tile_size // 2, self.tile_size // 2])
 self.tile_coords = final_coords.copy()
def getTiles(self, stack:bool=False, sampling_method:str='skeleton', mosaic_grid:tuple=(4,3), output_tile_size:int=128, tissue_th:tuple=(0.1, 0.7), seed:int=None):

 m, n = mosaic_grid
self.getTileCoords(num_tiles=n*m, sampling_method=sampling_method, tissue_th=tissue_th, seed=seed)
 output_img = np.ones([n * m, output_tile_size, output_tile_size, 3], dtype='uint8')* 255
for idx, coord in enumerate(self.tile_coords):
x, y = coord
left, right = np.int32(np.clip([x, x + self.tile_size], 0, self.dims[0]))
bottom, top = np.int32(np.clip([y, y + self.tile_size], 0, self.dims[1]))
tile = self.img[bottom:top, left:right].copy()
tile = padIfNeeded(tile, tgt_width=self.tile_size, tgt_height=self.tile_size)
 tile = cv2.resize(tile,(output_tile_size,)* 2)
 output_img[idx] = np.uint8(tile)
 if len(self.tile_coords)<m*n:
warnings.warn("Could not find enough unique tiles for the slide"
"(tiles: %s/%s, slide: %s" %(len(self.tile_coords), m*n, self.slide_fn))
if stack:
output_img = [np.hstack([output_img[i * n + j] for j in range(n)])for i in range(m)]
output_img = np.vstack(output_img)
 return np.array(output_img)
 def getTilesCancerStatus(self, stack:bool=False, mosaic_grid:tuple=(4,3)) :

 m, n = mosaic_grid
output_img = np.zeros([n * m], dtype='uint8')
 for idx, coord in enumerate(self.tile_coords):
x, y = coord
left, right = np.int32(np.clip([x, x + self.tile_size], 0, self.dims[0]))
bottom, top = np.int32(np.clip([y, y + self.tile_size], 0, self.dims[1]))
tile = self.mask[bottom:top, left:right].copy()
tile_cat = tileClassification(tile, self.data_provider)
 output_img[idx] = tile_cat
if stack:
output_img = [np.hstack([output_img[i * n + j] for j in range(n)])for i in range(m)]
output_img = np.vstack(output_img)
 return np.array(output_img)
 def visualizeCoverage(self, figsize=(16,16)) :

 background = self.ds_img.copy()
foreground = background.copy()
level_offset = 2-self.level
for coord in self.tile_coords:
x, y = coord
left, right = np.int32(np.clip([x, x + self.tile_size], 0, self.dims[0])/(4**level_offset))
bottom, top = np.int32(np.clip([y, y + self.tile_size], 0, self.dims[1])/(4**level_offset))
foreground[bottom:top, left:right] =(0, 255, 0)
 output = cv2.addWeighted(background, 0.7, foreground, 0.3, 0)
 plt.figure(figsize=figsize)
 plt.imshow(output)
 plt.show()<load_from_csv>
def build_model() :
model = Sequential()
model.add(efficient)
 model.add(layers.GlobalAveragePooling2D())
 model.add(layers.Dropout(0.5))
model.add(layers.Dense(5, activation='sigmoid'))
model.compile(
 loss='binary_crossentropy',
optimizer=Adam(lr=0.00005),
metrics=['accuracy'] 
)
 return model
class PandaDataset(Dataset):
def __init__(self, path, test, level,
tile_size, sz, mosaic_grid,
mean,std,
tissue_th=(0.2,0.7), sampling_method='skeleton', seed=123):
self.path = path
self.names = list(pd.read_csv(test ).image_id)
 self.level = level
self.sz = sz
self.tile_size = tile_size
self.mosaic_grid = mosaic_grid
self.mean = mean
self.std = std
self.tissue_th = tissue_th
self.sampling_method = sampling_method
self.seed = seed
self.N = mosaic_grid[0]*mosaic_grid[1]
def __len__(self):
return len(self.names)
 def __getitem__(self, idx):
name = self.names[idx]
fn = os.path.join(self.path,name+'.tiff')
 try:
slide = Slide(fn, level=self.level, tile_size=self.tile_size)
 tiles = slide.getTiles(mosaic_grid=self.mosaic_grid,
stack=False,
sampling_method=self.sampling_method,
output_tile_size=self.sz,
tissue_th=self.tissue_th, seed=self.seed)
 except Exception as e:
print("Error in tile generation: %s" %e)
 tiles = np.zeros(( self.N,self.sz,self.sz,3)).astype(np.float32)
 tiles = tiles.reshape(-1,self.sz,self.sz,3)
 tiles = torch.Tensor(1.0 - tiles/255.0)
 tiles =(tiles - self.mean)/self.std
return tiles.permute(0,3,1,2), name<define_variables>
kappa_metrics = Metrics()
est=EarlyStopping(monitor='val_loss',patience=5, min_delta=0.005)
 call_backs=[est,kappa_metrics]
history = model.fit_generator(
 data_generator,
steps_per_epoch=x_train.shape[0] / BATCH_SIZE,
validation_data=(x_val,y_val),
epochs=20,
callbacks=call_backs )
TRAIN_DATA = '.. /input/prostate-cancer-grade-assessment/train_images/'
TRAIN = '.. /input/prostate-cancer-grade-assessment/train.csv'
dls = []
def to_one(data, sz, mean, std, N):
img = torch.stack(data,1)
 img = img.view(3,-1,N,sz,sz ).permute(0,1,3,2,4 ).contiguous().view(3,-1,sz*N)
 img = 1.0 -(mean[...,None,None]+img*std[...,None,None])
 return Image(img)
 if os.path.exists(TRAIN_DATA):
for i, _ in enumerate(models):
ds = PandaDataset(
 TRAIN_DATA,
TRAIN,
level=level[i],
tile_size=tile_size[i],
sz=sz[i],
mosaic_grid=mosaic_grid[i],
mean=mean[i],
std=std[i],
tissue_th=tissue_th,
sampling_method=sampling_method[i],
seed=seed 
)
 dl = DataLoader(ds, batch_size=bs, num_workers=nworkers, shuffle=False)
 dls.append(dl)
 train_df = pd.read_csv(TRAIN ).set_index('image_id')
 for(x,y)in dl:
break
for img in x:
display(to_one(list(img), sz[i], mean[i], std[i], N[i]))<feature_engineering>
model.load_weights('model.h5')
 test_pred=[]
for i,img_code in enumerate(tqdm(test_df['id_code'])) :
img=preprocess_image(f'.. /input/aptos2019-blindness-detection/test_images/{img_code}.png')
 pred=model.predict(img[np.newaxis]/255)>0.5
pred=pred.astype(int ).sum(axis=1)- 1
test_pred.append(pred)
<statistical_test><EOS> 
test_pred=np.concatenate(test_pred,axis=0)
 test_pred=pd.Series(test_pred)
 test_df['diagnosis'] = test_pred
test_df.to_csv('submission.csv',index=False)
 print(test_df.head() )