Kaggle competition: RSNA Intracranial Hemorrhage Detection
<SOS> metric: weightedmeancolumnwiselogloss Kaggle data source: rsna-intracranial-hemorrhage-detection<prepare_x_and_y>
dir_csv = '.. /input/rsna-intracranial-hemorrhage-detection'
dir_train_img = '.. /input/rsna-train-stage-1-images-png-224x/stage_1_train_png_224x'
dir_test_img = '.. /input/rsna-test-stage-1-images-png-224x/stage_1_test_png_224x'
X_train, y_train = format_dataset(train_data)
 X_test = format_dataset(test_data)
 print(X_train.shape, y_train.shape, X_test.shape )<randomize_order>
n_classes = 6
n_epochs = 5
batch_size = 128
show_random_samples(X_train, y_train )<choose_model_class>
!git clone https://github.com/NVIDIA/apex && cd apex && pip install -v --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext"./
!pip install --upgrade efficientnet-pytorch
def create_small_dense_network() :
model = Sequential()
model.add(Input(shape=(96, 96, 1)))
 model.add(Flatten())
 model.add(Dense(units=100, activation='relu'))
model.add(Dense(units=30, activation=None))
return model<train_model>
from apex import amp
import os
import cv2
import glob
import pydicom
import numpy as np
import pandas as pd
from efficientnet_pytorch import EfficientNet
import torch
import torch.optim as optim
from albumentations import Compose, ShiftScaleRotate, Resize
from albumentations.pytorch import ToTensor
from torch.utils.data import Dataset
from tqdm import tqdm_notebook as tqdm
from matplotlib import pyplot as plt
model1 = create_small_dense_network()
es = EarlyStopping(monitor='val_loss', patience=10)
 mc = ModelCheckpoint('best_model1.h5', monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=True)
 model1.compile(optimizer='adam', loss='mean_squared_error', metrics=['mae'])
 hist1 = model1.fit(X_train, y_train, epochs=500, batch_size=256, verbose=0, validation_split=0.2, callbacks=[es, mc] )<load_pretrained>
class IntracranialDataset(Dataset):
def __init__(self, csv_file, path, labels, transform=None):
self.path = path
self.data = pd.read_csv(csv_file)
 self.transform = transform
self.labels = labels
def __len__(self):
return len(self.data)
 def __getitem__(self, idx):
img_name = os.path.join(self.path, self.data.loc[idx, 'Image'] + '.png')
 img = cv2.imread(img_name)
 if self.transform:
augmented = self.transform(image=img)
 img = augmented['image']
if self.labels:
labels = torch.tensor(
 self.data.loc[idx, ['epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural', 'any']])
 return {'image': img, 'labels': labels}
else:
return {'image': img}
model1.load_weights('best_model1.h5')
 show_random_preds(model1, X_test )<choose_model_class>
train = pd.read_csv(os.path.join(dir_csv, 'stage_1_train.csv'))
test = pd.read_csv(os.path.join(dir_csv, 'stage_1_sample_submission.csv'))
def create_convnet(n_outputs=30):
model = Sequential()
model.add(Convolution2D(32,(5,5), padding='same', input_shape=(96,96,1)))
 model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(Convolution2D(32,(5,5), padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(MaxPool2D(pool_size=(2,2)))
 model.add(Convolution2D(64,(3,3), padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(Convolution2D(64,(3,3), padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(MaxPool2D(pool_size=(2,2)))
 model.add(Convolution2D(96,(3,3), padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(Convolution2D(96,(3,3), padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(MaxPool2D(pool_size=(2,2)))
 model.add(Convolution2D(128,(3,3),padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(Convolution2D(128,(3,3),padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(MaxPool2D(pool_size=(2,2)))
 model.add(Convolution2D(256,(3,3),padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(Convolution2D(256,(3,3),padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(MaxPool2D(pool_size=(2,2)))
 model.add(Convolution2D(512,(3,3), padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(Convolution2D(512,(3,3), padding='same'))
model.add(LeakyReLU(alpha=0.1))
model.add(BatchNormalization())
 model.add(Flatten())
 model.add(Dense(512, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(n_outputs))
return model<train_model>
train[['ID', 'Image', 'Diagnosis']] = train['ID'].str.split('_', expand=True)
 train = train[['Image', 'Diagnosis', 'Label']]
train.drop_duplicates(inplace=True)
 train = train.pivot(index='Image', columns='Diagnosis', values='Label' ).reset_index()
train['Image'] = 'ID_' + train['Image']
train.head()
model2 = create_convnet()
es = EarlyStopping(monitor='val_loss', patience=10)
 mc = ModelCheckpoint('best_model2.h5', monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=True)
 model2.compile(optimizer=Adam() , loss='mean_squared_error', metrics=['mae'])
 hist2 = model2.fit(X_train, y_train, epochs=50, batch_size=128, verbose=0, validation_split=0.10, callbacks=[es, mc] )<load_pretrained>
png = glob.glob(os.path.join(dir_train_img, '*.png'))
png = [os.path.basename(png)[:-4] for png in png]
png = np.array(png)
 train = train[train['Image'].isin(png)]
train.to_csv('train.csv', index=False )
model2.load_weights('best_model2.h5')
 show_random_preds(model2, X_test )<categorify>
test[['ID','Image','Diagnosis']] = test['ID'].str.split('_', expand=True)
 test['Image'] = 'ID_' + test['Image']
test = test[['Image', 'Label']]
test.drop_duplicates(inplace=True)
 test.to_csv('test.csv', index=False )
class DataLoader(Sequence):
def __init__(self, X, y, batch_size, augmentations=None, as_rgb=False):
self.X, self.y = X, y
self.batch_size = batch_size
self.augment = augmentations
self.shuffle = True
self.as_rgb = as_rgb
self.on_epoch_end()
def __len__(self):

 return int(np.ceil(len(self.X)/ float(self.batch_size)))
 def __getitem__(self, idx):
indexes = self.indexes[idx*self.batch_size:(idx+1)*self.batch_size]
batch_X = self.X[indexes,...]
batch_y = self.y[indexes, :]
if self.as_rgb:
batch_X = np.tile(batch_X, reps=(1,1,1,3))
if self.augment is not None:
keypoints = np.array([ tuple(zip(point[::2], point[1::2])) for point in batch_y ])
 transformed = [ self.augment(image=x, keypoints=y)for x,y in zip(batch_X, keypoints)]
batch_X = np.stack([ z['image'] for z in transformed ], axis=0)
 batch_y = np.stack([ np.array(z['keypoints'] ).flatten(order='C')for z in transformed ], axis=0)
 return batch_X, batch_y
def on_epoch_end(self):

 self.indexes = np.arange(len(self.X))
if self.shuffle == True:
np.random.shuffle(self.indexes )<split>
transform_train = Compose([
ShiftScaleRotate() ,
ToTensor()
])
 transform_test= Compose([
ToTensor()
])
 train_dataset = IntracranialDataset(
 csv_file='train.csv', path=dir_train_img, transform=transform_train, labels=True)
 test_dataset = IntracranialDataset(
 csv_file='test.csv', path=dir_test_img, transform=transform_test, labels=False)
 data_loader_train = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=False, num_workers=4)
 data_loader_test = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=4 )
X_train2, X_valid, y_train2, y_valid = train_test_split(X_train, y_train, test_size=0.10, shuffle=True)
 transform = A.Compose([
A.ShiftScaleRotate(rotate_limit=30, p=0.5),
A.RandomBrightnessContrast(p=0.5),
A.GaussianBlur(p=0.5),
A.GaussNoise(var_limit=(1e-5, 1e-3), p=0.5),
], keypoint_params=A.KeypointParams(format='xy', remove_invisible=False))
train_loader = DataLoader(X_train2, y_train2, batch_size=128, augmentations=transform)
 print(X_train2.shape, y_train2.shape)
 print(X_valid.shape, y_valid.shape)
 x_batch, y_batch = train_loader[1]
show_random_samples(x_batch.squeeze() , y_batch )<train_on_grid>
device = torch.device("cuda:0")
 model = EfficientNet.from_pretrained('efficientnet-b0')
 model._fc = torch.nn.Linear(1280, n_classes)
 model.to(device)
 criterion = torch.nn.BCEWithLogitsLoss()
plist = [{'params': model.parameters() , 'lr': 2e-5}]
optimizer = optim.Adam(plist, lr=2e-5)
 model, optimizer = amp.initialize(model, optimizer, opt_level="O1")
es = EarlyStopping(monitor='val_loss', patience=20)
 mc = ModelCheckpoint('best_model3.h5', monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=True)
 model3 = create_convnet()
model3.compile(optimizer=Adam() , loss='mean_squared_error', metrics=['mae'])
 hist3 = model3.fit(train_loader, steps_per_epoch=len(train_loader),
validation_data=(X_valid, y_valid),
epochs=500, verbose=0, callbacks=[es, mc] )<find_best_model_class>
for epoch in range(n_epochs):
print('Epoch {}/{}'.format(epoch, n_epochs - 1))
print('-' * 10)
 model.train()
tr_loss = 0
tk0 = tqdm(data_loader_train, desc="Iteration")
 for step, batch in enumerate(tk0):
inputs = batch["image"]
labels = batch["labels"]
inputs = inputs.to(device, dtype=torch.float)
 labels = labels.to(device, dtype=torch.float)
 outputs = model(inputs)
 loss = criterion(outputs, labels)
 with amp.scale_loss(loss, optimizer)as scaled_loss:
scaled_loss.backward()
tr_loss += loss.item()
optimizer.step()
optimizer.zero_grad()
epoch_loss = tr_loss / len(data_loader_train)
 print('Training Loss: {:.4f}'.format(epoch_loss))
model3.load_weights('best_model3.h5')
 show_random_preds(model3, X_test )<load_pretrained>
for param in model.parameters() :
param.requires_grad = False
model.eval()
test_pred = np.zeros(( len(test_dataset)* n_classes, 1))
for i, x_batch in enumerate(tqdm(data_loader_test)) :
x_batch = x_batch["image"]
x_batch = x_batch.to(device, dtype=torch.float)
 with torch.no_grad() :
pred = model(x_batch)
 test_pred[(i * batch_size * n_classes):(( i + 1)* batch_size * n_classes)] = torch.sigmoid(
 pred ).detach().cpu().reshape(( len(x_batch)* n_classes, 1))
def create_specialist(n_outputs=30, weights=None, freeze=False):
model = create_convnet()
if weights is not None:
model.load_weights(weights)
 if freeze:
for layers in model.layers[:-10]:
layers.trainable = False
if n_outputs != 30:
model.layers.pop()
model.add(Dense(n_outputs))
return model
def train_specialist(model, keypoints_range, model_name):
train_data = pd.read_csv(train_dir)
 select_col_idx = list(range(*keypoints_range[model_name])) + [-1]
subdata = train_data.iloc[:, select_col_idx]
subdata = subdata.dropna()
X_train, y_train = format_dataset(subdata)
 X_train2, X_valid, y_train2, y_valid = train_test_split(X_train, y_train, test_size=0.10, shuffle=True)
 transform = A.Compose([A.ShiftScaleRotate(rotate_limit=30, p=0.5),
A.RandomBrightnessContrast(p=0.5),
A.GaussianBlur(p=0.5),
A.GaussNoise(var_limit=(1e-5, 1e-3), p=0.5)],
keypoint_params=A.KeypointParams(format='xy', remove_invisible=False))
train_loader = DataLoader(X_train2, y_train2, batch_size=128, augmentations=transform)
 es = EarlyStopping(monitor='val_loss', patience=10)
 mc = ModelCheckpoint(f'best_model_{model_name}.h5', monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=True)
 model.compile(optimizer=Adam() , loss='mean_squared_error', metrics=['mae'])
 hist = model.fit(train_loader, steps_per_epoch=len(train_loader),
validation_data=(X_valid, y_valid),
epochs=250, verbose=0, callbacks=[es, mc])
 model.load_weights(f'best_model_{model_name}.h5')
 return model, hist
class ConcatenateSpecialists:
def __init__(self, models):
self.models = models
def predict(self, X):
return np.hstack([ m.predict(X)for m in self.models ])
<load_pretrained>
submission = pd.read_csv(os.path.join(dir_csv, 'stage_1_sample_submission.csv'))
submission = pd.concat([submission.drop(columns=['Label']), pd.DataFrame(test_pred)], axis=1)
 submission.columns = ['ID', 'Label']
submission.to_csv('submission.csv', index=False)
 submission.head()
<find_best_params><EOS> 
!rm -rf /kaggle/working/apex
!rm test.csv
!rm train.csv