Kaggle competition: Telstra Network Disruptions
<SOS> metric: MulticlassLoss Kaggle data source: telstra-network-disruptions<install_modules>
sns.set_style("whitegrid")
 %matplotlib inline
!pip install image-classifiers<import_modules>
warnings.filterwarnings('ignore' )
tf.__version__<define_variables>
train = pd.read_csv('.. /input/telstra-recruiting-network/train.csv.zip')
 test = pd.read_csv('.. /input/telstra-recruiting-network/test.csv.zip')
 severity_type = pd.read_csv('.. /input/telstra-recruiting-network/severity_type.csv.zip', error_bad_lines= False, warn_bad_lines= False)
 resource_type = pd.read_csv('.. /input/telstra-recruiting-network/resource_type.csv.zip', error_bad_lines= False, warn_bad_lines= False)
 log_failure = pd.read_csv('.. /input/telstra-recruiting-network/log_feature.csv.zip', error_bad_lines= False, warn_bad_lines= False)
 event_type = pd.read_csv('.. /input/telstra-recruiting-network/event_type.csv.zip', error_bad_lines=False, warn_bad_lines= False )
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 )<choose_model_class>
train_1 = train.merge(severity_type, how = 'left', left_on='id', right_on='id')
 train_2 = train_1.merge(resource_type, how = 'left', left_on='id', right_on='id')
 train_3 = train_2.merge(log_failure, how = 'left', left_on='id', right_on='id')
 train_4 = train_3.merge(event_type, how = 'left', left_on='id', right_on='id' )
ResNet34, preprocess_input = Classifiers.get('resnet34' )<init_hyperparams>
train_4.drop_duplicates(subset= 'id', keep= 'first', inplace = True)
 train_4.head()
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
}
}<define_variables>
from catboost import CatBoostClassifier, Pool
from sklearn.model_selection import train_test_split
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"<define_variables>
X = train_4[['id', 'location', 'severity_type', 'resource_type',
'log_feature', 'volume', 'event_type']]
y = train_4.fault_severity
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<create_dataframe>
X_train, X_validation, y_train, y_validation = train_test_split(X, y, test_size=0.20, random_state=101 )
raw_dataset = tf.data.TFRecordDataset([TRAIN_TFREC + '/00-148.tfrec'])
 raw_dataset<categorify>
categorical_features_indices = np.where(X_train.dtypes == object)[0]
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()<feature_engineering>
train_dataset = Pool(data=X_train,
label=y_train,
cat_features=categorical_features_indices)
 eval_dataset = Pool(data=X_validation,
label=y_validation,
cat_features=categorical_features_indices )
@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<feature_engineering>
model = CatBoostClassifier(iterations=1000,
learning_rate=1,
depth=2,
loss_function='MultiClass',
random_seed=1,
bagging_temperature=22,
od_type='Iter',
metric_period=100,
od_wait=100 )
@tf.function
def _filtTP(x):
return x['is_tp'] == 1<data_type_conversions>
model.fit(train_dataset, eval_set= eval_dataset, plot= True )
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 )<normalization>
preds_class = model.predict(eval_dataset)
 preds_proba = model.predict_proba(eval_dataset )
@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 )<categorify>
test_1 = test.merge(severity_type, how = 'left', left_on='id', right_on='id')
 test_2 = test_1.merge(resource_type, how = 'left', left_on='id', right_on='id')
 test_3 = test_2.merge(log_failure, how = 'left', left_on='id', right_on='id')
 test_4 = test_3.merge(event_type, how = 'left', left_on='id', right_on='id' )
@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 )<normalization>
test_4.drop_duplicates(subset= 'id', keep= 'first', inplace = True)
 test_4.head()
@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"] )<choose_model_class>
test_4.isnull().sum()
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()<normalization>
predict_test=model.predict_proba(test_4)
 pred_df=pd.DataFrame(predict_test,columns=['predict_0', 'predict_1', 'predict_2'])
 submission_cat=pd.concat([test[['id']],pred_df],axis=1)
 submission_cat.to_csv('sub_cat_1.csv',index=False,header=True )