Kaggle competition: Quick, Draw! Doodle Recognition Challenge
<SOS> metric: MAP@{K} Kaggle data source: quick,-draw!-doodle-recognition-challenge<feature_engineering>
debug = True
if debug:
STEPS = 200
val_steps = 10
else:
STEPS = 800
val_steps = 100
STROKE_COUNT = 100
EPOCHS = 15
batchsize = 1000
train_df["images"] = [np.array(load_img(".. /input/train/images/{}.png".format(idx), grayscale=True)) / 255 for idx in tqdm_notebook(train_df.index)]<feature_engineering>
%matplotlib inline
def top_3_accuracy(x,y): return top_k_categorical_accuracy(x,y, 3)
 gc.enable()
def get_available_gpus() :
local_device_protos = device_lib.list_local_devices()
return [x.name for x in local_device_protos if x.device_type == 'GPU']
train_df["masks"] = [np.array(load_img(".. /input/train/masks/{}.png".format(idx), grayscale=True)) / 255 for idx in tqdm_notebook(train_df.index)]<feature_engineering>
def preds2catids(predictions):
return pd.DataFrame(np.argsort(-predictions, axis=1)[:, :3], columns=['a', 'b', 'c'])
 def top_3_accuracy(y_true, y_pred):
return top_k_categorical_accuracy(y_true, y_pred, k=3 )
train_df["coverage"] = train_df.masks.map(np.sum)/ pow(img_size_ori, 2 )<categorify>
def _stack_it(raw_strokes):

 stroke_vec = literal_eval(raw_strokes)
 in_strokes = [(xi,yi,i)
 for i,(x,y)in enumerate(stroke_vec)
 for xi,yi in zip(x,y)]
c_strokes = np.stack(in_strokes)
 c_strokes[:,2] = [1]+np.diff(c_strokes[:,2] ).tolist()
c_strokes[:,2] += 1
return pad_sequences(c_strokes.swapaxes(0, 1),
maxlen=STROKE_COUNT,
padding='post' ).swapaxes(0, 1)
def cov_to_class(val):
for i in range(0, 11):
if val * 10 <= i :
return i
train_df["coverage_class"] = train_df.coverage.map(cov_to_class )<split>
DP_DIR = '.. /input/shuffle-csv-50k'
INPUT_DIR = '.. /input/quickdraw-doodle-recognition'
BASE_SIZE = 256
NCSVS = 100
NCATS = 340
np.random.seed(seed=1987)
 tf.set_random_seed(seed=1987)
 def f2cat(filename: str)-> str:
return filename.split('.')[0]
def list_all_categories() :
files = os.listdir(os.path.join(INPUT_DIR, 'train_simplified'))
return sorted([f2cat(f)for f in files], key=str.lower)
ids_train, ids_valid, x_train, x_valid, y_train, y_valid, cov_train, cov_test, depth_train, depth_test = train_test_split(
 train_df.index.values,
np.array(train_df.images.map(upsample ).tolist() ).reshape(-1, img_size_target, img_size_target, 1),
np.array(train_df.masks.map(upsample ).tolist() ).reshape(-1, img_size_target, img_size_target, 1),
train_df.coverage.values,
train_df.z.values,
test_size=0.2, stratify=train_df.coverage_class, random_state=1337 )<choose_model_class>
def image_generator_xd(batchsize, ks):
while True:
for k in np.random.permutation(ks):
filename = os.path.join(DP_DIR, 'train_k{}.csv.gz.gz'.format(k))
for df in pd.read_csv(filename, chunksize=batchsize):
df['drawing'] = df['drawing'].map(_stack_it)
 x2 = np.stack(df['drawing'], 0)
 y = keras.utils.to_categorical(df.y, num_classes=NCATS)
 yield x2, y
def df_to_image_array_xd(df):
df['drawing'] = df['drawing'].map(_stack_it)
 x2 = np.stack(df['drawing'], 0)
 return x2
<concatenate>
train_datagen = image_generator_xd(batchsize=batchsize, ks=range(NCSVS - 2))
val_datagen = image_generator_xd(batchsize=batchsize, ks=range(NCSVS - 2, NCSVS))
def conv_block(m, dim, acti, bn, res, do=0.5):
n = Conv2D(dim, 3, activation=acti, padding='same' )(m)
 n = BatchNormalization()(n)if bn else n
n = SpatialDropout2D(do )(n)if do else n
n = Conv2D(dim, 3, activation=acti, padding='same' )(n)
 n = BatchNormalization()(n)if bn else n
return Concatenate()([m, n])if res else n
def level_block(m, dim, depth, inc, acti, do, bn, mp, up, res):
if depth > 0:
n = conv_block(m, dim, acti, bn, res)
 m = MaxPooling2D()(n)if mp else Conv2D(dim, 3, strides=2, padding='same' )(n)
 m = level_block(m, int(inc*dim), depth-1, inc, acti, do, bn, mp, up, res)
 if up:
m = UpSampling2D()(m)
 m = Conv2D(dim, 2, activation=acti, padding='same' )(m)
 else:
m = Conv2DTranspose(dim, 3, strides=2, activation=acti, padding='same' )(m)
 n = Concatenate()([n, m])
 m = conv_block(n, dim, acti, bn, res)
 else:
m = conv_block(m, dim, acti, bn, res, do=do)
 return m
def UNet(img_shape, out_ch=1, start_ch=64, depth=5, inc_rate=2., activation='relu',
dropout=0.5, batchnorm=False, maxpool=True, upconv=True, residual=True):
i = Input(shape=img_shape)
 o = level_block(i, start_ch, depth, inc_rate, activation, dropout, batchnorm, maxpool, upconv, residual)
 o = Conv2D(out_ch, 1, activation='sigmoid' )(o)
 return Model(inputs=i, outputs=o )<train_model>
stroke_read_model = Sequential()
stroke_read_model.add(BatchNormalization(input_shape =(None,)+(3,)))
 stroke_read_model.add(Conv1D(256,(5,), activation = 'relu'))
stroke_read_model.add(Dropout(0.2))
stroke_read_model.add(Conv1D(256,(5,), activation = 'relu'))
stroke_read_model.add(Dropout(0.2))
stroke_read_model.add(Conv1D(256,(3,), activation = 'relu'))
stroke_read_model.add(Dropout(0.2))
stroke_read_model.add(Bidirectional(LSTM(128, dropout = 0.3, recurrent_dropout= 0.3, return_sequences = True)))
 stroke_read_model.add(Bidirectional(LSTM(128,dropout = 0.3, recurrent_dropout= 0.3, return_sequences = True)))
 stroke_read_model.add(Bidirectional(LSTM(128,dropout = 0.3, recurrent_dropout= 0.3, return_sequences = False)))
 stroke_read_model.add(Dense(512, activation = 'relu'))
stroke_read_model.add(Dropout(0.2))
stroke_read_model.add(Dense(NCATS, activation = 'softmax'))
stroke_read_model.compile(optimizer = 'adam',
loss = 'categorical_crossentropy',
metrics = ['categorical_accuracy', top_3_accuracy])
 stroke_read_model.summary()
model = UNet(( img_size_target,img_size_target,1),start_ch=16,depth=5,batchnorm=True )<compute_test_metric>
weight_path="{}_weights.best.hdf5".format('stroke_lstm_bidirectional_relu')
 checkpoint = ModelCheckpoint(weight_path, monitor='val_loss', verbose=1,
save_best_only=True, mode='min', save_weights_only = True)
 reduceLROnPlat = ReduceLROnPlateau(monitor='val_loss', factor=0.8, patience=4,
verbose=1, mode='auto', epsilon=0.0001, cooldown=5, min_lr=0.0001)
 early = EarlyStopping(monitor="val_loss",
mode="min",
patience=3)
 callbacks_list = [checkpoint, early, reduceLROnPlat]
def iou_loss(y_true, y_pred):
y_true = tf.reshape(y_true, [-1])
 y_pred = tf.reshape(y_pred, [-1])
 intersection = tf.reduce_sum(y_true * y_pred)
 score =(intersection + 1.) /(tf.reduce_sum(y_true)+ tf.reduce_sum(y_pred)- intersection + 1.)
return 1 - score
def iou_bce_loss(y_true, y_pred):
return 0.5 * keras.losses.binary_crossentropy(y_true, y_pred)+ 0.5 * iou_loss(y_true, y_pred)
 def mean_iou(y_true, y_pred):
y_pred = tf.round(y_pred)
 intersect = tf.reduce_sum(y_true * y_pred, axis=[1, 2, 3])
 union = tf.reduce_sum(y_true, axis=[1, 2, 3])+ tf.reduce_sum(y_pred, axis=[1, 2, 3])
 smooth = tf.ones(tf.shape(intersect))
return tf.reduce_mean(( intersect + smooth)/(union - intersect + smooth))
model.compile(loss=iou_bce_loss, optimizer="adam", metrics=['accuracy', mean_iou] )<concatenate>
hist = stroke_read_model.fit_generator(train_datagen, steps_per_epoch=STEPS, epochs=EPOCHS, verbose=1,
validation_data=val_datagen, validation_steps = val_steps,
callbacks = callbacks_list)
 clear_output()
Vx = [np.flip(x, axis=0)for x in x_train]
Vy = [np.flip(x, axis=0)for x in y_train]
Hx = [np.flip(x, axis=1)for x in x_train]
Hy = [np.flip(x, axis=1)for x in y_train]
HVx = [np.flip(x, axis=1)for x in Vx]
HVy = [np.flip(x, axis=1)for x in Vy]
x_train = np.append(x_train, Vx, axis=0)
 y_train = np.append(y_train, Vy, axis=0)
 x_train = np.append(x_train, Hx, axis=0)
 y_train = np.append(y_train, Hy, axis=0)
 x_train = np.append(x_train, HVx, axis=0)
 y_train = np.append(y_train, HVy, axis=0 )<train_on_grid>
hist_df = pd.DataFrame(hist.history)
 hist_df.to_csv('hist_training.csv')
 hist_df.index = np.arange(1, len(hist_df)+1)
 fig, axs = plt.subplots(nrows=2, sharex=True, figsize=(16, 10))
axs[0].plot(hist_df.val_top_3_accuracy, lw=5, label='Validation Accuracy')
 axs[0].plot(hist_df.top_3_accuracy, lw=5, label='Training Accuracy')
 axs[0].set_ylabel('Accuracy')
 axs[0].set_xlabel('Epoch')
 axs[0].grid()
axs[0].legend(loc=0)
 axs[1].plot(hist_df.val_loss, lw=5, label='Validation MLogLoss')
 axs[1].plot(hist_df.loss, lw=5, label='Training MLogLoss')
 axs[1].set_ylabel('MLogLoss')
 axs[1].set_xlabel('Epoch')
 axs[1].grid()
axs[1].legend(loc=0)
 fig.savefig('hist.png', dpi=300)
 plt.show() ;
early_stopping = EarlyStopping(patience=10, verbose=1)
 model_checkpoint = ModelCheckpoint("./keras.model", save_best_only=True, verbose=1)
 reduce_lr = ReduceLROnPlateau(factor=0.1, patience=5, min_lr=0.0000005, verbose=1)
 clr = CyclicLR(base_lr=0.001, max_lr=0.0001, step_size=200, mode='triangular')
 def cosine_annealing(x):
lr = 0.001
epochs = 200
return lr*(np.cos(np.pi*x/epochs)+1.) /2
learning_rate = tf.keras.callbacks.LearningRateScheduler(cosine_annealing)
 epochs = 200
batch_size = 32
history = model.fit(x_train, y_train,
validation_data=[x_valid, y_valid],
epochs=epochs,
batch_size=batch_size,
callbacks=[early_stopping, model_checkpoint, learning_rate] )<predict_on_test>
valid_df = pd.read_csv(os.path.join(DP_DIR, 'train_k{}.csv.gz.gz'.format(NCSVS - 1)) , nrows=34000)
 x_valid = df_to_image_array_xd(valid_df)
 y_valid = keras.utils.to_categorical(valid_df.y, num_classes=NCATS)
 lstm_results = stroke_read_model.evaluate(x_valid, y_valid, batch_size = 4096)
 print('Accuracy: %2.1f%%, Top 3 Accuracy %2.1f%%' %(100*lstm_results[1], 100*lstm_results[2]))
preds_valid = model.predict(x_valid ).reshape(-1, img_size_target, img_size_target)
 preds_valid = np.array([downsample(x)for x in preds_valid])
 mask_valid = np.array([downsample(x)for x in y_valid] )<compute_train_metric>
sub_df = pd.read_csv(os.path.join(INPUT_DIR, 'test_simplified.csv'))
sub_df['drawing'] = sub_df['drawing'].map(_stack_it)
 sub_vec = np.stack(sub_df['drawing'].values, 0)
 sub_pred = stroke_read_model.predict(sub_vec, verbose=True, batch_size=4096)
thresholds = np.linspace(0, 1, 50)
 ious = np.array([iou_metric_batch(mask_valid, np.int32(preds_valid > threshold)) for threshold in tqdm_notebook(thresholds)] )<find_best_params>
top3 = preds2catids(sub_pred)
 cats = list_all_categories()
id2cat = {k: cat.replace(' ', '_')for k, cat in enumerate(cats)}
top3cats = top3.replace(id2cat)
 sub_df['word'] = top3cats['a'] + ' ' + top3cats['b'] + ' ' + top3cats['c']
sub_df.head()
<categorify><EOS> 
sub_df[['key_id', 'word']].to_csv('lstm_relu_datagen.csv', index=False )