Kaggle competition: Quick, Draw! Doodle Recognition Challenge
model_pred = np.zeros(( X_test_resized.shape[0], label_count))
for fold_i in range(NFOLD):
best_model_file_path = make_best_model_file_path(fold_i)
 model.load_weights(best_model_file_path)
 train_ds, val_ds = get_fold(fold_i)
 val_pred = model.predict(val_ds)
 val_pred_file_name = make_val_pred_file_path(fold_i)
 np.save(val_pred_file_name, val_pred)
 test_ds = make_test_ds(X_test_resized)
 print("Fold {0}".format(fold_i), end='', flush=True)
 for i in range(TTA_COUNT):
print('.', end='', flush=True)
 model_pred += model.predict(test_ds)
 print()
y_pred = np.argmax(model_pred, axis=1)
 print(y_pred.shape )<load_from_csv>
import tensorflow as tf
import os
submission_df = read_df('sample_submission.csv')
 submission_df<save_to_csv>
def apk(actual, predicted, k):
if actual not in predicted:
return 0.0
for i in range(k):
if actual in predicted[:i+1]:
return 1.0 / len(predicted[:i+1] )
submission_df['Label'] = y_pred
submission_df.to_csv("submission.csv", index=False)
 !head submission.csv<import_modules>
sub_df = pd.read_csv(data_path+'sample_submission.csv')
 print("test data 수:",len(sub_df))
sub_df.head()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import seaborn as sns
from sklearn.model_selection import train_test_split
import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import tensorflow.keras.layers.experimental.preprocessing as preprocessing<set_options>
train_file_path = data_path + 'train_raw/'
eiffel_df = pd.read_csv(train_file_path + 'The Eiffel Tower.csv')
 eiffel_df.head()
%matplotlib inline
plt.style.use('bmh')
 np.random.seed(42 )<load_from_csv>
train_simple_file_path = data_path + 'train_simplified/'
eiffel_simple_df = pd.read_csv(train_simple_file_path + 'The Eiffel Tower.csv')
 eiffel_simple_df.head()
data = pd.read_csv(".. /input/digit-recognizer/train.csv")
 holdout = pd.read_csv(".. /input/digit-recognizer/test.csv" )<prepare_x_and_y>
raw_images = [json.loads(draw)for draw in eiffel_df.head() ['drawing'].values]
simple_images = [json.loads(draw)for draw in eiffel_simple_df.head() ['drawing'].values]
X = data
y = X.pop('label')
 del data<feature_engineering>
print("======== 첫번째 raw drawing의 첫 획 Data 중 5개 Point 정보 =========")
 print("x좌표: ", json.loads(eiffel_df['drawing'][0])[0][0][:5])
 print("y좌표: ", json.loads(eiffel_df['drawing'][0])[0][1][:5])
 print("msec: ", json.loads(eiffel_df['drawing'][0])[0][2][:5])
 print("======== 첫번째 Simplified drawing의 첫 획 Data 중 5개 Point 정보 =========")
 print("x좌표: ", json.loads(eiffel_simple_df['drawing'][0])[0][0][:5])
 print("y좌표: ", json.loads(eiffel_simple_df['drawing'][0])[0][1][:5] )
X = X / 255.0
holdout = holdout / 255.0<categorify>
train_csvs= os.listdir(train_file_path)
 print("train_raw 폴더 내 파일 수:", len(train_csvs))
print(train_csvs[:5])
 file_size = 0
label_names = []
for csv_file in train_csvs:
file_size += os.path.getsize(train_file_path + csv_file)
 label_names.append(csv_file.replace('.csv',''))
print("파일 크기 : ", file_size//(1024*1024*1024),"GB")
 label_names = sorted(label_names,key=lambda x : str.lower(x+'.csv'))
X = X.values.reshape(-1,28,28,1)
 holdout = holdout.values.reshape(-1,28,28,1)
 y = keras.utils.to_categorical(y, num_classes = 10 )<split>
test_raw_df = pd.read_csv(data_path+"test_raw.csv")
 test_raw_df.head()
print(test_raw_df.shape )
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size =.1,
stratify = y,
random_state = 42 )<choose_model_class>
class DoodelGenerator(tf.keras.utils.Sequence):
def __init__(self, df_files, input_shape, batchsize,label_num=340, lw=3, state='Train', last_drop_r=0.0, mixup_r = 0.0):
self.df_files = df_files
self.file_sel = 0
self.batchsize = batchsize
self.input_shape = input_shape
self.label_num = label_num
self.lw = lw
self.state = state
self.last_drop_r = last_drop_r
self.mixup_r = mixup_r
self.on_epoch_end()
self.len = -(-len(self.df)//self.batchsize)
 def __len__(self):
return self.len
def __getitem__(self, index):
batch_idx = self.idx[index*self.batchsize:(index+1)*self.batchsize]
h,w,ch = self.input_shape
X = np.zeros(( len(batch_idx), h,w,ch))
y = np.zeros(( len(batch_idx), self.label_num))
df = self.df.loc[batch_idx]
mixup_num = int(self.batchsize*self.mixup_r)
 mixup_df = self.df.loc[np.random.randint(0,len(self.df),size=mixup_num)]
mixup_strokes=[]
mixup_labels=[]
for raw_strokes, label in mixup_df.values:
mixup_strokes.append(json.loads(raw_strokes))
mixup_labels.append(label)
 for i in range(self.batchsize):
raw_strokes = json.loads(df.drawing.values[i])
 if i < len(mixup_strokes):
X[i, :, :, ] = draw_raw_cv2(raw_strokes, size=h, lw=self.lw
, last_drop_r = self.last_drop_r,second_strokes=mixup_strokes[i])
 if self.state != 'Test':
ysm_mix = self.smooth_labels(to_categorical(mixup_labels[i], num_classes=self.label_num))
ysm_org = self.smooth_labels(to_categorical(df.y.values[i], num_classes=self.label_num))
y[i, :] =(ysm_mix*0.5)+(ysm_org*0.5)
 else:
X[i, :, :, ] = draw_raw_cv2(raw_strokes, size=h, lw=self.lw
, last_drop_r = self.last_drop_r)
 if self.state != 'Test':
y[i, :] = to_categorical(df.y.values[i], num_classes=self.label_num)
 if self.state != 'Test':
return X,y
else:
return X
def get_cur_df(self):
return self.df
def smooth_labels(self,labels, factor=0.1):
labels *=(1 - factor)
 labels +=(factor / labels.shape[0])
 return labels
def on_epoch_end(self):
self.df = pd.read_csv(self.df_files[self.file_sel])
 print('current step file : ', self.df_files[self.file_sel], 'state:', self.state, 'df_len:', self.df.shape[0])
 self.idx = np.tile(np.arange(len(self.df)) ,2)
 if self.state == 'Train':
np.random.shuffle(self.idx)
 self.file_sel =(self.file_sel+1)%len(self.df_files)
model = keras.Sequential([
layers.InputLayer(input_shape=[28, 28, 1]),
preprocessing.RandomRotation(factor = 0.10),
preprocessing.RandomTranslation(height_factor = 0.1, width_factor = 0.1),
preprocessing.RandomZoom(height_factor = 0.1, width_factor = 0.1),
layers.BatchNormalization(renorm = True),
layers.Conv2D(filters = 32, kernel_size = 5, activation = 'relu', padding = 'same'),
layers.Conv2D(filters = 32, kernel_size = 5, activation = 'relu', padding = 'same'),
layers.Dropout(0.25),
layers.Conv2D(filters = 128, kernel_size = 3, activation = 'relu', padding = 'same'),
layers.MaxPool2D() ,
layers.Conv2D(filters = 64, kernel_size =(3, 3), activation = 'relu', padding = 'same'),
layers.Conv2D(filters = 64, kernel_size =(3, 3), activation = 'relu', padding = 'same'),
layers.MaxPool2D(pool_size =(2, 2), strides =(2, 2)) ,
layers.Flatten() ,
layers.Dense(256, activation = 'relu'),
layers.Dense(10, activation = 'softmax'),
] )<choose_model_class>
hold_out_set= 'train_k99'
optimizer = keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
 model.compile(optimizer = optimizer , loss = "categorical_crossentropy", metrics=["accuracy"] )<define_variables>
!pip install efficientnet
def build_model(backbone= efn.EfficientNetB0, input_shape =(128,128,3), use_imagenet = 'imagenet'):
base_model = backbone(input_shape=input_shape, weights=use_imagenet,include_top= False)
 x = base_model.output
x = tf.keras.layers.GlobalAvgPool2D(name='gap' )(x)
 predictions = tf.keras.layers.Dense(len(label_names), activation='softmax', name='prediction' )(x)
 model = tf.keras.Model(inputs=base_model.input, outputs=predictions)
 return model
epochs = 300
batch_size = 64<choose_model_class>
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 tf.keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=3)
 def map_at3(y_true, y_pred):
map3 = tf.keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=1)*0.5
map3 += tf.keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=2)*0.17
map3 += tf.keras.metrics.top_k_categorical_accuracy(y_true, y_pred, k=3)*0.33
return map3
early_stopping = keras.callbacks.EarlyStopping(
 min_delta=0.001,
patience=10,
restore_best_weights=True,
)<train_model>
recipes = []
recipes.append({'backbone':efn.EfficientNetB7, "batch_size":30, 'name':'Efb7','val_sel':7,'input_shape':(128,128,3),'lw':2} )
optimizer = tf.keras.optimizers.Adam(epsilon=0.01)
 model.compile(
 optimizer=optimizer,
loss='categorical_crossentropy',
metrics=['accuracy'], 
)
 history = model.fit(X_train, y_train,
batch_size = batch_size,
epochs = epochs,
validation_data =(X_test, y_test),
callbacks = [early_stopping],
verbose = 2)
<predict_on_test>
ext_data_path = '/kaggle/input/doodle-model/'
results = model.predict(holdout)
 results = np.argmax(results,axis = 1)
 results = pd.Series(results, name = "Label" )<save_to_csv>
for i, recipe in enumerate(recipes):
model_name = recipe["name"] + '_val_' + str(recipe["val_sel"])+ '_ep2'
best_save_model_file = model_name + '.h5'
print('best_save_model_file path : ',best_save_model_file)
 model = build_model(backbone= recipe['backbone'], input_shape = recipe['input_shape'], use_imagenet = None)
 model.load_weights(ext_data_path + best_save_model_file)
 test_datagen = DoodelGenerator([data_path+"test_raw.csv"], input_shape=recipe['input_shape'], lw=recipe['lw']
, batchsize=recipe['batch_size'],state='Test')
 test_predictions = model.predict(test_datagen, verbose=1)
 top3 = preds2catids(test_predictions)
 id2cat = {k: cat.replace(' ', '_')for k, cat in enumerate(label_names)}
top3cats = top3.replace(id2cat)
 sub_df['word'] = top3cats['a'] + ' ' + top3cats['b'] + ' ' + top3cats['c']
submission = sub_df[['key_id', 'word']]
submission.to_csv('submission_'+model_name+'.csv', index=False )
submission = pd.concat(
 [pd.Series(range(1, 28001), name = "ImageId"),
results],
axis = 1)
 submission.to_csv("digits_submission.csv", index = False )<import_modules>
def balancing_predictions(test_prob, factor = 0.1, minfactor = 0.001, patient = 5, permit_cnt=332, max_search=10000, label_num=340):
maxk = float('inf')
 s_cnt = np.zeros(label_num)
 for i in range(max_search):
ctop1 = Counter(np.argmax(test_prob,axis=1))
ctop1 = sorted(ctop1.items() , key=itemgetter(1), reverse=True)
 if maxk > ctop1[0][1]:
maxk = ctop1[0][1]
else:
s_cnt[ctop1[0][0]]+=1
if np.max(s_cnt)>patient:
if factor< minfactor:
print('stop min factor')
 break
s_cnt=np.zeros(label_num)
 factor*=0.99
print('reduce factor: ', factor, ', current max category num: ', ctop1[0][1])
 if ctop1[0][1] <= permit_cnt:
print('idx: ',ctop1[0][0] ,', num: ', ctop1[0][1])
 break
test_prob[:,ctop1[0][0]] *=(1.0-factor)
 return test_prob
<load_from_csv><EOS> 
bal_test_prob = balancing_predictions(test_predictions)
 bal_top3 = preds2catids(bal_test_prob)
 bal_top3cats = bal_top3.replace(id2cat)
 sub_df['word'] = bal_top3cats['a'] + ' ' + bal_top3cats['b'] + ' ' + bal_top3cats['c']
bal_submission = sub_df[['key_id', 'word']]
bal_submission.to_csv('submission_bal_'+model_name+'.csv', index=False )