Kaggle competition: Digit Recognizer
<SOS> metric: categorizationaccuracy Kaggle data source: digit-recognizer<init_hyperparams>
!pip -q install tensorflow-gpu==2.0.0-beta1
!pip -q install tensorflow-addons
CUT = 5
STRIDE = 3
EPOCHS = 25
AUG_BATCH = GLOBAL_BATCH_SIZE
VAL_BATCH_SIZE = GLOBAL_BATCH_SIZE
LEARNING_RATE = 0.0015
WARMUP_LEARNING_RATE = 1e-5
WARMUP_EPOCHS = int(EPOCHS*0.1)
 PATIENCE = EPOCHS
N_FOLDS = 4
NUM_TRAINING_SAMPLES = no_of_training_samples
class params:
sample_rate = 48000
stft_window_seconds: float = 0.025
stft_hop_seconds: float = 0.005
frame_length: int = 1200
mel_bands: int = 512
mel_min_hz: float = 50.0
mel_max_hz: float = 24000.0
log_offset: float = 0.001
patch_window_seconds: float = 0.96
patch_hop_seconds: float = 0.48
patch_frames = int(round(patch_window_seconds / stft_hop_seconds))
patch_bands = mel_bands
height = mel_bands
width = CUT * 200
num_classes: int = 24
dropout = 0.35
classifier_activation: str = 'sigmoid'
IMAGE_SIZE = [params.height, params.width]
CLASSES = params.num_classes 
<feature_engineering>
BatchNormalization,
Dense,
Dropout,
Flatten,
Conv2D,
MaxPool2D, 
)
 AUTOTUNE = tf.data.experimental.AUTOTUNE
feature_description = {
'wav': tf.io.FixedLenFeature([], tf.string),
'recording_id': tf.io.FixedLenFeature([], tf.string),
'target' : tf.io.FixedLenFeature([], tf.float32),
'song_id': tf.io.FixedLenFeature([], tf.float32),
'tmin' : tf.io.FixedLenFeature([], tf.float32),
'fmin' : tf.io.FixedLenFeature([], tf.float32),
'tmax' : tf.io.FixedLenFeature([], tf.float32),
'fmax' : tf.io.FixedLenFeature([], tf.float32),
'is_tp' : tf.io.FixedLenFeature([], tf.int32)
 }
feature_dtype = {
'wav': tf.float32,
'recording_id': tf.string,
'target': tf.float32,
'song_id': tf.float32,
't_min': tf.float32,
'f_min': tf.float32,
't_max': tf.float32,
'f_max':tf.float32,
}<normalization>
IMG_HEIGHT = 28
IMG_WIDTH = 28
BATCH_SIZE = 128
BUFFER_SIZE = 1000
def waveform_to_log_mel_spectrogram(waveform,target_or_rec_id):

 window_length_samples = int(
 round(params.sample_rate * params.stft_window_seconds))
hop_length_samples = int(
 round(params.sample_rate * params.stft_hop_seconds))
fft_length = 2 ** int(np.ceil(np.log(window_length_samples)/ np.log(2.0)))
 num_spectrogram_bins = fft_length // 2 + 1
magnitude_spectrogram = tf.abs(tf.signal.stft(
 signals=waveform,
frame_length=params.frame_length,
frame_step=hop_length_samples,
fft_length= fft_length))
linear_to_mel_weight_matrix = tf.signal.linear_to_mel_weight_matrix(
 num_mel_bins=params.mel_bands,
num_spectrogram_bins=num_spectrogram_bins,
sample_rate=params.sample_rate,
lower_edge_hertz=params.mel_min_hz,
upper_edge_hertz=params.mel_max_hz)
 mel_spectrogram = tf.matmul(
 magnitude_spectrogram, linear_to_mel_weight_matrix)
 log_mel = tf.math.log(mel_spectrogram + params.log_offset)
 log_mel = tf.transpose(log_mel)
 log_mel_spectrogram = tf.reshape(log_mel , [tf.shape(log_mel)[0] ,tf.shape(log_mel)[1],1])
 spectrogram_hop_length_samples = int(
 round(params.sample_rate * params.stft_hop_seconds))
spectrogram_sample_rate = params.sample_rate / spectrogram_hop_length_samples
patch_window_length_samples = int(
 round(spectrogram_sample_rate * params.patch_window_seconds))
patch_hop_length_samples = int(
 round(spectrogram_sample_rate * params.patch_hop_seconds))
features = tf.signal.frame(
 signal=log_mel_spectrogram,
frame_length=patch_window_length_samples,
frame_step=patch_hop_length_samples,
axis=0)
 return log_mel_spectrogram, target_or_rec_id<categorify>
def reshape(image):
image = tf.reshape(image, [IMG_HEIGHT, IMG_WIDTH, 1])
 return image
def normalize(image):
image = tf.cast(image, tf.float32)
 image =(image / 127.5)- 1
return image
def random_crop(image):
cropped_image = tf.image.random_crop(
 image, size=[IMG_HEIGHT, IMG_WIDTH, 1])
 return cropped_image
def random_rotate(image):
rotate_angles = tf.random.normal([], stddev=0.2)
 image = tfa.image.rotate(image, rotate_angles)
 return image
def random_jitter(image):
image = tf.image.resize(image, [30, 30],
method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
 image = random_crop(image)
 return image
def preprocess_train(*features):
label = features[0]
image = tf.stack(features[1:], axis=-1)
 image = reshape(image)
 image = random_rotate(image)
 image = random_jitter(image)
 image = normalize(image)
 return image, label
def preprocess_eval(*features):
label = features[0]
image = tf.stack(features[1:], axis=-1)
 image = reshape(image)
 image = normalize(image)
 return image, label
def preprocess_test(*features):
image = tf.stack(features, axis=-1)
 image = reshape(image)
 image = normalize(image)
 return image
def frequency_masking(mel_spectrogram):
frequency_masking_para = 80,
frequency_mask_num = 2
fbank_size = tf.shape(mel_spectrogram)
 n, v = fbank_size[0], fbank_size[1]
for i in range(frequency_mask_num):
f = tf.random.uniform([], minval=0, maxval= tf.squeeze(frequency_masking_para), dtype=tf.int32)
 v = tf.cast(v, dtype=tf.int32)
 f0 = tf.random.uniform([], minval=0, maxval= tf.squeeze(v-f), dtype=tf.int32)
 mask = tf.concat(( tf.ones(shape=(n, v - f0 - f,1)) ,
tf.zeros(shape=(n, f,1)) ,
tf.ones(shape=(n, f0,1)) , 
),1)
 mel_spectrogram = mel_spectrogram * mask
return tf.cast(mel_spectrogram, dtype=tf.float32)
 def time_masking(mel_spectrogram):
time_masking_para = 40,
time_mask_num = 1
fbank_size = tf.shape(mel_spectrogram)
 n, v = fbank_size[0], fbank_size[1]
for i in range(time_mask_num):
t = tf.random.uniform([], minval=0, maxval=tf.squeeze(time_masking_para), dtype=tf.int32)
 t0 = tf.random.uniform([], minval=0, maxval= n-t, dtype=tf.int32)
 mask = tf.concat(( tf.ones(shape=(n-t0-t, v,1)) ,
tf.zeros(shape=(t, v,1)) ,
tf.ones(shape=(t0, v,1)) , 
), 0)
 mel_spectrogram = mel_spectrogram * mask
return tf.cast(mel_spectrogram, dtype=tf.float32)
 def random_brightness(image):
return tf.image.random_brightness(image, 0.2)
 def random_gamma(image):
return tf.image.random_contrast(image, lower = 0.1, upper = 0.3)
 def random_flip_right(image):
return tf.image.random_flip_left_right(image)
 def random_flip_up_down(image):
return tf.image.random_flip_left_right(image)
 def shift_scale_shear(image):
a0 = tf.random.uniform([], minval=0.9, maxval=1.1)
 a1 = tf.random.uniform([], minval=-0.05, maxval=0.05)
 a2 = tf.random.uniform([], minval=-params.width * 0.1, maxval = 0.1 * params.width)
 b0 = tf.random.uniform([], minval=-0.05, maxval=0.05)
 b1 = tf.random.uniform([], minval=0.9, maxval=1.1)
 b2 = tf.random.uniform([], minval=-params.height * 0.1, maxval = 0.1 * params.height)
 return tfa.image.transform(image, [a0, a1, a2, b0, b1, b2, 0, 0], interpolation="bilinear", fill_mode="reflect")
 def random_rotate(image):
angle = tf.random.uniform([], minval=-10, maxval=10)
 return tfa.image.rotate(image, angle, interpolation="nearest", fill_mode="reflect")
 available_ops = [
frequency_masking ,
time_masking,
random_brightness,
random_flip_up_down,
random_flip_right,
shift_scale_shear,
random_rotate
]
def apply_augmentation(image, target):
num_layers = int(np.random.uniform(low = 0, high = 3))
for layer_num in range(num_layers):
op_to_select = tf.random.uniform([], maxval=len(available_ops), dtype=tf.int32, seed = seed)
 for(i, op_name)in enumerate(available_ops):
image = tf.cond(
 tf.equal(i, op_to_select),
lambda selected_func=op_name,: selected_func(
 image),
lambda: image)
 return image, target<string_transform>
ds = tf.data.experimental.CsvDataset(
 ".. /input/train.csv",
[tf.int64] * 785,
header=True, 
)
 ds_test = tf.data.experimental.CsvDataset(
 ".. /input/test.csv",
[tf.int64] * 784,
header=True, 
)
 num_eval = int(42000 * 0.1)
 ds_eval = ds.take(num_eval)
 ds_train = ds.skip(num_eval)
 ds_train = ds_train.map(preprocess_train, num_parallel_calls=AUTOTUNE ).cache().shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 ds_eval = ds_eval.map(preprocess_eval, num_parallel_calls=AUTOTUNE ).cache().shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 ds_test = ds_test.map(preprocess_test, num_parallel_calls=AUTOTUNE ).batch(32 )
def string_split_semicolon(column):
split_labels_sc = tf.strings.split(column, sep=';')
 return split_labels_sc
def string_split_comma(column):
split_labels_c = tf.strings.split(column, sep=',')
 return split_labels_c
def get_label_info(label_info):
first_split = string_split_semicolon(label_info)
 remove_quotes = tf.strings.regex_replace(first_split, '"', "")
 label_info = string_split_comma(remove_quotes)
 return label_info<split>
model = tf.keras.models.Sequential(
 [
Conv2D(32,(3, 3), activation="relu", input_shape=(28, 28, 1)) ,
BatchNormalization() ,
Conv2D(32,(3, 3), activation="relu"),
BatchNormalization() ,
Conv2D(32,(5, 5), activation="relu", strides=2, padding="same"),
BatchNormalization() ,
Dropout(0.4),
Conv2D(64,(3, 3), activation="relu"),
BatchNormalization() ,
Conv2D(64,(3, 3), activation="relu"),
BatchNormalization() ,
Conv2D(64,(5, 5), activation="relu", strides=2, padding="same"),
BatchNormalization() ,
Dropout(0.4),
Conv2D(128,(4, 4), activation="relu"),
BatchNormalization() ,
Flatten() ,
Dropout(0.4),
Dense(10, activation="softmax"),
]
)
def read_original_tfrecord(example):
TFREC_FORMAT = {
'audio_wav': tf.io.FixedLenFeature([], tf.string),
'recording_id': tf.io.FixedLenFeature([], tf.string),
'label_info': tf.io.FixedLenFeature([], tf.string, default_value='-1,-1,0,0,0,0,1'),
}
example = tf.io.parse_single_example(example, TFREC_FORMAT)
 audio = example['audio_wav']
label_info = get_label_info(example['label_info'])
 species_id = tf.strings.to_number(tf.gather_nd(label_info, [0, 0]), tf.int32)
 tmin = tf.strings.to_number(tf.gather_nd(label_info, [0, 2]))
fmin = tf.strings.to_number(tf.gather_nd(label_info, [0, 3]))
tmax = tf.strings.to_number(tf.gather_nd(label_info, [0, 4]))
fmax = tf.strings.to_number(tf.gather_nd(label_info, [0, 5]))
is_tp = tf.strings.to_number(tf.gather_nd(label_info, [0, 6]), tf.int32)
 features = {'wav': audio,
'recording_id': example['recording_id'],
'target': species_id,
'tmin': tmin,
'tmax': tmax,
'fmin': fmin,
'fmax': fmax,
'is_tp': is_tp
}
return features<categorify>
model.compile(optimizer= tf.keras.optimizers.Adam(learning_rate=1e-3),
loss="sparse_categorical_crossentropy",
metrics=["sparse_categorical_accuracy"] )
def preprocess(image, target_or_rec_id):
image = tf.image.grayscale_to_rgb(image)
 image = tf.image.resize(image, [params.height,params.width])
 image = tf.image.per_image_standardization(image)
 return image , target_or_rec_id
def _cut_wav(sample, random_shift):
wav, _ = tf.audio.decode_wav(sample['wav'], desired_channels=1)
 tmin = tf.cast(sample['tmin'], tf.float32)
 fmin = tf.cast(sample['fmin'], tf.float32)
 tmax = tf.cast(sample['tmax'], tf.float32)
 fmax = tf.cast(sample['fmax'], tf.float32)
 tmax_s = tmax * tf.cast(params.sample_rate, tf.float32)
 tmin_s = tmin * tf.cast(params.sample_rate, tf.float32)
 cut_s = tf.cast(CUT * params.sample_rate, tf.float32)
 tsize_s = tmax_s - tmin_s
center_s =(tmax_s + tmin_s)/ 2
if random_shift:
shift_limit = tf.math.abs(cut_s - tsize_s)
 shift_s = tf.cast(tf.random.uniform([],-shift_limit/2,shift_limit/2),tf.float32)
 center_s += shift_s
all_s = tf.cast(60 * params.sample_rate, tf.float32)
 cut_min = tf.maximum(0., center_s - cut_s / 2)
 cut_min = tf.minimum(cut_min, all_s - cut_s)
 cut_min = tf.cast(cut_min, tf.int32)
 cut_max = cut_min + CUT * params.sample_rate
wav = tf.squeeze(wav[cut_min : cut_max])
 return wav
def read_labeled_tfrecord(sample, random_shift = False):
target = tf.cast(sample['target'],tf.float32)
 target = tf.squeeze(tf.one_hot([target,], depth = params.num_classes), axis = 0)
 wav = _cut_wav(sample, random_shift)
 return wav, target
def read_labeled_tfrecord_fp(sample, random_shift = False):
target = tf.cast(sample['target'],tf.float32)
 target = tf.squeeze(tf.one_hot([target,], depth = params.num_classes), axis = 0)
 target = target - 1
wav = _cut_wav(sample, random_shift)
 return wav, target
def read_unlabeled_tfrecord(example):
feature_description = {
'recording_id': tf.io.FixedLenFeature([], tf.string),
'audio_wav': tf.io.FixedLenFeature([], tf.string),
}
sample = tf.io.parse_single_example(example, feature_description)
 wav, _ = tf.audio.decode_wav(sample['audio_wav'], desired_channels=1)
 recording_id = tf.reshape(tf.cast(sample['recording_id'] , tf.string), [1])
 def _cut_audio(i):
_sample = {
'audio_wav': tf.reshape(wav[i*params.sample_rate*STRIDE:i*params.sample_rate*STRIDE + params.sample_rate*CUT], [params.sample_rate*CUT]),
'recording_id': sample['recording_id']
}
return _sample
return tf.map_fn(_cut_audio, tf.range(( 60 - CUT)//STRIDE + 1), dtype={
'audio_wav': tf.float32,
'recording_id': tf.string
} )<categorify>
lr_reduction = ReduceLROnPlateau(monitor="val_loss", patience=3, verbose=1, factor=0.5, min_lr=1e-5)
 history = model.fit(ds_train, epochs=30, validation_data=ds_eval, callbacks=[lr_reduction] )
def filter_tp_tfrecord(sample):
return tf.cast(sample['is_tp'], tf.bool )<categorify>
predictions = model.predict(ds_test )
<categorify><EOS> 
submission = pd.concat([pd.Series(range(1,28001), name="ImageId"), results], axis=1)
 submission.to_csv("cnn_submission.csv", index=False )