Kaggle competition: Traveling Santa 2018 - Prime Paths
<SOS> metric: TravelingSanta2 Kaggle data source: traveling-santa-2018-prime-paths<split>
t0 = time.time()
def train_model(x_train, y_train, train_transforms):
num_epochs = 120
batch_size = 128
test_batch_size = 256
lr = 1e-3
eta_min = 1e-5
t_max = 10
num_classes = y_train.shape[1]
x_trn, x_val, y_trn, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=SEED)
 train_dataset = FATTrainDataset(x_trn, y_trn, train_transforms)
 valid_dataset = FATTrainDataset(x_val, y_val, train_transforms)
 train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
 valid_loader = DataLoader(valid_dataset, batch_size=test_batch_size, shuffle=False)
 model = Classifier(num_classes=num_classes ).cuda()
criterion = nn.BCEWithLogitsLoss().cuda()
optimizer = Adam(params=model.parameters() , lr=lr, amsgrad=False)
 scheduler = CosineAnnealingLR(optimizer, T_max=t_max, eta_min=eta_min)
 best_epoch = -1
best_lwlrap = 0.
 mb = master_bar(range(num_epochs))
for epoch in mb:
start_time = time.time()
model.train()
avg_loss = 0.
 for x_batch, y_batch in train_loader:
preds = model(x_batch.cuda())
 loss = criterion(preds, y_batch.cuda())
 optimizer.zero_grad()
loss.backward()
optimizer.step()
avg_loss += loss.item() / len(train_loader)
 model.eval()
valid_preds = np.zeros(( len(x_val), num_classes))
avg_val_loss = 0.
 for i,(x_batch, y_batch)in enumerate(valid_loader):
preds = model(x_batch.cuda() ).detach()
loss = criterion(preds, y_batch.cuda())
 preds = torch.sigmoid(preds)
 valid_preds[i * test_batch_size:(i+1)* test_batch_size] = preds.cpu().numpy()
avg_val_loss += loss.item() / len(valid_loader)
 score, weight = calculate_per_class_lwlrap(y_val, valid_preds)
 lwlrap =(score * weight ).sum()
scheduler.step()
if(epoch + 1)% 1 == 0:
elapsed = time.time() - start_time
mb.write(f'Epoch {epoch+1} - avg_train_loss: {avg_loss:.4f} avg_val_loss: {avg_val_loss:.4f} val_lwlrap: {lwlrap:.6f} time: {elapsed:.0f}s')
 if lwlrap > best_lwlrap:
best_epoch = epoch + 1
best_lwlrap = lwlrap
torch.save(model.state_dict() , 'weight_best.pt')
 return {
'best_epoch': best_epoch,
'best_lwlrap': best_lwlrap,
}<train_model>
!conda install -y --channel numba numba
result = train_model(x_train, y_train, transforms_dict['train'] )<predict_on_test>
!pip install hdbscan
test_preds = predict_model(test_df['fname'], x_test, transforms_dict['test'], num_classes, tta=20 )<save_to_csv>
warnings.filterwarnings('ignore')
 seed = 2019
test_df[labels] = test_preds.values
test_df.to_csv('submission.csv', index=False)
 test_df.head()<set_options>
print(numba.__version__ )
py.init_notebook_mode(connected=True)
 %matplotlib inline
t1 = time.time()<load_from_csv>
cities = pd.read_csv('.. /input/cities.csv')
 cities["X"] = cities["X"].astype(np.float64)
 cities["Y"] = cities["Y"].astype(np.float64)
 is_not_prime = np.array([0 if isprime(i)else 1 for i in cities.index], dtype=np.int32)
 cities["is_not_prime"] = is_not_prime
cities.head(10 )
train_audio_path = '.. /input/freesound-audio-tagging-2019/train_curated/'
train_files = os.listdir(train_audio_path)
 train_annot = pd.read_csv('.. /input/freesound-audio-tagging-2019/train_curated.csv')
 test_audio_path = '.. /input/freesound-audio-tagging-2019/test/'
test_files = np.sort(os.listdir(test_audio_path))
print(test_files[:5])
 USE_WEIGHTS = False
len(train_files), len(test_files)
<count_unique_values>
XY = np.stack(( cities.X, cities.Y), axis=1)
 @numba.jit('f8(i4, i8[:])', nopython=True, parallel=False)
 def distance_chunk(offset, chunk):
pure_distance = 0.0
for path_index in numba.prange(chunk.shape[0] - 1):
id_from, id_to = chunk[path_index], chunk[path_index+1]
xy_from, xy_to = XY[id_from], XY[id_to]
dx, dy = xy_from[0] - xy_to[0], xy_from[1] - xy_to[1]
distance = sqrt(dx * dx + dy * dy)
 pure_distance += distance
return pure_distance
@numba.jit('f8(i4, i8[:])', nopython=True, parallel=False)
 def score_chunk(offset, chunk):
pure_distance, penalty = 0.0, 0.0
penalty_modulo = 9 - offset % 10
for path_index in numba.prange(chunk.shape[0] - 1):
id_from, id_to = chunk[path_index], chunk[path_index+1]
xy_from, xy_to = XY[id_from], XY[id_to]
dx, dy = xy_from[0] - xy_to[0], xy_from[1] - xy_to[1]
distance = sqrt(dx * dx + dy * dy)
 pure_distance += distance
if path_index % 10 == penalty_modulo and is_not_prime[id_from]:
penalty += distance
return pure_distance + 0.1 * penalty
@numba.jit('f8(i8[:])', nopython=True, parallel=False)
 def score_path(path):
return score_chunk(0, path)
 @numba.jit('f8(i8[:])', nopython=True, parallel=False)
 def distance_path(path):
return distance_chunk(0, path )
label_dict, classes, all_labels_set, first_labels_set = create_unique_labels(train_annot.labels)
 files = train_annot.fname
print(len(files), len(train_files))<categorify>
def write_lkh_files(lkh_df, filename_par, filename_tsp, filename_tour, filename_initial_tour=None, real=False, bw=False):
l = len(lkh_df)
 with open(filename_par, "w")as f:
f.write("PROBLEM_FILE = %s
" % filename_tsp)
 f.write("MOVE_TYPE = 8
")
 f.write("PATCHING_C = 3
")
 f.write("PATCHING_A = 2
")
 f.write("RUNS = 2
")
 f.write("OUTPUT_TOUR_FILE = %s
" % filename_tour)
 f.write("SEED = %d
" % seed)
 f.write("CANDIDATE_SET_TYPE = POPMUSIC
")
 f.write("POPMUSIC_SOLUTIONS = 12
")
 f.write("POPMUSIC_SAMPLE_SIZE = 14
")
 f.write("POPMUSIC_TRIALS = 1000
")
 f.write("POPMUSIC_MAX_NEIGHBORS = 14
")
 f.write("INITIAL_PERIOD = 2500
")
 f.write("MAX_TRIALS = 1000
")
 f.write("INITIAL_TOUR_ALGORITHM = QUICK-BORUVKA
")
 if filename_initial_tour is not None:
f.write("INITIAL_TOUR_FILE = %s
" % filename_initial_tour)
 f.write("TRACE_LEVEL = 1
")
 if bw == True:
f.write("BWTSP = %d %d %d
" %(len(lkh_df[lkh_df["is_not_prime"] == 0]), 9, 9999999999))
with open(filename_tsp, "w")as f:
f.write("NAME : SOLVER
")
 f.write("COMMENT : %d points
" % l)
 f.write("TYPE : TSP
")
 f.write("DIMENSION : %d
" % l)
 f.write("EDGE_WEIGHT_TYPE : EUC_2D
")
 f.write("NODE_COORD_TYPE : TWOD_COORDS
")
 f.write("NODE_COORD_SECTION
")
 for idx, row in lkh_df.iterrows() :
if real:
f.write("%d %.12f %.12f
" %(row["CityId"] + 1,(row["X"]),(row["Y"])))
 else:
f.write("%d %.9f %.9f
" %(row["CityId"] + 1,(row["X"])*1000.0,(row["Y"]*1000.0)))
 def read_lkh_tour(filename, mapping = None):
with open(filename, 'r')as f:
tour = []
i = 0
for line in f:
i = i + 1
if i > 6:
tour.append(line.rstrip('
'))
tour = [int(t)for t in tour if t != 'EOF']
tour = tour[:-1]
tour_map = [mapping[int(t)] for t in tour]
return tour_map
def lkh_ids_mapping(lkh_df):
mapping = {}
for idx, row in lkh_df.iterrows() :
mapping[int(row["CityId"] + 1)] = idx
return mapping
def read_cnc_tour(filename):
tour = open(filename ).read().split() [1:]
tour = list(map(int, tour))
if tour[-1] == 0: tour.pop()
return tour
def write_lkh_tour(path, filename_tour, comment="None"):
with open(filename_tour, "w")as f:
f.write("NAME : %s
" % filename_tour)
 f.write("COMMENT : %s
" % comment)
 f.write("COMMENT :
")
 f.write("TYPE : TOUR
")
 f.write("DIMENSION : %d
" % len(path))
f.write("TOUR_SECTION
")
 for p in path:
f.write("%d
" % p)
 f.write("-1
")
 f.write("EOF
" )
binarize = MultiLabelBinarizer(classes=classes)
 encode = LabelEncoder()
Y_split = encode.fit_transform(first_labels_set)
 Y = binarize.fit_transform(all_labels_set )<define_variables>
%%bash -e
wget http://akira.ruc.dk/~keld/research/LKH-3/LKH-3.0.5.tgz 
(tar xvfz LKH-3.0.5.tgz)
(cd LKH-3.0.5 && make CC=gcc CFLAGS='-IINCLUDE -Ofast -march=native -mtune=native -fPIC')
(cd LKH-3.0.5 && cp LKH.. /)
 rm -rf LKH-3.0.5 LKH-3.0.5.tgz
X_raw = []
for f in tqdm_notebook(files):
sample_rate, sample_ = wavfile.read(str(train_audio_path)+ f)
 X_raw.append(sample_ )<normalization>
write_lkh_files(cities, "cities.lkh.par", "cities.lkh.tsp", "cities.lkh.tour",
filename_initial_tour="cities.cnc.lkh.tour", real=False, bw=False )
def pad_audio(samples):
if len(samples)>= L: return samples
else: return np.pad(samples, pad_width=(L - len(samples), 0), mode='constant', constant_values=(0, 0))
def chop_audio(samples):
beg = np.random.randint(0, len(samples)- L)
 return samples[beg: beg + L]
def log_specgram(audio,
sample_rate,
window_size=20,
step_size=10, eps=1e-10):
nperseg = int(round(window_size * sample_rate / 1e3))
noverlap = int(round(step_size * sample_rate / 1e3))
freqs, times, spec = signal.spectrogram(audio,
fs=sample_rate,
window='hann',
nperseg=nperseg,
noverlap=noverlap,
detrend=False)
 return freqs, times, np.log(spec.astype(np.float32)+ eps )<define_variables>
class DataGenerator(keras.utils.Sequence):
'Generates data for Keras'
def __init__(self, list_IDs, labels, batch_size=32, dim=(256,256,1), n_channels=1,
n_classes=80, shuffle=True):
'Initialization'
self.dim = dim
self.batch_size = batch_size
self.labels = labels
self.list_IDs = list_IDs
self.n_channels = n_channels
self.n_classes = n_classes
self.shuffle = shuffle
self.on_epoch_end()
def __len__(self):
'Denotes the number of batches per epoch'
return int(np.ceil(len(self.list_IDs)/ self.batch_size))
def __getitem__(self, index):
'Generate one batch of data'
max_index = min(( index+1)*self.batch_size, len(self.list_IDs))
indexes = self.indexes[index*self.batch_size:max_index]
list_IDs_temp = [self.list_IDs[k] for k in indexes]
X, y = self.__data_generation(list_IDs_temp)
 return X, y
def on_epoch_end(self):
'Updates indexes after each epoch'
self.indexes = np.arange(len(self.list_IDs))
if self.shuffle == True:
np.random.shuffle(self.indexes)
 def __data_generation(self, list_IDs_temp):
'Generates data containing batch_size samples'
X = []
y = []
t1 = time.time()
for i, ID in enumerate(list_IDs_temp):
xx = X_raw[ID].copy()
xx = pad_audio(xx)
 if len(xx)> L:
xx = chop_audio(xx)
 _, _, specgram = log_specgram(xx, sample_rate=SAMPLE_RATE, window_size=10, step_size=5)
 X.append(specgram)
 y.append(self.labels[ID, :])
 t2 = time.time()
y = np.array(y, dtype='float32')
 X = np.expand_dims(np.array(X), -1)
 return X, y
class TestDataGenerator(keras.utils.Sequence):
'Generates data for Keras'
def __init__(self, test_files, test_base_path, batch_size=32, dim=(256,256,1), n_channels=1,
n_classes=80):
'Initialization'
self.dim = dim
self.batch_size = batch_size
self.test_base_path = test_base_path
self.test_files = test_files
self.n_channels = n_channels
self.n_classes = n_classes
self.on_epoch_end()
def __len__(self):
'Denotes the number of batches per epoch'
return int(np.ceil(len(self.test_files)/ self.batch_size))
def __getitem__(self, index):
'Generate one batch of data'
max_index = min(( index+1)*self.batch_size, len(self.test_files))
indexes = self.indexes[index*self.batch_size:max_index]
list_IDs_temp = [self.test_files[k] for k in indexes]
X = self.__data_generation(list_IDs_temp)
 return X
def on_epoch_end(self):
'Updates indexes after each epoch'
self.indexes = np.arange(len(self.test_files))
def __data_generation(self, list_IDs_temp):
'Generates data containing batch_size samples'
X = []
for i, ID in enumerate(list_IDs_temp):
sample_rate, xx = wavfile.read(str(self.test_base_path)+ ID)
 xx = pad_audio(xx)
 if len(xx)> L:
xx = chop_audio(xx)
 _, _, specgram = log_specgram(xx, sample_rate=SAMPLE_RATE, window_size=10, step_size=5)
 X.append(specgram)
 X = np.expand_dims(np.array(X), -1)
 return X<choose_model_class>
%%bash -e
if ! [[ -f./linkern ]]; then
wget http://www.math.uwaterloo.ca/tsp/concorde/downloads/codes/src/co031219.tgz
echo 'c3650a59c8d57e0a00e81c1288b994a99c5aa03e5d96a314834c2d8f9505c724 co031219.tgz' | sha256sum -c
tar xf co031219.tgz 
(cd concorde && CFLAGS='-Ofast -march=native -mtune=native -fPIC'./configure)
(cd concorde/LINKERN && make -j && cp linkern.. /.. /)
 rm -rf concorde co031219.tgz
fi
GlobalMaxPool2D, MaxPool2D, concatenate, Activation, Input, Dense, Dropout)
 def get_2d_conv_model(input_shape=(221, 298, 1), n_classes=80, learning_rate=0.001):
nclass = n_classes
inp = Input(shape=(input_shape[0],input_shape[1],1))
x = Convolution2D(96,(4,10), padding="same" )(inp)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 x = MaxPool2D()(x)
 x = Convolution2D(64,(4,10), padding="same" )(x)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 x = MaxPool2D()(x)
 x = Convolution2D(48,(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 = Dropout(0.5 )(x)
 x = Dense(80 )(x)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 x = Dense(80 )(x)
 x = BatchNormalization()(x)
 x = Activation("relu" )(x)
 out = Dense(nclass, activation='softmax' )(x)
 model = Model(inputs=inp, outputs=out)
 opt = Adam(learning_rate)
 model.compile(optimizer=opt, loss=binary_crossentropy, metrics=['categorical_accuracy'])
 return model<define_variables>
%%bash
time./linkern -K 1 -s 2019 -S cities.cnc.tour -R 999999999 -t 1800 cities.lkh.tsp >cities.cnc.log
modelname = 'custom-v1-'
test_gen = TestDataGenerator(test_files, test_audio_path, batch_size=128 )<split>
cnc_tour = np.array(read_cnc_tour("cities.cnc.tour"))
cnc_score = score_path(cnc_tour)
 print(f'Concorde distance is {distance_path(cnc_tour):.2f} and score is {score_path(cnc_tour):.2f} in {1800/60 :.1f} minutes' )
oof_y = np.zeros_like(Y, dtype='float32')
 test_Y = np.zeros(( len(test_files), 80), dtype='float32')
 kfold = StratifiedKFold(10, True, 6996)
 ifold = 0
for train_index, valid_index in kfold.split(X_raw, Y_split):
if ifold<=1:
print("--------------------------------------------")
 checkpoint = ModelCheckpoint(modelname + str(ifold)+ '.hdf5', monitor='val_categorical_accuracy', verbose=1,
save_best_only=True, save_weights_only=True, mode='auto', period=1)
 early = EarlyStopping(monitor='val_categorical_accuracy', min_delta=0.001, patience=12, verbose=1, mode='auto', restore_best_weights=True)
 reduce_lr = ReduceLROnPlateau(monitor='val_categorical_accuracy', factor=0.5, patience=6, verbose=1)
 model = get_2d_conv_model()
train_gen = DataGenerator(train_index, Y, batch_size=32, n_classes=80, shuffle=True)
 valid_gen = DataGenerator(valid_index, Y, batch_size=128, n_classes=80, shuffle=False)
 model.fit_generator(train_gen, epochs=60, verbose=0, callbacks=[checkpoint, early, reduce_lr], validation_data=valid_gen)
 res = model.predict_generator(valid_gen, verbose=0)
 res_Y = model.predict_generator(test_gen, verbose=0)
 for bag in range(9):
res_Y += model.predict_generator(test_gen, verbose=0)
 oof_y[valid_index, ] = res
test_Y = test_Y + res_Y / 10.
 ifold = ifold + 1
test_Y = test_Y / 5 
<define_variables>
write_lkh_tour([p+1 for p in cnc_tour], "cities.cnc.lkh.tour" )
def _one_sample_positive_class_precisions(scores, truth):

 num_classes = scores.shape[0]
pos_class_indices = np.flatnonzero(truth > 0)
 if not len(pos_class_indices):
return pos_class_indices, np.zeros(0)
 retrieved_classes = np.argsort(scores)[::-1]
class_rankings = np.zeros(num_classes, dtype=np.int)
 class_rankings[retrieved_classes] = range(num_classes)
 retrieved_class_true = np.zeros(num_classes, dtype=np.bool)
 retrieved_class_true[class_rankings[pos_class_indices]] = True
retrieved_cumulative_hits = np.cumsum(retrieved_class_true)
 precision_at_hits =(
 retrieved_cumulative_hits[class_rankings[pos_class_indices]] / 
(1 + class_rankings[pos_class_indices].astype(np.float)))
 return pos_class_indices, precision_at_hits
def calculate_per_class_lwlrap(truth, scores):

 assert truth.shape == scores.shape
num_samples, num_classes = scores.shape
precisions_for_samples_by_classes = np.zeros(( num_samples, num_classes))
for sample_num in range(num_samples):
pos_class_indices, precision_at_hits =(
 _one_sample_positive_class_precisions(scores[sample_num, :],
truth[sample_num, :]))
precisions_for_samples_by_classes[sample_num, pos_class_indices] =(
 precision_at_hits)
 labels_per_class = np.sum(truth > 0, axis=0)
 weight_per_class = labels_per_class / float(np.sum(labels_per_class))
per_class_lwlrap =(np.sum(precisions_for_samples_by_classes, axis=0)/
np.maximum(1, labels_per_class))
return per_class_lwlrap, weight_per_class
def calculate_overall_lwlrap_sklearn(truth, scores):

 sample_weight = np.sum(truth > 0, axis=1)
 nonzero_weight_sample_indices = np.flatnonzero(sample_weight > 0)
 overall_lwlrap = sklearn.metrics.label_ranking_average_precision_score(
 truth[nonzero_weight_sample_indices, :] > 0,
scores[nonzero_weight_sample_indices, :],
sample_weight=sample_weight[nonzero_weight_sample_indices])
 return overall_lwlrap
class lwlrap_accumulator(object):

 def __init__(self):
self.num_classes = 0
self.total_num_samples = 0
def accumulate_samples(self, batch_truth, batch_scores):

 assert batch_scores.shape == batch_truth.shape
num_samples, num_classes = batch_truth.shape
if not self.num_classes:
self.num_classes = num_classes
self._per_class_cumulative_precision = np.zeros(self.num_classes)
 self._per_class_cumulative_count = np.zeros(self.num_classes,
dtype=np.int)
 assert num_classes == self.num_classes
for truth, scores in zip(batch_truth, batch_scores):
pos_class_indices, precision_at_hits =(
 _one_sample_positive_class_precisions(scores, truth))
self._per_class_cumulative_precision[pos_class_indices] +=(
 precision_at_hits)
 self._per_class_cumulative_count[pos_class_indices] += 1
self.total_num_samples += num_samples
def per_class_lwlrap(self):

 return(self._per_class_cumulative_precision /
np.maximum(1, self._per_class_cumulative_count))
def per_class_weight(self):

 return(self._per_class_cumulative_count /
float(np.sum(self._per_class_cumulative_count)))
 def overall_lwlrap(self):

 return np.sum(self.per_class_lwlrap() * self.per_class_weight())
<compute_train_metric>
lkh_tour = np.array(read_lkh_tour("cities.lkh.tour", mapping=lkh_ids_mapping(cities)) )
truth = Y
scores = oof_y
print("lwlrap from sklearn.metrics =", calculate_overall_lwlrap_sklearn(truth, scores))<save_to_csv>
path = np.concatenate([lkh_tour.copy() , np.array([0])])
 print(path[0:10])
 print(path[-10:])
 print(f'LKH distance is {distance_path(path):.2f} and score is {score_path(path):.2f} in {21300/60 :.1f} minutes' )
sort_idx = np.argsort(classes ).astype(int)
 sample_sub = pd.read_csv('.. /input/freesound-audio-tagging-2019/sample_submission.csv')
 test_Y_sort = test_Y[:, sort_idx]
sample_sub.iloc[:, 1:] = test_Y_sort
sample_sub.to_csv('submission.csv', index=False)
 t2 = time.time()
print('Total time: ',(t2-t1))<import_modules>
t1 = time.time()
import gc
import os
import pickle
import random
import time
from collections import Counter, defaultdict
from functools import partial
from pathlib import Path
from psutil import cpu_count
import librosa
import numpy as np
import pandas as pd
from PIL import Image
from sklearn.model_selection import train_test_split
import torch
import torch.nn as nn
import torch.nn.functional as F
from fastprogress import master_bar, progress_bar
from torch.optim import Adam
from torch.optim.lr_scheduler import CosineAnnealingLR
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import transforms<set_options>
@numba.jit('f8(i8, i8, i8)', nopython=True, parallel=False)
 def cities_distance(offset, id_from, id_to):
xy_from, xy_to = XY[id_from], XY[id_to]
dx, dy = xy_from[0] - xy_to[0], xy_from[1] - xy_to[1]
distance = sqrt(dx * dx + dy * dy)
 if offset % 10 == 9 and is_not_prime[id_from]:
return 1.1 * distance
return distance
@numba.jit
def chunk_scores(chunk):
scores = np.zeros(10)
 pure_distance = 0
for i in numba.prange(chunk.shape[0] - 1):
id_from, id_to = chunk[i], chunk[i+1]
xy_from, xy_to = XY[id_from], XY[id_to]
dx, dy = xy_from[0] - xy_to[0], xy_from[1] - xy_to[1]
distance = sqrt(dx * dx + dy * dy)
 pure_distance += distance
if is_not_prime[id_from]:
scores[9-i%10] += distance
scores *= 0.1
scores += pure_distance
return scores
@numba.jit('f8(i8[:])', nopython=True, parallel=False)
 def sum_distance(ids):
res = 0
for i in numba.prange(len(ids)) :
for j in numba.prange(i + 1, len(ids)) :
res += cities_distance(0, ids[i], ids[j])
 return res
torch.cuda.is_available()<set_options>
def not_trivial_permutations(iterable):
perms = permutations(iterable)
 next(perms)
 yield from perms
def _not_trivial_indexes_permutations(length):
return np.array([list(p)for p in not_trivial_permutations(range(length)) ], dtype=np.int64)
 MAX_PERMS=11
PERMS_01 = _not_trivial_indexes_permutations(1)
 PERMS_02 = _not_trivial_indexes_permutations(2)
 PERMS_03 = _not_trivial_indexes_permutations(3)
 PERMS_04 = _not_trivial_indexes_permutations(4)
 PERMS_05 = _not_trivial_indexes_permutations(5)
 PERMS_06 = _not_trivial_indexes_permutations(6)
 PERMS_07 = _not_trivial_indexes_permutations(7)
 PERMS_08 = _not_trivial_indexes_permutations(8)
 PERMS_09 = _not_trivial_indexes_permutations(9)
 PERMS_10 = _not_trivial_indexes_permutations(10)
 PERMS_11 = _not_trivial_indexes_permutations(11)
 @numba.jit(nopython=True, parallel=False)
 def not_trivial_indexes_permutations(length):
if length == 2:
return PERMS_02
elif length == 3:
return PERMS_03
elif length == 4:
return PERMS_04
elif length == 5:
return PERMS_05
elif length == 6:
return PERMS_06
elif length == 7:
return PERMS_07
elif length == 8:
return PERMS_08
elif length == 9:
return PERMS_09
elif length == 10:
return PERMS_10
elif length == 11:
return PERMS_11
def seed_everything(seed):
random.seed(seed)
 os.environ['PYTHONHASHSEED'] = str(seed)
 np.random.seed(seed)
 torch.manual_seed(seed)
 torch.cuda.manual_seed(seed)
 torch.backends.cudnn.deterministic = True
SEED = 2019
seed_everything(SEED )<feature_engineering>
@numba.jit
def chunk_scores2(chunk):
scores = np.zeros(10)
 pure_distance = 0
for i in numba.prange(chunk.shape[0] - 1):
id_from, id_to = chunk[i], chunk[i+1]
xy_from, xy_to = XY[id_from], XY[id_to]
dx, dy = xy_from[0] - xy_to[0], xy_from[1] - xy_to[1]
distance = sqrt(dx * dx + dy * dy)
 pure_distance += distance
if is_not_prime[id_from]:
scores[9-i%10] += distance
scores *= 0.1
scores += pure_distance
return scores
@numba.jit(nopython=True, parallel=False)
 def range_length(length):
return [p for p in range(length)]
N_JOBS = cpu_count()
os.environ['MKL_NUM_THREADS'] = str(N_JOBS)
 os.environ['OMP_NUM_THREADS'] = str(N_JOBS)
 DataLoader = partial(DataLoader, num_workers=N_JOBS )<define_variables>
kdt = KDTree(XY)
 cs = [2, 3, 4]
cs_nearest = [17, 10, 8]
cs_radius = [12, 10, 6]
tuples = []
for c, n, r in zip(cs, cs_nearest, cs_radius):
print(f'
Generating tuples for N={c} with nearest={n} and radius={r}...')
 Nuplets = set()
for city_id in tqdm(cities.index, mininterval=2.0):
dists, neibs = kdt.query([XY[city_id]], k=n)
 for Nuplet in combinations(neibs[0], c):
if all(Nuplet):
Nuplets.add(tuple(sorted(Nuplet)))
 if r > 0:
neibs = kdt.query_radius([XY[city_id]], r=r, count_only=False, return_distance=False)
 for Nuplet in combinations(neibs[0], c):
if all(Nuplet):
Nuplets.add(tuple(sorted(Nuplet)))
 tuples.append(Nuplets)
 print(f'{len(Nuplets)} cities for N={c} are selected.')
 for t,i in zip(tuples, range(len(tuples))):
t = np.array(list(t))
distances = np.array(list(map(sum_distance, tqdm(t))))
order = distances.argsort()
tuples[i] = t[order]
def _one_sample_positive_class_precisions(scores, truth):

 num_classes = scores.shape[0]
pos_class_indices = np.flatnonzero(truth > 0)
 if not len(pos_class_indices):
return pos_class_indices, np.zeros(0)
 retrieved_classes = np.argsort(scores)[::-1]
class_rankings = np.zeros(num_classes, dtype=np.int)
 class_rankings[retrieved_classes] = range(num_classes)
 retrieved_class_true = np.zeros(num_classes, dtype=np.bool)
 retrieved_class_true[class_rankings[pos_class_indices]] = True
retrieved_cumulative_hits = np.cumsum(retrieved_class_true)
 precision_at_hits =(
 retrieved_cumulative_hits[class_rankings[pos_class_indices]] / 
(1 + class_rankings[pos_class_indices].astype(np.float)))
 return pos_class_indices, precision_at_hits
def calculate_per_class_lwlrap(truth, scores):

 assert truth.shape == scores.shape
num_samples, num_classes = scores.shape
precisions_for_samples_by_classes = np.zeros(( num_samples, num_classes))
for sample_num in range(num_samples):
pos_class_indices, precision_at_hits =(
 _one_sample_positive_class_precisions(scores[sample_num, :],
truth[sample_num, :]))
precisions_for_samples_by_classes[sample_num, pos_class_indices] =(
 precision_at_hits)
 labels_per_class = np.sum(truth > 0, axis=0)
 weight_per_class = labels_per_class / float(np.sum(labels_per_class))
per_class_lwlrap =(np.sum(precisions_for_samples_by_classes, axis=0)/
np.maximum(1, labels_per_class))
return per_class_lwlrap, weight_per_class<define_variables>
@numba.jit(numba.int64[:](numba.int64[:], numba.int64[:,:], numba.int64, numba.int64), nopython=True, parallel=False)
 def optN(path, tmptuples, max_chunk_len, full_reverse_rank):
path_index = np.argsort(path[:-1])
 for iids in numba.prange(len(tmptuples)) :
ids = tmptuples[iids]
s = sorted(path_index[ids])
 head, tail = path[s[0]-1], path[s[-1]+1]
if len(s)== 2:
chunks = [path[s[0]:s[0]+1],
path[s[0]+1:s[1]],
path[s[1]:s[1]+1]]
elif len(s)== 3:
chunks = [path[s[0]:s[0]+1],
path[s[0]+1:s[1]],
path[s[1]:s[1]+1],
path[s[1]+1:s[2]],
path[s[2]:s[2]+1]]
elif len(s)== 4:
chunks = [path[s[0]:s[0]+1],
path[s[0]+1:s[1]],
path[s[1]:s[1]+1],
path[s[1]+1:s[2]],
path[s[2]:s[2]+1],
path[s[2]+1:s[3]],
path[s[3]:s[3]+1]]
elif len(s)== 5:
chunks = [path[s[0]:s[0]+1],
path[s[0]+1:s[1]],
path[s[1]:s[1]+1],
path[s[1]+1:s[2]],
path[s[2]:s[2]+1],
path[s[2]+1:s[3]],
path[s[3]:s[3]+1],
path[s[3]+1:s[4]],
path[s[4]:s[4]+1]]
chunks = [chunk for chunk in chunks if len(chunk)]
if len(chunks)> max_chunk_len:
continue
scores = [chunk_scores2(chunk)for chunk in chunks]
lindexes_permutation = range_length(len(chunks))
lscore = 0.0
offset = s[0]-1
last_city_id = head
for iindex in numba.prange(len(lindexes_permutation)) :
index = lindexes_permutation[iindex]
chunk = chunks[index]
chunk_scores_ = scores[index]
lscore += cities_distance(offset % 10, last_city_id, chunk[0])
 lscore += chunk_scores_[(offset + 1)% 10]
last_city_id = chunk[-1]
offset += len(chunk)
 default_score = lscore + cities_distance(offset % 10, last_city_id, tail)
 best_score = default_score
nti = not_trivial_indexes_permutations(len(chunks))
for iindexes_permutation in numba.prange(len(nti)) :
indexes_permutation = nti[iindexes_permutation]
lscore = 0.0
offset = s[0]-1
last_city_id = head
for iindex in numba.prange(len(indexes_permutation)) :
index = indexes_permutation[iindex]
chunk = chunks[index]
chunk_scores_ = scores[index]
lscore += cities_distance(offset % 10, last_city_id, chunk[0])
 lscore += chunk_scores_[(offset + 1)% 10]
last_city_id = chunk[-1]
offset += len(chunk)
 score = lscore + cities_distance(offset % 10, last_city_id, tail)
 if score < best_score:
permutation = [chunks[i] for i in indexes_permutation]
tl = 0
for t in range(len(permutation)) :
tl = tl + len(permutation[t])
 z = np.zeros(tl, dtype=np.int64)
 tl = 0
for t in range(len(permutation)) :
z[tl:tl+len(permutation[t])] = permutation[t]
tl = tl + len(permutation[t])
 best_chunk = np.zeros(len(z)+ 2, dtype=np.int64)
 best_chunk[0] = head
best_chunk[1:-1] = z[:]
best_chunk[-1] = tail
best_score = score
if best_score < default_score:
path[s[0]-1:s[-1]+2] = best_chunk
path_index = np.argsort(path[:-1])
 print('New total score is ', score_path(path), ', Permutating path at indexes ', s, 'Progress: ', int(iids*100.0/len(tmptuples)))
 return path.copy()
dataset_dir = Path('.. /input/freesound-audio-tagging-2019')
 preprocessed_dir = Path('.. /input/fat2019_prep_mels1' )<define_variables>
def check_reverse(p):
sr = score_path(p[::-1])
 s = score_path(p)
 if sr < s:
print("Reverse better than initial: %.1f vs %.1f" %(sr, s))
return p[::-1]
else:
print("Reverse not better than initial: %.1f vs %.1f" %(sr, s))
return p
csvs = {
'train_curated': dataset_dir / 'train_curated.csv',
'train_noisy': preprocessed_dir / 'trn_noisy_best50s.csv',
'sample_submission': dataset_dir / 'sample_submission.csv',
}
dataset = {
'train_curated': dataset_dir / 'train_curated',
'train_noisy': dataset_dir / 'train_noisy',
'test': dataset_dir / 'test',
}
mels = {
'train_curated': preprocessed_dir / 'mels_train_curated.pkl',
'train_noisy': preprocessed_dir / 'mels_trn_noisy_best50s.pkl',
'test': preprocessed_dir / 'mels_test.pkl',
}<load_from_csv>
initial_path = check_reverse(path.copy() )
train_curated = pd.read_csv(csvs['train_curated'])
 train_noisy = pd.read_csv(csvs['train_noisy'])
 train_df = pd.concat([train_curated, train_noisy], sort=True, ignore_index=True)
 train_df.head()<load_from_csv>
new_path = optN(initial_path, tuples[0], 11, 0 )
test_df = pd.read_csv(csvs['sample_submission'])
 test_df.head()<data_type_conversions>
print(f'Total score after stage 1 is {score_path(new_path):.2f} in {(time.time() -t1)/60.0:.1f} min' )
labels = test_df.columns[1:].tolist()
labels<define_variables>
t2 = time.time()
new_path1 = optN(new_path.copy() , tuples[1], 11, 0 )
num_classes = len(labels)
 num_classes<prepare_x_and_y>
print(f'Total score after stage 2 is {score_path(new_path1):.2f} in {(time.time() -t2)/60.0:.1f} min' )
y_train = np.zeros(( len(train_df), num_classes)).astype(int)
 for i, row in enumerate(train_df['labels'].str.split(',')) :
for label in row:
idx = labels.index(label)
 y_train[i, idx] = 1
y_train.shape<load_pretrained>
t3 = time.time()
new_path2 = optN(new_path1.copy() , tuples[2], 11, 0 )
with open(mels['train_curated'], 'rb')as curated, open(mels['train_noisy'], 'rb')as noisy:
x_train = pickle.load(curated)
 x_train.extend(pickle.load(noisy))
with open(mels['test'], 'rb')as test:
x_test = pickle.load(test)
 len(x_train), len(x_test )<categorify>
print(f'Total score after stage 3 is {score_path(new_path2):.2f} in {(time.time() -t3)/60.0:.1f} min' )
class FATTestDataset(Dataset):
def __init__(self, fnames, mels, transforms, tta=5):
super().__init__()
self.fnames = fnames
self.mels = mels
self.transforms = transforms
self.tta = tta
def __len__(self):
return len(self.fnames)* self.tta
def __getitem__(self, idx):
new_idx = idx % len(self.fnames)
 image = Image.fromarray(self.mels[new_idx], mode='RGB')
 time_dim, base_dim = image.size
crop = random.randint(0, time_dim - base_dim)
 image = image.crop([crop, 0, crop + base_dim, base_dim])
 image = self.transforms(image ).div_(255)
 fname = self.fnames[new_idx]
return image, fname<categorify>
print(f'Total local optimizations time is {(time.time() -t1)/60.0:.1f} min' )
transforms_dict = {
'train': transforms.Compose([
transforms.RandomHorizontalFlip(0.5),
transforms.ToTensor() ,
]),
'test': transforms.Compose([
transforms.RandomHorizontalFlip(0.5),
transforms.ToTensor() ,
]),
}<define_search_model>
print(f'Final score is {score_path(new_path2):.2f}' )
class ConvBlock(nn.Module):
def __init__(self, in_channels, out_channels):
super().__init__()
self.conv1 = nn.Sequential(
 nn.Conv2d(in_channels, out_channels, 3, 1, 1),
nn.BatchNorm2d(out_channels),
nn.ReLU() , 
)
 self.conv2 = nn.Sequential(
 nn.Conv2d(out_channels, out_channels, 3, 1, 1),
nn.BatchNorm2d(out_channels),
nn.ReLU() , 
)
 self._init_weights()
def _init_weights(self):
for m in self.modules() :
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight)
 if m.bias is not None:
nn.init.zeros_(m.bias)
 elif isinstance(m, nn.BatchNorm2d):
nn.init.constant_(m.weight, 1)
 nn.init.zeros_(m.bias)
 def forward(self, x):
x = self.conv1(x)
 x = self.conv2(x)
 x = F.avg_pool2d(x, 2)
 return x<choose_model_class>
pd.DataFrame({'Path': new_path2} ).to_csv('submission.csv', index=False )
class Classifier(nn.Module):
def __init__(self, num_classes):
super().__init__()
self.conv = nn.Sequential(
 ConvBlock(in_channels=3, out_channels=64),
ConvBlock(in_channels=64, out_channels=128),
ConvBlock(in_channels=128, out_channels=256),
ConvBlock(in_channels=256, out_channels=512), 
)
 self.fc = nn.Sequential(
 nn.Dropout(0.2),
nn.Linear(512, 128),
nn.PReLU() ,
nn.BatchNorm1d(128),
nn.Dropout(0.1),
nn.Linear(128, num_classes), 
)
 def forward(self, x):
x = self.conv(x)
 x = torch.mean(x, dim=3)
 x, _ = torch.max(x, dim=2)
 x = self.fc(x)
 return x<choose_model_class>
print(f'Total kernel time is {(time.time() -t0)/60.0:.1f} min' )
<split><EOS>