Kaggle competition: Lyft Motion Prediction for Autonomous Vehicles
<SOS> metric: PostProcessorKernel Kaggle data source: lyft-motion-prediction-autonomous-vehicles<define_variables>
pd.options.display.max_columns=305
class sample_gen(object):
def __init__(self, file_class_mapping, other_class = "new_whale"):
self.file_class_mapping= file_class_mapping
self.class_to_list_files = defaultdict(list)
 self.list_other_class = []
self.list_all_files = list(file_class_mapping.keys())
 self.range_all_files = list(range(len(self.list_all_files)))
 for file, class_ in file_class_mapping.items() :
if class_ == other_class:
self.list_other_class.append(file)
 else:
self.class_to_list_files[class_].append(file)
 self.list_classes = list(set(self.file_class_mapping.values()))
self.range_list_classes= range(len(self.list_classes))
self.class_weight = np.array([len(self.class_to_list_files[class_])for class_ in self.list_classes])
 self.class_weight = self.class_weight/np.sum(self.class_weight)
 def get_sample(self):
class_idx = np.random.choice(self.range_list_classes, 1, p=self.class_weight)[0]
examples_class_idx = np.random.choice(range(len(self.class_to_list_files[self.list_classes[class_idx]])) , 2)
 positive_example_1, positive_example_2 = \
self.class_to_list_files[self.list_classes[class_idx]][examples_class_idx[0]],\
self.class_to_list_files[self.list_classes[class_idx]][examples_class_idx[1]]
negative_example = None
while negative_example is None or self.file_class_mapping[negative_example] == \
self.file_class_mapping[positive_example_1]:
negative_example_idx = np.random.choice(self.range_all_files, 1)[0]
negative_example = self.list_all_files[negative_example_idx]
return positive_example_1, negative_example, positive_example_2
def read_and_resize(filepath):
im = Image.open(( filepath)).convert('RGB')
 im = im.resize(( image_size, image_size))
return np.array(im, dtype="float32")
 def augment(im_array):
if np.random.uniform(0, 1)> 0.9:
im_array = np.fliplr(im_array)
 return im_array
def gen(triplet_gen):
while True:
list_positive_examples_1 = []
list_negative_examples = []
list_positive_examples_2 = []
for i in range(batch_size):
positive_example_1, negative_example, positive_example_2 = triplet_gen.get_sample()
path_pos1 = join(path_train, positive_example_1)
 path_neg = join(path_train, negative_example)
 path_pos2 = join(path_train, positive_example_2)
 positive_example_1_img = read_and_resize(path_pos1)
 negative_example_img = read_and_resize(path_neg)
 positive_example_2_img = read_and_resize(path_pos2)
 positive_example_1_img = augment(positive_example_1_img)
 negative_example_img = augment(negative_example_img)
 positive_example_2_img = augment(positive_example_2_img)
 list_positive_examples_1.append(positive_example_1_img)
 list_negative_examples.append(negative_example_img)
 list_positive_examples_2.append(positive_example_2_img)
 A = preprocess_input(np.array(list_positive_examples_1))
B = preprocess_input(np.array(list_positive_examples_2))
C = preprocess_input(np.array(list_negative_examples))
label = None
yield({'anchor_input': A, 'positive_input': B, 'negative_input': C}, label )<compute_test_metric>
paths = [
".. /input/lyft-best-performing-public-kernels/lyft-ensembling-raster-sizes.csv",
".. /input/lyft-best-performing-public-kernels/lyft-prediction-with-multi-mode-confidence.csv",
]
weights = [0.4, 0.6]
def triplet_loss(inputs, dist='sqeuclidean', margin='maxplus'):
anchor, positive, negative = inputs
positive_distance = K.square(anchor - positive)
 negative_distance = K.square(anchor - negative)
 if dist == 'euclidean':
positive_distance = K.sqrt(K.sum(positive_distance, axis=-1, keepdims=True))
negative_distance = K.sqrt(K.sum(negative_distance, axis=-1, keepdims=True))
elif dist == 'sqeuclidean':
positive_distance = K.sum(positive_distance, axis=-1, keepdims=True)
 negative_distance = K.sum(negative_distance, axis=-1, keepdims=True)
 loss = positive_distance - negative_distance
if margin == 'maxplus':
loss = K.maximum(0.0, 1 + loss)
 elif margin == 'softplus':
loss = K.log(1 + K.exp(loss))
return K.mean(loss)
 def triplet_loss_np(inputs, dist='sqeuclidean', margin='maxplus'):
anchor, positive, negative = inputs
positive_distance = np.square(anchor - positive)
 negative_distance = np.square(anchor - negative)
 if dist == 'euclidean':
positive_distance = np.sqrt(np.sum(positive_distance, axis=-1, keepdims=True))
negative_distance = np.sqrt(np.sum(negative_distance, axis=-1, keepdims=True))
elif dist == 'sqeuclidean':
positive_distance = np.sum(positive_distance, axis=-1, keepdims=True)
 negative_distance = np.sum(negative_distance, axis=-1, keepdims=True)
 loss = positive_distance - negative_distance
if margin == 'maxplus':
loss = np.maximum(0.0, 1 + loss)
 elif margin == 'softplus':
loss = np.log(1 + np.exp(loss))
return np.mean(loss)
 def check_loss() :
batch_size = 10
shape =(batch_size, 4096)
 p1 = normalize(np.random.random(shape))
n = normalize(np.random.random(shape))
p2 = normalize(np.random.random(shape))
input_tensor = [K.variable(p1), K.variable(n), K.variable(p2)]
out1 = K.eval(triplet_loss(input_tensor))
input_np = [p1, n, p2]
out2 = triplet_loss_np(input_np)
 assert out1.shape == out2.shape
print(np.linalg.norm(out1))
print(np.linalg.norm(out2))
print(np.linalg.norm(out1-out2))<choose_model_class>
conf_cols = np.array(["conf_0", "conf_1", "conf_2"] )
def GetModel() :
base_model = ResNet50(weights='imagenet', include_top=False, pooling='max')
 for layer in base_model.layers:
layer.trainable = False
x = base_model.output
x = Dropout(0.6 )(x)
 x = Dense(embedding_dim )(x)
 x = Lambda(lambda x: K.l2_normalize(x,axis=1))(x)
 embedding_model = Model(base_model.input, x, name="embedding")
 input_shape =(image_size, image_size, 3)
 anchor_input = Input(input_shape, name='anchor_input')
 positive_input = Input(input_shape, name='positive_input')
 negative_input = Input(input_shape, name='negative_input')
 anchor_embedding = embedding_model(anchor_input)
 positive_embedding = embedding_model(positive_input)
 negative_embedding = embedding_model(negative_input)
 inputs = [anchor_input, positive_input, negative_input]
outputs = [anchor_embedding, positive_embedding, negative_embedding]
triplet_model = Model(inputs, outputs)
 triplet_model.add_loss(K.mean(triplet_loss(outputs)))
 return embedding_model, triplet_model<split>
xy_cols = [[],[],[]]
for i in range(50):
for j in range(3):
xy_cols[j].append(f"coord_x{j}{i}")
 xy_cols[j].append(f"coord_y{j}{i}")
 xy_cols[0][:10]
data = pd.read_csv(path_csv)
 train, test = train_test_split(data, train_size=0.7, random_state=1337)
 file_id_mapping_train = {k: v for k, v in zip(train.Image.values, train.Id.values)}
file_id_mapping_test = {k: v for k, v in zip(test.Image.values, test.Id.values)}
gen_tr = gen(sample_gen(file_id_mapping_train))
gen_te = gen(sample_gen(file_id_mapping_test))
checkpoint = ModelCheckpoint(path_model, monitor='loss', verbose=1, save_best_only=True, mode='min')
 early = EarlyStopping(monitor="val_loss", mode="min", patience=2)
 callbacks_list = [checkpoint, early]<find_best_params>
COLUMNS = ["timestamp", "track_id"] + list(conf_cols)+ xy_cols[0] + xy_cols[1] + xy_cols[2]
embedding_model, triplet_model = GetModel()<define_variables>
def sort_df(df, sort_timestamp_track_id=True):
conf_orders = np.argsort(-df[conf_cols].values,1)
 XY = np.stack([df[xy_cols[0]].values,df[xy_cols[1]].values, df[xy_cols[2]].values], axis=1)
 XY = XY[np.arange(len(XY)) [:, None], conf_orders]
df2 = pd.DataFrame(columns = COLUMNS)
 df2["timestamp"] = df["timestamp"].values
df2["track_id"] = df["track_id"].values
df2[xy_cols[0] + xy_cols[1] + xy_cols[2]] = XY.reshape(-1,300)
 df2[conf_cols] = df[conf_cols].values[np.arange(len(df)) [:, None], conf_orders]
if sort_timestamp_track_id:
df2.sort_values(["timestamp", "track_id"], inplace=True)
 df2.reset_index(inplace=True, drop=True)
 return df2
for i, layer in enumerate(embedding_model.layers):
print(i, layer.name, layer.trainable )<set_options>
%%time
df = None
for path,w in zip(paths,weights):
print(w, path)
 temp = pd.read_csv(path)
 temp = sort_df(temp)
 temp[COLUMNS[5:]] *= w
if df is None:
df = temp
else:
df[COLUMNS[2:]] += temp[COLUMNS[2:]]
df[conf_cols] /= df[conf_cols].sum(1 ).values[:, None]
sample = pd.read_csv(".. /input/lyft-motion-prediction-autonomous-vehicles/multi_mode_sample_submission.csv")
 df = sample[["timestamp", "track_id"]].merge(df, on=["timestamp", "track_id"])
 sample.shape, df.shape
<train_model><EOS> 
df.to_csv("submission.csv", index=False, float_format='%.6f' )