Kaggle competition: TGS Salt Identification Challenge
<SOS> metric: IntersectionOverUnionObjectSegmentation Kaggle data source: tgs-salt-identification-challenge<choose_model_class>
plt.style.use('seaborn-white')
 sns.set_style("white")
model.compile(optimizer=optimizers.Nadam(learning_rate=0.00006), loss='categorical_crossentropy', metrics=['accuracy'] )<train_model>
t_start = time.time()
version = 11
basic_name = f'Unet_resnet_version_{version}'
save_model_name = basic_name + '.model'
submission_file = basic_name + '.csv'
print(save_model_name)
 print(submission_file )
result = model.fit(datagen.flow(x_train, y_train, batch_size=batch_size), epochs=75,
initial_epoch=50, validation_data=(x_valid, y_valid),verbose=1 )<set_options>
img_size_ori = 101
img_size_target = 101
epochs = 75
batch_size = 32
def upsample(img):
if img_size_ori == img_size_target:
return img
return resize(img,(img_size_target, img_size_target), mode='constant', preserve_range=True)
 def downsample(img):
if img_size_ori == img_size_target:
return img
return resize(img,(img_size_ori, img_size_ori), mode='constant', preserve_range=True)
gc.collect()<train_model>
train_df = pd.read_csv(".. /input/tgs-salt-identification-challenge/train.csv", index_col="id", usecols=[0])
 depths_df = pd.read_csv(".. /input/tgs-salt-identification-challenge/depths.csv", index_col="id")
 train_df = train_df.join(depths_df)
 test_df = depths_df[~depths_df.index.isin(train_df.index)]
path = '.. /input/plant-seedlings-classification/test/*.png'
files = glob(path)
 testImg = []
testId = []
j = 1
num = len(files)
 for img in files:
print("Obtain images: " + str(j)+ "/" + str(num), end='\r')
 testId.append(img.split('/')[-1])
 testImg.append(cv2.resize(cv2.imread(img),(dim, dim)))
 j += 1
testImg = np.asarray(testImg )<drop_column>
train_df["images"] = [np.array(load_img(".. /input/tgs-salt-identification-challenge/train/images/{}.png".format(idx), grayscale=True)) / 255 for idx in tqdm_notebook(train_df.index)]
clearTestImg = preProcessImage(testImg,getEx=True )<categorify>
train_df["masks"] = [np.array(load_img(".. /input/tgs-salt-identification-challenge/train/masks/{}.png".format(idx), grayscale=True)) / 255 for idx in tqdm_notebook(train_df.index)]
clearTestImg = clearTestImg / 255<predict_on_test>
train_df["coverage"] = train_df.masks.map(np.sum)/ pow(img_size_ori, 2 )
pred = model.predict(clearTestImg )<save_to_csv>
def cov_to_class(val):
for i in range(0, 11):
if val * 10 <= i :
return i
train_df["coverage_class"] = train_df.coverage.map(cov_to_class )
predNum = np.argmax(pred, axis=1)
 predStr = []
for i in range(len(predNum)) :
predStr.append(enc.categories_[0][predNum[i]])
 res = {'file': testId, 'species': predStr}
res = pd.DataFrame(res)
 res.to_csv("submission.csv", index=False )<save_model>
ids_train, ids_valid, x_train, x_valid, y_train, y_valid, cov_train, cov_test, depth_train, depth_test = train_test_split(
 train_df.index.values,
np.array(train_df.images.map(upsample ).tolist() ).reshape(-1,img_size_target, img_size_target, 1),
np.array(train_df.masks.map(upsample ).tolist() ).reshape(-1, img_size_target, img_size_target, 1),
train_df.coverage.values,
train_df.z.values,
test_size = 0.05 , stratify=train_df.coverage_class, random_state=42 )
model.save("saved_model" )<set_options>
def BatchActivate(x):
x = BatchNormalization()(x)
 x = Activation('relu' )(x)
 return x
def convolution_block(x, filters, size, strides=(1,1), padding='same', activation=True):
x = Conv2D(filters, size, strides=strides, padding=padding )(x)
 if activation == True:
x = BatchActivate(x)
 return x
def residual_block(blockInput, num_filters=16, batch_activate = False):
x = BatchActivate(blockInput)
 x = convolution_block(x, num_filters,(3,3))
x = convolution_block(x, num_filters,(3,3), activation=False)
 x = Add()([x, blockInput])
 if batch_activate:
x = BatchActivate(x)
 return x
%reload_ext autoreload
%autoreload 2
%matplotlib inline<import_modules>
size =(3, 3)
 def build_model(input_layer, start_neurons, DropoutRatio = 0.5):
conv1 = Conv2D(start_neurons * 1, size, activation="relu", padding="same" )(input_layer)
 conv1 = residual_block(conv1,start_neurons * 1)
 conv1 = residual_block(conv1,start_neurons * 1, True)
 pool1 = MaxPooling2D(( 2, 2))(conv1)
 pool1 = Dropout(DropoutRatio/2 )(pool1)
 conv2 = Conv2D(start_neurons * 2, size, activation=None, padding="same" )(pool1)
 conv2 = residual_block(conv2,start_neurons * 2)
 conv2 = residual_block(conv2,start_neurons * 2, True)
 pool2 = MaxPooling2D(( 2, 2))(conv2)
 pool2 = Dropout(DropoutRatio )(pool2)
 conv3 = Conv2D(start_neurons * 4, size, activation=None, padding="same" )(pool2)
 conv3 = residual_block(conv3,start_neurons * 4)
 conv3 = residual_block(conv3,start_neurons * 4, True)
 pool3 = MaxPooling2D(( 2, 2))(conv3)
 pool3 = Dropout(DropoutRatio )(pool3)
 conv4 = Conv2D(start_neurons * 8, size, activation=None, padding="same" )(pool3)
 conv4 = residual_block(conv4,start_neurons * 8)
 conv4 = residual_block(conv4,start_neurons * 8, True)
 pool4 = MaxPooling2D(( 2, 2))(conv4)
 pool4 = Dropout(DropoutRatio )(pool4)
 convm = Conv2D(start_neurons * 16, size, activation=None, padding="same" )(pool4)
 convm = residual_block(convm,start_neurons * 16)
 convm = residual_block(convm,start_neurons * 16, True)
 deconv4 = Conv2DTranspose(start_neurons * 8, size, strides=(2, 2), padding="same" )(convm)
 uconv4 = concatenate([deconv4, conv4])
 uconv4 = Dropout(DropoutRatio )(uconv4)
 uconv4 = Conv2D(start_neurons * 8,(3, 3), activation=None, padding="same" )(uconv4)
 uconv4 = residual_block(uconv4,start_neurons * 8)
 uconv4 = residual_block(uconv4,start_neurons * 8, True)
 deconv3 = Conv2DTranspose(start_neurons * 4, size, strides=(2, 2), padding="valid" )(uconv4)
 uconv3 = concatenate([deconv3, conv3])
 uconv3 = Dropout(DropoutRatio )(uconv3)
 uconv3 = Conv2D(start_neurons * 4,(3, 3), activation=None, padding="same" )(uconv3)
 uconv3 = residual_block(uconv3,start_neurons * 4)
 uconv3 = residual_block(uconv3,start_neurons * 4, True)
 deconv2 = Conv2DTranspose(start_neurons * 2, size, strides=(2, 2), padding="same" )(uconv3)
 uconv2 = concatenate([deconv2, conv2])
 uconv2 = Dropout(DropoutRatio )(uconv2)
 uconv2 = Conv2D(start_neurons * 2,(3, 3), activation=None, padding="same" )(uconv2)
 uconv2 = residual_block(uconv2,start_neurons * 2)
 uconv2 = residual_block(uconv2,start_neurons * 2, True)
 deconv1 = Conv2DTranspose(start_neurons * 1, size, strides=(2, 2), padding="valid" )(uconv2)
 uconv1 = concatenate([deconv1, conv1])
 uconv1 = Dropout(DropoutRatio )(uconv1)
 uconv1 = Conv2D(start_neurons * 1,(3, 3), activation=None, padding="same" )(uconv1)
 uconv1 = residual_block(uconv1,start_neurons * 1)
 uconv1 = residual_block(uconv1,start_neurons * 1, True)
 output_layer_noActi = Conv2D(1,(1,1), padding="same", activation=None )(uconv1)
 output_layer = Activation('sigmoid' )(output_layer_noActi)
 return output_layer
from fastai import *
from fastai.vision import *
import os
import pandas as pd
from fastai.metrics import error_rate<define_variables>
def get_iou_vector(A, B):
batch_size = A.shape[0]
metric = []
for batch in range(batch_size):
t, p = A[batch]>0, B[batch]>0
intersection = np.logical_and(t, p)
 union = np.logical_or(t, p)
 iou =(np.sum(intersection > 0)+ 1e-10)/(np.sum(union > 0)+ 1e-10)
 thresholds = np.arange(0.5, 1, 0.05)
 s = []
for thresh in thresholds:
s.append(iou > thresh)
 metric.append(np.mean(s))
return np.mean(metric)
 def my_iou_metric(label, pred):
return tf.py_func(get_iou_vector, [label, pred > 0.3], tf.float64)
 def my_iou_metric_2(label, pred):
return tf.py_func(get_iou_vector, [label, pred > 0.1], tf.float64)
 def my_iou_metric_3(label, pred):
return tf.py_func(get_iou_vector, [label, pred > 0.3], tf.float64 )
train_dir = '.. /input/plant-seedlings-classification/train/'
test_dir = '.. /input/plant-seedlings-classification/test/'<load_pretrained>
def lovasz_grad(gt_sorted):

 gts = tf.reduce_sum(gt_sorted)
 intersection = gts - tf.cumsum(gt_sorted)
 union = gts + tf.cumsum(1.- gt_sorted)
 jaccard = 1.- intersection / union
jaccard = tf.concat(( jaccard[0:1], jaccard[1:] - jaccard[:-1]), 0)
 return jaccard
def lovasz_hinge(logits, labels, per_image=True, ignore=None):

 if per_image:
def treat_image(log_lab):
log, lab = log_lab
log, lab = tf.expand_dims(log, 0), tf.expand_dims(lab, 0)
 log, lab = flatten_binary_scores(log, lab, ignore)
 return lovasz_hinge_flat(log, lab)
 losses = tf.map_fn(treat_image,(logits, labels), dtype=tf.float32)
 loss = tf.reduce_mean(losses)
 else:
loss = lovasz_hinge_flat(*flatten_binary_scores(logits, labels, ignore))
return loss
def lovasz_hinge_flat(logits, labels):

 def compute_loss() :
labelsf = tf.cast(labels, logits.dtype)
 signs = 2.* labelsf - 1.
 errors = 1.- logits * tf.stop_gradient(signs)
 errors_sorted, perm = tf.nn.top_k(errors, k=tf.shape(errors)[0], name="descending_sort")
 gt_sorted = tf.gather(labelsf, perm)
 grad = lovasz_grad(gt_sorted)
 loss = tf.tensordot(tf.nn.relu(errors_sorted), tf.stop_gradient(grad), 1, name="loss_non_void")
 return loss
loss = tf.cond(tf.equal(tf.shape(logits)[0], 0),
lambda: tf.reduce_sum(logits)* 0.,
compute_loss,
strict=True,
name="loss" 
)
 return loss
def flatten_binary_scores(scores, labels, ignore=None):

 scores = tf.reshape(scores,(-1,))
labels = tf.reshape(labels,(-1,))
if ignore is None:
return scores, labels
valid = tf.not_equal(labels, ignore)
 vscores = tf.boolean_mask(scores, valid, name='valid_scores')
 vlabels = tf.boolean_mask(labels, valid, name='valid_labels')
 return vscores, vlabels
def lovasz_loss(y_true, y_pred):
y_true, y_pred = K.cast(K.squeeze(y_true, -1), 'int32'), K.cast(K.squeeze(y_pred, -1), 'float32')
 logits = y_pred
loss = lovasz_hinge(logits, y_true, per_image = True, ignore = None)
 return loss
tfms = get_transforms()
data = ImageDataBunch.from_folder(
 path = train_dir,
test=".. /test",
valid_pct = 0.2,
bs = 16,
size = 336,
ds_tfms = tfms,
num_workers = 0
).normalize(imagenet_stats)
 data
print(data.classes)
 data.show_batch()<choose_model_class>
def _bn_relu(input):

 norm = BatchNormalization(axis=CHANNEL_AXIS )(input)
 return Activation("relu" )(norm)
 def _conv_bn_relu(**conv_params):

 filters = conv_params["filters"]
kernel_size = conv_params["kernel_size"]
strides = conv_params.setdefault("strides",(1, 1))
kernel_initializer = conv_params.setdefault("kernel_initializer", "he_normal")
 padding = conv_params.setdefault("padding", "same")
 kernel_regularizer = conv_params.setdefault("kernel_regularizer", l2(1.e-4))
def f(input):
conv = Conv2D(filters=filters, kernel_size=kernel_size,
strides=strides, padding=padding,
kernel_initializer=kernel_initializer,
kernel_regularizer=kernel_regularizer )(input)
 return _bn_relu(conv)
 return f
def _bn_relu_conv(**conv_params):

 filters = conv_params["filters"]
kernel_size = conv_params["kernel_size"]
strides = conv_params.setdefault("strides",(1, 1))
kernel_initializer = conv_params.setdefault("kernel_initializer", "he_normal")
 padding = conv_params.setdefault("padding", "same")
 kernel_regularizer = conv_params.setdefault("kernel_regularizer", l2(1.e-4))
def f(input):
activation = _bn_relu(input)
 return Conv2D(filters=filters, kernel_size=kernel_size,
strides=strides, padding=padding,
kernel_initializer=kernel_initializer,
kernel_regularizer=kernel_regularizer )(activation)
 return f
def _shortcut(input, residual):

 input_shape = K.int_shape(input)
 residual_shape = K.int_shape(residual)
 stride_width = int(round(input_shape[ROW_AXIS] / residual_shape[ROW_AXIS]))
stride_height = int(round(input_shape[COL_AXIS] / residual_shape[COL_AXIS]))
equal_channels = input_shape[CHANNEL_AXIS] == residual_shape[CHANNEL_AXIS]
shortcut = input
if stride_width > 1 or stride_height > 1 or not equal_channels:
shortcut = Conv2D(filters=residual_shape[CHANNEL_AXIS],
kernel_size=(1, 1),
strides=(stride_width, stride_height),
padding="valid",
kernel_initializer="he_normal",
kernel_regularizer=l2(0.0001))(input)
 return add([shortcut, residual])
 def basic_block(filters, init_strides=(1, 1), is_first_block_of_first_layer=False):

 def f(input):
if is_first_block_of_first_layer:
conv1 = Conv2D(filters=filters, kernel_size=(3, 3),
strides=init_strides,
padding="same",
kernel_initializer="he_normal",
kernel_regularizer=l2(1e-4))(input)
 else:
conv1 = _bn_relu_conv(filters=filters, kernel_size=(3, 3),
strides=init_strides )(input)
 residual = _bn_relu_conv(filters=filters, kernel_size=(3, 3))(conv1)
 return _shortcut(input, residual)
 return f
def _residual_block(block_function, filters, repetitions, is_first_layer=False):

 def f(input):
for i in range(repetitions):
init_strides =(1, 1)
 if i == 0 and not is_first_layer:
init_strides =(2, 2)
 input = block_function(filters=filters, init_strides=init_strides,
is_first_block_of_first_layer=(is_first_layer and i == 0))(input)
 return input
return f
def _handle_dim_ordering() :
global ROW_AXIS
global COL_AXIS
global CHANNEL_AXIS
if K.image_dim_ordering() == 'tf':
ROW_AXIS = 1
COL_AXIS = 2
CHANNEL_AXIS = 3
else:
CHANNEL_AXIS = 1
ROW_AXIS = 2
COL_AXIS = 3
def _get_block(identifier):
if isinstance(identifier, six.string_types):
res = globals().get(identifier)
 if not res:
raise ValueError('Invalid {}'.format(identifier))
return res
return identifier
class ResnetBuilder(object):
@staticmethod
def build(input_shape, block_fn, repetitions,input_tensor):
_handle_dim_ordering()
if len(input_shape)!= 3:
raise Exception("Input shape should be a tuple(nb_channels, nb_rows, nb_cols)")
 if K.image_dim_ordering() == 'tf':
input_shape =(input_shape[1], input_shape[2], input_shape[0])
 block_fn = _get_block(block_fn)
 if input_tensor is None:
img_input = Input(shape=input_shape)
 else:
if not K.is_keras_tensor(input_tensor):
img_input = Input(tensor=input_tensor, shape=input_shape)
 else:
img_input = input_tensor
conv1 = _conv_bn_relu(filters=64, kernel_size=(7, 7), strides=(2, 2))(img_input)
 pool1 = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding="same" )(conv1)
 block = pool1
filters = 64
for i, r in enumerate(repetitions):
block = _residual_block(block_fn, filters=filters, repetitions=r, is_first_layer=(i == 0))(block)
 filters *= 2
block = _bn_relu(block)
 model = Model(inputs=img_input, outputs=block)
 return model
@staticmethod
def build_resnet_34(input_shape,input_tensor):
return ResnetBuilder.build(input_shape, basic_block, [3, 4, 6, 3],input_tensor )
learn = cnn_learner(data, models.resnet152, metrics=accuracy, model_dir="/tmp/models" )<train_model>
def UResNet34(input_shape=(128, 128, 1), classes=1, decoder_filters=16, decoder_block_type='upsampling',
encoder_weights="imagenet", input_tensor=None, activation='sigmoid', **kwargs):
backbone = ResnetBuilder.build_resnet_34(input_shape=input_shape,input_tensor=input_tensor)
 input_layer = backbone.input
output_layer = build_model(input_layer, 16,0.5)
 model = Model(input_layer, output_layer)
 c = optimizers.adam(lr = 0.01)
 model.compile(loss="binary_crossentropy", optimizer=c, metrics=[my_iou_metric])
 model.name = 'u-resnet34'
return model
learn.fit_one_cycle(3 )<choose_model_class>
model1 = UResNet34(input_shape =(1,img_size_target,img_size_target))
interp = ClassificationInterpretation.from_learner(learn )<predict_on_test>
x_train = np.append(x_train, [np.fliplr(x)for x in x_train], axis=0)
 y_train = np.append(y_train, [np.fliplr(x)for x in y_train], axis=0 )
class_score, y = learn.get_preds(DatasetType.Test)
 class_score = np.argmax(class_score, axis=1 )<define_variables>
model_checkpoint = ModelCheckpoint(save_model_name,monitor='my_iou_metric',
mode = 'max', save_best_only=True, verbose=1)
 reduce_lr = ReduceLROnPlateau(monitor='my_iou_metric', mode = 'max',factor=0.5, patience=5, min_lr=0.0001, verbose=1)
 history = model1.fit(x_train, y_train,
validation_data=[x_valid, y_valid],
epochs=epochs,
batch_size=batch_size,
callbacks=[ model_checkpoint,reduce_lr],
verbose=1 )
predicted_classes = [data.classes[i] for i in class_score]
predicted_classes[:10]<save_to_csv>
model1 = load_model(save_model_name,custom_objects={'my_iou_metric': my_iou_metric})
 input_x = model1.layers[0].input
output_layer = model1.layers[-1].input
model = Model(input_x, output_layer)
 c = optimizers.adam(lr = 0.01)
 model.compile(loss=lovasz_loss, optimizer=c, metrics=[my_iou_metric_2])
submission = pd.DataFrame({
"file": os.listdir(test_dir),
"species": predicted_classes
})
 submission.to_csv("submission_resnet152.csv", index=False)
 submission[:10]<import_modules>
early_stopping = EarlyStopping(monitor='val_my_iou_metric_2', mode = 'max',patience=20, verbose=1)
 model_checkpoint = ModelCheckpoint(save_model_name,monitor='val_my_iou_metric_2',
mode = 'max', save_best_only=True, verbose=1)
 reduce_lr = ReduceLROnPlateau(monitor='val_my_iou_metric_2', mode = 'max',factor=0.5, patience=5, min_lr=0.0001, verbose=1)
 history = model.fit(x_train, y_train,
validation_data=[x_valid, y_valid],
epochs=epochs,
batch_size=batch_size,
callbacks=[model_checkpoint,reduce_lr,early_stopping],
verbose=1 )
import tensorflow as tf
from tensorflow import keras
from tensorflow import one_hot
from tensorflow.keras.applications import xception
from tensorflow.keras.preprocessing import image
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
from IPython.display import clear_output
import gc<define_variables>
model = load_model(save_model_name,custom_objects={'my_iou_metric_2': my_iou_metric_2,
'lovasz_loss': lovasz_loss} )
CATEGORIES = os.listdir("/kaggle/input/plant-seedlings-classification/train")
 CATEGORIES<choose_model_class>
def predict_result(model,x_test,img_size_target):
x_test_reflect = np.array([np.fliplr(x)for x in x_test])
 preds_test = model.predict(x_test ).reshape(-1, img_size_target, img_size_target)
 preds_test2_refect = model.predict(x_test_reflect ).reshape(-1, img_size_target, img_size_target)
 preds_test += np.array([ np.fliplr(x)for x in preds_test2_refect])
 return preds_test/2
pretrained = xception.Xception(input_shape=[240,240, 3], include_top=False )<set_options>
preds_valid = predict_result(model,x_valid,img_size_target )
pretrained.trainable = False<choose_model_class>
thresholds_ori = np.linspace(0.3, 0.7, 31)
 thresholds = np.log(thresholds_ori/(1-thresholds_ori))
ious = np.array([iou_metric_batch(y_valid, preds_valid > threshold)for threshold in tqdm_notebook(thresholds)])
 print(ious )
model = tf.keras.Sequential([
pretrained,
tf.keras.layers.GlobalAveragePooling2D() ,
tf.keras.layers.Dense(100, activation="relu"),
tf.keras.layers.BatchNormalization(trainable = True,axis=1),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(50, activation="relu"),
tf.keras.layers.BatchNormalization(trainable = True,axis=1),
tf.keras.layers.Dense(12,activation='softmax')
 ] )<choose_model_class>

 def rle_encode(im):

 pixels = im.flatten(order = 'F')
 pixels = np.concatenate([[0], pixels, [0]])
 runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
runs[1::2] -= runs[::2]
return ' '.join(str(x)for x in runs )
model.compile(optimizer=tf.keras.optimizers.Nadam(learning_rate=0.001),
loss=tf.keras.losses.CategoricalCrossentropy() ,
metrics=['accuracy'] )<define_variables>
preds_test = predict_result(model,x_test,img_size_target )
train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
 rotation_range=20,
zoom_range=0.15,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.15,
horizontal_flip=True,
brightness_range=[0.4,1],
rescale=1.0/255.0)
 test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1.0/255.0)
 pathh = "/kaggle/input/plant-seedlings-classification/train/"<train_model>
t1 = time.time()
pred_dict = {idx: rle_encode(np.round(downsample(preds_test[i])> threshold_best)) for i, idx in enumerate(tqdm_notebook(test_df.index.values)) }
t2 = time.time()
print(f"Usedtime = {t2-t1} s" )
result = model.fit(train_datagen.flow_from_directory(pathh,
target_size=(240, 240),
color_mode='rgb',
class_mode='categorical',
batch_size=64,
shuffle=True),
epochs=20,
verbose=1 )<load_pretrained>
sub = pd.DataFrame.from_dict(pred_dict,orient='index')
 sub.index.names = ['id']
sub.columns = ['rle_mask']
sub.to_csv(submission_file )
pretrained.trainable = True
model.get_layer('xception' ).trainable<choose_model_class>
t_finish = time.time()
print(f"Kernel run time = {(t_finish-t_start)/3600} hours" )