Kaggle competition: Freesound General-Purpose Audio Tagging Challenge
<SOS> metric: MAP@{K} Kaggle data source: freesound-audio-tagging<set_options>
COMPLETE_RUN = False
torch.cuda.is_available()<import_modules>
np.random.seed(1001)
 %matplotlib inline
matplotlib.style.use('ggplot' )
from fastai.structured import *
from fastai.column_data import *<set_options>
train = pd.read_csv(".. /input/freesound-audio-tagging/train.csv")
 test = pd.read_csv(".. /input/freesound-audio-tagging/sample_submission.csv" )
np.set_printoptions(threshold=50, edgeitems=20)
 PATH='./'<import_modules>
print("Number of training examples=", train.shape[0], " Number of classes=", len(train.label.unique()))
from IPython.display import HTML, display<load_from_csv>
print('Minimum samples per category = ', min(train.label.value_counts()))
print('Maximum samples per category = ', max(train.label.value_counts()))
train = pd.read_csv('.. /input/train.csv')
 test = pd.read_csv('.. /input/test.csv' )<filter>
fname = '.. /input/freesound-audio-tagging/audio_train/' + '00044347.wav'
ipd.Audio(fname )
train.loc[train['idhogar'] == '2b58d945f'][['Id', 'idhogar', 'v2a1', 'tipovivi1', 'tipovivi2', 'tipovivi3', 'tipovivi4', 'tipovivi5']]<categorify>
wav = wave.open(fname)
 print("Sampling(frame)rate = ", wav.getframerate())
 print("Total samples(frames)= ", wav.getnframes())
 print("Duration = ", wav.getnframes() /wav.getframerate() )
def show_null(df):
df_null = df.isnull().sum()
print(df_null[df_null>0])
 def show_inf(df):
df_inf = df.isinf().sum()
print(df_inf[df_inf>0])
 def fill_null_value(df):
df['v2a1'].fillna(0, inplace=True)
 df['v18q1'].fillna(0, inplace=True)
 df['rez_esc'].fillna(-1, inplace=True)
 df['meaneduc'].fillna(df['escolari'], inplace=True)
 df['SQBmeaned'].fillna(df['meaneduc']**2, inplace=True)
 return df
def replace_yes_no(df, column):
mapping = {'yes': 1, 'no': 0}
df[column] = [mapping[item] if item in mapping else float(item)for item in df[column]]
return df
def calculate_dependency(df):
dep = []
for index, row in df.iterrows() :
if row['hogar_adul'] == row['hogar_mayor']:
if row['hogar_adul'] > 0:
dep.append(( row['hogar_nin'] + row['hogar_mayor'])* 2 / row['hogar_adul'])
 else:
dep.append(4)
 else:
dep.append(( row['hogar_nin'] + row['hogar_mayor'])/(row['hogar_adul'] - row['hogar_mayor']))
df['dependency'] = dep
return df
def pick_features(df):
return df[['v2a1', 'hacdor', 'hacapo', 'tipovivi2', 'computer', 'total_dis', 'tipovivi4', 'lugar5', 'lugar3', 'female', 'no_toilet_or_energy', 'toilet_and_refrig', 'wall_cond', 'floor_cond', 'roof_cond', 'home_cond', 'SQB_home_cond', 'v14a', 'refrig', 'v18q1', 'pisonotiene', 'cielorazo', 'abastaguadentro', 'abastaguafuera', 'abastaguano', 'noelec', 'sanitario1', 'energcocinar1', 'energcocinar4', 'elimbasu4', 'elimbasu5', 'dependency', 'overcrowding', 'SQBovercrowding', 'tipovivi1', 'tipovivi2', 'tipovivi3', 'tipovivi4']]
def add_total_disable(df):
print('add_total_disable')
 df['total_dis'] = df['dis']
for index, row in df[df.dis == 1].iterrows() :
others = df[df.idhogar == row['idhogar']]
for index_2, row in others.iterrows() :
if index != index_2:
df.loc[index_2, 'total_dis'] += 1
df['avg_dis_adult'] = df['dis'] / df['total_adults']
df['avg_dis'] = df['dis'] / df['tamhog']
return df
def add_total_adults(df):
print('add_total_adults')
 df['is_adult'] = df.apply(lambda x: int(bool(int(x['age']/18))), axis=1)
 def get_total_adults(x):
if x['parentesco1'] == 1:
value = df.loc[df.idhogar == x['idhogar']]['is_adult'].sum()
if value == 0:
return 0.01
else:
return value
else:
return 0
df['total_adults'] = df.apply(get_total_adults, axis=1)
 return df
def add_avg_devices(df):
df['avg_qmobilephone_adult'] = df['qmobilephone']/df['total_adults']
df['avg_qmobilephone'] = df['qmobilephone']/df['tamhog']
df['avg_computer_adult'] = df['computer'] / df['total_adults']
df['avg_computer'] = df['computer'] / df['tamhog']
df['avg_television_room'] = df['television'] / df['rooms']
df['avg_television_adult'] = df['television'] / df['total_adults']
df['avg_television'] = df['television'] / df['tamhog']
df['avg_tablet'] = df['v18q1'] / df['tamhog']
df['avg_tablet_adult'] = df['v18q1'] / df['total_adults']
return df
def add_education_score(df):
print('add_education_score')
 df['edu_level'] = df['instlevel9']*(2**8)+ df['instlevel8']*(2**7)+ df['instlevel7']*(2**6)+ df['instlevel6']*(2**5)+ df['instlevel5']*(2**4)+ df['instlevel4']*(2**3)+ df['instlevel3']*(2**2)+ df['instlevel2']*(2**1)+ df['instlevel1']
def get_total_adults_edu(x):
if x['parentesco1'] == 1:
adults = df.loc[(df.idhogar == x['idhogar'])&(df.is_adult == 1)]
if len(adults)> 0:
return adults['edu_level'].sum() / len(adults)
 else:
return 0
else:
return 0
df['adults_edu'] = df.apply(get_total_adults_edu, axis=1)
 return df
def add_no_toilet_or_energy(df):
df['no_toilet_or_energy'] = df['energcocinar1'] + df['sanitario1']
df['toilet_and_refrig'] = df['v14a'] + df['refrig']
df['wall_cond'] = df.apply(lambda row: row['epared1'] + 2*row['epared2'] + 4*row['epared3'], axis=1)
 df['floor_cond'] = df.apply(lambda row: row['etecho1'] + 2*row['etecho2'] + 4*row['etecho3'], axis=1)
 df['roof_cond'] = df.apply(lambda row: row['eviv1'] + 2*row['eviv2'] + 4*row['eviv3'], axis=1)
 df['home_cond'] = df.apply(lambda row: row['wall_cond'] + row['floor_cond'] + row['roof_cond'], axis=1)
 df['SQB_home_cond'] = df.apply(lambda row: row['home_cond']**2, axis=1)
 return df 
<categorify>
rate, data = wavfile.read(fname)
 print("Sampling(frame)rate = ", rate)
 print("Total samples(frames)= ", data.shape)
 print(data )
train = fill_null_value(train)
 train = replace_yes_no(train, 'edjefe')
 train = replace_yes_no(train, 'edjefa')
 train = calculate_dependency(train)
 train = add_total_adults(train)
 train = add_total_disable(train)
 train = add_no_toilet_or_energy(train)
 train = add_education_score(train)
 test = fill_null_value(test)
 test = replace_yes_no(test, 'edjefe')
 test = replace_yes_no(test, 'edjefa')
 test = calculate_dependency(test)
 test = add_total_adults(test)
 test = add_total_disable(test)
 test = add_no_toilet_or_energy(test)
 test = add_education_score(test)
<categorify>
ModelCheckpoint, TensorBoard, ReduceLROnPlateau)
 GlobalMaxPool1D, Input, MaxPool1D, concatenate)
<create_dataframe>
class Config(object):
def __init__(self,
sampling_rate=16000, audio_duration=2, n_classes=41,
use_mfcc=False, n_folds=10, learning_rate=0.0001,
max_epochs=50, n_mfcc=20):
self.sampling_rate = sampling_rate
self.audio_duration = audio_duration
self.n_classes = n_classes
self.use_mfcc = use_mfcc
self.n_mfcc = n_mfcc
self.n_folds = n_folds
self.learning_rate = learning_rate
self.max_epochs = max_epochs
self.audio_length = self.sampling_rate * self.audio_duration
if self.use_mfcc:
self.dim =(self.n_mfcc, 1 + int(np.floor(self.audio_length/512)) , 1)
 else:
self.dim =(self.audio_length, 1 )
<filter>
class DataGenerator(Sequence):
def __init__(self, config, data_dir, list_IDs, labels=None,
batch_size=64, preprocessing_fn=lambda x: x):
self.config = config
self.data_dir = data_dir
self.list_IDs = list_IDs
self.labels = labels
self.batch_size = batch_size
self.preprocessing_fn = preprocessing_fn
self.on_epoch_end()
self.dim = self.config.dim
def __len__(self):
return int(np.ceil(len(self.list_IDs)/ self.batch_size))
def __getitem__(self, index):
indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]
list_IDs_temp = [self.list_IDs[k] for k in indexes]
return self.__data_generation(list_IDs_temp)
 def on_epoch_end(self):
self.indexes = np.arange(len(self.list_IDs))
def __data_generation(self, list_IDs_temp):
cur_batch_size = len(list_IDs_temp)
 X = np.empty(( cur_batch_size, *self.dim))
input_length = self.config.audio_length
for i, ID in enumerate(list_IDs_temp):
file_path = self.data_dir + ID
data, _ = librosa.core.load(file_path, sr=self.config.sampling_rate,
res_type='kaiser_fast')
 if len(data)> input_length:
max_offset = len(data)- input_length
offset = np.random.randint(max_offset)
 data = data[offset:(input_length+offset)]
else:
if input_length > len(data):
max_offset = input_length - len(data)
 offset = np.random.randint(max_offset)
 else:
offset = 0
data = np.pad(data,(offset, input_length - len(data)- offset), "constant")
 if self.config.use_mfcc:
data = librosa.feature.mfcc(data, sr=self.config.sampling_rate,
n_mfcc=self.config.n_mfcc)
 data = np.expand_dims(data, axis=-1)
 else:
data = self.preprocessing_fn(data)[:, np.newaxis]
X[i,] = data
if self.labels is not None:
y = np.empty(cur_batch_size, dtype=int)
 for i, ID in enumerate(list_IDs_temp):
y[i] = self.labels[ID]
return X, to_categorical(y, num_classes=self.config.n_classes)
 else:
return X
train_head = train.loc[train.parentesco1 == 1]
test_head = test.loc[test.parentesco1 == 1]<categorify>
def audio_norm(data):
max_data = np.max(data)
 min_data = np.min(data)
 data =(data-min_data)/(max_data-min_data+1e-6)
 return data-0.5
def get_overfit_training(ptrain):
traind = ptrain
ntrain = ptrain[ptrain.Target == 1]
ntrain['age'] += 1
traind = traind.append(ntrain)
 ntrain['age'] += 1
traind = traind.append(ntrain)
 ntrain['age'] += 1
traind = traind.append(ntrain)
 ntrain['age'] -= 4
traind = traind.append(ntrain)
 ntrain['age'] -= 1
traind = traind.append(ntrain)
 ntrain['age'] -= 1
traind = traind.append(ntrain)
 ntrain['age'] -= 1
traind = traind.append(ntrain)
 n2train = ptrain[ptrain.Target == 2]
n2train['age'] += 1
traind = traind.append(n2train)
 n2train['age'] += 1
traind = traind.append(n2train)
 n2train['age'] -=3
traind = traind.append(n2train)
 n3train = ptrain[ptrain.Target == 3]
n3train['age'] += 1
traind = traind.append(n3train)
 n2train['age'] += 1
traind = traind.append(n3train)
 n2train['age'] += 1
traind = traind.append(n3train)
 n2train['age'] -= 4
traind = traind.append(n3train)
 return traind
ptrain_head = get_overfit_training(train_head); ptrain_head.shape<prepare_output>
def get_1d_dummy_model(config):
nclass = config.n_classes
input_length = config.audio_length
inp = Input(shape=(input_length,1))
x = GlobalMaxPool1D()(inp)
 out = Dense(nclass, activation=softmax )(x)
 model = models.Model(inputs=inp, outputs=out)
 opt = optimizers.Adam(config.learning_rate)
 model.compile(optimizer=opt, loss=losses.categorical_crossentropy, metrics=['acc'])
 return model
def get_1d_conv_model(config):
nclass = config.n_classes
input_length = config.audio_length
inp = Input(shape=(input_length,1))
x = Convolution1D(16, 9, activation=relu, padding="valid" )(inp)
 x = Convolution1D(16, 9, activation=relu, padding="valid" )(x)
 x = MaxPool1D(16 )(x)
 x = Dropout(rate=0.1 )(x)
 x = Convolution1D(32, 3, activation=relu, padding="valid" )(x)
 x = Convolution1D(32, 3, activation=relu, padding="valid" )(x)
 x = MaxPool1D(4 )(x)
 x = Dropout(rate=0.1 )(x)
 x = Convolution1D(32, 3, activation=relu, padding="valid" )(x)
 x = Convolution1D(32, 3, activation=relu, padding="valid" )(x)
 x = MaxPool1D(4 )(x)
 x = Dropout(rate=0.1 )(x)
 x = Convolution1D(256, 3, activation=relu, padding="valid" )(x)
 x = Convolution1D(256, 3, activation=relu, padding="valid" )(x)
 x = GlobalMaxPool1D()(x)
 x = Dropout(rate=0.2 )(x)
 x = Dense(64, activation=relu )(x)
 x = Dense(1028, activation=relu )(x)
 out = Dense(nclass, activation=softmax )(x)
 model = models.Model(inputs=inp, outputs=out)
 opt = optimizers.Adam(config.learning_rate)
 model.compile(optimizer=opt, loss=losses.categorical_crossentropy, metrics=['acc'])
 return model
ptest_head = test_head.copy()
ptest_head['Target'] = np.random.randint(1, high=5, size=ptest_head.shape[0] )<feature_engineering>
LABELS = list(train.label.unique())
 label_idx = {label: i for i, label in enumerate(LABELS)}
train.set_index("fname", inplace=True)
 test.set_index("fname", inplace=True)
 train["label_idx"] = train.label.apply(lambda x: label_idx[x])
 if not COMPLETE_RUN:
train = train[:2000]
test = test[:2000]
ptrain_target = ptrain_head['Target']
ptrain_head.drop('Target', axis=1, inplace=True)
 ptrain_head['Target'] = ptrain_target
a =(ptrain_head.columns == ptest_head.columns)
 a[a == False]<prepare_output>
config = Config(sampling_rate=16000, audio_duration=2, n_folds=10, learning_rate=0.001)
 if not COMPLETE_RUN:
config = Config(sampling_rate=100, audio_duration=1, n_folds=2, max_epochs=1 )
ptrain_head.set_index('Id', inplace=True)
 ptest_head.set_index('Id', inplace=True )<concatenate>
pred_list = []
for i in range(10):
pred_list.append(np.load(".. /input/freesound-prediction-file/test_predictions_%d.npy"%i))
prediction = np.ones_like(pred_list[0])
 for pred in pred_list:
prediction = prediction*pred
prediction = prediction**(1./len(pred_list))
top_3 = np.array(LABELS)[np.argsort(-prediction, axis=1)[:, :3]]
predicted_labels = [' '.join(list(x)) for x in top_3]
test = pd.read_csv('.. /input/freesound-audio-tagging/sample_submission.csv')
 test['label'] = predicted_labels
test[['fname', 'label']].to_csv("1d_conv_ensembled_submission.csv", index=False )
alld = ptrain_head.append(ptest_head )<filter>
SAMPLE_RATE = 44100
fname = '.. /input/freesound-audio-tagging/audio_train/' + '00044347.wav'
wav, _ = librosa.core.load(fname, sr=SAMPLE_RATE)
 wav = wav[:2*44100]
alld.loc[set(ptrain_head.index.tolist())].shape == ptrain_head.shape<set_options>
mfcc = librosa.feature.mfcc(wav, sr = SAMPLE_RATE, n_mfcc=40)
 mfcc.shape
pd.options.mode.chained_assignment = None<set_options>
GlobalMaxPool2D, MaxPool2D, concatenate, Activation)
pd.set_option('display.max_columns', 500)
 pd.set_option('display.width', 1000 )<define_variables>
def get_2d_dummy_model(config):
nclass = config.n_classes
inp = Input(shape=(config.dim[0],config.dim[1],1))
x = GlobalMaxPool2D()(inp)
 out = Dense(nclass, activation=softmax )(x)
 model = models.Model(inputs=inp, outputs=out)
 opt = optimizers.Adam(config.learning_rate)
 model.compile(optimizer=opt, loss=losses.categorical_crossentropy, metrics=['acc'])
 return model
def get_2d_conv_model(config):
nclass = config.n_classes
inp = Input(shape=(config.dim[0],config.dim[1],1))
x = Convolution2D(32,(4,10), padding="same" )(inp)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 x = MaxPool2D()(x)
 x = Convolution2D(32,(4,10), padding="same" )(x)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 x = MaxPool2D()(x)
 x = Convolution2D(32,(4,10), padding="same" )(x)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 x = MaxPool2D()(x)
 x = Convolution2D(32,(4,10), padding="same" )(x)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 x = MaxPool2D()(x)
 x = Flatten()(x)
 x = Dense(64 )(x)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 out = Dense(nclass, activation=softmax )(x)
 model = models.Model(inputs=inp, outputs=out)
 opt = optimizers.Adam(config.learning_rate)
 model.compile(optimizer=opt, loss=losses.categorical_crossentropy, metrics=['acc'])
 return model
cats = ['hacdor', 'rooms', 'hacapo', 'v14a', 'refrig', 'r4h1',
'r4h2', 'r4m1', 'r4m2', 'tamhog', 'tamviv', 'escolari',
'hhsize', 'pared', 'piso', 'techo', 'cielorazo', 'abastagua', 'electricity', 'sanitario',
'energcocinar', 'elimbasu', 'epared', 'etecho', 'eviv', 'dis', 'male_or_famale', 'estadocivil',
'hogar_nin', 'hogar_adul', 'hogar_mayor', 'hogar_total', 'instlevel', 'bedrooms', 'tipovivi',
'computer', 'television', 'mobilephone', 'lugar', 'area', 'is_adult']<define_variables>
config = Config(sampling_rate=44100, audio_duration=2, n_folds=10,
learning_rate=0.001, use_mfcc=True, n_mfcc=40)
 if not COMPLETE_RUN:
config = Config(sampling_rate=44100, audio_duration=2, n_folds=2,
max_epochs=1, use_mfcc=True, n_mfcc=40 )
to_drop = ['v18q', 'r4h3', 'r4m3', 'r4t1', 'r4t2', 'r4t3', 'parentesco', 'idhogar', 'SQB', 'agesq', ]<define_variables>
def prepare_data(df, config, data_dir):
X = np.empty(shape=(df.shape[0], config.dim[0], config.dim[1], 1))
input_length = config.audio_length
for i, fname in enumerate(df.index):
print(fname)
 file_path = data_dir + fname
data, _ = librosa.core.load(file_path, sr=config.sampling_rate, res_type="kaiser_fast")
 if len(data)> input_length:
max_offset = len(data)- input_length
offset = np.random.randint(max_offset)
 data = data[offset:(input_length+offset)]
else:
if input_length > len(data):
max_offset = input_length - len(data)
 offset = np.random.randint(max_offset)
 else:
offset = 0
data = np.pad(data,(offset, input_length - len(data)- offset), "constant")
 data = librosa.feature.mfcc(data, sr=config.sampling_rate, n_mfcc=config.n_mfcc)
 data = np.expand_dims(data, axis=-1)
 X[i,] = data
return X
to_merge = ['pared', 'piso', 'techo', 'abastagua',
{'electricity': ['public', 'planpri', 'noelec', 'coopele']},
'sanitario', 'energcocinar', 'elimbasu', 'epared', 'etecho',
'eviv', {'male_or_famale': ['male', 'female']},
'estadocivil', 'instlevel', 'tipovivi', 'lugar', 'area']<data_type_conversions>
pred_list = []
for i in range(10):
pred_list.append(np.load(".. /input/freesound-prediction-data-2d-conv-reduced-lr/test_predictions_%d.npy"%i))
prediction = np.ones_like(pred_list[0])
 for pred in pred_list:
prediction = prediction*pred
prediction = prediction**(1./len(pred_list))
top_3 = np.array(LABELS)[np.argsort(-prediction, axis=1)[:, :3]]
predicted_labels = [' '.join(list(x)) for x in top_3]
test = pd.read_csv('.. /input/freesound-audio-tagging/sample_submission.csv')
 test['label'] = predicted_labels
test[['fname', 'label']].to_csv("2d_conv_ensembled_submission.csv", index=False )
<drop_column><EOS> 
pred_list = []
for i in range(10):
pred_list.append(np.load(".. /input/freesound-prediction-data-2d-conv-reduced-lr/test_predictions_%d.npy"%i))
for i in range(10):
pred_list.append(np.load(".. /input/freesound-prediction-file/test_predictions_%d.npy"%i))
prediction = np.ones_like(pred_list[0])
 for pred in pred_list:
prediction = prediction*pred
prediction = prediction**(1./len(pred_list))
top_3 = np.array(LABELS)[np.argsort(-prediction, axis=1)[:, :3]]
predicted_labels = [' '.join(list(x)) for x in top_3]
test = pd.read_csv('.. /input/freesound-audio-tagging/sample_submission.csv')
 test['label'] = predicted_labels
test[['fname', 'label']].to_csv("1d_2d_ensembled_submission.csv", index=False )