Kaggle competition: Rainforest Connection Species Audio Detection
<SOS> metric: WeightedLabelRankingAveragePrecision Kaggle data source: rainforest-connection-species-audio-detection<create_dataframe>
!pip install image-classifiers
dataset_test = DicomDataset(df_test_study, df_test)
 test_loader = DataLoader(
 dataset_test,
batch_size=1,
shuffle=False,
num_workers=num_cpu,
pin_memory=True,
collate_fn=my_collate
)<compute_train_metric>
tf.__version__
lastfunc = nn.Sigmoid().to(device, non_blocking=True )<categorify>
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 batch_padding(batch):
bs, ch, d = batch.shape
d_new = int(np.ceil(d/64)*64)
 batch_new = torch.from_numpy(np.zeros([bs, ch, d_new], np.float32)).to(device, non_blocking=True)
 batch_new[:, :, :d] = batch
return batch_new<choose_model_class>
ResNet34, preprocess_input = Classifiers.get('resnet34' )
NUM_FOLDS = 5
df_pred_image = []
df_pred_study = []
starttime = time.time()
verbose = False
model_b0s = []
model_b2s = []
model_1dcnns = []
model_1dcnn_b2s = []
for fold in range(NUM_FOLDS):
model_b0s.append(MyEffNet_b0().to(device, non_blocking=True))
model_b2s.append(MyEffNet_b0(base_model='tf_efficientnet_b2_ns' ).to(device, non_blocking=True))
model_1dcnns.append(CNN1D(input_ch=num_features1_1 ).to(device, non_blocking=True))
model_1dcnn_b2s.append(CNN1D(input_ch=num_features1_2 ).to(device, non_blocking=True))
model_b0s[fold].load_state_dict(torch.load("{}/weight_epoch_16_fold{}.pth".format(weight_dir1_1, fold+1)))
 model_b2s[fold].load_state_dict(torch.load("{}/weight_epoch_16_fold{}.pth".format(weight_dir1_2, fold+1)))
 model_1dcnns[fold].load_state_dict(torch.load("{}/cnn_weight_best_fold{}.pth".format(weight_dir2_1, fold+1)))
 model_1dcnn_b2s[fold].load_state_dict(torch.load("{}/cnn_weight_best_fold{}.pth".format(weight_dir2_2, fold+1)))
 model_b0s[fold].eval()
model_b2s[fold].eval()
model_1dcnns[fold].eval()
model_1dcnn_b2s[fold].eval()
for study_index,(images, df_study)in enumerate(test_loader):
if time.time() -starttime>TIME_LIMIT and LIMIT_OVER==False:
print("index: {}, {:.1f}, time limit over!!!".format(study_index, time.time() -starttime))
LIMIT_OVER = True
if study_index>=100: break
if verbose: print("load index {} done".format(study_index), time.time() -starttime)
 if(study_index+1)%10==0:
print("{}/{}, sec: {:.1f}".format(study_index+1, len(df_test_study), time.time() -starttime))
num_batches = int(np.ceil(images.shape[0]/BATCH_SIZE))
num_images = len(df_study)
 df_study_image = df_study[[col_groupby, col_index, 'SeriesInstanceUID']]
df_study_study = df_study[[col_groupby]].iloc[:1]
for fold in range(NUM_FOLD):
model_b0 = model_b0s[fold]
model_b2 = model_b2s[fold]
model_1dcnn = model_1dcnns[fold]
model_1dcnn_b2 = model_1dcnn_b2s[fold]
features = []
features_b2 = []
for batch_index in range(num_batches):
with torch.no_grad() :
with torch.cuda.amp.autocast() :
batch = images[batch_index*BATCH_SIZE:(batch_index+1)*BATCH_SIZE].to(device, non_blocking=True)
 _, feature = model_b0.feature(batch)
 if LIMIT_OVER!=True:
_, feature_b2 = model_b2.feature(batch)
 features.append(feature)
 features_b2.append(feature_b2)
 features = torch.cat(features, axis=0)
 features = torch.transpose(features, 0,1 ).reshape([1, num_features1_1, -1])
 features = batch_padding(features)
 if LIMIT_OVER!=True:
features_b2 = torch.cat(features_b2, axis=0)
 features_b2 = torch.transpose(features_b2, 0,1 ).reshape([1, num_features1_2, -1])
 features_b2 = batch_padding(features_b2)
 with torch.no_grad() :
output1, output2 = model_1dcnn(features)
 output2 = output2[:,-1:]
output1 = lastfunc(output1)
 output2 = lastfunc(output2)[:,:,:num_images]
if LIMIT_OVER!=True:
output1_b2, output2_b2 = model_1dcnn_b2(features_b2)
 output2_b2 = output2_b2[:,-1:]
output1_b2 = lastfunc(output1_b2)
 output2_b2 = lastfunc(output2_b2)[:,:,:num_images]
for i, col in enumerate(col_targets[:-1]):
df_study_study["{}_pred_fold{}".format(col, fold+1)] = output1[0, i].data.cpu().numpy()
if LIMIT_OVER!=True:
df_study_study["{}_pred_fold{}_b2".format(col, fold+1)] = output1_b2[0, i].data.cpu().numpy()
else:
df_study_study["{}_pred_fold{}_b2".format(col, fold+1)] = output1[0, i].data.cpu().numpy()
df_study_image["{}_pred_fold{}".format(col_targets[-1], fold+1)] = output2[0, 0].data.cpu().numpy()
if LIMIT_OVER!=True:
df_study_image["{}_pred_fold{}_b2".format(col_targets[-1], fold+1)] = output2_b2[0, 0].data.cpu().numpy()
else:
df_study_image["{}_pred_fold{}_b2".format(col_targets[-1], fold+1)] = output2[0, 0].data.cpu().numpy()
df_pred_study.append(df_study_study)
 df_pred_image.append(df_study_image)
<concatenate>
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, 784)
 },
'model_params': {
'batchsize_per_tpu': 16,
'iteration_per_epoch': 64,
'epoch': 25,
'arch': ResNet34,
'arch_preprocess': preprocess_input,
'freeze_to': 0,
'loss': {
'fn': tfa.losses.SigmoidFocalCrossEntropy,
'params': {},
},
'optim': {
'fn': tfa.optimizers.RectifiedAdam,
'params': {'lr': 2e-3, 'total_steps': 18*64, 'warmup_proportion': 0.3, 'min_lr': 1e-6},
},
'mixup': True
}
}
df_pred_image = pd.concat(df_pred_image ).reset_index(drop=True)
 df_pred_study = pd.concat(df_pred_study ).reset_index(drop=True)
 print(df_pred_image.shape, df_pred_study.shape)
 df_pred_image.head()<feature_engineering>
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"
for col in col_targets[:-1]:
cols_tmp = []
for fold in range(NUM_FOLD):
cols_tmp.append("{}_pred_fold{}".format(col, fold+1))
cols_tmp.append("{}_pred_fold{}_b2".format(col, fold+1))
df_pred_study[col] = df_pred_study[cols_tmp].values.mean(axis=1)
 df_pred_study.head(30 )<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
cols_tmp = []
for fold in range(NUM_FOLD):
cols_tmp.append("{}_pred_fold{}".format(col_targets[-1], fold+1))
cols_tmp.append("{}_pred_fold{}_b2".format(col_targets[-1], fold+1))
df_pred_image[col_targets[-1]] = df_pred_image[cols_tmp].values.mean(axis=1)
 df_pred_image.head()<compute_test_metric>
raw_dataset = tf.data.TFRecordDataset([TRAIN_TFREC + '/00-148.tfrec'])
 raw_dataset
def solve_conflict(df_pred_s, df_pred, TH_NEGATIVE=0.5, TH_INDETERMINATE = 0.5, verbose=True):
index_indeterminate = df_pred_s['indeterminate']>TH_INDETERMINATE
index_negative =(index_indeterminate==False)&(df_pred_s['negative_exam_for_pe']>TH_NEGATIVE)
 index_positive =(index_indeterminate==False)&(index_negative==False)
 index_negative_and_negative_lte_05 = index_negative &(df_pred_s['negative_exam_for_pe']<=0.5)
 df_pred_s['negative_exam_for_pe'][index_negative_and_negative_lte_05] = 0.5001
index_indeterminate_and_indeterminate_lte_05 = index_indeterminate &(df_pred_s['indeterminate']<=0.5)
 df_pred_s['indeterminate'][index_indeterminate_and_indeterminate_lte_05] = 0.5001
index_indeterminate_and_negative_gt_05 = index_indeterminate &(df_pred_s['negative_exam_for_pe']>0.5)
 df_pred_s['negative_exam_for_pe'][index_indeterminate_and_negative_gt_05] = 0.5
index_negative_and_indeterminate_gt_05 = index_negative &(df_pred_s['indeterminate']>0.5)
 df_pred_s['indeterminate'][index_negative_and_indeterminate_gt_05] = 0.5
index_positive_and_negative_gt_05 = index_positive &(df_pred_s['negative_exam_for_pe']>0.5)
 df_pred_s['negative_exam_for_pe'][index_positive_and_negative_gt_05] = 0.5
index_positive_and_indeterminate_gt_05 = index_positive &(df_pred_s['indeterminate']>0.5)
 df_pred_s['indeterminate'][index_positive_and_indeterminate_gt_05] = 0.5
index_negative_and_rv_lv_ratio_lt_1_gt_05 =(index_positive==False)&(df_pred_s['rv_lv_ratio_lt_1']>0.5)
 df_pred_s['rv_lv_ratio_lt_1'][index_negative_and_rv_lv_ratio_lt_1_gt_05] = 0.5
index_negative_and_rv_lv_ratio_gte_1_gt_05 =(index_positive==False)&(df_pred_s['rv_lv_ratio_gte_1']>0.5)
 df_pred_s['rv_lv_ratio_gte_1'][index_negative_and_rv_lv_ratio_gte_1_gt_05] = 0.5
index_negative_and_central_pe_gt_05 =(index_positive==False)&(df_pred_s['central_pe']>0.5)
 index_negative_and_rightsided_pe_gt_05 =(index_positive==False)&(df_pred_s['rightsided_pe']>0.5)
 df_pred_s['rightsided_pe'][index_negative_and_rightsided_pe_gt_05] = 0.5
index_negative_and_leftsided_pe_gt_05 =(index_positive==False)&(df_pred_s['leftsided_pe']>0.5)
 df_pred_s['leftsided_pe'][index_negative_and_leftsided_pe_gt_05] = 0.5
index_negative_and_chronic_pe_gt_05 =(index_positive==False)&(df_pred_s['chronic_pe']>0.5)
 df_pred_s['chronic_pe'][index_negative_and_chronic_pe_gt_05] = 0.5
index_negative_and_acute_and_chronic_pe_gt_05 =(index_positive==False)&(df_pred_s['acute_and_chronic_pe']>0.5)
 df_pred_s['acute_and_chronic_pe'][index_negative_and_acute_and_chronic_pe_gt_05] = 0.5
index_positive_and_rv_gte_lv = index_positive &(df_pred_s['rv_lv_ratio_lt_1']<=df_pred_s['rv_lv_ratio_gte_1'])
 index_positive_and_rv_lt_lv = index_positive &(df_pred_s['rv_lv_ratio_lt_1']>df_pred_s['rv_lv_ratio_gte_1'])
 index_positive_and_rv_gte_lv_and_rv_lv_ratio_gte_1_lte_05 =\ 
(index_positive_and_rv_gte_lv)&(df_pred_s['rv_lv_ratio_gte_1']<=0.5)
 df_pred_s['rv_lv_ratio_gte_1'][index_positive_and_rv_gte_lv_and_rv_lv_ratio_gte_1_lte_05] = 0.5001
index_positive_and_rv_gte_lv_and_rv_lv_ratio_lt_1_gt_05 =\ 
(index_positive_and_rv_gte_lv)&(df_pred_s['rv_lv_ratio_lt_1']>0.5)
 df_pred_s['rv_lv_ratio_lt_1'][index_positive_and_rv_gte_lv_and_rv_lv_ratio_lt_1_gt_05] = 0.5
index_positive_and_rv_lt_lv_and_rv_lv_ratio_lt_1_lte_05 =\ 
(index_positive_and_rv_lt_lv)&(df_pred_s['rv_lv_ratio_lt_1']<=0.5)
 df_pred_s['rv_lv_ratio_lt_1'][index_positive_and_rv_lt_lv_and_rv_lv_ratio_lt_1_lte_05] = 0.5001
index_positive_and_rv_lt_lv_and_rv_lv_ratio_gte_1_gt_05 =\ 
(index_positive_and_rv_lt_lv)&(df_pred_s['rv_lv_ratio_gte_1']>0.5)
 df_pred_s['rv_lv_ratio_gte_1'][index_positive_and_rv_lt_lv_and_rv_lv_ratio_gte_1_gt_05] = 0.5
index_positive_and_central_is_greatest = index_positive &(df_pred_s['central_pe']>=df_pred_s['rightsided_pe'])&(df_pred_s['central_pe']>=df_pred_s['leftsided_pe'])
 index_positive_and_right_is_greatest = index_positive &(index_positive_and_central_is_greatest==False)&(df_pred_s['rightsided_pe']>=df_pred_s['leftsided_pe'])
 index_positive_and_left_is_greatest = index_positive &(index_positive_and_central_is_greatest==False)&(index_positive_and_right_is_greatest==False)
 index_positive_and_central_is_greatest_and_central_pe_lte_05 =(index_positive_and_central_is_greatest)&(df_pred_s['central_pe']<=0.5)
 df_pred_s['central_pe'][index_positive_and_central_is_greatest_and_central_pe_lte_05] = 0.5001
index_positive_and_right_is_greatest_and_rightsided_pe_lte_05 =(index_positive_and_right_is_greatest)&(df_pred_s['rightsided_pe']<=0.5)
 df_pred_s['rightsided_pe'][index_positive_and_right_is_greatest_and_rightsided_pe_lte_05] = 0.5001
index_positive_and_left_is_greatest_and_leftsided_pe_lte_05 =(index_positive_and_left_is_greatest)&(df_pred_s['leftsided_pe']<=0.5)
 df_pred_s['leftsided_pe'][index_positive_and_left_is_greatest_and_leftsided_pe_lte_05] = 0.5001
index_double_positive = index_positive &(df_pred_s['chronic_pe']>0.5)&(df_pred_s['acute_and_chronic_pe']>0.5)
 index_double_positive_and_chronic_lte_acute_and_chronic = index_double_positive &(df_pred_s['chronic_pe']<=df_pred_s['acute_and_chronic_pe'])
 df_pred_s['chronic_pe'][index_double_positive_and_chronic_lte_acute_and_chronic] = 0.5
index_double_positive_and_chronic_gt_acute_and_chronic = index_double_positive &(df_pred_s['chronic_pe']>df_pred_s['acute_and_chronic_pe'])
 df_pred_s['acute_and_chronic_pe'][index_double_positive_and_chronic_gt_acute_and_chronic] = 0.5
df_pred_s['positive'] = 0
df_pred_s['positive'][index_positive] = 1
df_pred2 = pd.merge(df_pred, df_pred_s[[col_groupby, 'positive']], on=col_groupby, how='left')
 df_agg = df_pred.groupby(col_groupby)['pe_present_on_image'].agg('max' ).reset_index()
df_agg.columns = [col_groupby, 'pe_present_on_image_pred_max']
df_pred2 = pd.merge(df_pred2, df_agg, on=col_groupby, how='left')
 df_pred2['peak'] = df_pred2['pe_present_on_image']==df_pred2['pe_present_on_image_pred_max']
index_positive_i = df_pred2['positive']==1
index_negative_and_pe_present_on_image_gt_05_i =(index_positive_i==False)&(df_pred2['pe_present_on_image']>0.5)
 df_pred['pe_present_on_image'][index_negative_and_pe_present_on_image_gt_05_i] = 0.5
index_positive_and_peak_and_pe_present_on_image_lte_05_i = index_positive_i &(df_pred2['peak'])&(df_pred2['pe_present_on_image']<=0.5)
 df_pred['pe_present_on_image'][index_positive_and_peak_and_pe_present_on_image_lte_05_i] = 0.5001
if verbose:
print("num study", len(df_pred_s))
print("num image", len(df_pred))
print("split to 3 classes")
 print(" num predicted_as_negative:", index_negative.sum())
 print(" num predicted_as_indeterminate:", index_indeterminate.sum())
 print(" num predicted_as_positive:", index_positive.sum())
 print("process 3 class conflict")
 print(" num predicted_as_negative and negative<=0.5:", index_negative_and_negative_lte_05.sum())
 print(" num predicted_as_indeterminate and indeterminate<=0.5:", index_indeterminate_and_indeterminate_lte_05.sum())
 print(" num predicted_as_indeterminate and negative_exam_for_pe>0.5:", index_indeterminate_and_negative_gt_05.sum())
 print(" num predicted_as_negative and indeterminate>0.5:", index_negative_and_indeterminate_gt_05.sum())
 print(" num predicted_as_positive and negative_exam_for_pe>0.5:", index_positive_and_negative_gt_05.sum())
 print(" num predicted_as_positive and indeterminate>0.5:", index_positive_and_indeterminate_gt_05.sum())
 print("process negative case")
 print(" num predicted_as_not_positive and rv_lv_ratio_lt_1>0.5:", index_negative_and_rv_lv_ratio_lt_1_gt_05.sum())
 print(" num predicted_as_not_positive and rv_lv_ratio_gte_1>0.5:", index_negative_and_rv_lv_ratio_gte_1_gt_05.sum())
 print(" num predicted_as_not_positive and central_pe>0.5:", index_negative_and_central_pe_gt_05.sum())
 print(" num predicted_as_not_positive and central_pe>0.5:", index_negative_and_rightsided_pe_gt_05.sum())
 print(" num predicted_as_not_positive and leftsided_pe>0.5:", index_negative_and_leftsided_pe_gt_05.sum())
 print(" num predicted_as_not_positive and chronic_pe>0.5:", index_negative_and_chronic_pe_gt_05.sum())
 print(" num predicted_as_not_positive and acute_and_chronic_pe>0.5:", index_negative_and_acute_and_chronic_pe_gt_05.sum())
 print("process positive case")
 print(" num predicted_as_positive and rv_lv_ratio_lt_1<=rv_lv_ratio_gte_1:", index_positive_and_rv_gte_lv.sum())
 print(" num predicted_as_positive and rv_lv_ratio_lt_1>rv_lv_ratio_gte_1:", index_positive_and_rv_lt_lv.sum())
 print(" num predicted_as_positive and(rv_lv_ratio_lt_1<=rv_lv_ratio_gte_1)and(rv_lv_ratio_gte_1<=0.5): ",
index_positive_and_rv_gte_lv_and_rv_lv_ratio_gte_1_lte_05.sum())
 print(" num predicted_as_positive and(rv_lv_ratio_lt_1<=rv_lv_ratio_gte_1)and rv_lv_ratio_lt_1>0.5: ",
index_positive_and_rv_gte_lv_and_rv_lv_ratio_lt_1_gt_05.sum())
 print(" num predicted_as_positive and(rv_lv_ratio_lt_1>rv_lv_ratio_gte_1)and rv_lv_ratio_lt_1<=0.5: ",
index_positive_and_rv_lt_lv_and_rv_lv_ratio_lt_1_lte_05.sum())
 print(" num predicted_as_positive and(rv_lv_ratio_lt_1>rv_lv_ratio_gte_1)and rv_lv_ratio_gte_1>0.5: ",
index_positive_and_rv_lt_lv_and_rv_lv_ratio_gte_1_gt_05.sum())
 print(" num predicted_as_positive and central is greatest:", index_positive_and_central_is_greatest.sum())
 print(" num predicted_as_positive and right is greatest:", index_positive_and_right_is_greatest.sum())
 print(" num predicted_as_positive and left is greatest:", index_positive_and_left_is_greatest.sum())
 print(" num predicted_as_positive and central is greatest and central_pe<=0.5:", index_positive_and_central_is_greatest_and_central_pe_lte_05.sum())
 print(" num predicted_as_positive and right is greatest and rightsided_pe<=0.5:", index_positive_and_right_is_greatest_and_rightsided_pe_lte_05.sum())
 print(" num predicted_as_positive and left is greatest and leftsided_pe<=0.5:", index_positive_and_left_is_greatest_and_leftsided_pe_lte_05.sum())
 print(" num both chronic_pe and acute_and_chronic_pe is positive:", index_double_positive.sum())
 print(" num both chronic_pe and acute_and_chronic_pe is positive and chronic<=acute_and_chronic:", index_double_positive_and_chronic_lte_acute_and_chronic.sum())
 print(" num both chronic_pe and acute_and_chronic_pe is positive and chronic>acute_and_chronic:", index_double_positive_and_chronic_gt_acute_and_chronic.sum())
 print("process image level")
 print(" num img of predicted_as_positive:", index_positive_i.sum())
 print(" num img of predicted_as_negative:",(index_positive_i==0 ).sum())
 print(" num img of peak:", df_pred2['peak'].sum())
 print(" num img of predicted_as_negative and pe_present_on_image>0.5:", index_negative_and_pe_present_on_image_gt_05_i.sum())
 print(" num img of predicted_as_positive and peak and pe_present_on_image<=0.5:", index_positive_and_peak_and_pe_present_on_image_lte_05_i.sum())
 return df_pred_s, df_pred 
<merge>
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()
df_pred_study_const, df_pred_image_const = solve_conflict(df_pred_study, df_pred_image)
 df_pred_study_const.head()<concatenate>
@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
df_sub_pred = copy.deepcopy(df_pred_image_const[[col_index, col_targets[-1]]])
 df_sub_pred.columns = ['id', 'label']
for i, col in enumerate(col_targets[:-1]):
df_tmp = df_pred_study_const[[col_groupby, col]]
df_tmp.columns = ['id', 'label']
df_tmp['id'] = df_tmp['id'] + '_{}'.format(col)
 df_sub_pred = pd.concat([df_sub_pred, df_tmp])
 df_sub_pred = df_sub_pred.reset_index(drop=True)
 print(df_sub_pred.shape)
 df_sub_pred.head()<load_from_csv>
@tf.function
def _filtTP(x):
return x['is_tp'] == 1
df_sub = pd.read_csv(df_sub_path)
 print(df_sub.shape)
 df_sub.head()<merge>
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 )
df_sub = pd.merge(df_sub[['id']], df_sub_pred, on='id', how='left')
 print(df_sub.shape)
 df_sub.head()<feature_engineering>
@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 )
mean_targets = [
0.674681,
0.021569,
0.040115,
0.019920,
0.055090,
0.212117,
0.257590,
0.129139,
0.174612,
0.289885,
]
df_sub_mean = copy.deepcopy(df_test_full[[col_index]])
 df_sub_mean.columns = ['id']
df_sub_mean['label'] = mean_targets[-1]
for i, col in enumerate(col_targets[:-1]):
df_tmp = df_test_full_study[[col_groupby]]
df_tmp.columns = ['id']
df_tmp['label'] = mean_targets[i]
df_tmp['id'] = df_tmp['id'] + '_{}'.format(col)
 df_sub_mean = pd.concat([df_sub_mean, df_tmp])
 df_sub_mean = df_sub_mean.reset_index(drop=True)
 print(df_sub_mean.shape )<merge>
@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 )
df_sub['label'][pd.isna(df_sub['label'])] = pd.merge(df_sub[['id']], df_sub_mean, on='id', how='left')['label'][pd.isna(df_sub['label'])]
df_sub.head(20 )<merge>
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 = 50
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)
 image = tf.squeeze(image, axis=0)
 return image
if training:
gau = tf.keras.layers.GaussianNoise(0.3)
 image = tf.cond(tf.random.uniform([])< 0.5, lambda: gau(image, training=True), lambda: image)
 image = tf.image.random_brightness(image, 0.2)
 image = tf.image.random_flip_left_right(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"] )
def check_consistency2(df_exam, df_image, test):

 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<compute_test_metric>
def create_model() :
def Classifier(shape_):
backbone = cfg['model_params']['arch'](( shape_), include_top=False, weights='imagenet')
 def cbr(x, out_layer, kernel, stride, dilation):
x = Conv2D(out_layer, kernel_size=kernel, dilation_rate=dilation, strides=stride, padding="same" )(x)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 return x
def wave_block(x, filters, kernel_size, n):
dilation_rates = [2**i for i in range(n)]
x = Conv2D(filters = filters,
kernel_size = 1,
padding = 'same' )(x)
 res_x = x
for dilation_rate in dilation_rates:
tanh_out = Conv2D(filters = filters,
kernel_size = kernel_size,
padding = 'same',
activation = 'tanh',
dilation_rate = dilation_rate )(x)
 sigm_out = Conv2D(filters = filters,
kernel_size = kernel_size,
padding = 'same',
activation = 'sigmoid',
dilation_rate = dilation_rate )(x)
 x = Multiply()([tanh_out, sigm_out])
 x = Conv2D(filters = filters,
kernel_size = 1,
padding = 'same' )(x)
 res_x = Add()([res_x, x])
 return res_x
def wavenet(layer):
x = cbr(layer, 192, 7, 1, 1)
 x = BatchNormalization()(x)
 x = wave_block(x, 192, 3, 1)
 x = cbr(x, 96, 7, 1, 1)
 x = BatchNormalization()(x)
 x = wave_block(x, 96, 3, 1)
 x = cbr(x, 48, 5, 1, 1)
 x = BatchNormalization()(x)
 x = wave_block(x, 48, 3, 1)
 return x
def wavenet1(layer):
x = cbr(layer, 4, 7, 1, 1)
 x = BatchNormalization()(x)
 x = wave_block(x, 3, 3, 1)
 x = cbr(x, 3, 7, 1, 1)
 x = BatchNormalization()(x)
 x = wave_block(x, 16, 3, 1)
 x = cbr(x, 3, 5, 1, 1)
 return x
x0 = backbone
print('1')
 x1 = tf.keras.layers.GlobalAveragePooling2D()(x0.layers[-1].output)
 x3 = tf.keras.layers.GlobalAveragePooling2D()(x0.layers[-7].output)
 x5 = tf.keras.layers.GlobalAveragePooling2D()(x0.layers[-18].output)
 print('2')
 x1=wavenet(x0.layers[-1].output)
 x3=wavenet(x0.layers[-7].output)
 x5=wavenet(x0.layers[-18].output)
 x1 = tf.keras.layers.GlobalAveragePooling2D()(x1)
 x3 = tf.keras.layers.GlobalAveragePooling2D()(x3)
 x5 = tf.keras.layers.GlobalAveragePooling2D()(x5)
 print('4')
 x = tf.concat([x1,x3,x5],axis = 1)
 x = tf.keras.layers.Dropout(0.7 )(x)
 x = tf.keras.layers.Dense(192 )(x)
 x = tf.keras.layers.Dropout(0.4 )(x)
 output = tf.keras.layers.Softmax(dtype='float32' )(x)
 output =tf.keras.layers.Dense(CLASS_N )(x)
 print('5')
 model = tf.keras.models.Model(inputs = x0.input, outputs = output)
 return model
return Classifier([HEIGHT,WIDTH,3])
 model = create_model()
model.summary()
error = check_consistency2(df_pred_study_const, df_pred_image_const, df_test )<save_to_csv>
@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)
 alpha = 0.2
t = tf.compat.v1.distributions.Beta(alpha, alpha ).sample([len(inp)])
 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
if len(error)==0:
df_sub.to_csv('submission.csv', index=None)
 else:
print("error!" )<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() )
USE_POST_PROCESS = True<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() )
PATH_CSV = '.. /input/rsna-str-pulmonary-embolism-detection/test.csv'
PATH_CSV_SUB = '.. /input/rsna-str-pulmonary-embolism-detection/sample_submission.csv'
PATH_FOLDER = '.. /input/rsna-str-pulmonary-embolism-detection/test'
USE_FOLDS = [0, 2]
PATH_STAGE1_ARGS_LIST = ['.. /input/rsna-emboli-ckpts/stage1/fold{}_ResNext101.json'.format(i)for i in USE_FOLDS]
PATH_STAGE1_MODEL_LIST = ['.. /input/rsna-emboli-ckpts/stage1/fold{}_ResNext101.pt'.format(i)for i in USE_FOLDS]
PATH_STAGE2_ARGS_LIST = ['.. /input/rsna-emboli-ckpts/stage2_pseudo/F{}GRUPseudo.json'.format(i)for i in USE_FOLDS]
PATH_STAGE2_MODEL_LIST = ['.. /input/rsna-emboli-ckpts/stage2_pseudo/F{}GRUPseudo.pt'.format(i)for i in USE_FOLDS]
TX_STAGE2_ARGS = '.. /input/rsna-emboli-ckpts/args_tx.json'
TX_STAGE2_MODEL = '.. /input/rsna-emboli-ckpts/fold_0_epoch_12_txGRUall.pt'
PATH_KH = '.. /input/submission-kh3/kh/weight_files' 
<data_type_conversions>
table = pd.DataFrame({'indices': indices, 'species_id': spid, 'recording_id': recid})
 table
class CTData(torch.utils.data.Dataset):
def __init__(self, path_folder, uids):
self.path_folder = path_folder
self.uids = uids
def get_pixels_hu(self, slices):
image = np.stack([s.pixel_array for s in slices])
 image = image.astype(np.int16)
 for slice_number in range(len(slices)) :
intercept = slices[slice_number].RescaleIntercept
slope = slices[slice_number].RescaleSlope
if slope != 1:
image[slice_number] = slope \
* image[slice_number].astype(np.float64)
 image[slice_number] = image[slice_number].astype(np.int16)
 image[slice_number] += np.int16(intercept)
 image = np.array(image, dtype=np.int16)
 image[image < -1024] = -1024
return image
def get_pixels_kaggle(self, slices:list)->(np.array, list):
image = np.stack([(s.pixel_array * s.RescaleSlope)+ s.RescaleIntercept for s in slices])
 return image.astype('float32')
 def load_scan(self, path_to_dir, order_by_instance_number=False):
dicom_paths = glob.glob(path_to_dir + '/*/*.dcm')
 dicom_slices = [dicom.read_file(x, force=True)for x in dicom_paths]
zipped = list(zip(dicom_slices, dicom_paths))
if order_by_instance_number:
zipped.sort(key = lambda x:int(x[0].InstanceNumber))
else:
zipped.sort(key = lambda x: float(x[0].ImagePositionPatient[2]))
dicom_slices = list(list(zip(*zipped)) [0])
 dicom_paths = list(list(zip(*zipped)) [1])
 return dicom_slices, dicom_paths
def windowing(self, img, mode="pe"):
if mode == "mediastinal":
WL = 40
WW = 450
elif mode == "pe":
WL = 100
WW = 700
elif mode == "lung":
WL = -600
WW = 1500
upper, lower = WL + WW // 2, WL - WW // 2
X = np.clip(img.copy() , lower, upper)
 X = X - lower
X = X /(upper - lower)
 return X
def mk_preprocess(self, image):

 img = image[:, 32:480, 32:480]
img0 = self.windowing(img, "mediastinal")[np.newaxis]
img1 = self.windowing(img, "pe")[np.newaxis]
img2 = self.windowing(img, "lung")[np.newaxis]
img = np.concatenate(( img0, img1, img2), axis=0)
 img = img.astype(np.float32)
 return img
def __len__(self):
return len(self.uids)
 def __getitem__(self, index):

 t0 = time.time()
uid = self.uids[index]
path_to_dcm = os.path.join(self.path_folder, self.uids[index])
 dicom_slices, dicom_paths = self.load_scan(path_to_dcm)
 dicom_pixels = self.get_pixels_hu(dicom_slices)
 dicom_pixels_mk = self.mk_preprocess(dicom_pixels)
 dicom_pixels_kh = self.get_pixels_kaggle(dicom_slices)
 img_num = len(dicom_slices)
 locs = np.zeros(( img_num,), np.float32)
 for i in range(img_num):
locs[i] = dicom_slices[i].ImagePositionPatient[2]
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
locs = locs.astype('float32')
 dicom_pixels = dicom_pixels.astype('float32')
 dicom_pixels_kh = kh_model_all.preprocess(dicom_pixels_kh)
 print('one item time: ', time.time() - t0)
 return uid, dicom_paths, dicom_pixels_mk, dicom_pixels_kh, locs<load_pretrained>
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
class FeatSeqALLModel(object):
def __init__(self, stage1_args_path, stage1_model_path, stage2_args_path, stage2_model_path, tx_args_path=None, tx_model_path=None):
super(FeatSeqALLModel, self ).__init__()
self.has_tx = False
if tx_args_path is not None:
self.has_tx = True
with open(stage1_args_path, "rb")as j:
stage1_args = json.load(j)
 stage1_args = Namespace(**stage1_args)
 self.stage1_model = slicenet.ResNext(stage1_args, use_pretrained=False)
 stage1_load_checkpoint = torch.load(stage1_model_path)
 self.stage1_model.load_state_dict(stage1_load_checkpoint["model"], strict=True)
 self.stage1_model.embedder.fc = torch.nn.Identity()
self.stage1_model.cuda()
with open(stage2_args_path, "rb")as j:
stage2_args = json.load(j)
 stage2_args = Namespace(**stage2_args)
 self.stage2_model = featseqallnet.FeatGRUALL(stage2_args, use_pretrained=False)
 stage2_load_checkpoint = torch.load(stage2_model_path)
 self.stage2_model.load_state_dict(stage2_load_checkpoint["model"], strict=True)
 self.stage2_model.cuda()
if self.has_tx:
with open(tx_args_path, "rb")as j:
tx_args = json.load(j)
 tx_args = Namespace(**tx_args)
 self.tx_model = featseqallnet.FeatTxGruALL(tx_args, use_pretrained=False)
 tx_load_checkpoint = torch.load(tx_model_path)
 self.tx_model.load_state_dict(tx_load_checkpoint["model"], strict=True)
 self.tx_model.cuda()
def predict(self, pixel_arrays, batch_size=64, verbosity=0):
self.stage1_model.eval()
with torch.no_grad() :
image_feats = []
f_len = pixel_arrays.shape[1]
batch_images = []
for center_loc in range(f_len):
h5_file = np.array(pixel_arrays[:, center_loc, :, :])
 image = h5_file
batch_images.append(image)
 if(len(batch_images)== batch_size)or(center_loc ==(f_len-1)) :
batch = torch.from_numpy(np.array(batch_images))
batch = batch.cuda()
result = self.stage1_model(batch)
 image_feats.extend(result.detach().cpu().numpy())
 if verbosity:
pass
torch.cuda.empty_cache()
batch_images = []
self.stage2_model.eval()
with torch.no_grad() :
feats = torch.from_numpy(np.array(image_feats)[np.newaxis])
 feats = feats.cuda()
results = self.stage2_model(feats)
 logits = results[0,:,0]
exam_logits = logits[:9]
image_logits = logits[9:]
if self.has_tx:
self.tx_model.eval()
with torch.no_grad() :
tx_results = self.tx_model(feats)
 tx_logits = tx_results[0,:,0]
tx_exam_logits = tx_logits[:9]
tx_image_logits = tx_logits[9:]
exam_logits =(exam_logits + tx_exam_logits)/ 2
image_logits =(image_logits + tx_image_logits)/ 2
torch.cuda.empty_cache()
return exam_logits, image_logits 
<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
start_time = time.time()
feat_seq_all_model_list = [FeatSeqALLModel(
 stage1_args_path=PATH_STAGE1_ARGS_LIST[0],
stage1_model_path=PATH_STAGE1_MODEL_LIST[0],
stage2_args_path=PATH_STAGE2_ARGS_LIST[0],
stage2_model_path=PATH_STAGE2_MODEL_LIST[0],
tx_args_path=TX_STAGE2_ARGS,
tx_model_path=TX_STAGE2_MODEL),
FeatSeqALLModel(
 stage1_args_path=PATH_STAGE1_ARGS_LIST[1],
stage1_model_path=PATH_STAGE1_MODEL_LIST[1],
stage2_args_path=PATH_STAGE2_ARGS_LIST[1],
stage2_model_path=PATH_STAGE2_MODEL_LIST[1])]
print(time.time() - start_time, ' s for loading models' )<choose_model_class>
@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 )
def sigmoid(x):
x = np.array(x)
 return 1 /(1 +np.exp(-x))
kh_model_all = kh_model.KHModel(
 weight_dir = PATH_KH,
fold = None
)<feature_engineering>
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
def post_process(exam_logits, image_logits, epsilon=1e-15):
if exam_logits[0] > 0.5:
exam_logits[1:] = np.clip(exam_logits[1:], epsilon, 0.5-epsilon)
 image_logits = np.clip(image_logits, epsilon, 0.5-epsilon)
 elif exam_logits[1] > 0.5:
image_logits = np.clip(image_logits, epsilon, 0.5-epsilon)
 else:
if image_logits.max() <= 0.5:
image_logits[np.argmax(image_logits)] = 0.5+epsilon
if exam_logits[7] > 0.5 and exam_logits[8] > 0.5:
if exam_logits[7] >= exam_logits[8]:
exam_logits[8] = np.clip(exam_logits[8], epsilon, 0.5-epsilon)
 else:
exam_logits[7] = np.clip(exam_logits[7], epsilon, 0.5-epsilon)
 if exam_logits[7] <= 0.5 and exam_logits[8] <= 0.5:
if exam_logits[7] >= exam_logits[8]:
exam_logits[7] = 0.5+epsilon
else:
exam_logits[8] = 0.5+epsilon
if exam_logits[4] <= 0.5 and exam_logits[5] <= 0.5 and exam_logits[6] <= 0.5:
idx_max = np.argmax([exam_logits[4], exam_logits[5], exam_logits[6]])
 if idx_max == 0:
exam_logits[4] = 0.5+epsilon
elif idx_max == 1:
exam_logits[5] = 0.5+epsilon
else:
exam_logits[6] = 0.5+epsilon
if exam_logits[2] > 0.5 and exam_logits[3] > 0.5:
if exam_logits[2] >= exam_logits[3]:
exam_logits[3] = np.clip(exam_logits[3], 0, 0.5-epsilon)
 else:
exam_logits[2] = np.clip(exam_logits[2], 0, 0.5-epsilon)
 return exam_logits, image_logits 
<remove_duplicates>
class RMAC:
def __init__(self, shape, levels=3, power=None, overlap=0.4, norm_fm=False, sum_fm=True, verbose=False):
self.shape = shape
self.sum_fm = sum_fm
self.norm = norm_fm
self.power = power
steps = np.asarray([2, 3, 4, 5, 6, 7])
 B, H, W, D = shape
w = min([W, H])
 w2 = w // 2 - 1
b = np.asarray(( max(H, W)- w)) /(steps - 1);
idx = np.argmin(np.abs(((w**2 - w*b)/(w**2)) -overlap))
Wd = 0
Hd = 0
if H < W:
Wd = idx + 1
elif H > W:
Hd = idx + 1
self.regions = []
for l in range(levels):
wl = int(2 * w/(l+2)) ;
wl2 = int(wl / 2 - 1);
b = 0 if not(l + Wd)else(( W - wl)/(l + Wd))
cenW = np.asarray(np.floor(wl2 + np.asarray(range(l+Wd+1)) * b), dtype=np.int32)- wl2
b = 0 if not(l + Hd)else(( H - wl)/(l + Hd))
cenH = np.asarray(np.floor(wl2 + np.asarray(range(l+Hd+1)) * b), dtype=np.int32)- wl2
for i in cenH:
for j in cenW:
if i >= W or j >= H:
continue
ie = i+wl
je = j+wl
if ie >= W:
ie = W
if je >= H:
je = H
if ie - i < 1 or je - j < 1:
continue
self.regions.append(( i,j,ie,je))
if verbose:
print('RMAC regions = %s' % self.regions)
 def rmac(self, x):
y = []
for r in self.regions:
x_sliced = x[:, r[1]:r[3], r[0]:r[2], :]
if self.power is None:
x_maxed = tf.reduce_max(x_sliced, axis=(1,2))
else:
x_maxed = tf.reduce_mean(( x_sliced ** self.power), axis=(2,3)) **(1.0 / self.power)
 x_maxed = tf.pow(tf.reduce_mean(( tf.pow(x_sliced, self.power)) , axis=(2,3)) ,(1.0 / self.power))
y.append(x_maxed)
 y = tf.stack(y, axis=0)
 y = tf.transpose(y, [1,0,2])
 if self.norm:
y = tf.math.l2_normalize(y, 2)
 if self.sum_fm:
y = tf.reduce_mean(y, axis=(1))
return y
df_test = pd.read_csv(PATH_CSV)
 print('StudyInstanceUID :', len(df_test.StudyInstanceUID.drop_duplicates()))
test_uids = list(df_test.StudyInstanceUID.drop_duplicates())
 DEBUG =(df_test.shape[0]==146853)
 if DEBUG:
test_uids = test_uids[:3]
print('Is DEBUG: ', DEBUG )<define_variables>
def train_and_inference(splits, split_id):
print("split_id", 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'])
 idx_train_tf = tf.constant(splits[split_id][0])
 idx_val_tf = tf.constant(splits[split_id][1])
 dataset = create_train_dataset(batchsize, idx_train_tf)
 vdataset = create_val_dataset(batchsize, idx_val_tf)
 optimizer = cfg['model_params']['optim']['fn'](**cfg['model_params']['optim']['params'])
 with strategy.scope() :
model = create_model()
model.compile(optimizer=optimizer, loss=loss_fn, metrics=[LWLRAP(CLASS_N)])
 history = model.fit(dataset,
steps_per_epoch=cfg['model_params']['iteration_per_epoch'],
epochs=cfg['model_params']['epoch'],
validation_data=vdataset,
callbacks=[
tf.keras.callbacks.ReduceLROnPlateau(
 'val_lwlrap', patience=10 
),
tf.keras.callbacks.ModelCheckpoint(
 filepath='model_best_%d.h5' % split_id,
save_weights_only=True,
monitor='val_lwlrap',
mode='max',
save_best_only=True),
])
 plot_history(history, 'history_%d.png' % split_id)
 model.load_weights('model_best_%d.h5' % split_id)
 return inference(model )
target_cols_kh = ['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_target_cols = ['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']
reorder_idxs = [0, 8, 4, 6, 7, 3, 5, 1, 2]
[target_cols_kh[i] for i in reorder_idxs] == exam_target_cols<define_variables>
sub = pd.read_csv('.. /input/resnetwavenet851/submission.csv' )
df_save = {}<load_pretrained>
sub2 = pd.read_csv('.. /input/automl-inference-audio-detection-soliset/submission.csv' )
ctdata = CTData(path_folder = PATH_FOLDER, uids = test_uids)
 ctloader = torch.utils.data.DataLoader(ctdata, shuffle=False, batch_size=1, num_workers=1, pin_memory=False)
 t0 = time.time()
for uid, dicom_paths, pixel_arrays_mk, pixel_arrays_kh, locs in tqdm(ctloader):
uid = uid[0]
dps = [dp[0] for dp in dicom_paths]
uid_iids = [dp.split('/')[-1][:-4] for dp in dps]
pixel_arrays_mk = np.array(pixel_arrays_mk)[0]
t00 = time.time()
for mi, feat_seq_all_model in enumerate(feat_seq_all_model_list):
uid_exam_logits, uid_image_logits = feat_seq_all_model.predict(pixel_arrays_mk, batch_size=64, verbosity=DEBUG)
 mi_uid_exam_preds = torch.sigmoid(uid_exam_logits ).detach().cpu().numpy()
mi_uid_image_preds = torch.sigmoid(uid_image_logits ).detach().cpu().numpy()
if mi == 0:
uid_exam_preds_list = mi_uid_exam_preds[:, np.newaxis]
uid_image_preds_list = mi_uid_image_preds[:, np.newaxis]
else:
uid_exam_preds_list = np.concatenate(( uid_exam_preds_list, mi_uid_exam_preds[:, np.newaxis]), axis=1)
 uid_image_preds_list = np.concatenate(( uid_image_preds_list, mi_uid_image_preds[:, np.newaxis]), axis=1)
 print('one inference time: ', time.time() - t00)
 uid_exam_preds_mk = uid_exam_preds_list[:, 0] * 2/3 + uid_exam_preds_list[:, 1] * 1/3
uid_image_preds_mk = uid_image_preds_list[:, 0] * 2/3 + uid_image_preds_list[:, 1] * 1/3
pixel_arrays_kh = pixel_arrays_kh[0]
locs = np.expand_dims(np.array(locs), -1)
 result_image6, result_exam6 = kh_model_all.predict(pixel_arrays_kh, locs, batch_size=32)
 result_image = np.mean([result_image6], axis=0)
 result_exam = np.mean([result_exam6], axis=0)
 result_image_bh = sigmoid(result_image)
 result_exam_bh = sigmoid(result_exam)
 uid_exam_preds_bh = result_exam_bh[reorder_idxs]
uid_image_preds_bh = result_image_bh[:, 0]
uid_exam_preds = uid_exam_preds_mk * 2/3 + uid_exam_preds_bh * 1/3
uid_image_preds = uid_image_preds_mk * 2/3 + uid_image_preds_bh* 1/3
print(uid_exam_preds)
 print(uid_image_preds[:20])
 if USE_POST_PROCESS:
uid_exam_preds, uid_image_preds = post_process(uid_exam_preds, uid_image_preds)
 for(exam_label, exam_label_pred)in zip(exam_target_cols, uid_exam_preds):
df_save[uid+'_'+exam_label] = exam_label_pred
for(iid, iid_pred)in zip(uid_iids, uid_image_preds):
df_save[iid] = iid_pred
print('Total Time: ', time.time() - t0, 'seconds' )<create_dataframe>
sub.iloc[:,1:]=sub.iloc[:,1:]*0.30+sub2.iloc[:,1:]*0.70
<save_to_csv><EOS> 
sub.to_csv("submission.csv", index=False )