Kaggle competition: ALASKA2 Image Steganalysis
<SOS> metric: WeightedAUC Kaggle data source: alaska2-image-steganalysis<split>
!pip install -q efficientnet_pytorch
Compose, HorizontalFlip, CLAHE, HueSaturationValue,
RandomBrightness, RandomContrast, RandomGamma, OneOf, Resize,
ToFloat, ShiftScaleRotate, GridDistortion, ElasticTransform, JpegCompression, HueSaturationValue,
RGBShift, RandomBrightness, RandomContrast, Blur, MotionBlur, MedianBlur, GaussNoise, CenterCrop,
IAAAdditiveGaussianNoise, GaussNoise, OpticalDistortion, RandomSizedCrop, VerticalFlip 
)
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.2, stratify=train_df.coverage_class, random_state= 1234 )<define_search_model>
seed = 42
print(f'setting everything to seed {seed}')
 random.seed(seed)
 os.environ['PYTHONHASHSEED'] = str(seed)
 np.random.seed(seed)
 torch.manual_seed(seed)
 torch.cuda.manual_seed(seed)
 torch.backends.cudnn.deterministic = True
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 
<choose_model_class>
data_dir = '.. /input/alaska2-image-steganalysis'
folder_names = ['JMiPOD/', 'JUNIWARD/', 'UERD/']
class_names = ['Normal', 'JMiPOD_75', 'JMiPOD_90', 'JMiPOD_95',
'JUNIWARD_75', 'JUNIWARD_90', 'JUNIWARD_95',
'UERD_75', 'UERD_90', 'UERD_95']
class_labels = { name: i for i, name in enumerate(class_names)}
def build_model(input_layer, start_neurons, DropoutRatio = 0.4):
conv1 = Conv2D(start_neurons * 1,(3, 3), activation=None, 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,(3, 3), 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,(3, 3), 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,(3, 3), 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,(3, 3), 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,(3, 3), 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,(3, 3), 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,(3, 3), 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,(3, 3), 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<compute_test_metric>
train_df = pd.read_csv('.. /input/alaska2trainvalsplit/alaska2_train_df.csv')
 val_df = pd.read_csv('.. /input/alaska2trainvalsplit/alaska2_val_df.csv' )
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.5], tf.float64)
 def my_iou_metric_2(label, pred):
return tf.py_func(get_iou_vector, [label, pred >0], tf.float64 )<compute_train_metric>
class Alaska2Dataset(Dataset):
def __init__(self, df, augmentations=None):
self.data = df
self.augment = augmentations
def __len__(self):
return len(self.data)
 def __getitem__(self, idx):
fn, label = self.data.loc[idx]
im = cv2.imread(fn)[:, :, ::-1]
if self.augment:
im = self.augment(image=im)
 return im, label
img_size = 512
AUGMENTATIONS_TRAIN = Compose([
VerticalFlip(p=0.5),
HorizontalFlip(p=0.5),
ToFloat(max_value=255),
ToTensor()
], p=1)
 AUGMENTATIONS_TEST = Compose([
ToFloat(max_value=255),
ToTensor()
], p=1)
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<concatenate>
class Net(nn.Module):
def __init__(self, num_classes):
super().__init__()
self.model = EfficientNet.from_pretrained('efficientnet-b0')
 self.dense_output = nn.Linear(1280, num_classes)
 def forward(self, x):
feat = self.model.extract_features(x)
 feat = F.avg_pool2d(feat, feat.size() [2:] ).reshape(-1, 1280)
 return self.dense_output(feat )
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)
 print(x_train.shape)
 print(y_valid.shape )<choose_model_class>
models = os.listdir('.. /input/alaska2-efficientnet-trained-model-weights/')
 models
input_layer = Input(( img_size_target, img_size_target, 1))
output_layer = build_model(input_layer, 16,0.5)
 model1 = Model(input_layer, output_layer)
 c = optimizers.adam(lr = 0.01)
 model1.compile(loss="binary_crossentropy", optimizer=c, metrics=[my_iou_metric])
<train_model>
tpu_models = [fn for fn in models if 'model_effnet' in fn]
tpu_models
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.6, patience=5, min_lr=0.0001, verbose=1)
 epochs = 50
batch_size = 32
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=2 )<choose_model_class>
gpu_models = [fn for fn in models if 'efficientnetb0_lb' in fn]
gpu_models
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])
<train_model>
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.6, patience=5, min_lr=0.0001, verbose=1)
 epochs = 50
batch_size = 32
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=2 )<load_pretrained>
loaded_gpu_models = []
for fn in gpu_models:
device = 'cuda'
model = Net(num_classes=len(class_labels)).to(device)
 model.load_state_dict(torch.load(( '.. /input/alaska2-efficientnet-trained-model-weights/' + fn)))
 loaded_gpu_models.append(model )
model = load_model(save_model_name,custom_objects={'my_iou_metric_2': my_iou_metric_2,
'lovasz_loss': lovasz_loss})
<predict_on_test>
class Alaska2TestDataset(Dataset):
def __init__(self, df, augmentations=None):
self.data = df
self.augment = augmentations
def __len__(self):
return len(self.data)
 def __getitem__(self, idx):
fn = self.data.loc[idx][0]
im = cv2.imread(fn)[:, :, ::-1]
if self.augment:
im = self.augment(image=im)
 return im
test_filenames = sorted(glob(f"{data_dir}/Test/*.jpg"))
test_df = pd.DataFrame({'ImageFileName': list(
 test_filenames)}, columns=['ImageFileName'])
 batch_size = 16
num_workers = 4
test_dataset = Alaska2TestDataset(test_df, augmentations=AUGMENTATIONS_TEST)
 test_loader = torch.utils.data.DataLoader(test_dataset,
batch_size=batch_size,
num_workers=num_workers,
shuffle=False,
drop_last=False )
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<predict_on_test>
test_df['Id'] = test_df['ImageFileName'].apply(lambda x: x.split(os.sep)[-1])
 for k, model in enumerate(loaded_gpu_models):
model.eval()
preds = []
tk0 = tqdm(test_loader)
 with torch.no_grad() :
for i, im in enumerate(tk0):
inputs = im["image"].to(device)
 im = inputs.flip(2)
 outputs = model(im)
 im = inputs.flip(3)
 outputs =(0.25*outputs + 0.25*model(im))
outputs =(outputs + 0.5*model(inputs))
preds.extend(F.softmax(outputs, 1 ).cpu().numpy())
 preds = np.array(preds)
 labels = preds.argmax(1)
 new_preds = np.zeros(( len(preds),))
new_preds[labels != 0] = preds[labels != 0, 1:].sum(1)
 new_preds[labels == 0] = 1 - preds[labels == 0, 0]
test_df['Label' + str(k)] = new_preds
test_df = test_df.drop('ImageFileName', axis=1 )
preds_valid = predict_result(model,x_valid,img_size_target )<compute_train_metric>
test_df['max'] = test_df.iloc[:, 1:ncol].max(axis=1)
 test_df['min'] = test_df.iloc[:, 1:ncol].min(axis=1)
 test_df['mean'] = test_df.iloc[:, 1:ncol].mean(axis=1)
 test_df['median'] = test_df.iloc[:, 1:ncol].median(axis=1 )
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 )<categorify>
cutoff_lo = 0.3
cutoff_hi = 0.7
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 )<predict_on_test>
test_df['Label'] = test_df['mean']
test_df[['Id', 'Label']].to_csv('stack_mean.csv', index=False, float_format='%.6f')
 test_df['Label'] = test_df['median']
test_df[['Id', 'Label']].to_csv('stack_median.csv', index=False, float_format='%.6f' )
preds_test = predict_result(model,x_test,img_size_target )<save_to_csv>
test_df['Label'] = np.where(np.all(test_df.iloc[:,1:ncol] > cutoff_lo, axis=1), 1,
np.where(np.all(test_df.iloc[:,1:ncol] < cutoff_hi, axis=1),
0, test_df['median']))
test_df[['Id', 'Label']].to_csv('stack_pushout_median.csv', index=False, float_format='%.6f' )
sub = pd.DataFrame.from_dict(pred_dict,orient='index')
 sub.index.names = ['id']
sub.columns = ['rle_mask']
sub.to_csv(submission_file )<train_model>
test_df['Label'] = np.where(np.all(test_df.iloc[:,1:ncol] > cutoff_lo, axis=1),
test_df['max'],
np.where(np.all(test_df.iloc[:,1:ncol] < cutoff_hi, axis=1),
test_df['min'],
test_df['mean']))
test_df[['Id', 'Label']].to_csv('stack_minmax_mean.csv', index=False, float_format='%.6f' )
<set_options><EOS> 
test_df['Label'] = np.where(np.all(test_df.iloc[:,1:ncol] > cutoff_lo, axis=1),
test_df['max'],
np.where(np.all(test_df.iloc[:,1:ncol] < cutoff_hi, axis=1),
test_df['min'],
test_df['median']))
test_df[['Id', 'Label']].to_csv('stack_minmax_median.csv', index=False, float_format='%.6f' )