Kaggle competition: TGS Salt Identification Challenge
<SOS> metric: IntersectionOverUnionObjectSegmentation Kaggle data source: tgs-salt-identification-challenge<import_modules>
try:
except ImportError:
def lovasz_grad(gt_sorted):

 p = len(gt_sorted)
 gts = gt_sorted.sum()
intersection = gts - gt_sorted.float().cumsum(0)
 union = gts +(1 - gt_sorted ).float().cumsum(0)
 jaccard = 1.- intersection / union
if p > 1:
jaccard[1:p] = jaccard[1:p] - jaccard[0:-1]
return jaccard
def iou_binary(preds, labels, EMPTY=1., ignore=None, per_image=True):

 if not per_image:
preds, labels =(preds,),(labels,)
 ious = []
for pred, label in zip(preds, labels):
intersection =(( label == 1)&(pred == 1)).sum()
union =(( label == 1)|(( pred == 1)&(label != ignore)) ).sum()
if not union:
iou = EMPTY
else:
iou = float(intersection)/ union
ious.append(iou)
 iou = mean(ious)
 return 100 * iou
def iou(preds, labels, C, EMPTY=1., ignore=None, per_image=False):

 if not per_image:
preds, labels =(preds,),(labels,)
 ious = []
for pred, label in zip(preds, labels):
iou = []
for i in range(C):
if i != ignore:
intersection =(( label == i)&(pred == i)).sum()
union =(( label == i)|(( pred == i)&(label != ignore)) ).sum()
if not union:
iou.append(EMPTY)
 else:
iou.append(float(intersection)/ union)
 ious.append(iou)
 ious = map(mean, zip(*ious))
return 100 * np.array(ious)
 def lovasz_hinge(logits, labels, per_image=True, ignore=None):

 if per_image:
loss = mean(lovasz_hinge_flat(*flatten_binary_scores(log.unsqueeze(0), lab.unsqueeze(0), ignore))
for log, lab in zip(logits, labels))
else:
loss = lovasz_hinge_flat(*flatten_binary_scores(logits, labels, ignore))
return loss
def lovasz_hinge_flat(logits, labels):

 if len(labels)== 0:
return logits.sum() * 0.
 signs = 2.* labels.float() - 1.
 errors =(1.- logits * Variable(signs))
errors_sorted, perm = torch.sort(errors, dim=0, descending=True)
 perm = perm.data
gt_sorted = labels[perm]
grad = lovasz_grad(gt_sorted)
 loss = torch.dot(F.elu(errors_sorted)+1, Variable(grad))
return loss
def flatten_binary_scores(scores, labels, ignore=None):

 scores = scores.view(-1)
 labels = labels.view(-1)
 if ignore is None:
return scores, labels
valid =(labels != ignore)
 vscores = scores[valid]
vlabels = labels[valid]
return vscores, vlabels
class StableBCELoss(torch.nn.modules.Module):
def __init__(self):
super(StableBCELoss, self ).__init__()
def forward(self, input, target):
neg_abs = - input.abs()
loss = input.clamp(min=0)- input * target +(1 + neg_abs.exp() ).log()
return loss.mean()
def binary_xloss(logits, labels, ignore=None):

 logits, labels = flatten_binary_scores(logits, labels, ignore)
 loss = StableBCELoss()(logits, Variable(labels.float()))
return loss
def lovasz_softmax(probas, labels, only_present=False, per_image=False, ignore=None):

 if per_image:
loss = mean(lovasz_softmax_flat(*flatten_probas(prob.unsqueeze(0), lab.unsqueeze(0), ignore), only_present=only_present)
 for prob, lab in zip(probas, labels))
else:
loss = lovasz_softmax_flat(*flatten_probas(probas, labels, ignore), only_present=only_present)
 return loss
def lovasz_softmax_flat(probas, labels, only_present=False):

 C = probas.size(1)
 losses = []
for c in range(C):
fg =(labels == c ).float()
if only_present and fg.sum() == 0:
continue
errors =(Variable(fg)- probas[:, c] ).abs()
errors_sorted, perm = torch.sort(errors, 0, descending=True)
 perm = perm.data
fg_sorted = fg[perm]
losses.append(torch.dot(errors_sorted, Variable(lovasz_grad(fg_sorted))))
return mean(losses)
 def flatten_probas(probas, labels, ignore=None):

 B, C, H, W = probas.size()
probas = probas.permute(0, 2, 3, 1 ).contiguous().view(-1, C)
 labels = labels.view(-1)
 if ignore is None:
return probas, labels
valid =(labels != ignore)
 vprobas = probas[valid.nonzero().squeeze() ]
vlabels = labels[valid]
return vprobas, vlabels
def xloss(logits, labels, ignore=None):

 return F.cross_entropy(logits, Variable(labels), ignore_index=255)
 def mean(l, ignore_nan=False, empty=0):

 l = iter(l)
 if ignore_nan:
l = ifilterfalse(np.isnan, l)
 try:
n = 1
acc = next(l)
 except StopIteration:
if empty == 'raise':
raise ValueError('Empty mean')
 return empty
for n, v in enumerate(l, 2):
acc += v
if n == 1:
return acc
return acc / n
import matplotlib.pyplot as plt
from glob import glob
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.preprocessing.image import ImageDataGenerator
from keras.layers import BatchNormalization
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
import cv2
import numpy as np
import pandas as pd
from keras import layers
from keras import models
from keras import optimizers
from keras.preprocessing.image import img_to_array, load_img
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D,GlobalMaxPool2D
from keras.layers.normalization import BatchNormalization
from keras.optimizers import Adam<define_variables>
torch.cuda.set_device(0 )
TRAIN_DATA_DIR = '/kaggle/input/plant-seedlings-classification/train/*/*.png'
TEST_DATA_DIR = '/kaggle/input/plant-seedlings-classification/test/*.png'<define_variables>
MASKS_FN = 'train.csv'
TRAIN_DN = Path('train/images/')
 MASKS_DN = Path('train/masks/')
 TEST = Path('test/images/')
 PATH = Path('/kaggle/input/tgs-salt-identification-challenge/')
 PATH128 = Path('/tmp/128/')
 TMP = Path('/tmp/')
 MODEL = Path('/tmp/model/')
 PRETRAINED = Path('/kaggle/input/fork-of-is-there-salt-resnet34/model/resnet34_issalt.h5')
 seg = pd.read_csv(PATH/MASKS_FN ).set_index('id')
 seg.head()
sz = 128
bs = 64
nw = 4
data = glob(TRAIN_DATA_DIR)
 training_data=[]
training_label=[]
data_count= len(data)
 print("Reading Data")
 for d in data:
training_data.append(cv2.resize(cv2.imread(d),(240,240)))
 training_label.append(d.split('/')[-2])
 print("Data Read Complete")
 training_data = np.asarray(training_data)
 training_label = pd.DataFrame(training_label )<categorify>
train_names_png = [TRAIN_DN/f for f in os.listdir(PATH/TRAIN_DN)]
train_names = list(seg.index.values)
 masks_names_png = [MASKS_DN/f for f in os.listdir(PATH/MASKS_DN)]
test_names_png = [TEST/f for f in os.listdir(PATH/TEST)]
LabelEncode = preprocessing.LabelEncoder()
LabelEncode.fit(training_label[0])
 new_label = LabelEncode.transform(training_label[0])
 clearalllabels = np_utils.to_categorical(new_label)
 print(training_data.shape, clearalllabels.shape )<split>
with ThreadPoolExecutor(4)as e: e.map(resize_mask, train_names_png )
x_train,x_test,y_train,y_test = train_test_split(training_data,clearalllabels,test_size=0.2,random_state=1,stratify=clearalllabels)
 print(x_train.shape,x_test.shape,y_train.shape,y_test.shape )<data_type_conversions>
with ThreadPoolExecutor(4)as e: e.map(resize_mask, masks_names_png )
x_train = x_train.astype('float32')/ 255
x_test = x_test.astype('float32')/ 255<choose_model_class>
with ThreadPoolExecutor(4)as e: e.map(resize_mask, test_names_png )
data_generator = ImageDataGenerator(rotation_range=20,
zoom_range=0.2,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
vertical_flip=True,
)<train_model>
class CustomDataset(FilesDataset):
def __init__(self, fnames, y, transform, path):
self.y=y
assert(len(fnames)==len(y))
super().__init__(fnames, transform, path)
 def get_x(self, i):
return open_image(os.path.join(self.path,self.fnames[i]))
def get_y(self, i):
return open_image(os.path.join(self.path,self.y[i]))
def get_c(self): return 0
data_generator.fit(x_train )<import_modules>
class TestFilesDataset(FilesDataset):
def __init__(self, fnames, y, transform, path):
self.y=y
self.th = 1
super().__init__(fnames, transform, path)
 def get_x(self, i):
return np.fliplr(open_image(os.path.join(self.path, self.fnames[i])))
 def get_y(self, i):
return np.fliplr(open_image(os.path.join(self.path,self.y[i])))
 def get_c(self): return 0
import tensorflow as tf<choose_model_class>
def IoU_np(pred, targs, thres=0):
pred =(pred>thres)
 intersection =(pred*targs ).sum()
return intersection /(( pred+targs ).sum() - intersection + 1.0)
 def IoU(pred, targs, thres=0):
pred =(pred>thres ).float()
intersection =(pred*targs ).sum()
return intersection /(( pred+targs ).sum() - intersection + 1.0 )
tf.keras.backend.clear_session()
model = Sequential()
model.add(Conv2D(filters=64, kernel_size=(3, 3), input_shape=(240, 240, 3), activation='relu'))
model.add(BatchNormalization(axis=3))
model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(( 2, 2)))
 model.add(BatchNormalization(axis=3))
model.add(Dropout(0.1))
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu'))
model.add(BatchNormalization(axis=3))
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(( 2, 2)))
 model.add(BatchNormalization(axis=3))
model.add(Dropout(0.1))
model.add(GlobalMaxPool2D())
 model.add(Flatten())
 model.add(Dense(100, activation='relu'))
model.add(BatchNormalization())
 model.add(Dropout(0.5))
model.add(Dense(50, activation='relu'))
model.add(BatchNormalization())
 model.add(Dropout(0.5))
model.add(Dense(12, activation='softmax')) 
<choose_model_class>
def get_base(f, cut):
layers = cut_model(f(True), cut)
 return nn.Sequential(*layers)
 def load_pretrained(model, path):
weights = torch.load(PRETRAINED, map_location=lambda storage, loc: storage)
 model.load_state_dict(weights, strict=False)
 return model
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'] )<train_model>
class SaveFeatures() :
features=None
def __init__(self, m): self.hook = m.register_forward_hook(self.hook_fn)
 def hook_fn(self, module, input, output): self.features = output
def remove(self): self.hook.remove()
model_history=model.fit_generator(data_generator.flow(x_train,y_train,batch_size=16),epochs=200,
validation_data=(x_test,y_test),callbacks=model_checkpoint )<compute_test_metric>
class UnetBlock(nn.Module):
def __init__(self, up_in, x_in, n_out):
super().__init__()
up_out = x_out = n_out//2
self.x_conv = nn.Conv2d(x_in, x_out, 1)
 self.tr_conv = nn.ConvTranspose2d(up_in, up_out, 2, stride=2)
 self.bn = nn.BatchNorm2d(n_out)
 def forward(self, up_p, x_p):
up_p = self.tr_conv(up_p)
 x_p = self.x_conv(x_p)
 cat_p = torch.cat([up_p,x_p], dim=1)
 return self.bn(F.relu(cat_p))
score, acc = model.evaluate(x_test,y_test)
 score1, acc1 = model.evaluate(x_train,y_train)
 print('Test score:', score,' Test accuracy:', acc)
 print('Train score:', score1,' Train accuracy:',acc1)
<set_options>
class Unet34(nn.Module):
def __init__(self, rn):
super().__init__()
self.rn = rn
self.sfs = [SaveFeatures(rn[i])for i in [2,4,5,6]]
self.up1 = UnetBlock(512,256,256)
 self.up2 = UnetBlock(256,128,256)
 self.up3 = UnetBlock(256,64,256)
 self.up4 = UnetBlock(256,64,256)
 self.cSE = nn.Sequential(nn.AdaptiveAvgPool2d(1),
nn.Conv2d(512,256,1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 512,1),
nn.Sigmoid() 
)
 self.sSE = nn.Sequential(nn.Conv2d(512,512,1),
nn.Sigmoid())
 self.up5 = nn.ConvTranspose2d(256, 1, 2, stride=2)
 def forward(self,x):
x = F.dropout(F.relu(self.rn(x)) ,0.3)
 x = torch.addcmul(x * self.cSE(x), 1, x, self.sSE(x))
x1 = self.up1(x, self.sfs[3].features)
 x2 = self.up2(x1, self.sfs[2].features)
 x = self.up3(x2, self.sfs[1].features)
 x = self.up4(x, self.sfs[0].features)
 x = self.up5(x)
 x = torch.cat(( x,
F.interpolate(( x2),scale_factor=8,mode='bilinear',align_corners=True),
F.interpolate(( x1),scale_factor=16,mode='bilinear', align_corners=True)
),1)
 return F.dropout(x[:,0],0.3)
 def close(self):
for sf in self.sfs: sf.remove()
path_to_test = TEST_DATA_DIR
pics = glob(path_to_test)
 testimages = []
tests = []
num = len(pics)
 print(pics)
 for i in pics:
tests.append(i.split('/')[-1])
 testimages.append(cv2.resize(cv2.imread(i),(240,240)))
 testimages= np.asarray(testimages )<data_type_conversions>
class UnetModel() :
def __init__(self,model,name='unet'):
self.model,self.name = model,name
def get_layer_groups(self, precompute):
lgs = list(split_by_idxs(children(self.model.rn), [lr_cut]))
return lgs + [children(self.model)[1:]]
testimages = testimages.astype('float32')/ 255<save_to_csv>
x_names = [f'{x}.png' for x in train_names]
x_names_path = np.array([str(TRAIN_DN/x)for x in x_names])
 y_names = [x for x in x_names]
y_names_path = np.array([str(MASKS_DN/x)for x in x_names] )
prediction = model.predict(testimages)
 pred = np.argmax(prediction,axis=1)
 predStr = LabelEncode.classes_[pred]
submission = {'file':tests,'species':predStr}
submission = pd.DataFrame(submission)
 submission.to_csv("Prediction.csv",index=False )<load_pretrained>
class RandomRotate2(CoordTransform):

 def __init__(self, deg, p=0.75, mode=cv2.BORDER_REFLECT, tfm_y=TfmType.NO):
super().__init__(tfm_y)
 self.deg,self.p = deg,p
if tfm_y == TfmType.COORD or tfm_y == TfmType.CLASS:
self.modes =(mode,cv2.BORDER_CONSTANT)
 else:
self.modes =(mode,mode)
 def set_state(self):
self.store.rdeg = rand0(self.deg)
 self.store.rp = random.random() <self.p
def do_transform(self, x, is_y):
if self.store.rp: x = rotate_cv(x, self.store.rdeg,
mode = self.modes[0],
interpolation=cv2.INTER_NEAREST if is_y else cv2.INTER_AREA)
 return x
model_json = model.to_json()
with open("plant_seedling.json", "w")as json_file:
json_file.write(model_json)
 model.save_weights("plant-seedling.h5")
 print("Saved model to disk" )<define_variables>
aug_tfms = [RandomRotate2(4, tfm_y=TfmType.CLASS),
RandomFlip(tfm_y=TfmType.CLASS),
RandomStretch(0.2,tfm_y=TfmType.CLASS),
RandomLighting(0.05, 0.05, tfm_y=TfmType.CLASS)]
tfms = tfms_from_model(resnet34, sz=sz, pad=0, crop_type=CropType.NO, tfm_y=TfmType.CLASS, aug_tfms=aug_tfms)
 def get_data(val_idxs): 
(( val_x,trn_x),(val_y,trn_y)) = split_by_idx(val_idxs, x_names_path, y_names_path)
 datasets = ImageData.get_ds(CustomDataset,(trn_x,trn_y),(val_x,val_y), tfms,(test_x, test_x), path=PATH128)
 return ImageData(PATH128, datasets, bs=32, num_workers=nw, classes=None)
dim = 160
path = '.. /input/plant-seedlings-classification/train/*/*.png'
files = glob(path)
 trainImg = []
trainLabel = []
j = 1
num = len(files)
 for img in files:
print(str(j)+ "/" + str(num), end="\r")
 trainImg.append(cv2.resize(cv2.imread(img),(dim, dim)))
 trainLabel.append(img.split('/')[-2])
 j += 1
trainImg = np.asarray(trainImg)
 trainLabel = pd.DataFrame(trainLabel )<drop_column>
f = resnet34
cut,lr_cut = model_meta[f]
def get_learner(md):
m_base = load_pretrained(get_base(f, cut),PRETRAINED)
 m = to_gpu(Unet34(m_base))
models = UnetModel(m)
 learn = ConvLearner(md, models, tmp_name=TMP, models_name=MODEL)
 learn.opt_fn=optim.Adam
learn.crit = nn.BCEWithLogitsLoss()
learn.metrics=[accuracy_thresh(0.5), IoU]
learn.clip = 0.25
return learn
clearTrainImg = preProcessImage(trainImg )<prepare_x_and_y>
n_folds = 5
val_size = 4000//n_folds
actual_its = []
lr=3e-3
wd=1e-7
lrs = np.array([lr/100,lr/10,lr/3])
 test_x = np.array(test_names_png)
 out=np.zeros(( 18000,sz,sz))
alpha = 0
x_train = clearTrainImg / 255.0<categorify>
for i in [0,1,2]:
print(f'Fold{i}------------------------------------')
 val_idxs=list(range(i*val_size,(i+1)*val_size))
md = get_data(val_idxs)
 learn = get_learner(md)
 learn.freeze_to(1)
 print(f'fit(lrs, wd): {lrs, wd}')
 learn.fit(lrs, 1, wds=wd, cycle_len=20,use_clr_beta=(10,10, 0.85, 0.9),best_save_name='best1')
 print('unfreezing')
 learn.unfreeze()
learn.load('best1')
 learn.crit = lovasz_hinge
learn.fit(lrs/10, 1, wds=wd, cycle_len=20,use_clr_beta=(10,10, 0.85, 0.9),best_save_name='best2')
 learn.load('best2')
 print(f'computing test set: {i}')
 p = learn.predict(is_test=True)
 learn.save(f'{i}-model')
 print('Computing optimal threshold')
 preds, targs = learn.predict_with_targs()
IoUs=[]
for a in np.arange(0, 1, 0.1):
IoUs.append(IoU_np(preds, targs, a))
IoU_max = np.array(IoUs ).argmax()
print(f'optimal Threshold: {IoU_max/10.0}')
 alpha+=IoU_max/10.0
print('TTA')
 md.test_dl.dataset = TestFilesDataset(test_x,test_x,tfms[1],PATH128)
 p_f = learn.predict(is_test=True)
 p_f = p_f[:,:,::-1]
out =(p+p_f)/2
actual_its.append(i )
enc = OneHotEncoder(categories='auto')
 y_train = enc.fit_transform(trainLabel ).toarray()<split>
print(f'Last Iteration group [0,1,2]: {i} ' )
sss = StratifiedShuffleSplit(n_splits=1, test_size=0.16, random_state=42)
 for train_index, test_index in sss.split(x_train, y_train):
print("Using {} for training and {} for validation".format(len(train_index), len(test_index)))
 x_train, x_valid = x_train[train_index], x_train[test_index]
y_train, y_valid = y_train[train_index], y_train[test_index]<set_options>
for i in [3,4]:
print(f'Fold{i}------------------------------------')
 val_idxs=list(range(i*val_size,(i+1)*val_size))
md = get_data(val_idxs)
 learn = get_learner(md)
 learn.freeze_to(1)
 print(f'fit(lrs, wd): {lrs, wd}')
 learn.fit(lrs, 1, wds=wd, cycle_len=20,use_clr_beta=(10,10, 0.85, 0.9),best_save_name='best1')
 print('unfreezing')
 learn.unfreeze()
learn.load('best1')
 learn.crit = lovasz_hinge
learn.fit(lrs/10, 1, wds=wd, cycle_len=20,use_clr_beta=(10,10, 0.85, 0.9),best_save_name='best2')
 learn.load('best2')
 print(f'computing test set: {i}')
 p = learn.predict(is_test=True)
 learn.save(f'{i}-model')
 print('Computing optimal threshold')
 preds, targs = learn.predict_with_targs()
IoUs=[]
for a in np.arange(0, 1, 0.1):
IoUs.append(IoU_np(preds, targs, a))
IoU_max = np.array(IoUs ).argmax()
print(f'optimal Threshold: {IoU_max/10.0}')
 alpha+=IoU_max/10.0
print('TTA')
 md.test_dl.dataset = TestFilesDataset(test_x,test_x,tfms[1],PATH128)
 p_f = learn.predict(is_test=True)
 p_f = p_f[:,:,::-1]
out =(p+p_f)/2
actual_its.append(i )
datagen = 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,
vertical_flip=True,
brightness_range=[0.4,1],
rescale=1.0/255.0)
 datagen.fit(x_train )<choose_model_class>
print(actual_its)
 out = out/n_folds
alpha = alpha/n_folds
num_classes = 12
learning_rate = 0.001
batch_size = 32
base_model = Xception(input_shape=(dim, dim, 3), include_top=False,weights='imagenet')
 base_model.trainable = False
model = Sequential([
base_model,
GlobalAveragePooling2D() ,
Dense(100, activation="relu"),
BatchNormalization(trainable = True,axis=1),
Dropout(0.5),
Dense(50, activation="relu"),
BatchNormalization(trainable = True,axis=1),
Dense(num_classes,activation='softmax')
 ])
 model.compile(optimizer = optimizers.Nadam(learning_rate=learning_rate),
loss = 'categorical_crossentropy',
metrics=['accuracy'])
 result = model.fit(datagen.flow(x_train, y_train, batch_size=batch_size), verbose = 1,
batch_size=batch_size, epochs=25, validation_data=(x_valid, y_valid)) 
(loss, accuracy)= model.evaluate(x_valid, y_valid)
 print("[INFO] loss={:.4f}, accuracy: {:.4f}%".format(loss,accuracy * 100))<load_pretrained>
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 )
base_model.trainable = True
model.get_layer('xception' ).trainable<choose_model_class>
sub = pd.DataFrame(list(zip(name_list, tmp_list)) , columns = ['id', 'rle_mask'] )
model.compile(optimizer=optimizers.Nadam(learning_rate=0.0006), loss='categorical_crossentropy', metrics=['accuracy'] )<train_model>
sub.to_csv('submission.csv', index=False )
<set_options><EOS> 
sub.to_csv('submission.csv', index=False )