Kaggle competition: Rainforest Connection Species Audio Detection
<SOS> metric: WeightedLabelRankingAveragePrecision Kaggle data source: rainforest-connection-species-audio-detection<feature_engineering>
from IPython.display import Image
def add_ft_extractor(resnet):
resnet.extract_ft = lambda x: forward_extract_ft(resnet, x)
 def forward_extract_ft(self, x):
x = self.conv1(x)
 x = self.bn1(x)
 x = self.relu(x)
 x = self.maxpool(x)
 x = self.layer1(x)
 x = self.layer2(x)
 x = self.layer3(x)
 x = self.layer4(x)
 x = self.avgpool(x)
 ft = torch.flatten(x, 1)
 x = self.fc(ft)
 return x.view(-1), ft
def add_ft_extractor_enet(effnet):
effnet.forward = lambda x: forward_extract_ft_enet(effnet, x)
 def forward_extract_ft_enet(self, x):
x = self.extract_features(x)
 x = self._avg_pooling(x)
 ft = x.flatten(start_dim=1)
 x = self._dropout(ft)
 x = self._fc(x)
 return x.view(-1), ft<choose_model_class>
!pip install tensorflow-addons-0.12.1
def define_model(name, num_classes=1):
if "resnext" in name:
model = resnext50_32x4d(pretrained=False)
 model.nb_ft = model.fc.in_features
model.fc = nn.Linear(model.nb_ft, num_classes)
 add_ft_extractor(model)
 else:
model = EfficientNet.from_name(name)
 model.nb_ft = model._fc.in_features
model._fc = nn.Linear(model.nb_ft, num_classes)
 add_ft_extractor_enet(model)
 return model 
<choose_model_class>
!pip install image-classifiers
class RNNModel(nn.Module):
def __init__(self, ft_dim=2048, lstm_dim=64, dense_dim=256, use_msd=False, num_classes=9):
super().__init__()
self.use_msd = use_msd
self.mlp = nn.Sequential(
 nn.Linear(ft_dim, dense_dim * 2),
nn.ReLU() ,
nn.Linear(dense_dim * 2, dense_dim),
nn.ReLU() , 
)
 self.lstm = nn.LSTM(dense_dim, lstm_dim, batch_first=True, bidirectional=True)
 self.logits_exam = nn.Sequential(
 nn.Linear(lstm_dim * 4 + dense_dim * 2, lstm_dim),
nn.ReLU() ,
nn.Linear(lstm_dim, num_classes), 
)
 self.logits_img = nn.Sequential(
 nn.Linear(lstm_dim * 2 + dense_dim, lstm_dim),
nn.ReLU() ,
nn.Linear(lstm_dim, 1), 
)
 self.high_dropout = nn.Dropout(p=0.5)
 def forward(self, x):
features = self.mlp(x)
 features2, _ = self.lstm(features)
 features = torch.cat([features, features2], -1)
 mean = features.mean(1)
 max_, _ = features.max(1)
 pooled = torch.cat([mean, max_], -1)
 if self.use_msd and self.training:
logits_exam = torch.mean(
 torch.stack(
 [self.logits_exam(self.high_dropout(pooled)) for _ in range(5)],
dim=0, 
),
dim=0, 
)
 logits_img = torch.mean(
 torch.stack(
 [self.logits_img(self.high_dropout(features)) for _ in range(5)],
dim=0, 
),
dim=0, 
)
 else:
logits_exam = self.logits_exam(pooled)
 logits_img = self.logits_img(features)
 return logits_exam, logits_img.squeeze(-1 )<categorify>
tf.__version__
def post_process(exam_pred, image_pred, eps=1e-6):
has_pe_image = image_pred.max() > 0.5 
(negative_exam_for_pe, rv_lv_ratio_gte_1, rv_lv_ratio_lt_1, leftsided_pe,
chronic_pe, rightsided_pe, acute_and_chronic_pe, central_pe, indeterminate)= exam_pred
broken = False
if has_pe_image:
if rv_lv_ratio_gte_1 < 0.5 and rv_lv_ratio_lt_1 < 0.5:
broken = True
max_ = np.max([leftsided_pe, rightsided_pe, central_pe])
 if max_ < 0.5:
broken = True
if not broken and has_pe_image:
if rv_lv_ratio_gte_1 > 0.5 and rv_lv_ratio_lt_1 > 0.5:
if rv_lv_ratio_gte_1 > rv_lv_ratio_lt_1:
rv_lv_ratio_lt_1 = 0.5 - eps
else:
rv_lv_ratio_gte_1 = 0.5 - eps
min_ = np.min([chronic_pe, acute_and_chronic_pe])
 if min_ > 0.5:
if chronic_pe > acute_and_chronic_pe:
acute_and_chronic_pe = 0.5 - eps
else:
chronic_pe = 0.5 - eps
if broken:
image_pred = np.clip(image_pred, 0, 0.5 - eps)
 assert image_pred.max() < 0.5
has_pe_image = image_pred.max() > 0.5
if not has_pe_image:
if indeterminate > 0.5 and negative_exam_for_pe > 0.5:
if indeterminate > negative_exam_for_pe:
negative_exam_for_pe = 0.5 - eps
else:
indeterminate = 0.5 - eps
elif indeterminate < 0.5 and negative_exam_for_pe < 0.5:
if indeterminate > negative_exam_for_pe:
indeterminate = 0.5 + eps
else:
negative_exam_for_pe = 0.5 + eps 
(rv_lv_ratio_gte_1, rv_lv_ratio_lt_1, leftsided_pe,
chronic_pe, rightsided_pe, acute_and_chronic_pe, central_pe)= np.clip(
 exam_pred[[1, 2, 3, 4, 5, 6, 7]],
0,
0.5 - eps 
)
 return np.array([
negative_exam_for_pe,
rv_lv_ratio_gte_1,
rv_lv_ratio_lt_1,
leftsided_pe,
chronic_pe,
rightsided_pe,
acute_and_chronic_pe,
central_pe,
indeterminate,
]), image_pred<feature_engineering>
SEED = 42
def seed_everything(seed):
random.seed(seed)
 os.environ['PYTHONHASHSEED'] = str(seed)
 np.random.seed(seed)
 tf.random.set_seed(seed)
 seed_everything(SEED )
def check_consistency(sub, test):

 for i in test['StudyInstanceUID'].unique() :
df_tmp = sub.loc[sub.id.str.contains(i, regex = False)].reset_index(drop = True)
 df_tmp['StudyInstanceUID'] = df_tmp['id'].str.split('_' ).str[0]
df_tmp['label_type'] = df_tmp['id'].str.split('_' ).str[1:].apply(lambda x: '_'.join(x))
del df_tmp['id']
if i == test['StudyInstanceUID'].unique() [0]:
df = df_tmp.copy()
else:
df = pd.concat([df, df_tmp], axis = 0)
 df_exam = df.pivot(index = 'StudyInstanceUID', columns = 'label_type', values = 'label')
 df_image = sub.loc[sub.id.isin(test.SOPInstanceUID)].reset_index(drop = True)
 df_image = df_image.merge(test, how = 'left', left_on = 'id', right_on = 'SOPInstanceUID')
 df_image.rename(columns = {"label": "pe_present_on_image"}, inplace = True)
 del df_image['id']
df = df_exam.merge(df_image, how = 'left', on = 'StudyInstanceUID')
 ids = ['StudyInstanceUID', 'SeriesInstanceUID', 'SOPInstanceUID']
labels = [c for c in df.columns if c not in ids]
df = df[ids + labels]
df['positive_images_in_exam'] = df['StudyInstanceUID'].map(df.groupby(['StudyInstanceUID'] ).pe_present_on_image.max())
 df_pos = df.loc[df.positive_images_in_exam > 0.5]
df_neg = df.loc[df.positive_images_in_exam <= 0.5]
rule1a = df_pos.loc[(( df_pos.rv_lv_ratio_lt_1 > 0.5)& 
(df_pos.rv_lv_ratio_gte_1 > 0.5)) | 
(( df_pos.rv_lv_ratio_lt_1 <= 0.5)& 
(df_pos.rv_lv_ratio_gte_1 <= 0.5)) ].reset_index(drop = True)
 rule1a['broken_rule'] = '1a'
rule1b = df_pos.loc[(df_pos.central_pe <= 0.5)& 
(df_pos.rightsided_pe <= 0.5)& 
(df_pos.leftsided_pe <= 0.5)].reset_index(drop = True)
 rule1b['broken_rule'] = '1b'
rule1c = df_pos.loc[(df_pos.acute_and_chronic_pe > 0.5)& 
(df_pos.chronic_pe > 0.5)].reset_index(drop = True)
 rule1c['broken_rule'] = '1c'
rule1d = df_pos.loc[(df_pos.indeterminate > 0.5)| 
(df_pos.negative_exam_for_pe > 0.5)].reset_index(drop = True)
 rule1d['broken_rule'] = '1d'
rule2a = df_neg.loc[(( df_neg.indeterminate > 0.5)& 
(df_neg.negative_exam_for_pe > 0.5)) | 
(( df_neg.indeterminate <= 0.5)& 
(df_neg.negative_exam_for_pe <= 0.5)) ].reset_index(drop = True)
 rule2a['broken_rule'] = '2a'
rule2b = df_neg.loc[(df_neg.rv_lv_ratio_lt_1 > 0.5)| 
(df_neg.rv_lv_ratio_gte_1 > 0.5)| 
(df_neg.central_pe > 0.5)| 
(df_neg.rightsided_pe > 0.5)| 
(df_neg.leftsided_pe > 0.5)| 
(df_neg.acute_and_chronic_pe > 0.5)| 
(df_neg.chronic_pe > 0.5)].reset_index(drop = True)
 rule2b['broken_rule'] = '2b'
errors = pd.concat([rule1a, rule1b, rule1c, rule1d, rule2a, rule2b], axis = 0)
 print('Found', len(errors), 'inconsistent predictions')
 return errors<define_variables>
ResNet34, preprocess_input = Classifiers.get('resnet34' )
def extract_features(models, dataset, batch_size=32):
fts = np.empty(( 0, models[0].nb_ft))
zs = np.empty(0)
 preds = np.empty(0)
 loader = DataLoader(
 dataset,
batch_size=batch_size,
shuffle=False,
num_workers=1,
drop_last=False,
pin_memory=True 
)
 with torch.no_grad() :
for x, z in loader:
fts_tmp = []
preds_tmp = []
for model in models:
pred, ft = model(x.cuda())
 preds_tmp.append(torch.sigmoid(pred ).detach().cpu().numpy())
 fts_tmp.append(ft.detach().cpu().numpy())
 preds = np.concatenate([preds, np.mean(preds_tmp, 0)])
 fts = np.concatenate([fts, np.mean(fts_tmp, 0)])
 zs = np.concatenate([zs, z.numpy() ])
 order = np.argsort(zs)
 fts = fts[order]
preds = preds[order]
return preds, fts, order<prepare_output>
cfg = {
'parse_params': {
'cut_time': 10,
},
'data_params': {
'sample_time': 6,
'spec_fmax': 24000.0,
'spec_fmin': 40.0,
'spec_mel': 384,
'mel_power': 2,
'img_shape':(384, 768)
 },
'model_params': {
'batchsize_per_tpu': 18,
'iteration_per_epoch': 192,
'epoch': 30,
'arch': ResNet34,
'arch_preprocess': preprocess_input,
'freeze_to': 0,
'loss': {
'fn': tfa.losses.SigmoidFocalCrossEntropy,
'params': {'alpha':0.25,
'gamma':2.0}
},
'optim': {
'fn': tfa.optimizers.RectifiedAdam,
'params': {'lr': 1e-3, 'total_steps': 30*192*8, 'warmup_proportion': 0.3, 'min_lr': 3e-6},
},
'mixup': True
}
}
def pred_to_sub(unique_df, df, pred_exams, pred_imgs, orders):
df_dic = {}
for i, study in enumerate(unique_df['StudyInstanceUID'].values):
reverse_order = np.argsort(orders[i])
 for t, target in enumerate(EXAM_TARGETS):
name = f'{study}_{target}'
label = pred_exams[i][t]
df_dic[name] = label
df_patient = df[df['StudyInstanceUID'] == study]
for s, sop in enumerate(df_patient['SOPInstanceUID'].values):
df_dic[sop] = pred_imgs[i][reverse_order[s]]
sub = pd.DataFrame.from_dict(df_dic, orient='index', columns=['label'] ).reset_index()
return sub.rename({'index': 'id'}, axis=1 )<load_from_csv>
strategy = tf.distribute.experimental.TPUStrategy(tpu)
 AUTOTUNE = tf.data.experimental.AUTOTUNE
GCS_DS_PATH = KaggleDatasets().get_gcs_path('rfcx-species-audio-detection')
 TRAIN_TFREC = GCS_DS_PATH + "/tfrecords/train"
TEST_TFREC = GCS_DS_PATH + "/tfrecords/test"
df_test = pd.read_csv(DATA_PATH + "test.csv" )<feature_engineering>
CUT = cfg['parse_params']['cut_time']
SR = 48000
TIME = cfg['data_params']['sample_time']
FMAX = cfg['data_params']['spec_fmax']
FMIN = cfg['data_params']['spec_fmin']
N_MEL = cfg['data_params']['spec_mel']
HEIGHT, WIDTH = cfg['data_params']['img_shape']
CLASS_N = 24
paths_test = [DATA_PATH + f"test/{study}/{series}/" for study, series in df_test[['StudyInstanceUID', 'SeriesInstanceUID']].values]
df_test['path'] = paths_test<remove_duplicates>
raw_dataset = tf.data.TFRecordDataset([TRAIN_TFREC + '/00-148.tfrec'])
 raw_dataset
unique_df_test = df_test[['path', 'StudyInstanceUID', 'SeriesInstanceUID']].drop_duplicates().reset_index(drop=True )<define_variables>
feature_description = {
'recording_id': tf.io.FixedLenFeature([], tf.string, default_value=''),
'audio_wav': tf.io.FixedLenFeature([], tf.string, default_value=''),
'label_info': tf.io.FixedLenFeature([], tf.string, default_value=''),
}
parse_dtype = {
'audio_wav': tf.float32,
'recording_id': tf.string,
'species_id': tf.int32,
'songtype_id': tf.int32,
't_min': tf.float32,
'f_min': tf.float32,
't_max': tf.float32,
'f_max':tf.float32,
'is_tp': tf.int32
}
@tf.function
def _parse_function(example_proto):
sample = tf.io.parse_single_example(example_proto, feature_description)
 wav, _ = tf.audio.decode_wav(sample['audio_wav'], desired_channels=1)
 label_info = tf.strings.split(sample['label_info'], sep='"')[1]
labels = tf.strings.split(label_info, sep=';')
 @tf.function
def _cut_audio(label):
items = tf.strings.split(label, sep=',')
 spid = tf.squeeze(tf.strings.to_number(items[0], tf.int32))
soid = tf.squeeze(tf.strings.to_number(items[1], tf.int32))
tmin = tf.squeeze(tf.strings.to_number(items[2]))
fmin = tf.squeeze(tf.strings.to_number(items[3]))
tmax = tf.squeeze(tf.strings.to_number(items[4]))
fmax = tf.squeeze(tf.strings.to_number(items[5]))
tp = tf.squeeze(tf.strings.to_number(items[6], tf.int32))
tmax_s = tmax * tf.cast(SR, tf.float32)
 tmin_s = tmin * tf.cast(SR, tf.float32)
 cut_s = tf.cast(CUT * SR, tf.float32)
 all_s = tf.cast(60 * SR, tf.float32)
 tsize_s = tmax_s - tmin_s
cut_min = tf.cast(
 tf.maximum(0.0,
tf.minimum(tmin_s -(cut_s - tsize_s)/ 2,
tf.minimum(tmax_s +(cut_s - tsize_s)/ 2, all_s)- cut_s)
), tf.int32 
)
 cut_max = cut_min + CUT * SR
_sample = {
'audio_wav': tf.reshape(wav[cut_min:cut_max], [CUT*SR]),
'recording_id': sample['recording_id'],
'species_id': spid,
'songtype_id': soid,
't_min': tmin - tf.cast(cut_min, tf.float32)/tf.cast(SR, tf.float32),
'f_min': fmin,
't_max': tmax - tf.cast(cut_min, tf.float32)/tf.cast(SR, tf.float32),
'f_max': fmax,
'is_tp': tp
}
return _sample
samples = tf.map_fn(_cut_audio, labels, dtype=parse_dtype)
 return samples
parsed_dataset = raw_dataset.map(_parse_function ).unbatch()
CP_PATH = ".. /input/peweights/"<define_variables>
@tf.function
def _cut_wav(x):
cut_min = tf.random.uniform([], maxval=(CUT-TIME)*SR, dtype=tf.int32)
 cut_max = cut_min + TIME * SR
cutwave = tf.reshape(x['audio_wav'][cut_min:cut_max], [TIME*SR])
 y = {}
y.update(x)
 y['audio_wav'] = cutwave
y['t_min'] = tf.maximum(0.0, x['t_min'] - tf.cast(cut_min, tf.float32)/ SR)
 y['t_max'] = tf.maximum(0.0, x['t_max'] - tf.cast(cut_min, tf.float32)/ SR)
 return y
@tf.function
def _cut_wav_val(x):
cut_min =(CUT-TIME)*SR // 2
cut_max = cut_min + TIME * SR
cutwave = tf.reshape(x['audio_wav'][cut_min:cut_max], [TIME*SR])
 y = {}
y.update(x)
 y['audio_wav'] = cutwave
y['t_min'] = tf.maximum(0.0, x['t_min'] - tf.cast(cut_min, tf.float32)/ SR)
 y['t_max'] = tf.maximum(0.0, x['t_max'] - tf.cast(cut_min, tf.float32)/ SR)
 return y
efficientnets = [f"efficientnet-b3__{i}.pt" for i in range(5)]
rnns_1 = [f'rnn_2_{i}.pt' for i in range(5)]
rnns_2 = [f'rnn_3_{i}.pt' for i in range(5)]<load_pretrained>
@tf.function
def _filtTP(x):
return x['is_tp'] == 1
first_lvl_models = []
for weights in efficientnets:
model = define_model('efficientnet-b3' ).cuda().eval()
model = load_model_weights(model, CP_PATH + weights)
 first_lvl_models.append(model )<load_pretrained>
def show_wav(sample, ax):
wav = sample["audio_wav"].numpy()
rate = SR
ax.plot(np.arange(len(wav)) / rate, wav)
 ax.set_title(
 sample["recording_id"].numpy().decode()
+("/%d" % sample["species_id"])
 +("TP" if sample["is_tp"] else "FP"))
return Audio(( wav * 2**15 ).astype(np.int16), rate=rate)
 fig, ax = plt.subplots(figsize=(15, 3))
show_wav(next(iter(parsed_dataset)) , ax )
second_lvl_models = []
for weights in rnns_1:
model = RNNModel(
 ft_dim=1536,
lstm_dim=64,
use_msd=True,
).cuda().eval()
model = load_model_weights(model, CP_PATH + weights)
 second_lvl_models.append(model)
<define_variables>
@tf.function
def _wav_to_spec(x):
mel_power = cfg['data_params']['mel_power']
stfts = tf.signal.stft(x["audio_wav"], frame_length=2048, frame_step=512, fft_length=2048)
 spectrograms = tf.abs(stfts)** mel_power
num_spectrogram_bins = stfts.shape[-1]
lower_edge_hertz, upper_edge_hertz, num_mel_bins = FMIN, FMAX, N_MEL
linear_to_mel_weight_matrix = tf.signal.linear_to_mel_weight_matrix(
 num_mel_bins, num_spectrogram_bins, SR, lower_edge_hertz,
upper_edge_hertz)
 mel_spectrograms = tf.tensordot(
 spectrograms, linear_to_mel_weight_matrix, 1)
 mel_spectrograms.set_shape(spectrograms.shape[:-1].concatenate(
 linear_to_mel_weight_matrix.shape[-1:]))
log_mel_spectrograms = tf.math.log(mel_spectrograms + 1e-6)
 y = {
'audio_spec': tf.transpose(log_mel_spectrograms),
}
y.update(x)
 return y
spec_dataset = parsed_dataset.filter(_filtTP ).map(_cut_wav ).map(_wav_to_spec )
IS_PUBLIC = len(unique_df_test)<= 650
DO_PUBLIC = True
DO_PRIVATE = True
DO_INFERENCE =(IS_PUBLIC and DO_PUBLIC)or(not IS_PUBLIC and DO_PRIVATE )<create_dataframe>
@tf.function
def _create_annot(x):
targ = tf.one_hot(x["species_id"], CLASS_N, on_value=x["is_tp"], off_value=0)
 return {
'input': x["audio_spec"],
'target': tf.cast(targ, tf.float32)
 }
annot_dataset = spec_dataset.map(_create_annot )
if DO_INFERENCE:
all_pred_exams = []
all_pred_imgs = []
orders = []
for path, study, series in tqdm(unique_df_test.values):
df_patient = df_test[df_test['StudyInstanceUID'] == study].reset_index(drop=True)
 dataset = PatientDataset(df_patient, path, normalizer())
 ')
 preds_1, fts, order = extract_features(first_lvl_models, dataset, batch_size=16)
 orders.append(order)
 ')
 pred_exams = []
pred_imgs = []
for model in second_lvl_models:
pred_exam, pred_img = inference_second_lvl(model, fts)
 pred_exams.append(pred_exam)
 pred_imgs.append(pred_img)
 pred_exams = np.mean(pred_exams, 0)
 pred_imgs = np.mean(pred_imgs, 0)
 pred_exams, pred_imgs = post_process(pred_exams, pred_imgs, eps=1e-6)
 all_pred_exams.append(pred_exams)
 all_pred_imgs.append(pred_imgs)
 sub = pred_to_sub(unique_df_test, df_test, all_pred_exams, all_pred_imgs, orders)
 else:
sub = pd.read_csv(DATA_PATH + "sample_submission.csv" )<compute_test_metric>
@tf.function
def _preprocess_img(x, training=False, test=False):
image = tf.expand_dims(x, axis=-1)
 image = tf.image.resize(image, [HEIGHT, WIDTH])
 image = tf.image.per_image_standardization(image)
 @tf.function
def _specaugment(image):
ERASE_TIME = 76
ERASE_MEL = 16
image = tf.expand_dims(image, axis=0)
 xoff = tf.random.uniform([2], minval=ERASE_TIME//2, maxval=WIDTH-ERASE_TIME//2, dtype=tf.int32)
 xsize = tf.random.uniform([2], minval=ERASE_TIME//2, maxval=ERASE_TIME, dtype=tf.int32)
 yoff = tf.random.uniform([2], minval=ERASE_MEL//2, maxval=HEIGHT-ERASE_MEL//2, dtype=tf.int32)
 ysize = tf.random.uniform([2], minval=ERASE_MEL//2, maxval=ERASE_MEL, dtype=tf.int32)
 mask_y = tf.math.logical_and(new_y0[:, tf.newaxis] <= target, target <= new_y1[:, tf.newaxis])
 mask_x = tf.math.logical_and(new_x0[:, tf.newaxis] <= target, target <= new_x1[:, tf.newaxis])
 mask = tf.cast(tf.math.logical_and(mask_y[:, :, tf.newaxis], mask_x[:, tf.newaxis, :]), tf.float32)
 new_images = images * tf.broadcast_to(1 - mask[:, :, :, tf.newaxis], [batch_size, DIM, DIM, 3])+ \
image = tfa.image.cutout(image, [HEIGHT, xsize[0]], offset=[HEIGHT//2, xoff[0]])
 image = tfa.image.cutout(image, [HEIGHT, xsize[1]], offset=[HEIGHT//2, xoff[1]])
 image = tfa.image.cutout(image, [ysize[0], WIDTH], offset=[yoff[0], WIDTH//2])
 image = tfa.image.cutout(image, [ysize[1], WIDTH], offset=[yoff[1], WIDTH//2])
 image = tf.squeeze(image, axis=0)
 return image
@tf.function
def _random_crop_and_resize(image):
ratio =(3/4,4/3)
 crop_scale = tf.random.uniform([1], minval=0.8, maxval=1.0, dtype=tf.float32)[0]
log_ratio =(tf.math.log(ratio[0]), tf.math.log(ratio[1]))
aspect_ratio = tf.math.exp(tf.random.uniform([1], minval= log_ratio[0], maxval= log_ratio[1], dtype=tf.float32)) [0]
if HEIGHT<WIDTH:
image = tf.image.random_crop(image , [HEIGHT*crop_scale, HEIGHT*crop_scale*aspect_ratio,1])
 else:
image = tf.image.random_crop(image , [ WIDTH*crop_scale ,WIDTH*crop_scale*aspect_ratio,1])
 image = tf.image.resize(image, [HEIGHT, WIDTH])
 return image
if training:
gau = tf.keras.layers.GaussianNoise(0.3)
 image = tf.cond(tf.random.uniform([])< 0.25, lambda: gau(image, training=True), lambda: image)
 image = tf.image.random_brightness(image, 0.2)
 image= tf.cond(tf.random.uniform([])< 0.33 ,lambda : _random_crop_and_resize(image), lambda: image)
 image = tf.cond(tf.random.uniform([])< 0.5, lambda: _specaugment(image), lambda: image)
 if test:
pass
image =(image - tf.reduce_min(image)) /(tf.reduce_max(image)- tf.reduce_min(image)) * 255.0
image = tf.image.grayscale_to_rgb(image)
 image = cfg['model_params']['arch_preprocess'](image)
 return image
@tf.function
def _preprocess(x):
image = _preprocess_img(x['input'], training=True, test=False)
 return(image, x["target"])
 @tf.function
def _preprocess_val(x):
image = _preprocess_img(x['input'], training=False, test=False)
 return(image, x["target"])
 @tf.function
def _preprocess_test(x):
image = _preprocess_img(x['audio_spec'], training=False, test=True)
 return(image, x["recording_id"] )
check_consistency(sub, df_test )<save_to_csv>
def create_model() :
with strategy.scope() :
backbone = cfg['model_params']['arch'](( 224, 224, 3), include_top=False, weights='imagenet')
 if cfg['model_params']['freeze_to'] is None:
for layer in backbone.layers:
layer.trainable = False
else:
for layer in backbone.layers[:cfg['model_params']['freeze_to']]:
layer.trainable = False
model = tf.keras.Sequential([
backbone,
tf.keras.layers.GlobalAveragePooling2D() ,
tf.keras.layers.BatchNormalization() ,
tf.keras.layers.Dropout(0.4),
tf.keras.layers.Dense(1024, activation='relu', kernel_initializer=tf.keras.initializers.he_normal()),
tf.keras.layers.BatchNormalization() ,
tf.keras.layers.Dropout(0.4),
tf.keras.layers.Dense(CLASS_N, bias_initializer=tf.keras.initializers.Constant(-2.))])
 return model
model = create_model()
model.summary()
sub.to_csv('submission.csv', index=False)
 sub<install_modules>
@tf.function
def _mixup(inp, targ):
indice = tf.range(len(inp))
indice = tf.random.shuffle(indice)
 sinp = tf.gather(inp, indice, axis=0)
 starg = tf.gather(targ, indice, axis=0)
 if tf.random.uniform([1], minval= 0, maxval= 1, dtype=tf.float32)<0.5:
alpha = 0.4
t = tf.compat.v1.distributions.Beta(alpha, alpha ).sample([len(inp)])
 else:
t = tf.random.uniform([len(inp)], minval= 0, maxval=0.5, dtype=tf.float32)
 tx = tf.reshape(t, [-1, 1, 1, 1])
 ty = tf.reshape(t, [-1, 1])
 x = inp * tx + sinp *(1-tx)
 y = targ * ty + starg *(1-ty)
 return x, y
package_path = '.. /input/efficientnet-pytorch-07/efficientnet_pytorch-0.7.0'
!cp.. /input/gdcm-conda-install/gdcm.tar.
 !tar -xvzf gdcm.tar
!conda install --offline./gdcm/gdcm-2.8.9-py37h71b2a6d_0.tar.bz2<define_variables>
tfrecs = sorted(tf.io.gfile.glob(TRAIN_TFREC + '/*.tfrec'))
parsed_trainval =(tf.data.TFRecordDataset(tfrecs, num_parallel_reads=AUTOTUNE)
.map(_parse_function, num_parallel_calls=AUTOTUNE ).unbatch() 
.filter(_filtTP ).enumerate() )
CFG = {
'train': False,
'train_img_path': '.. /input/rsna-str-pulmonary-embolism-detection/train',
'test_img_path': '.. /input/rsna-str-pulmonary-embolism-detection/test',
'cv_fold_path': '.. /input/stratified-validation-strategy/rsna_train_splits_fold_20.csv',
'train_path': '.. /input/rsna-str-pulmonary-embolism-detection/train.csv',
'test_path': '.. /input/rsna-str-pulmonary-embolism-detection/test.csv',
'image_target_cols': [
'pe_present_on_image',
],
'exam_target_cols': [
'negative_exam_for_pe',
'rv_lv_ratio_gte_1',
'rv_lv_ratio_lt_1',
'leftsided_pe',
'chronic_pe',
'rightsided_pe',
'acute_and_chronic_pe',
'central_pe',
'indeterminate'
],
'img_num': 200,
'img_size': 256,
'lr': 0.0005,
'epochs': 3,
'device': 'cuda',
'train_bs': 2,
'accum_iter': 8,
'verbose_step': 1,
'num_workers': 4,
'efbnet': 'efficientnet-b0',
'train_folds': [np.arange(0,16),
np.concatenate([np.arange(0,12), np.arange(16,20)]),
np.concatenate([np.arange(0,8), np.arange(12,20)]),
np.concatenate([np.arange(0,4), np.arange(8,20)]),
np.arange(4,20),
],
'valid_folds': [np.arange(16,20),
np.arange(12,16),
np.arange(8,12),
np.arange(4,8),
np.arange(0,4)
 ],
'model_path': '.. /input/kh-rsna-model',
'tag': 'efb0_stage2_multilabel'
}
SEED = 42321
def seed_everything(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
torch.backends.cudnn.benchmark = True
def window(img, WL=50, WW=350):
upper, lower = WL+WW//2, WL-WW//2
X = np.clip(img.copy() , lower, upper)
 X = X - np.min(X)
 X = X / np.max(X)
 return X
def get_img(path):
d = pydicom.read_file(path)


 img =(d.pixel_array * d.RescaleSlope)+ d.RescaleIntercept
r = window(img, -600, 1500)
 g = window(img, 100, 700)
 b = window(img, 40, 400)
 res = np.concatenate([r[:, :, np.newaxis],
g[:, :, np.newaxis],
b[:, :, np.newaxis]], axis=-1)
 res = zoom(res, [CFG['img_size']/res.shape[0], CFG['img_size']/res.shape[1], 1.], prefilter=False, order=1)
 return res
class RSNADatasetStage1(Dataset):
def __init__(
 self, df, label_smoothing, data_root,
image_subsampling=True, transforms=None, output_label=True 
):
super().__init__()
self.df = df.reset_index(drop=True ).copy()
self.label_smoothing = label_smoothing
self.transforms = transforms
self.data_root = data_root
self.output_label = output_label
def __len__(self):
return self.df.shape[0]
def __getitem__(self, index: int):
if self.output_label:
target = self.df[CFG['image_target_cols']].values[index]
path = "{}/{}/{}/{}.dcm".format(self.data_root,
self.df.iloc[index]['StudyInstanceUID'],
self.df.iloc[index]['SeriesInstanceUID'],
self.df.iloc[index]['SOPInstanceUID'])
 img = get_img(path)
 if self.transforms:
img = self.transforms(image=img)['image']
if self.output_label == True:
target = np.clip(target, self.label_smoothing, 1 - self.label_smoothing)
 return img, target
else:
return img
class RSNADataset(Dataset):
def __init__(
 self, df, label_smoothing, data_root,
image_subsampling=True, transforms=None, output_label=True 
):
super().__init__()
self.df = df
self.patients = self.df['StudyInstanceUID'].unique()
self.image_subsampling = image_subsampling
self.label_smoothing = label_smoothing
self.transforms = transforms
self.data_root = data_root
self.output_label = output_label
def get_patients(self):
return self.patients
def __len__(self):
return len(self.patients)
 def __getitem__(self, index: int):
patient = self.patients[index]
df_ = self.df.loc[self.df.StudyInstanceUID == patient]
per_image_feats = get_stage1_columns()
if self.image_subsampling:
img_num = min(CFG['img_num'], df_.shape[0])
 img_ix = np.random.choice(np.arange(df_.shape[0]), replace=False, size=img_num)
 imgs = np.zeros(( CFG['img_num'],), np.float32)
 per_image_preds = np.zeros(( CFG['img_num'], len(per_image_feats)) , np.float32)
 locs = np.zeros(( CFG['img_num'],), np.float32)
 image_masks = np.zeros(( CFG['img_num'],), np.float32)
 image_masks[:img_num] = 1.
 if self.output_label:
exam_label = df_[CFG['exam_target_cols']].values[0]
image_labels = np.zeros(( CFG['img_num'], len(CFG['image_target_cols'])) , np.float32)
 else:
img_num = df_.shape[0]
img_ix = np.arange(df_.shape[0])
 imgs = np.zeros(( img_num,), np.float32)
 per_image_preds = np.zeros(( img_num, len(per_image_feats)) , np.float32)
 locs = np.zeros(( img_num,), np.float32)
 image_masks = np.zeros(( img_num,), np.float32)
 image_masks[:img_num] = 1.
 if self.output_label:
exam_label = df_[CFG['exam_target_cols']].values[0]
image_labels = np.zeros(( img_num, len(CFG['image_target_cols'])) , np.float32)
 for i, im_ix in enumerate(img_ix):
path = "{}/{}/{}/{}.dcm".format(self.data_root,
df_['StudyInstanceUID'].values[im_ix],
df_['SeriesInstanceUID'].values[im_ix],
df_['SOPInstanceUID'].values[im_ix])
 d = pydicom.read_file(path)
 locs[i] = d.ImagePositionPatient[2]
per_image_preds[i,:] = df_[per_image_feats].values[im_ix,:]
if self.output_label == True:
image_labels[i] = df_[CFG['image_target_cols']].values[im_ix]
seq_ix = np.argsort(locs)

locs = locs[seq_ix]
locs[1:img_num] = locs[1:img_num]-locs[0:img_num-1]
locs[0] = 0
per_image_preds = per_image_preds[seq_ix]
if self.output_label == True:
image_labels = image_labels[seq_ix]
image_labels = np.clip(image_labels, self.label_smoothing, 1 - self.label_smoothing)
 exam_label = np.clip(exam_label, self.label_smoothing, 1 - self.label_smoothing)
 return imgs, per_image_preds, locs, image_labels, exam_label, image_masks
else:
return imgs, per_image_preds, locs, img_num, index, seq_ix
HorizontalFlip, VerticalFlip, IAAPerspective, ShiftScaleRotate, CLAHE, RandomRotate90,
Transpose, ShiftScaleRotate, Blur, OpticalDistortion, GridDistortion, HueSaturationValue,
IAAAdditiveGaussianNoise, GaussNoise, MotionBlur, MedianBlur, IAAPiecewiseAffine,
IAASharpen, IAAEmboss, RandomBrightnessContrast, Flip, OneOf, Compose, Normalize, Cutout 
)
 def get_train_transforms() :
return Compose([
ToTensorV2(p=1.0),
], p=1.)

 def get_valid_transforms() :
return Compose([
ToTensorV2(p=1.0),
], p=1.)

 class RNSAImageFeatureExtractor(nn.Module):
def __init__(self):
super().__init__()
self.cnn_model = EfficientNet.from_name(CFG['efbnet'])
 self.pooling = nn.AdaptiveAvgPool2d(1)
 def get_dim(self):
return self.cnn_model._fc.in_features
def forward(self, x):
feats = self.cnn_model.extract_features(x)
 return self.pooling(feats ).view(x.shape[0], -1)
 class RSNAImgClassifierSingle(nn.Module):
def __init__(self):
super().__init__()
self.cnn_model = RNSAImageFeatureExtractor()
self.image_predictors = nn.Linear(self.cnn_model.get_dim() , 1)
 def forward(self, imgs):
imgs_embdes = self.cnn_model(imgs)
 image_preds = self.image_predictors(imgs_embdes)
 return image_preds
class RSNAImgClassifier(nn.Module):
def __init__(self):
super().__init__()
self.cnn_model = RNSAImageFeatureExtractor()
self.image_predictors = nn.Linear(self.cnn_model.get_dim() , 9)
 def forward(self, imgs):
imgs_embdes = self.cnn_model(imgs)
 image_preds = self.image_predictors(imgs_embdes)
 return image_preds
class TimeDistributed(nn.Module):
def __init__(self, module, batch_first=True):
super(TimeDistributed, self ).__init__()
self.module = module
self.batch_first = batch_first
def forward(self, x):

 x_size= x.size()
c_in = x.contiguous().view(x_size[0] * x_size[1], *x_size[2:])
 c_out = self.module(c_in)
 r_in = c_out.view(x_size[0], x_size[1], -1)
 if self.batch_first is False:
r_in = r_in.permute(1, 0, 2)
 return r_in
class RSNAClassifier(nn.Module):
def __init__(self, hidden_size=64):
super().__init__()
self.gru = nn.GRU(len(get_stage1_columns())+1, hidden_size, bidirectional=True, batch_first=True, num_layers=2)
 self.image_predictors = TimeDistributed(nn.Linear(hidden_size*2, 1))
self.exam_predictor = nn.Linear(hidden_size*2*2, 9)
 def forward(self, img_preds, locs):
embeds = torch.cat([img_preds, locs.view(locs.shape[0], locs.shape[1], 1)], dim=2)
 embeds, _ = self.gru(embeds)
 image_preds = self.image_predictors(embeds)
 avg_pool = torch.mean(embeds, 1)
 max_pool, _ = torch.max(embeds, 1)
 conc = torch.cat([avg_pool, max_pool], 1)
 exam_pred = self.exam_predictor(conc)
 return image_preds, exam_pred
def rsna_wloss_inference(y_true_img, y_true_exam, y_pred_img, y_pred_exam, chunk_sizes):

 y_true_img, y_true_exam, y_pred_img, y_pred_exam = torch.tensor(y_true_img, dtype=torch.float32), torch.tensor(y_true_exam, dtype=torch.float32), torch.tensor(y_pred_img, dtype=torch.float32), torch.tensor(y_pred_exam, dtype=torch.float32)
 y_true_img_chunks, y_true_exam_chunks, y_pred_img_chunks, y_pred_exam_chunks = torch.split(y_true_img, chunk_sizes, dim=0), torch.split(y_true_exam, chunk_sizes, dim=0), torch.split(y_pred_img, chunk_sizes, dim=0), torch.split(y_pred_exam, chunk_sizes, dim=0)
 label_w = torch.tensor([0.0736196319, 0.2346625767, 0.0782208589, 0.06257668712, 0.1042944785, 0.06257668712, 0.1042944785, 0.1877300613, 0.09202453988] ).view(1, -1)
 img_w = 0.07361963
bce_func = torch.nn.BCELoss(reduction='none')
 total_loss = torch.tensor(0, dtype=torch.float32)
 total_weights = torch.tensor(0, dtype=torch.float32)
 for i,(y_true_img_, y_true_exam_, y_pred_img_, y_pred_exam_)in enumerate(zip(y_true_img_chunks, y_true_exam_chunks, y_pred_img_chunks, y_pred_exam_chunks)) :
exam_loss = bce_func(y_pred_exam_[0, :], y_true_exam_[0, :])
 exam_loss = torch.sum(exam_loss*label_w, 1)[0]
image_loss = bce_func(y_pred_img_, y_true_img_)
 img_num = chunk_sizes[i]
qi = torch.sum(y_true_img_)/img_num
image_loss = torch.sum(img_w*qi*image_loss)
 total_loss += exam_loss+image_loss
total_weights += label_w.sum() + img_w*qi*img_num
final_loss = total_loss/total_weights
return final_loss
def rsna_wloss_train(y_true_img, y_true_exam, y_pred_img, y_pred_exam, image_masks, device):
label_w = torch.tensor([0.0736196319, 0.2346625767, 0.0782208589, 0.06257668712, 0.1042944785, 0.06257668712, 0.1042944785, 0.1877300613, 0.09202453988] ).view(1, -1 ).to(device)
 img_w = 0.07361963
bce_func = torch.nn.BCEWithLogitsLoss(reduction='none' ).to(device)
 total_loss = torch.tensor(0, dtype=torch.float32 ).to(device)
 total_weights = torch.tensor(0, dtype=torch.float32 ).to(device)
 for i in range(y_true_img.shape[0]):
exam_loss = bce_func(y_pred_exam[i, :], y_true_exam[i, :])
 exam_loss = torch.sum(exam_loss*label_w, 1)[0]
img_mask = image_masks[i]
image_loss = bce_func(y_pred_img[i,:], y_true_img[i,:] ).flatten()
image_loss = image_loss*img_mask
img_num = torch.sum(img_mask)
 qi = torch.sum(y_true_img[i,:])/img_num
image_loss = torch.sum(img_w*qi*image_loss)
 total_loss += exam_loss+image_loss
total_weights += label_w.sum() + img_w*qi*img_num
final_loss = total_loss/total_weights
return final_loss, total_loss, total_weights
def rsna_wloss_valid(y_true_img, y_true_exam, y_pred_img, y_pred_exam, image_masks, device):
label_w = torch.tensor([0.0736196319, 0.2346625767, 0.0782208589, 0.06257668712, 0.1042944785, 0.06257668712, 0.1042944785, 0.1877300613, 0.09202453988] ).view(1, -1 ).to(device)
 img_w = 0.07361963
bce_func = torch.nn.BCEWithLogitsLoss(reduction='none' ).to(device)
 total_loss = torch.tensor(0, dtype=torch.float32 ).to(device)
 total_weights = torch.tensor(0, dtype=torch.float32 ).to(device)
 for i in range(y_true_img.shape[0]):
exam_loss = bce_func(y_pred_exam[i, :], y_true_exam[i, :])
 exam_loss = torch.sum(exam_loss*label_w, 1)[0]
img_mask = image_masks[i]
image_loss = bce_func(y_pred_img[i,:], y_true_img[i,:] ).flatten()
image_loss = image_loss*img_mask
img_num = torch.sum(img_mask)
 qi = torch.sum(y_true_img[i,:])/img_num
image_loss = torch.sum(img_w*qi*image_loss)
 total_loss += exam_loss+image_loss
total_weights += label_w.sum() + img_w*qi*img_num
final_loss = total_loss/total_weights
return final_loss, total_loss, total_weights
def prepare_train_dataloader(train, cv_df, train_fold, valid_fold):
train_patients = cv_df.loc[cv_df.fold.isin(train_fold), 'StudyInstanceUID'].unique()
valid_patients = cv_df.loc[cv_df.fold.isin(valid_fold), 'StudyInstanceUID'].unique()
train_ = train.loc[train.StudyInstanceUID.isin(train_patients),:].reset_index(drop=True)
 valid_ = train.loc[train.StudyInstanceUID.isin(valid_patients),:].reset_index(drop=True)
 train_ds = RSNADataset(train_, 0.0, CFG['train_img_path'], image_subsampling=True, transforms=get_train_transforms() , output_label=True)
 valid_ds = RSNADataset(valid_, 0.0, CFG['train_img_path'], image_subsampling=False, transforms=get_valid_transforms() , output_label=True)
 train_loader = torch.utils.data.DataLoader(
 train_ds,
batch_size=CFG['train_bs'],
pin_memory=True,
drop_last=False,
shuffle=True,
num_workers=CFG['num_workers'], 
)
 val_loader = torch.utils.data.DataLoader(
 valid_ds,
batch_size=1,
num_workers=CFG['num_workers'],
shuffle=False,
pin_memory=True, 
)
 return train_loader, val_loader
def train_one_epoch(epoch, model, device, scaler, optimizer, train_loader):
model.train()
t = time.time()
loss_sum = 0
loss_w_sum = 0
for step,(imgs, per_image_preds, locs, image_labels, exam_label, image_masks)in enumerate(train_loader):
imgs = imgs.to(device ).float()
per_image_preds = per_image_preds.to(device ).float()
locs = locs.to(device ).float()
image_masks = image_masks.to(device ).float()
image_labels = image_labels.to(device ).float()
exam_label = exam_label.to(device ).float()
with autocast() :
image_preds, exam_pred = model(per_image_preds, locs)
 loss, total_loss, total_weights = rsna_wloss_train(image_labels, exam_label, image_preds, exam_pred, image_masks, device)
 scaler.scale(loss ).backward()
loss_sum += total_loss.detach().item()
loss_w_sum += total_weights.detach().item()
if(( step + 1)% CFG['accum_iter'] == 0)or(( step + 1)== len(train_loader)) :
scaler.step(optimizer)
 scaler.update()
optimizer.zero_grad()
if(( step + 1)% CFG['verbose_step'] == 0)or(( step + 1)== len(train_loader)) :
print(
 f'epoch {epoch} train step {step+1}/{len(train_loader)}, ' + \
f'loss: {loss_sum/loss_w_sum:.4f}, ' + \
f'time: {(time.time() - t):.4f}', end= '\r' if(step + 1)!= len(train_loader)else '
' 
)
 def post_process(exam_pred, image_pred):
rv_lv_ratio_lt_1_ix = CFG['exam_target_cols'].index('rv_lv_ratio_lt_1')
 rv_lv_ratio_gte_1_ix = CFG['exam_target_cols'].index('rv_lv_ratio_gte_1')
 central_pe_ix = CFG['exam_target_cols'].index('central_pe')
 rightsided_pe_ix = CFG['exam_target_cols'].index('rightsided_pe')
 leftsided_pe_ix = CFG['exam_target_cols'].index('leftsided_pe')
 acute_and_chronic_pe_ix = CFG['exam_target_cols'].index('acute_and_chronic_pe')
 chronic_pe_ix = CFG['exam_target_cols'].index('chronic_pe')
 negative_exam_for_pe_ix = CFG['exam_target_cols'].index('negative_exam_for_pe')
 indeterminate_ix = CFG['exam_target_cols'].index('indeterminate')
 has_pe_image = torch.max(image_pred, 1)[0][0] > 0
rv_lv_ratios = exam_pred[:, [rv_lv_ratio_lt_1_ix, rv_lv_ratio_gte_1_ix]]
rv_lv_ratios_1_a = nn.functional.softmax(rv_lv_ratios, dim=1)
 rv_lv_ratios_1_a = torch.log(rv_lv_ratios_1_a/(1-rv_lv_ratios_1_a))
exam_pred[:, [rv_lv_ratio_lt_1_ix, rv_lv_ratio_gte_1_ix]] = torch.where(has_pe_image, rv_lv_ratios_1_a, rv_lv_ratios)
 crl_pe = exam_pred[:, [central_pe_ix, rightsided_pe_ix, leftsided_pe_ix]]
has_no_pe = torch.max(crl_pe ,1)[0] <= 0
max_val = torch.max(crl_pe, 1)[0]
crl_pe_1_b = torch.where(crl_pe==max_val, 0.0001-crl_pe+crl_pe, crl_pe)
 exam_pred[:, [central_pe_ix, rightsided_pe_ix, leftsided_pe_ix]] = torch.where(has_pe_image*has_no_pe, crl_pe_1_b, crl_pe)
 ac_pe = exam_pred[:, [acute_and_chronic_pe_ix, chronic_pe_ix]]
both_ac_ch = torch.min(ac_pe ,1)[0] > 0
ac_pe_1_c = nn.functional.softmax(ac_pe, dim=1)
 ac_pe_1_c = torch.log(ac_pe_1_c/(1-ac_pe_1_c))
exam_pred[:, [acute_and_chronic_pe_ix, chronic_pe_ix]] = torch.where(has_pe_image*both_ac_ch, ac_pe_1_c, ac_pe)
 neg_ind = exam_pred[:, [negative_exam_for_pe_ix, indeterminate_ix]]
neg_ind_1d = torch.clamp(neg_ind, max=0)
 exam_pred[:, [negative_exam_for_pe_ix, indeterminate_ix]] = torch.where(has_pe_image, neg_ind_1d, neg_ind)
 ne_inde = exam_pred[:, [negative_exam_for_pe_ix, indeterminate_ix]]
ne_inde_2_a = nn.functional.softmax(ne_inde, dim=1)
 ne_inde_2_a = torch.log(ne_inde_2_a/(1-ne_inde_2_a))
exam_pred[:, [negative_exam_for_pe_ix, indeterminate_ix]] = torch.where(~has_pe_image, ne_inde_2_a, ne_inde)
 all_other_exam_labels = exam_pred[:, [rv_lv_ratio_lt_1_ix, rv_lv_ratio_gte_1_ix,
central_pe_ix, rightsided_pe_ix, leftsided_pe_ix,
acute_and_chronic_pe_ix, chronic_pe_ix]]
all_other_exam_labels_2_b = torch.clamp(all_other_exam_labels, max=0)
 exam_pred[:, [rv_lv_ratio_lt_1_ix, rv_lv_ratio_gte_1_ix,
central_pe_ix, rightsided_pe_ix, leftsided_pe_ix,
acute_and_chronic_pe_ix, chronic_pe_ix]] = torch.where(~has_pe_image, all_other_exam_labels_2_b, all_other_exam_labels)
 return exam_pred, image_pred
def valid_one_epoch(epoch, model, device, scheduler, val_loader, schd_loss_update=False):
model.eval()
t = time.time()
loss_sum = 0
loss_w_sum = 0
for step,(imgs, per_image_preds, locs, image_labels, exam_label, image_masks)in enumerate(val_loader):
imgs = imgs.to(device ).float()
per_image_preds = per_image_preds.to(device ).float()
locs = locs.to(device ).float()
image_masks = image_masks.to(device ).float()
image_labels = image_labels.to(device ).float()
exam_label = exam_label.to(device ).float()
image_preds, exam_pred = model(per_image_preds, locs)
 exam_pred, image_preds= post_process(exam_pred, image_preds)
 loss, total_loss, total_weights = rsna_wloss_valid(image_labels, exam_label, image_preds, exam_pred, image_masks, device)
 loss_sum += total_loss.detach().item()
loss_w_sum += total_weights.detach().item()
if(( step + 1)% CFG['verbose_step'] == 0)or(( step + 1)== len(val_loader)) :
print(
 f'epoch {epoch} valid Step {step+1}/{len(val_loader)}, ' + \
f'loss: {loss_sum/loss_w_sum:.4f}, ' + \
f'time: {(time.time() - t):.4f}', end='\r' if(step + 1)!= len(val_loader)else '
' 
)
 if schd_loss_update:
scheduler.step(loss_sum/loss_w_sum)
 else:
scheduler.step()
def check_label_consistency(checking_df):
df = checking_df.copy()
print(df.shape)
 df['positive_images_in_exam'] = df['StudyInstanceUID'].map(df.groupby(['StudyInstanceUID'] ).pe_present_on_image.max())
 df_pos = df.loc[df.positive_images_in_exam > 0.5]
df_neg = df.loc[df.positive_images_in_exam <= 0.5]
rule1a = df_pos.loc[(( df_pos.rv_lv_ratio_lt_1 > 0.5)& 
(df_pos.rv_lv_ratio_gte_1 > 0.5)) | 
(( df_pos.rv_lv_ratio_lt_1 <= 0.5)& 
(df_pos.rv_lv_ratio_gte_1 <= 0.5)) ].reset_index(drop = True)
 rule1a['broken_rule'] = '1a'
rule1b = df_pos.loc[(df_pos.central_pe <= 0.5)& 
(df_pos.rightsided_pe <= 0.5)& 
(df_pos.leftsided_pe <= 0.5)].reset_index(drop = True)
 rule1b['broken_rule'] = '1b'
rule1c = df_pos.loc[(df_pos.acute_and_chronic_pe > 0.5)& 
(df_pos.chronic_pe > 0.5)].reset_index(drop = True)
 rule1c['broken_rule'] = '1c'
rule1d = df_pos.loc[(df_pos.indeterminate > 0.5)| 
(df_pos.negative_exam_for_pe > 0.5)].reset_index(drop = True)
 rule1d['broken_rule'] = '1d'
rule2a = df_neg.loc[(( df_neg.indeterminate > 0.5)& 
(df_neg.negative_exam_for_pe > 0.5)) | 
(( df_neg.indeterminate <= 0.5)& 
(df_neg.negative_exam_for_pe <= 0.5)) ].reset_index(drop = True)
 rule2a['broken_rule'] = '2a'
rule2b = df_neg.loc[(df_neg.rv_lv_ratio_lt_1 > 0.5)| 
(df_neg.rv_lv_ratio_gte_1 > 0.5)| 
(df_neg.central_pe > 0.5)| 
(df_neg.rightsided_pe > 0.5)| 
(df_neg.leftsided_pe > 0.5)| 
(df_neg.acute_and_chronic_pe > 0.5)| 
(df_neg.chronic_pe > 0.5)].reset_index(drop = True)
 rule2b['broken_rule'] = '2b'
errors = pd.concat([rule1a, rule1b, rule1c, rule1d, rule2a, rule2b], axis = 0)
 print('label in-consistency counts:', errors.shape)
 if errors.shape[0] > 0:
print(errors.broken_rule.value_counts())
 print(errors)
 assert False
def inference(modellist, device, df, root_path):
modellist_eval = []
for model in modellist:
modellist_eval.append(model.eval())
 t = time.time()
ds = RSNADataset(df, 0.0, root_path, image_subsampling=False, transforms=get_valid_transforms() , output_label=False)
 dataloader = torch.utils.data.DataLoader(
 ds,
batch_size=1,
num_workers=CFG['num_workers'],
shuffle=False,
pin_memory=True, 
)
 patients = ds.get_patients()
res_dfs = []
for step,(imgs, per_image_preds, locs, img_num, index, seq_ix)in enumerate(dataloader):
imgs = imgs.to(device ).float()
per_image_preds = per_image_preds.to(device ).float()
locs = locs.to(device ).float()
index = index.detach().numpy() [0]
seq_ix = seq_ix.detach().numpy() [0,:]
patient_filt =(df.StudyInstanceUID == patients[index])
 patient_df = pd.DataFrame()
patient_df['SOPInstanceUID'] = df.loc[patient_filt, 'SOPInstanceUID'].values[seq_ix]
patient_df['SeriesInstanceUID'] = df.loc[patient_filt, 'SeriesInstanceUID'].values
patient_df['StudyInstanceUID'] = patients[index]
for c in CFG['image_target_cols']+CFG['exam_target_cols']:
patient_df[c] = 0.0
image_preds = 0
exam_pred = 0
for model in modellist_eval:
image_preds_part, exam_pred_part = model(per_image_preds, locs)
 image_preds+=image_preds_part/5
exam_pred+=exam_pred_part/5
image_preds, exam_pred = model(per_image_preds, locs)
 print(image_preds.shape, exam_pred.shape)
 exam_pred, image_preds = post_process(exam_pred, image_preds)
 exam_pred = torch.sigmoid(exam_pred ).cpu().detach().numpy()
image_preds = torch.sigmoid(image_preds ).cpu().detach().numpy()
patient_df[CFG['exam_target_cols']] = exam_pred[0]
patient_df[CFG['image_target_cols']] = image_preds[0,:]
res_dfs += [patient_df]


if(( step + 1)% CFG['verbose_step'] == 0)or(( step + 1)== len(dataloader)) :
print(
 f'Inference Step {step+1}/{len(dataloader)}, ' + \
f'time: {(time.time() - t):.4f}', end='\r' if(step + 1)!= len(dataloader)else '
' 
)
 res_dfs = pd.concat(res_dfs, axis=0 ).reset_index(drop=True)
 res_dfs = df[['SOPInstanceUID', 'SeriesInstanceUID', 'StudyInstanceUID']].merge(res_dfs, on=['SOPInstanceUID', 'SeriesInstanceUID', 'StudyInstanceUID'], how='left')
 print(res_dfs[CFG['image_target_cols']+CFG['exam_target_cols']].head(5))
print(res_dfs[CFG['image_target_cols']+CFG['exam_target_cols']].tail(5))
assert res_dfs.shape[0] == df.shape[0]
check_label_consistency(res_dfs)
 return res_dfs
STAGE1_CFGS = [
{
'tag': 'efb0_stage1',
'model_constructor': RSNAImgClassifierSingle,
'dataset_constructor': RSNADatasetStage1,
'output_len': 1
},
{
'tag': 'efb0_stage1_multilabel',
'model_constructor': RSNAImgClassifier,
'dataset_constructor': RSNADatasetStage1,
'output_len': 9
},
]
STAGE1_CFGS_TAG = 'efb0-stage1-single-multi-label'
def get_stage1_columns() :
new_feats = []
for cfg in STAGE1_CFGS:
for i in range(cfg['output_len']):
f = cfg['tag']+'_'+str(i)
 new_feats += [f]
return new_feats
def update_stage1_oof_preds(df, cv_df):
res_file_name = STAGE1_CFGS_TAG+"-train.csv"
new_feats = get_stage1_columns()
for f in new_feats:
df[f] = 0
if os.path.isfile(res_file_name):
df = pd.read_csv(res_file_name)
 print('img acc:',(( df[new_feats[0]]>0)==df[CFG['image_target_cols'][0]] ).mean())
 return df
for fold,(train_fold, valid_fold)in enumerate(zip(CFG['train_folds'], CFG['valid_folds'])) :
if fold < 0:
continue
valid_patients = cv_df.loc[cv_df.fold.isin(valid_fold), 'StudyInstanceUID'].unique()
filt = df.StudyInstanceUID.isin(valid_patients)
 valid_ = df.loc[filt,:].reset_index(drop=True)
 image_preds_all_list = []
for cfg in STAGE1_CFGS:
valid_ds = cfg['dataset_constructor'](valid_, 0.0, CFG['train_img_path'], image_subsampling=False, transforms=get_valid_transforms() , output_label=True)
 val_loader = torch.utils.data.DataLoader(
 valid_ds,
batch_size=256,
num_workers=CFG['num_workers'],
shuffle=False,
pin_memory=False,
sampler=SequentialSampler(valid_ds)
)
 device = torch.device(CFG['device'])
 model = cfg['model_constructor']().to(device)
 model.load_state_dict(torch.load('{}/model_fold_{}_{}'.format(CFG['model_path'], fold, cfg['tag'])))
 model.eval()
image_preds_all = []
correct_count = 0
count = 0
for step,(imgs, target)in enumerate(val_loader):
imgs = imgs.to(device ).float()
target = target.to(device ).float()
image_preds = model(imgs)
 if len(image_preds.shape)== 1:
image_preds = image_preds.view(-1, 1)
 correct_count +=(( image_preds[:,0]>0)== target[:,0] ).sum().detach().item()
count += imgs.shape[0]
image_preds_all += [image_preds.cpu().detach().numpy() ]
print('acc: {:.4f}, {}, {}, {}/{}'.format(correct_count/count, correct_count, count, step+1, len(val_loader)) , end='\r')
 print()
image_preds_all = np.concatenate(image_preds_all, axis=0)
 image_preds_all_list += [image_preds_all]
del model, val_loader
torch.cuda.empty_cache()
image_preds_all_list = np.concatenate(image_preds_all_list, axis=1)
 df.loc[filt, new_feats] = image_preds_all_list
df.to_csv(res_file_name, index=False)
 return df
def update_stage1_test_preds(df):
new_feats = get_stage1_columns()
for f in new_feats:
df[f] = 0
image_preds_all_list = []
test_ds = RSNADatasetStage1(df, 0.0, CFG['test_img_path'], image_subsampling=False, transforms=get_valid_transforms() , output_label=False)
 test_loader = torch.utils.data.DataLoader(
 test_ds,
batch_size=256,
num_workers=CFG['num_workers'],
shuffle=False,
pin_memory=False,
sampler=SequentialSampler(test_ds)
)
 device = torch.device(CFG['device'])
 image_preds_all = []
image_preds_all2 = []
for step, imgs in enumerate(tqdm(test_loader)) :
imgs = imgs.to(device ).float()
image_preds_part = 0
image_preds2_part = 0
for strs in ['fold_0','fold_1','fold_2','fold_3','fold_4']:
device = torch.device(CFG['device'])
 model_stage1_single = RSNAImgClassifierSingle().to(device)
 model_stage1_single.load_state_dict(torch.load('{}/model_{}_{}'.format(CFG['model_path'],strs, 'efb0_stage1')))
 model_stage1_single.eval()
model_stage1 = RSNAImgClassifier().to(device)
 model_stage1.load_state_dict(torch.load('{}/model_{}_{}'.format(CFG['model_path'],strs, 'efb0_stage1_multilabel')))
 model_stage1.eval()
image_preds = model_stage1_single(imgs)
 image_preds2 = model_stage1(imgs)
 image_preds = image_preds.cpu().detach().numpy()
image_preds2 = image_preds2.cpu().detach().numpy()
image_preds_part+=image_preds/5
image_preds2_part+=image_preds2/5
image_preds_all += [image_preds_part]
image_preds_all2 += [image_preds2_part]
image_preds_all = np.concatenate(image_preds_all, axis=0)
 image_preds_all2 = np.concatenate(image_preds_all2, axis=0)
 image_preds_all_list += [image_preds_all]
image_preds_all_list += [image_preds_all2]
del model_stage1_single,model_stage1, test_loader
torch.cuda.empty_cache()
image_preds_all_list = np.concatenate(image_preds_all_list, axis=1)
 df.loc[:,new_feats] = image_preds_all_list
return df
if __name__ == '__main__':
if CFG['train']:
seed_everything(SEED)
 if CFG['train']:
train_df = pd.read_csv(CFG['train_path'])
 cv_df = pd.read_csv(CFG['cv_fold_path'])
 with torch.no_grad() :
train_df = update_stage1_oof_preds(train_df,cv_df)
 else:
do_full=len(os.listdir(".. /input/rsna-str-pulmonary-embolism-detection/test/")) >600
if path.exists('.. /input/rsna-str-pulmonary-embolism-detection/train')and not do_full:
test_df=pd.read_csv(CFG['test_path'] ).head(500)
 else:
test_df=pd.read_csv(CFG['test_path'])
 with torch.no_grad() :
test_df = update_stage1_test_preds(test_df)
 test_df.to_csv('test_df_stage1.csv',index=False)
 if CFG['train']:
for fold,(train_fold, valid_fold)in enumerate(zip(CFG['train_folds'], CFG['valid_folds'])) :
train_loader, val_loader = prepare_train_dataloader(train_df, cv_df, train_fold, valid_fold)
 device = torch.device(CFG['device'])
 model = RSNAClassifier().to(device)
 scaler = GradScaler()
optimizer = torch.optim.Adam(model.parameters() , lr=CFG['lr'])
 scheduler = torch.optim.lr_scheduler.StepLR(optimizer, gamma=0.1, step_size=1); schd_loss_update=False
for epoch in range(CFG['epochs']):
train_one_epoch(epoch, model, device, scaler, optimizer, train_loader)
 with torch.no_grad() :
valid_one_epoch(epoch, model, device, scheduler, val_loader, schd_loss_update=schd_loss_update)
 torch.save(model.state_dict() ,'{}/model_fold_{}_{}'.format(CFG['model_path'], fold, CFG['tag']))
model.load_state_dict(torch.load('{}/model_fold_{}_{}'.format(CFG['model_path'], fold, CFG['tag'])))
 valid_patients = cv_df.loc[cv_df.fold.isin(valid_fold), 'StudyInstanceUID'].unique()
valid_ = train_df.loc[train_df.StudyInstanceUID.isin(valid_patients),:].reset_index(drop=True)
 with torch.no_grad() :
val_pred_df = inference(model, device, valid_, CFG['train_img_path'])
 target = valid_[CFG['image_target_cols']].values
pred =(val_pred_df[CFG['image_target_cols']].values > 0.5 ).astype(int)
 print('Image PE Accuracy: {:.3f}'.format(( target==pred ).mean() *100))
loss = rsna_wloss_inference(valid_[CFG['image_target_cols']].values, valid_[CFG['exam_target_cols']].values,
val_pred_df[CFG['image_target_cols']].values, val_pred_df[CFG['exam_target_cols']].values,
list(valid_.groupby('StudyInstanceUID', sort=False)['SOPInstanceUID'].count()))
print('Validation loss = {:.4f}'.format(loss.detach().item()))
del model, optimizer, train_loader, val_loader, scaler, scheduler
torch.cuda.empty_cache()
train_loader, val_loader = prepare_train_dataloader(train_df, cv_df, np.arange(0, 20), np.array([]))
device = torch.device(CFG['device'])
 model = RSNAClassifier().to(device)
 scaler = GradScaler()
optimizer = torch.optim.Adam(model.parameters() , lr=CFG['lr'])
 scheduler = torch.optim.lr_scheduler.StepLR(optimizer, gamma=0.1, step_size=1); schd_loss_update=False
for epoch in range(CFG['epochs']):
train_one_epoch(epoch, model, device, scaler, optimizer, train_loader)
 torch.save(model.state_dict() ,'{}/model_{}'.format(CFG['model_path'], CFG['tag']))
else:
device = torch.device(CFG['device'])
 modellist = []
for strs in ['fold_0','fold_1','fold_2','fold_3','fold_4']:
model = RSNAClassifier().to(device)
 model.load_state_dict(torch.load('{}/model_{}_{}'.format(CFG['model_path'],strs, CFG['tag'])))
 modellist.append(model)
 print('begin infer')
 test_pred_df = inference(modellist, device, test_df, CFG['test_img_path'])
 print('end infer')
 test_pred_df.to_csv('kh_submission_raw.csv')
 ids = []
labels = []
gp_mean = test_pred_df.loc[:, ['StudyInstanceUID']+CFG['exam_target_cols']].groupby('StudyInstanceUID', sort=False ).mean()
for col in CFG['exam_target_cols']:
ids += [[patient+'_'+col for patient in gp_mean.index]]
labels += [gp_mean[col].values]
ids += [test_pred_df.SOPInstanceUID.values]
labels += [test_pred_df[CFG['image_target_cols']].values[:,0]]
ids = np.concatenate(ids)
 labels = np.concatenate(labels)
 assert len(ids)== len(labels)
 submission = pd.DataFrame()
submission['id'] = ids
submission['label'] = labels
print(submission.head(3))
print(submission.tail(3))
print(submission.shape)
 submission.loc[submission.id.str.contains('_'),'label'] *=0.92
submission.to_csv('submission.csv', index=False )<define_variables>
indices = []
spid = []
recid = []
for i, sample in tqdm(parsed_trainval.prefetch(AUTOTUNE)) :
indices.append(i.numpy())
 spid.append(sample['species_id'].numpy())
 recid.append(sample['recording_id'].numpy().decode() )
starttime = time.time()<load_from_zip>
table = pd.DataFrame({'indices': indices, 'species_id': spid, 'recording_id': recid})
 table
!cp.. /input/gdcm-conda-install/gdcm.tar.
 !tar -xvzf gdcm.tar
!conda install --offline./gdcm/gdcm-2.8.9-py37h71b2a6d_0.tar.bz2<set_options>
def create_idx_filter(indice):
@tf.function
def _filt(i, x):
return tf.reduce_any(indice == i)
 return _filt
@tf.function
def _remove_idx(i, x):
return x
warnings.filterwarnings('ignore')
 pd.set_option('display.max_columns', 100 )<define_variables>
def create_train_dataset(batchsize, train_idx):
global parsed_trainval
parsed_train =(parsed_trainval 
.filter(create_idx_filter(train_idx)) 
.map(_remove_idx))
dataset =(parsed_train.cache() 
.shuffle(len(train_idx)) 
.repeat() 
.map(_cut_wav, num_parallel_calls=AUTOTUNE)
.map(_wav_to_spec, num_parallel_calls=AUTOTUNE)
.map(_create_annot, num_parallel_calls=AUTOTUNE)
.map(_preprocess, num_parallel_calls=AUTOTUNE)
.batch(batchsize))
if cfg['model_params']['mixup']:
dataset =(dataset.map(_mixup, num_parallel_calls=AUTOTUNE)
.prefetch(AUTOTUNE))
else:
dataset = dataset.prefetch(AUTOTUNE)
 return dataset
def create_val_dataset(batchsize, val_idx):
global parsed_trainval
parsed_val =(parsed_trainval 
.filter(create_idx_filter(val_idx)) 
.map(_remove_idx))
vdataset =(parsed_val 
.map(_cut_wav_val, num_parallel_calls=AUTOTUNE)
.map(_wav_to_spec, num_parallel_calls=AUTOTUNE)
.map(_create_annot, num_parallel_calls=AUTOTUNE)
.map(_preprocess_val, num_parallel_calls=AUTOTUNE)
.batch(8*strategy.num_replicas_in_sync)
.cache())
 return vdataset
col_index = 'SOPInstanceUID'
col_groupby = 'StudyInstanceUID'
df_test_path = ".. /input/rsna-str-pulmonary-embolism-detection/test.csv"
df_train_path = ".. /input/rsna-str-pulmonary-embolism-detection/train.csv"
df_sub_path = ".. /input/rsna-str-pulmonary-embolism-detection/sample_submission.csv"
test_image_path = ".. /input/rsna-str-pulmonary-embolism-detection/test/"
train_image_path = ".. /input/rsna-str-pulmonary-embolism-detection/train/"
LEN_PUBLIC = 146853
DEBUG = False
num_cpu = multiprocessing.cpu_count()
num_features1_1 = 1280
num_features1_2 = 1408
weight_dir1_1 = ".. /input/rsna2020-1/201022_6_CNN_b0_1loss_512_fp16_bs80_lr1e3(2)/201022_6_CNN_b0_1loss_512_fp16_bs80_lr1e3"
weight_dir2_1 = ".. /input/rsna2020-1/201025_3_2ndNNs_features_pool_flip_new/201025_3_2ndNNs_features_pool_flip_new"
weight_dir1_2 = ".. /input/rsna2020-1/201024_5_b2_1loss_512_fp16_bs80_lr1e3/201024_5_b2_1loss_512_fp16_bs80_lr1e3"
weight_dir2_2 = ".. /input/rsna2020-1/201026_3_2ndNNs_features_pool_flip_b0b2/201026_3_2ndNNs_features_pool_flip_b0b2"
do_full = False
BATCH_SIZE = 64
NUM_FOLD = 5
TIME_LIMIT = 60*60*7
LIMIT_OVER = False<define_variables>
@tf.function
def _one_sample_positive_class_precisions(example):
y_true, y_pred = example
retrieved_classes = tf.argsort(y_pred, direction='DESCENDING')
 class_rankings = tf.argsort(retrieved_classes)
 retrieved_class_true = tf.gather(y_true, retrieved_classes)
 retrieved_cumulative_hits = tf.math.cumsum(tf.cast(retrieved_class_true, tf.float32))
idx = tf.where(y_true)[:, 0]
i = tf.boolean_mask(class_rankings, y_true)
 r = tf.gather(retrieved_cumulative_hits, i)
 c = 1 + tf.cast(i, tf.float32)
 precisions = r / c
dense = tf.scatter_nd(idx[:, None], precisions, [y_pred.shape[0]])
 return dense
class LWLRAP(tf.keras.metrics.Metric):
def __init__(self, num_classes, name='lwlrap'):
super().__init__(name=name)
 self._precisions = self.add_weight(
 name='per_class_cumulative_precision',
shape=[num_classes],
initializer='zeros', 
)
 self._counts = self.add_weight(
 name='per_class_cumulative_count',
shape=[num_classes],
initializer='zeros', 
)
 def update_state(self, y_true, y_pred, sample_weight=None):
precisions = tf.map_fn(
 fn=_one_sample_positive_class_precisions,
elems=(y_true, y_pred),
dtype=(tf.float32), 
)
 increments = tf.cast(precisions > 0, tf.float32)
 total_increments = tf.reduce_sum(increments, axis=0)
 total_precisions = tf.reduce_sum(precisions, axis=0)
 self._precisions.assign_add(total_precisions)
 self._counts.assign_add(total_increments)
 def result(self):
per_class_lwlrap = self._precisions / tf.maximum(self._counts, 1.0)
 per_class_weight = self._counts / tf.reduce_sum(self._counts)
 overall_lwlrap = tf.reduce_sum(per_class_lwlrap * per_class_weight)
 return overall_lwlrap
def reset_states(self):
self._precisions.assign(self._precisions * 0)
 self._counts.assign(self._counts * 0 )
col_targets = [
'negative_exam_for_pe',
'indeterminate',
'chronic_pe',
'acute_and_chronic_pe',
'central_pe',
'leftsided_pe',
'rightsided_pe',
'rv_lv_ratio_gte_1',
'rv_lv_ratio_lt_1',
'pe_present_on_image',
]<load_from_csv>
def _parse_function_test(example_proto):
sample = tf.io.parse_single_example(example_proto, feature_description)
 wav, _ = tf.audio.decode_wav(sample['audio_wav'], desired_channels=1)
 @tf.function
def _cut_audio(i):
_sample = {
'audio_wav': tf.reshape(wav[i*SR*TIME:(i+1)*SR*TIME], [SR*TIME]),
'recording_id': sample['recording_id']
}
return _sample
return tf.map_fn(_cut_audio, tf.range(60//TIME), dtype={
'audio_wav': tf.float32,
'recording_id': tf.string
})
 def inference(model):
tdataset =(tf.data.TFRecordDataset(tf.io.gfile.glob(TEST_TFREC + '/*.tfrec'), num_parallel_reads=AUTOTUNE)
.map(_parse_function_test, num_parallel_calls=AUTOTUNE ).unbatch() 
.map(_wav_to_spec, num_parallel_calls=AUTOTUNE)
.map(_preprocess_test, num_parallel_calls=AUTOTUNE)
.batch(128*(60//TIME)).prefetch(AUTOTUNE))
rec_ids = []
probs = []
for inp, rec_id in tqdm(tdataset):
with strategy.scope() :
pred = model.predict_on_batch(tf.reshape(inp, [-1, HEIGHT, WIDTH, 3]))
prob = tf.sigmoid(pred)
 prob = tf.reduce_max(tf.reshape(prob, [-1, 60//TIME, CLASS_N]), axis=1)
 rec_id_stack = tf.reshape(rec_id, [-1, 60//TIME])
 for rec in rec_id.numpy() :
assert len(np.unique(rec)) == 1
rec_ids.append(rec_id_stack.numpy() [:,0])
 probs.append(prob.numpy())
 crec_ids = np.concatenate(rec_ids)
 cprobs = np.concatenate(probs)
 sub = pd.DataFrame({
'recording_id': list(map(lambda x: x.decode() , crec_ids.tolist())) ,
**{f's{i}': cprobs[:,i] for i in range(CLASS_N)}
})
 sub = sub.sort_values('recording_id')
 return sub
if os.path.exists('.. /input/rsna-str-pulmonary-embolism-detection/train')and not do_full:
df_test_full=pd.read_csv(df_test_path)
 df_test_full_study = df_test_full[df_test_full[col_groupby].duplicated() ==False]
df_test=pd.read_csv(df_test_path ).head(2000)
 else:
df_test_full=pd.read_csv(df_test_path)
 df_test_full_study = df_test_full[df_test_full[col_groupby].duplicated() ==False]
df_test=pd.read_csv(df_test_path)
 print(df_test.shape)
 df_test.head()<sort_values>
import pickle as pk
df_test = df_test.sort_values([col_groupby, col_index] ).reset_index(drop=True)
 df_test.head()<feature_engineering>
def inference_only(splits, split_id):
batchsize = cfg['model_params']['batchsize_per_tpu'] * strategy.num_replicas_in_sync
print("batchsize", batchsize)
 loss_fn = cfg['model_params']['loss']['fn'](from_logits=True, **cfg['model_params']['loss']['params'])
 optimizer = cfg['model_params']['optim']['fn'](**cfg['model_params']['optim']['params'])
 model = create_model()
with strategy.scope() :
model.compile(optimizer=optimizer, loss=loss_fn, metrics=[LWLRAP(CLASS_N)])
 model.load_weights('model_cut12_st10_best_%d.h5' % split_id)
 return inference(model )
df_test['dicom_path'] = test_image_path + "/" +\
df_test[col_groupby].values + "/" + \
df_test['SeriesInstanceUID'].values + "/" + \
df_test[col_index].values + ".dcm"
print(df_test['dicom_path'][0])
 df_test.head()<merge>
histories= list(
 map(
 lambda i: train(splits, i),
range(len(splits)) 
)
 )
df_test_study = df_test[df_test[col_groupby].duplicated() ==False]
df_test_study['start_index'] = df_test_study.index.values
df_tmp = df_test.groupby(col_groupby)[col_index].agg(len ).reset_index()
df_tmp.columns = [col_groupby, 'num_images']
df_test_study = pd.merge(df_test_study, df_tmp, on=col_groupby)
 print(df_test_study.shape)
 df_test_study.head()<create_dataframe>
class DicomDataset(Dataset):
def __init__(self, X_study, X_image, transform=None, meta=False, verbose=False):
self.X_study = X_study
self.X_image = X_image
self.transform = transform
self.verbose = verbose
def __getitem__(self, index):
study = self.X_study[col_groupby][index]
start_index = self.X_study['start_index'][index]
end_index = self.X_study['start_index'][index] + self.X_study['num_images'][index]
df_study = self.X_image.iloc[start_index:end_index].reset_index(drop=True)
 images_study = []
z_pos = []
for i in range(len(df_study)) :
tmp_path = df_study['dicom_path'][i]
try:
tmp_dcm = pydicom.dcmread(tmp_path)
 tmp_npy = np.asarray(tmp_dcm.pixel_array)
 images_study.append(tmp_npy)
 if i==0:
RescaleSlope = tmp_dcm['RescaleSlope'].value
RescaleIntercept = tmp_dcm['RescaleIntercept'].value
PatientPosition = tmp_dcm['PatientPosition'].value
z_pos.append(tmp_dcm['ImagePositionPatient'].value[-1])
 except:
print("loading error!!!, study: {}, index: {}".format(study, i))
tmp_npy = np.zeros([512, 512], np.int16)
 images_study.append(tmp_npy)
 if i==0:
RescaleSlope = 1
RescaleIntercept = -1024
PatientPosition = 'HFS'
z_pos.append(-10000-i)
 images_study = np.array(images_study)
 z_pos = np.array(z_pos)
 images_study = images_study[np.argsort(z_pos)]
df_study['z_pos'] = z_pos
df_study = df_study.sort_values('z_pos' ).reset_index(drop=True)
 df_study['series_index'] = np.arange(len(df_study))
if self.verbose: print(images_study.shape)
 if self.verbose: print(z_pos)
 if self.verbose: print(RescaleIntercept, RescaleSlope, PatientPosition)
 images_study_processed =(images_study.astype(np.float32)* RescaleSlope + RescaleIntercept)/1000
if PatientPosition=='FFP':
images_study_processed = images_study_processed[:, ::-1, ::-1]
images_study_processed = images_study_processed.reshape([-1, 1, 512, 512] ).astype(np.float16)
 return images_study_processed, df_study
def __len__(self):
return len(self.X_study )<concatenate>
sub = sum(
 map(
 lambda i: inference_only(splits, i ).set_index('recording_id'),
range(len(splits)) 
)
 ).reset_index()
def my_collate(batch):
return torch.Tensor(batch[0][0]), batch[0][1]<define_search_space>
sub.to_csv("submission.csv", index=False )
<define_search_model><EOS> 
FileLink(r'submission.csv' )