Kaggle competition: RSNA Pneumonia Detection Challenge
<SOS> metric: RSNAObjectDetectionAP Kaggle data source: rsna-pneumonia-detection-challenge<save_to_csv>
import os
import sys
import random
import math
import numpy as np
import cv2
import matplotlib.pyplot as plt
import json
import pydicom
from imgaug import augmenters as iaa
from tqdm import tqdm
import pandas as pd
import glob
subm[["Patient_Week","FVC","Confidence"]].to_csv("submission_regression.csv", index=False )<prepare_output>
DATA_DIR = '/kaggle/input'
ROOT_DIR = '/kaggle/working'
reg_sub = subm[["Patient_Week","FVC","Confidence"]].copy()<sort_values>
!git clone https://www.github.com/matterport/Mask_RCNN.git
os.chdir('Mask_RCNN')
df1 = img_sub.sort_values(by=['Patient_Week'], ascending=True ).reset_index(drop=True)
 df2 = reg_sub.sort_values(by=['Patient_Week'], ascending=True ).reset_index(drop=True )<feature_engineering>
train_dicom_dir = os.path.join(DATA_DIR, 'stage_1_train_images')
 test_dicom_dir = os.path.join(DATA_DIR, 'stage_1_test_images' )
df = df1[['Patient_Week']].copy()
df['FVC'] = FVC_weight*df1['FVC'] +(1-FVC_weight)*df2['FVC']
df['Confidence'] = Confidence_weight*df1['Confidence'] +(1-Confidence_weight)*df2['Confidence']
df.head()<save_to_csv>
def get_dicom_fps(dicom_dir):
dicom_fps = glob.glob(dicom_dir+'/'+'*.dcm')
 return list(set(dicom_fps))
def parse_dataset(dicom_dir, anns):
image_fps = get_dicom_fps(dicom_dir)
 image_annotations = {fp: [] for fp in image_fps}
for index, row in anns.iterrows() :
fp = os.path.join(dicom_dir, row['patientId']+'.dcm')
 image_annotations[fp].append(row)
 return image_fps, image_annotations
df.to_csv('submission.csv', index=False )<create_dataframe>
class DetectorConfig(Config):

 NAME = 'pneumonia'
GPU_COUNT = 1
IMAGES_PER_GPU = 8
BACKBONE = 'resnet50'
NUM_CLASSES = 2
IMAGE_MIN_DIM = 256
IMAGE_MAX_DIM = 256
RPN_ANCHOR_SCALES =(32, 64, 128, 256)
 TRAIN_ROIS_PER_IMAGE = 32
MAX_GT_INSTANCES = 3
DETECTION_MAX_INSTANCES = 3
DETECTION_MIN_CONFIDENCE = 0.7
DETECTION_NMS_THRESHOLD = 0.1
STEPS_PER_EPOCH = 200
config = DetectorConfig()
config.display()
df_issa1 = df.copy()<install_modules>
class DetectorDataset(utils.Dataset):

 def __init__(self, image_fps, image_annotations, orig_height, orig_width):
super().__init__(self)
 self.add_class('pneumonia', 1, 'Lung Opacity')
 for i, fp in enumerate(image_fps):
annotations = image_annotations[fp]
self.add_image('pneumonia', image_id=i, path=fp,
annotations=annotations, orig_height=orig_height, orig_width=orig_width)
 def image_reference(self, image_id):
info = self.image_info[image_id]
return info['path']
def load_image(self, image_id):
info = self.image_info[image_id]
fp = info['path']
ds = pydicom.read_file(fp)
 image = ds.pixel_array
if len(image.shape)!= 3 or image.shape[2] != 3:
image = np.stack(( image,)* 3, -1)
 return image
def load_mask(self, image_id):
info = self.image_info[image_id]
annotations = info['annotations']
count = len(annotations)
 if count == 0:
mask = np.zeros(( info['orig_height'], info['orig_width'], 1), dtype=np.uint8)
 class_ids = np.zeros(( 1,), dtype=np.int32)
 else:
mask = np.zeros(( info['orig_height'], info['orig_width'], count), dtype=np.uint8)
 class_ids = np.zeros(( count,), dtype=np.int32)
 for i, a in enumerate(annotations):
if a['Target'] == 1:
x = int(a['x'])
 y = int(a['y'])
 w = int(a['width'])
 h = int(a['height'])
 mask_instance = mask[:, :, i].copy()
cv2.rectangle(mask_instance,(x, y),(x+w, y+h), 255, -1)
 mask[:, :, i] = mask_instance
class_ids[i] = 1
return mask.astype(np.bool), class_ids.astype(np.int32 )
Dropout_model = 0.3856
FVC_weight = 0.2
Confidence_weight = 0
!pip install.. /input/kerasapplications/keras-team-keras-applications-3b180cb -f./ --no-index
!pip install.. /input/efficientnet/efficientnet-1.1.0/ -f./ --no-index 
<load_from_csv>
anns = pd.read_csv(os.path.join(DATA_DIR, 'stage_1_train_labels.csv'))
anns.head()
def seed_everything(seed=2020):
random.seed(seed)
 os.environ['PYTHONHASHSEED'] = str(seed)
 np.random.seed(seed)
 tf.random.set_seed(seed)
 seed_everything(42)
 config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.compat.v1.Session(config=config)
 train = pd.read_csv('.. /input/osic-pulmonary-fibrosis-progression/train.csv' )<feature_engineering>
image_fps, image_annotations = parse_dataset(train_dicom_dir, anns=anns )
def expandFVC_Percent(DS):
DS['FVC_Percent'] = DS['FVC'] / DS['Percent']
return DS<merge>
ds = pydicom.read_file(image_fps[0])
 image = ds.pixel_array
def expandFE(data_set):
data_set['MinWeeks'] = data_set.groupby('Patient')['Weeks'].transform('min')
 sub_tr = data_set.loc[data_set['Weeks']==data_set['MinWeeks']]
sub_tr['MinFVC'] = sub_tr['FVC']
sub_tr = sub_tr[['Patient', 'MinFVC']]
merged = data_set.merge(sub_tr, on='Patient', how='outer')
 data_set=merged
data_set['MinFVC'] =(data_set['MinFVC'] - data_set['MinFVC'].min())/(data_set['MinFVC'].max() -data_set['MinFVC'].min())
 print(data_set.sample(5))
return data_set<concatenate>
ORIG_SIZE = 1024
train = expandFE(train)
<define_variables>
image_fps_list = list(image_fps)
 random.seed(42)
 random.shuffle(image_fps_list)
 val_size = 1500
image_fps_val = image_fps_list[:val_size]
image_fps_train = image_fps_list[val_size:]
print(len(image_fps_train), len(image_fps_val))
class IGenerator(Sequence):
BAD_ID = ['ID00011637202177653955184', 'ID00052637202186188008618']
def __init__(self, keys, a, tab, batch_size=8):
self.keys = [k for k in keys if k not in self.BAD_ID]
self.a = a
self.tab = tab
self.batch_size = batch_size
self.train_data = {}
for p in train.Patient.values:
self.train_data[p] = os.listdir(f'.. /input/osic-pulmonary-fibrosis-progression/train/{p}/')
 def __len__(self):
return math.ceil(len(self.keys)/ float(self.batch_size))
def __getitem__(self, idx):
x = []
a, tab = [], []
keys = np.random.choice(self.keys, size = self.batch_size)
 for k in keys:
try:
self.train_data[k].sort()
mx_len = len(self.train_data[k])
 i = np.random.choice(self.train_data[k][mx_len//3:mx_len//3*2], size=1)[0]
img = get_img(f'.. /input/osic-pulmonary-fibrosis-progression/train/{k}/{i}')
 x.append(img)
 a.append(self.a[k])
 tab.append(self.tab[k])
 except:
print(k, i)
 x, a, tab = np.array(x), np.array(a), np.array(tab)
 x = np.expand_dims(x, axis=-1)
 return [x, tab] , a<choose_model_class>
dataset_train = DetectorDataset(image_fps_train, image_annotations, ORIG_SIZE, ORIG_SIZE)
 dataset_train.prepare()
Dense, Dropout, Activation, Flatten, Input, BatchNormalization, GlobalAveragePooling2D, Add, Conv2D, AveragePooling2D,
LeakyReLU, Concatenate 
)
 def get_efficientnet(model, shape):
models_dict = {
'b0': efn.EfficientNetB0(input_shape=shape,weights=None,include_top=False),
'b1': efn.EfficientNetB1(input_shape=shape,weights=None,include_top=False),
'b2': efn.EfficientNetB2(input_shape=shape,weights=None,include_top=False),
'b3': efn.EfficientNetB3(input_shape=shape,weights=None,include_top=False),
'b4': efn.EfficientNetB4(input_shape=shape,weights=None,include_top=False),
'b5': efn.EfficientNetB5(input_shape=shape,weights=None,include_top=False),
'b6': efn.EfficientNetB6(input_shape=shape,weights=None,include_top=False),
'b7': efn.EfficientNetB7(input_shape=shape,weights=None,include_top=False)
 }
return models_dict[model]
def build_model(shape=(512, 512, 1), model_class=None):
inp = Input(shape=shape)
 base = get_efficientnet(model_class, shape)
 x = base(inp)
 x = GlobalAveragePooling2D()(x)
 inp2 = Input(shape=(5,))
x2 = tf.keras.layers.GaussianNoise(0.2 )(inp2)
 x = Concatenate()([x, x2])
 x = Dropout(Dropout_model )(x)
 x = Dense(1 )(x)
 model = Model([inp, inp2] , x)
 return model<compute_test_metric>
dataset_val = DetectorDataset(image_fps_val, image_annotations, ORIG_SIZE, ORIG_SIZE)
 dataset_val.prepare()
def score(fvc_true, fvc_pred, sigma):
sigma_clip = np.maximum(sigma, 70)
 delta = np.abs(fvc_true - fvc_pred)
 delta = np.minimum(delta, 1000)
 sq2 = np.sqrt(2)
 metric =(delta / sigma_clip)*sq2 + np.log(sigma_clip* sq2)
 return np.mean(metric)
 subs = []
q = -1<load_from_csv>
model = modellib.MaskRCNN(mode='training', config=config, model_dir=ROOT_DIR)
 model.load_weights(COCO_WEIGHTS_PATH, by_name=True, exclude=[
"mrcnn_class_logits", "mrcnn_bbox_fc",
"mrcnn_bbox", "mrcnn_mask"] )
q = -1
print(q )<load_from_csv>
LEARNING_RATE = 0.005
warnings.filterwarnings("ignore" )
sub = pd.read_csv('.. /input/osic-pulmonary-fibrosis-progression/sample_submission.csv')
 test = pd.read_csv('.. /input/osic-pulmonary-fibrosis-progression/test.csv')
 A_test, B_test, P_test,W, FVC= {}, {}, {},{},{}
STD, WEEK = {}, {}<save_to_csv>
%%time
model.train(dataset_train, dataset_val,
learning_rate=LEARNING_RATE*2,
epochs=2,
layers='heads',
augmentation=None)
 history = model.keras_model.history.history.copy()
N = len(subs)
 print(N)
 sub = subs[0].copy()
sub["FVC"] = 0
sub["Confidence"] = 0
for i in range(N):
sub["FVC"] += subs[0]["FVC"] *(1/N)
 sub["Confidence"] += subs[0]["Confidence"] *(1/N)
 sub[["Patient_Week","FVC","Confidence"]].to_csv("submission_img.csv", index=False)
 img_sub = sub[["Patient_Week","FVC","Confidence"]].copy()
print(img_sub.sample(5))<load_from_csv>
%%time
model.train(dataset_train, dataset_val,
learning_rate=LEARNING_RATE,
epochs=7,
layers='all',
augmentation=augmentation)
 news = model.keras_model.history.history
for k in news: history[k] = history[k] + news[k]
ROOT = ".. /input/osic-pulmonary-fibrosis-progression"
BATCH_SIZE=128
tr = pd.read_csv(f"{ROOT}/train.csv")
 tr.drop_duplicates(keep=False, inplace=True, subset=['Patient','Weeks'])
 chunk = pd.read_csv(f"{ROOT}/test.csv")
 print("add infos")
 sub = pd.read_csv(f"{ROOT}/sample_submission.csv")
 sub['Patient'] = sub['Patient_Week'].apply(lambda x:x.split('_')[0])
 sub['Weeks'] = sub['Patient_Week'].apply(lambda x: int(x.split('_')[-1]))
sub = sub[['Patient','Weeks','Confidence','Patient_Week']]
sub = sub.merge(chunk.drop('Weeks', axis=1), on="Patient")
 tr['WHERE'] = 'train'
chunk['WHERE'] = 'val'
sub['WHERE'] = 'test'
data = tr.append([chunk, sub])
 print(tr.shape, chunk.shape, sub.shape, data.shape)
 print(tr.Patient.nunique() , chunk.Patient.nunique() , sub.Patient.nunique() ,
data.Patient.nunique() )<feature_engineering>
%%time
model.train(dataset_train, dataset_val,
learning_rate=LEARNING_RATE/5,
epochs=15,
layers='all',
augmentation=augmentation)
 news = model.keras_model.history.history
for k in news: history[k] = history[k] + news[k]
data['min_week'] = data['Weeks']
data.loc[data.WHERE=='test','min_week'] = np.nan
data['min_week'] = data.groupby('Patient')['min_week'].transform('min')
 base = data.loc[data.Weeks == data.min_week]
base = base[['Patient','FVC']].copy()
base.columns = ['Patient','min_FVC']
base['nb'] = 1
base['nb'] = base.groupby('Patient')['nb'].transform('cumsum')
 base = base[base.nb==1]
base.drop('nb', axis=1, inplace=True)
 data = data.merge(base, on='Patient', how='left')
 data['base_week'] = data['Weeks'] - data['min_week']
del base
COLS = ['Sex','SmokingStatus']
FE = []
for col in COLS:
for mod in data[col].unique() :
FE.append(mod)
 data[mod] =(data[col] == mod ).astype(int)
 data['age'] =(data['Age'] - data['Age'].min())/(data['Age'].max() - data['Age'].min())
 data['BASE'] =(data['min_FVC'] - data['min_FVC'].min())/(data['min_FVC'].max() - data['min_FVC'].min())
 data['week'] =(data['base_week'] - data['base_week'].min())/(data['base_week'].max() - data['base_week'].min())
 data['percent'] =(data['Percent'] - data['Percent'].min())/(data['Percent'].max() - data['Percent'].min())
 data['FVC_Percent'] = data['FVC'] / data['Percent']
FE += ['age','percent','week','BASE']
tr = data.loc[data.WHERE=='train']
chunk = data.loc[data.WHERE=='val']
sub = data.loc[data.WHERE=='test']
del data
C1, C2 = tf.constant(70, dtype='float32'), tf.constant(1000, dtype="float32")
 def score(y_true, y_pred):
tf.dtypes.cast(y_true, tf.float32)
 tf.dtypes.cast(y_pred, tf.float32)
 sigma = y_pred[:, 2] - y_pred[:, 0]
fvc_pred = y_pred[:, 1]
sigma_clip = tf.maximum(sigma, C1)
 delta = tf.abs(y_true[:, 0] - fvc_pred)
 delta = tf.minimum(delta, C2)
 sq2 = tf.sqrt(tf.dtypes.cast(2, dtype=tf.float32))
metric =(delta / sigma_clip)*sq2 + tf.math.log(sigma_clip* sq2)
 return K.mean(metric)
 def qloss(y_true, y_pred):
qs = [0.2, 0.50, 0.8]
q = tf.constant(np.array([qs]), dtype=tf.float32)
 e = y_true - y_pred
v = tf.maximum(q*e,(q-1)*e)
 return K.mean(v)
 def mloss(_lambda):
def loss(y_true, y_pred):
return _lambda * qloss(y_true, y_pred)+(1 - _lambda)*score(y_true, y_pred)
 return loss
def make_model(nh):
z = L.Input(( nh,), name="Patient")
 x = L.Dense(100, activation="relu", name="d1" )(z)
 x = L.Dense(100, activation="relu", name="d2" )(x)
 p1 = L.Dense(3, activation="linear", name="p1" )(x)
 p2 = L.Dense(3, activation="relu", name="p2" )(x)
 preds = L.Lambda(lambda x: x[0] + tf.cumsum(x[1], axis=1),
name="preds" )([p1, p2])
 model = M.Model(z, preds, name="CNN")
 model.compile(loss=mloss(0.65), optimizer=tf.keras.optimizers.Adam(lr=0.1, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.01, amsgrad=False), metrics=[score])
 return model
print(FE )<train_on_grid>
epochs = range(1,len(next(iter(history.values())))+1)
 pd.DataFrame(history, index=epochs )
y = tr['FVC'].values
z = tr[FE].values
print(z.shape)
 ze = sub[FE].values
print(ze.shape)
 nh = z.shape[1]
print(nh)
 pe = np.zeros(( ze.shape[0], 3))
pred = np.zeros(( z.shape[0], 3))
net = make_model(nh)
 print(net.summary())
 print(net.count_params())
 NFOLD = 5
kf = KFold(n_splits=NFOLD )<train_model>
class InferenceConfig(DetectorConfig):
GPU_COUNT = 1
IMAGES_PER_GPU = 1
inference_config = InferenceConfig()
model = modellib.MaskRCNN(mode='inference',
config=inference_config,
model_dir=ROOT_DIR)
 assert model_path != "", "Provide path to trained weights"
print("Loading weights from ", model_path)
 model.load_weights(model_path, by_name=True )
cnt = 0
EPOCHS = 800
y = y.astype(np.float32)
 for tr_idx, val_idx in kf.split(z):
cnt += 1
print(f"FOLD {cnt}")
 net = make_model(nh)
 net.fit(z[tr_idx], y[tr_idx], batch_size=BATCH_SIZE, epochs=EPOCHS,
validation_data=(z[val_idx], y[val_idx]), verbose=0)
 print("train", net.evaluate(z[tr_idx], y[tr_idx], verbose=0, batch_size=BATCH_SIZE))
print("val", net.evaluate(z[val_idx], y[val_idx], verbose=0, batch_size=BATCH_SIZE))
print("predict val...")
 pred[val_idx] = net.predict(z[val_idx], batch_size=BATCH_SIZE, verbose=0)
 print("predict test...")
 pe += net.predict(ze, batch_size=BATCH_SIZE, verbose=0)/ NFOLD<create_dataframe>
test_image_fps = get_dicom_fps(test_dicom_dir )
df_issa2 = df.copy()<save_to_csv>
def predict(image_fps, filepath='submission.csv', min_conf=0.95):
resize_factor = ORIG_SIZE / config.IMAGE_SHAPE[0]
with open(filepath, 'w')as file:
file.write("patientId,PredictionString
")
 for image_id in tqdm(image_fps):
ds = pydicom.read_file(image_id)
 image = ds.pixel_array
if len(image.shape)!= 3 or image.shape[2] != 3:
image = np.stack(( image,)* 3, -1)
 image, window, scale, padding, crop = utils.resize_image(
 image,
min_dim=config.IMAGE_MIN_DIM,
min_scale=config.IMAGE_MIN_SCALE,
max_dim=config.IMAGE_MAX_DIM,
mode=config.IMAGE_RESIZE_MODE)
 patient_id = os.path.splitext(os.path.basename(image_id)) [0]
results = model.detect([image])
 r = results[0]
out_str = ""
out_str += patient_id
out_str += ","
assert(len(r['rois'])== len(r['class_ids'])== len(r['scores']))
if len(r['rois'])== 0:
pass
else:
num_instances = len(r['rois'])
 for i in range(num_instances):
if r['scores'][i] > min_conf:
out_str += ' '
out_str += str(round(r['scores'][i], 2))
out_str += ' '
x1 = r['rois'][i][1]
y1 = r['rois'][i][0]
width = r['rois'][i][3] - x1
height = r['rois'][i][2] - y1
bboxes_str = "{} {} {} {}".format(x1*resize_factor, y1*resize_factor, \
width*resize_factor, height*resize_factor)
 out_str += bboxes_str
file.write(out_str+"
" )
df_issa1.to_csv('df_issa1.csv', index=False)
 df_issa2.to_csv('df_issa2.csv', index=False )<prepare_output>
submission_fp = os.path.join(ROOT_DIR, 'submission.csv')
 predict(test_image_fps, filepath=submission_fp)
 print(submission_fp )
x = 0.6
df = df_issa1.copy()
df['FVC'] = x*df_issa1['FVC'] +(1-x)*df_issa2['FVC']
df['Confidence'] = x*df_issa1['Confidence'] +(1-x)*df_issa2['Confidence']
df.head()<save_to_csv>
output = pd.read_csv(submission_fp, names=['patientId', 'PredictionString'])
 output.head(60 )
<install_modules><EOS> 
!rm -rf /kaggle/working/Mask_RCNN