Kaggle competition: Quick, Draw! Doodle Recognition Challenge
Y_train_init = training_dataset['label']
X_train_init = training_dataset.drop(labels=['label'], axis=1 )<prepare_x_and_y>
import tensorflow as tf
import keras
from keras.layers import Conv2D, GlobalAveragePooling2D, MaxPooling2D, GlobalAveragePooling1D, Conv1D, MaxPooling1D
from keras.layers import Dense, Dropout, Flatten, Activation, Input, BatchNormalization
from keras.layers import CuDNNLSTM as LSTM
from keras.layers.merge import concatenate
from keras.metrics import categorical_crossentropy, top_k_categorical_accuracy, categorical_accuracy
from keras.models import Sequential, Model
from keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint,TensorBoard, LearningRateScheduler
from keras.optimizers import Adam,Adagrad,RMSprop,SGD
from keras.applications import Xception, MobileNet, MobileNetV2, xception, mobilenet
from keras.utils.np_utils import to_categorical
from keras.preprocessing.sequence import pad_sequences
from sklearn.preprocessing import LabelEncoder
from keras.metrics import top_k_categorical_accuracy
from tqdm import tqdm_notebook as tqdm
from ast import literal_eval
import glob
from multiprocessing import Pool
from functools import partial
from itertools import repeat
from itertools import product
<prepare_x_and_y>
SH_DIR = '.. /input/shufflecsvs/shuffle-csvs/shuffle-csvs/'
INPUT_DIR = '.. /input/quickdraw-doodle-recognition/'
Y_train = training_dataset['label']
X_train = training_dataset.drop(labels=['label'], axis=1)
 nums = 10<prepare_x_and_y>
SEED = 42
np.random.seed(seed=SEED)
 tf.set_random_seed(seed=SEED )
X_test = testing_dataset.values<feature_engineering>
def apk(actual, predicted, k=3):

 if len(predicted)> k:
predicted = predicted[:k]
score = 0.0
num_hits = 0.0
for i, p in enumerate(predicted):
if p in actual and p not in predicted[:i]:
num_hits += 1.0
score += num_hits /(i + 1.0)
 if not actual:
return 0.0
return score / min(len(actual), k)
 def mapk(actual, predicted, k=3):

 return np.mean([apk(a, p, k)for a, p in zip(actual, predicted)])
 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 )
X_train = X_train/255.0<feature_engineering>
mobile_BASE_SIZE = 256
mobile_NCSVS = 100
mobile_NCATS = 340
mobile_STEPS = 800
mobile_EPOCHS = 70
mobile_SIZE = 64
mobile_BATCHSIZE = 128
lstm_batch_size = 128
lstm_STROKE_COUNT = 196
BATCHSIZE = 128
X_test = X_test/ 255.0<categorify>
def image_generator_xd(size, batchsize, ks, lw=6, time_color=True):
while True:
for k in np.random.permutation(ks):
filename = os.path.join(SH_DIR, 'train_k{}.csv.gz'.format(k))
for df in pd.read_csv(filename, chunksize=batchsize):
df['drawing'] = df['drawing'].apply(json.loads)
 x = np.zeros(( len(df), size, size, 1))
for i, raw_strokes in enumerate(df.drawing.values):
x[i, :, :, 0] = draw_cv2(raw_strokes, size=size, lw=lw,
time_color=time_color)
 x = mobilenet.preprocess_input(x ).astype(np.float32)
 y = keras.utils.to_categorical(df.y, num_classes=NCATS)
 yield x, y
Y_train = to_categorical(Y_train, num_classes=nums )<define_variables>
def df_to_image_array_xd(df, size, lw=6, time_color=True):
df['drawing'] = df['drawing'].apply(json.loads)
 x = np.zeros(( len(df), size, size, 1))
for i, raw_strokes in enumerate(df.drawing.values):
x[i, :, :, 0] = draw_cv2(raw_strokes, size=size, lw=lw, time_color=time_color)
 x = mobilenet.preprocess_input(x ).astype(np.float32)
 return x
random_seed = 2<import_modules>
def df_to_sequence_array(df, time_size):
df['drawing'] = df['drawing'].apply(json.loads)
 x = np.zeros(( len(df), time_size, 3))
for i, raw_strokes in enumerate(df.drawing.values):
x[i, : ,: ] = _stack_it(raw_strokes, time_size)
 return x
from sklearn.model_selection import train_test_split<import_modules>
def _stack_it(raw_strokes, time_size):

 in_strokes = [(xi,yi,i)
 for i,(x,y)in enumerate(raw_strokes)
 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=time_size,
padding='post' ).swapaxes(0, 1 )
from sklearn.model_selection import train_test_split<split>
def read_batch(samples=5,
start_row=0,
max_rows = 1000):

 out_df_list = []
for c_path in ALL_TRAIN_PATHS:
c_df = pd.read_csv(c_path, nrows=max_rows, skiprows=start_row)
 c_df.columns=COL_NAMES
out_df_list += [c_df.sample(samples)[['drawing', 'word']]]
full_df = pd.concat(out_df_list)
 full_df['drawing'] = full_df['drawing'].\
map(_stack_it)
 return full_df
X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, random_state=random_seed, test_size = 0.3 )<import_modules>
def image_generator_xd(size,time_size, batchsize, ks, lw=6, time_color=True):
while True:
for k in np.random.permutation(ks):
filename = os.path.join(SH_DIR, 'train_k{}.csv.gz'.format(k))
for df in pd.read_csv(filename, chunksize=batchsize):
df['drawing'] = df['drawing'].apply(json.loads)
 x = np.zeros(( len(df), size, size, 1))
x_lstm = np.zeros(( len(df), time_size, 3))
for i, raw_strokes in enumerate(df.drawing.values):
x[i, :, :, 0] = draw_cv2(raw_strokes, size=size, lw=lw,
time_color=time_color)
 x_lstm[i, :, :] = _stack_it(raw_strokes, time_size)
 x = mobilenet.preprocess_input(x ).astype(np.float32)
 y = keras.utils.to_categorical(df.y, num_classes=mobile_NCATS)
 yield [x, x_lstm], y
from keras import Sequential
from keras.layers import Dense, MaxPooling2D, Dropout, Flatten, Conv2D, BatchNormalization
from keras.callbacks import ReduceLROnPlateau, LearningRateScheduler
from keras.preprocessing.image import ImageDataGenerator<choose_model_class>
train_datagen = image_generator_xd(size = mobile_SIZE, time_size=lstm_STROKE_COUNT, batchsize=mobile_BASE_SIZE, ks= range(mobile_NCSVS-1))
x, y =next(train_datagen )
batch_size = 65
epochs = 23
model = Sequential()
model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same', input_shape=(28, 28, 1)))
 model.add(BatchNormalization(scale=False,center=True))
model.add(MaxPooling2D(padding='same', pool_size=(2, 2)))
 model.add(Conv2D(filters=32, kernel_size=(5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(padding='same', pool_size=(2, 2)))
 model.add(Dropout(0.25))
model.add(Conv2D(filters=64, kernel_size=(5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(padding='same', pool_size=(2, 2)))
 model.add(Conv2D(filters=64, kernel_size=(7, 7), activation='relu', padding='same'))
model.add(MaxPooling2D(padding='same', pool_size=(2, 2)))
 model.add(Dropout(0.25))
model.add(Conv2D(filters=128, kernel_size=(5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(padding='same', pool_size=(2, 2)))
 model.add(Flatten())
 model.add(Dense(128, activation='relu'))
model.add(Dropout(0.25))
model.add(BatchNormalization(scale=False,center=True))
model.add(Dense(nums, activation='softmax'))<choose_model_class>
valid_df = pd.read_csv(os.path.join(SH_DIR, 'train_k{}.csv.gz'.format(mobile_NCSVS-1)) , nrows = 34000)
model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])
<statistical_test>
iterable_1 = product(np.array_split(valid_df, 100), [mobile_SIZE])
 iterable_2 = product(np.array_split(valid_df, 100), [lstm_STROKE_COUNT] )
t = 1
def decide_f(t):
if t < 5:
f =.5
else:
f =.9
t = t + 1
return(f)
 reduce_lr = ReduceLROnPlateau(monitor='val_acc', factor=decide_f(t),verbose=1,
patience=2, min_lr=0.00000000001 )<init_hyperparams>
with Pool(processes=NJOBS)as p:
x_valid = p.starmap(df_to_image_array_xd, iterable_1)
 with Pool(processes=NJOBS)as p:
x_lstm_valid = p.starmap(df_to_sequence_array, iterable_2 )
datagen = ImageDataGenerator(
 featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=15,
zoom_range = 0.1,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=False,
vertical_flip=False )<train_model>
x_valid = np.vstack(np.array(x_valid))
x_lstm_valid = np.vstack(np.array(x_lstm_valid))
y_valid = keras.utils.to_categorical(valid_df.y, num_classes=mobile_NCATS)
 print(
 'mobile_valid size :{} \
RNN valid size : {} \
y_valid size : {}'.format(x_valid.shape, x_lstm_valid.shape, y_valid.shape))
datagen.fit(X_train)
 h = model.fit_generator(datagen.flow(X_train,Y_train, batch_size=batch_size),
epochs = epochs, validation_data =(X_val,Y_val),
verbose = 1, steps_per_epoch=X_train.shape[0] // batch_size
, callbacks=[reduce_lr],)
 final_loss, final_acc = model.evaluate(X_val, Y_val, verbose=0)
 print("Final loss: {0:.6f}, final accuracy: {1:.6f}".format(final_loss, final_acc)) 
<predict_on_test>
def mobiel_net(size):
base_model = MobileNet(weights = None, input_shape=(size, size,1), include_top=False ,alpha=1.)
x= base_model.output
x= GlobalAveragePooling2D()(x)
 return x, base_model.input
prediction = model.predict(X_test)
<prepare_output>
def lstm_model(time_size ,f_size):
stroke_input = Input(shape=(time_size, f_size), name = 'lstm_input')
 batch_norm = BatchNormalization()(stroke_input)
 conv1 = Conv1D(48,(5,), activation='relu' )(batch_norm)
 conv2 = Conv1D(64,(5,), activation='relu' )(conv1)
 conv3 = Conv1D(96,(3,), activation='relu' )(conv2)

max_pool = MaxPooling1D(pool_size = 4 )(conv3)

lstm1 = LSTM(128, return_sequences=True )(max_pool)
 lstm2 = LSTM(128, return_sequences=False )(lstm1)

batch_norm_2 = BatchNormalization()(lstm2)

return batch_norm_2, stroke_input
label = np.argmax(prediction, axis=1 )<define_variables>
mobile_model, mobile_input = mobiel_net(mobile_SIZE)
 sequence_model, sequence_input = lstm_model(lstm_STROKE_COUNT, 3 )
test_id = np.reshape(range(1, len(prediction)+ 1), label.shape )<save_to_csv>
merge = concatenate([mobile_model, sequence_model] )
my_submission = pd.DataFrame({'ImageId': test_id, 'Label': label})
 my_submission.to_csv('submission.csv', index=False )<set_options>

 hidden_1 = Dense(512, activation='relu' )(merge)
 merge_batch_norm = BatchNormalization()(hidden_1)

output = Dense(mobile_NCATS, activation = 'softmax' )(merge_batch_norm)
 merge_model = Model(inputs = [mobile_input, sequence_input ], output = output, name = 'merge_model_fin_70' )
%matplotlib inline<load_from_csv>
def compile_and_train(model, num_epochs, BATCHSIZE, OPTIMIZER):
model.compile(optimizer=OPTIMIZER(lr=0.002), loss='categorical_crossentropy',
metrics=[categorical_crossentropy, categorical_accuracy, top_3_accuracy])
 directory_path = '.. /working/weights/{}/'.format(model.name)
 log_path = '.. /working/logs/{}/'.format(model.name)
 directory_check(directory_path)
 directory_check(log_path)
 file_name = model.name + '.{epoch:02d}-{loss:.2f}.h5'
filepath = os.path.join(directory_path, file_name)
 callbacks = [
ReduceLROnPlateau(monitor='val_top_3_accuracy', factor = 0.75, patience=3, min_delta=0.001, mode='max', min_lr=1e-5, verbose=1),
ModelCheckpoint(filepath, monitor='val_top_3_accuracy', mode= 'max', save_best_only=True, save_weights_only=True),
TensorBoard(log_dir=log_path, histogram_freq=0, batch_size=BATCHSIZE)
 ]
hist = model.fit_generator(
 train_datagen, steps_per_epoch = mobile_STEPS, epochs = num_epochs, verbose = 1,
validation_data =([x_valid,x_lstm_valid], y_valid),
callbacks = callbacks 
)
 weight_files = glob.glob('{}*'.format(directory_path))
weight_file = max(weight_files, key = os.path.getctime)
 return hist, weight_file
train = pd.read_csv("/kaggle/input/digit-recognizer/train.csv")
 test = pd.read_csv("/kaggle/input/digit-recognizer/test.csv")
 y_train = train["label"]
x_train = train.drop(labels = ["label"], axis = 1)
 x_train = x_train.values.reshape(-1,28,28,1)
 test = test.values.reshape(-1,28,28,1)
 del train
X_train /= 255
test /= 255<categorify>
model_his, model_weight = compile_and_train(merge_model, 60 , BATCHSIZE, Adam )
y_train = to_categorical(y_train, num_classes = 10 )<split>
history_df = pd.concat([pd.DataFrame(model_his.history)],sort = True )
random_seed = 2
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train,
test_size = 0.2, random_state = random_seed )<choose_model_class>
valid_predictions = merge_model.predict([x_valid, x_lstm_valid], batch_size=BATCHSIZE, verbose=1)
 map3 = mapk(valid_df[['y']].values, preds2catids(valid_predictions ).values)
 print('MAP3 : {:.3f}'.format(map3))
def create_model() :
def add_conv_block(model, num_filters):
model.add(Conv2D(num_filters,3,activation='relu', padding = 'same'))
model.add(BatchNormalization())
 model.add(Conv2D(num_filters,3, activation= 'relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.5))
return model
model = tf.keras.models.Sequential()
model.add(Input(shape=(28,28,1)))
 model = add_conv_block(model, 32)
 model = add_conv_block(model, 64)
 model = add_conv_block(model, 128)
 model.add(Flatten())
 model.add(Dense(128, activation="relu"))
model.add(Dense(128, activation="relu"))
model.add(Dense(10,activation = 'softmax'))
model.compile(
 loss = 'categorical_crossentropy',
optimizer = 'adam', metrics = ['accuracy'] 
)
 return model
model = create_model()
model.summary()<train_model>
test = pd.read_csv(os.path.join(INPUT_DIR, 'test_simplified.csv'))
test.head()
h = model.fit(
 x_train,y_train,
validation_data =(x_val,y_val),
epochs=20,batch_size=30
)<predict_on_test>
x_test = df_to_image_array_xd(test.copy() , mobile_SIZE)
 x_lstm_test = df_to_sequence_array(test.copy() , lstm_STROKE_COUNT)
 print(test.shape, x_test.shape)
 print(test.shape, x_lstm_test.shape )
results = model.predict(test)
 results = np.argmax(results,axis = 1)
 results = pd.Series(results,name="Label" )<save_to_csv>
test_predictions = merge_model.predict([x_test,x_lstm_test], batch_size=BATCHSIZE, verbose=1)
 top3 = preds2catids(test_predictions)
 top3.head()
submission = pd.concat([pd.Series(range(1,28001),name = "ImageId"),results],axis = 1)
 submission.to_csv("cnn_mnist_datagen.csv",index=False )<set_options>
cats = list_all_categories()
id2cat = {k : cat.replace(' ', '_')for k, cat in enumerate(cats)}
top3cats = top3.replace(id2cat)
 top3cats.head()
<load_from_csv><EOS> 
test['word'] = top3cats['a'] + ' ' + top3cats['b'] + ' ' + top3cats['c']
submission = test[['key_id', 'word']]
submission.to_csv('{}-submission-fin.csv'.format(merge_model.name), index=False )