Kaggle competition: Facial Keypoints Detection
<SOS> metric: RMSE Kaggle data source: facial-keypoints-detection<save_to_csv>
!unzip.. /input/facial-keypoints-detection/test.zip
!unzip.. /input/facial-keypoints-detection/training.zip
submission_df.to_csv('submission_New8.csv', index=False )<set_options>
%matplotlib inline
pd.set_option('max_columns', None)
 plt.style.use('fivethirtyeight')
 %matplotlib inline
py.init_notebook_mode(connected=True)
 warnings.filterwarnings('ignore')
 print("Libraries imported!" )<train_model>
device = torch.device('cuda:0' )
class BaseModel(object):

 def __init__(self, train_df, test_df, target, features, categoricals=[],
n_splits=3, cv_method="KFold", group=None, task="regression",
parameter_tuning=False, scaler=None, verbose=True):
self.train_df = train_df
self.test_df = test_df
self.target = target
self.features = features
self.n_splits = n_splits
self.categoricals = categoricals
self.cv_method = cv_method
self.group = group
self.task = task
self.parameter_tuning = parameter_tuning
self.scaler = scaler
self.cv = self.get_cv()
self.verbose = verbose
self.params = self.get_params()
self.y_pred, self.score, self.model, self.oof, self.y_val, self.fi_df = self.fit()
def train_model(self, train_set, val_set):
raise NotImplementedError
def get_params(self):
raise NotImplementedError
def convert_dataset(self, x_train, y_train, x_val, y_val):
raise NotImplementedError
def convert_x(self, x):
return x
def calc_metric(self, y_true, y_pred):
if self.task == "classification":
return log_loss(y_true, y_pred)
 elif self.task == "regression":
return np.sqrt(mean_squared_error(y_true, y_pred))
def get_cv(self):
if self.cv_method == "KFold":
cv = KFold(n_splits=self.n_splits, shuffle=True, random_state=42)
 return cv.split(self.train_df)
 elif self.cv_method == "StratifiedKFold":
cv = StratifiedKFold(n_splits=self.n_splits, shuffle=True, random_state=42)
 return cv.split(self.train_df, self.train_df[self.target])
 elif self.cv_method == "TimeSeriesSplit":
cv = TimeSeriesSplit(max_train_size=None, n_splits=self.n_splits)
 return cv.split(self.train_df)
 elif self.cv_method == "GroupKFold":
cv = GroupKFold(n_splits=self.n_splits, shuffle=True, random_state=42)
 return cv.split(self.train_df, self.train_df[self.target], self.group)
 elif self.cv_method == "StratifiedGroupKFold":
cv = StratifiedGroupKFold(n_splits=self.n_splits, shuffle=True, random_state=42)
 return cv.split(self.train_df, self.train_df[self.target], self.group)
 def fit(self):
oof_pred = np.zeros(( self.train_df.shape[0],))
y_vals = np.zeros(( self.train_df.shape[0],))
y_pred = np.zeros(( self.test_df.shape[0],))
if self.group is not None:
if self.group in self.features:
self.features.remove(self.group)
 if self.group in self.categoricals:
self.categoricals.remove(self.group)
 fi = np.zeros(( self.n_splits, len(self.features)))
 if self.scaler is not None:
numerical_features = [f for f in self.features if f not in self.categoricals]
self.train_df[numerical_features] = self.train_df[numerical_features].fillna(self.train_df[numerical_features].median())
 self.test_df[numerical_features] = self.test_df[numerical_features].fillna(self.test_df[numerical_features].median())
 self.train_df[self.categoricals] = self.train_df[self.categoricals].fillna(self.train_df[self.categoricals].mode().iloc[0])
 self.test_df[self.categoricals] = self.test_df[self.categoricals].fillna(self.test_df[self.categoricals].mode().iloc[0])
 if self.scaler == "MinMax":
scaler = MinMaxScaler()
elif self.scaler == "Standard":
scaler = StandardScaler()
df = pd.concat([self.train_df[numerical_features], self.test_df[numerical_features]], ignore_index=True)
 scaler.fit(df[numerical_features])
 x_test = self.test_df.copy()
x_test[numerical_features] = scaler.transform(x_test[numerical_features])
 x_test = [np.absolute(x_test[i])for i in self.categoricals] + [x_test[numerical_features]]
else:
x_test = self.test_df[self.features]
for fold,(train_idx, val_idx)in enumerate(self.cv):
x_train, x_val = self.train_df.loc[train_idx, self.features], self.train_df.loc[val_idx, self.features]
y_train, y_val = self.train_df.loc[train_idx, self.target], self.train_df.loc[val_idx, self.target]
if self.scaler is not None:
x_train[numerical_features] = scaler.transform(x_train[numerical_features])
 x_val[numerical_features] = scaler.transform(x_val[numerical_features])
 x_train = [np.absolute(x_train[i])for i in self.categoricals] + [x_train[numerical_features]]
x_val = [np.absolute(x_val[i])for i in self.categoricals] + [x_val[numerical_features]]
train_set, val_set = self.convert_dataset(x_train, y_train, x_val, y_val)
 model, importance = self.train_model(train_set, val_set)
 fi[fold, :] = importance
conv_x_val = self.convert_x(x_val)
 y_vals[val_idx] = y_val
oof_pred[val_idx] = model.predict(conv_x_val ).reshape(oof_pred[val_idx].shape)
 x_test = self.convert_x(x_test)
 y_pred += model.predict(x_test ).reshape(y_pred.shape)/ self.n_splits
print('Partial score of fold {} is: {}'.format(fold, self.calc_metric(y_val, oof_pred[val_idx])))
 fi_df = pd.DataFrame()
for n in np.arange(self.n_splits):
tmp = pd.DataFrame()
tmp["features"] = self.features
tmp["importance"] = fi[n, :]
tmp["fold"] = n
fi_df = pd.concat([fi_df, tmp], ignore_index=True)
 gfi = fi_df[["features", "importance"]].groupby(["features"] ).mean().reset_index()
fi_df = fi_df.merge(gfi, on="features", how="left", suffixes=('', '_mean'))
loss_score = self.calc_metric(self.train_df[self.target], oof_pred)
 if self.verbose:
print('Our oof loss score is: ', loss_score)
 return y_pred, loss_score, model, oof_pred, y_vals, fi_df
def plot_feature_importance(self, rank_range=[1, 50]):
fig, ax = plt.subplots(1, 1, figsize=(10, 20))
sorted_df = self.fi_df.sort_values(by = "importance_mean", ascending=False ).reset_index().iloc[self.n_splits *(rank_range[0]-1): self.n_splits * rank_range[1]]
sns.barplot(data=sorted_df, x ="importance", y ="features", orient='h')
 ax.set_xlabel("feature importance")
 ax.spines['top'].set_visible(False)
 ax.spines['right'].set_visible(False)
 return sorted_df<train_model>
class FacialKeypoiuntsTrainDataset(Dataset):

 def __init__(self, data_file, transform=None):
self.transform = transform
dataset = pd.read_csv(data_file)
 dataset.fillna(method='ffill', inplace=True)
 self.images = dataset['Image']
dataset = dataset.drop(['Image'], axis=1)
 self.positions_name = list(dataset.columns)
 self.positions = dataset.to_numpy()
def __len__(self):
return len(self.positions)
 def __getitem__(self, index):

 x = self.images[index]
x = np.array([float(x)for x in x.split(' ')])
 x = x.reshape(( 96, 96))
img = np.stack(( x, x, x), axis=-1)/ 255.
 y = self.positions[index]
sample = {'img': img, 'landmarks': y}
if self.transform:
sample = self.transform(sample)
 return sample
def show_samples(self, indices, title=None, count=10):

 plt.figure(figsize=(count*3, 3))
display_indices = indices[:count]
if title:
plt.suptitle(title)
 for i, index in enumerate(display_indices):
sample = self.__getitem__(index)
 x, y = sample['img'], sample['landmarks']
x = np.asarray(x)
 y = np.asarray(y)
 y = y.reshape(( y.size // 2, 2))
plt.subplot(1, count, i + 1)
 if self.transform:
plt.imshow(np.transpose(x,(1, 2, 0)))
 else:
plt.imshow(x)
 plt.scatter(y[:, 0], y[:, 1], s=15, marker='.', c='r')
 plt.grid(False)
 plt.axis('off' )
class LgbModel(BaseModel):

 def train_model(self, train_set, val_set):
verbosity = 100 if self.verbose else 0
model = lgb.train(self.params, train_set, num_boost_round = 5000, valid_sets=[train_set, val_set], verbose_eval=verbosity)
 fi = model.feature_importance(importance_type="gain")
 return model, fi
def convert_dataset(self, x_train, y_train, x_val, y_val):
train_set = lgb.Dataset(x_train, y_train, categorical_feature=self.categoricals)
 val_set = lgb.Dataset(x_val, y_val, categorical_feature=self.categoricals)
 return train_set, val_set
def get_params(self):
params = {
'num_leaves': 127,
'min_data_in_leaf': 50,
'max_depth': -1,
'learning_rate': 0.005,
"boosting_type": "gbdt",
"bagging_seed": 11,
"verbosity": -1,
'random_state': 42,
}
if self.task == "regression":
params["objective"] = "regression"
params["metric"] = "rmse"
elif self.task == "classification":
params["objective"] = "binary"
params["metric"] = "binary_logloss"
if self.parameter_tuning == True:
def objective(trial):
train_x, test_x, train_y, test_y = train_test_split(self.train_df[self.features],
self.train_df[self.target],
test_size=0.3, random_state=42)
 dtrain = lgb.Dataset(train_x, train_y, categorical_feature=self.categoricals)
 dtest = lgb.Dataset(test_x, test_y, categorical_feature=self.categoricals)
 hyperparams = {'num_leaves': trial.suggest_int('num_leaves', 24, 1024),
'boosting_type': 'gbdt',
'objective': params["objective"],
'metric': params["metric"],
'max_depth': trial.suggest_int('max_depth', 4, 16),
'min_child_weight': trial.suggest_int('min_child_weight', 1, 20),
'feature_fraction': trial.suggest_uniform('feature_fraction', 0.4, 1.0),
'bagging_fraction': trial.suggest_uniform('bagging_fraction', 0.4, 1.0),
'bagging_freq': trial.suggest_int('bagging_freq', 1, 7),
'min_child_samples': trial.suggest_int('min_child_samples', 5, 100),
'lambda_l1': trial.suggest_loguniform('lambda_l1', 1e-8, 10.0),
'lambda_l2': trial.suggest_loguniform('lambda_l2', 1e-8, 10.0),
'early_stopping_rounds': 100
}
model = lgb.train(hyperparams, dtrain, valid_sets=dtest, verbose_eval=500)
 pred = model.predict(test_x)
 if self.task == "classification":
return log_loss(test_y, pred)
 elif self.task == "regression":
return np.sqrt(mean_squared_error(test_y, pred))
study = optuna.create_study(direction='minimize')
 study.optimize(objective, n_trials=50)
 print('Number of finished trials: {}'.format(len(study.trials)))
 print('Best trial:')
 trial = study.best_trial
print(' Value: {}'.format(trial.value))
print(' Params: ')
 for key, value in trial.params.items() :
print(' {}: {}'.format(key, value))
params = trial.params
params["learning_rate"] = 0.001
plot_optimization_history(study)
 return params<train_model>
class FacialKeypoiuntsTestDataset(Dataset):

 def __init__(self, data_file):
self.dataset = pd.read_csv(data_file)
 def __len__(self):
return len(self.dataset)
 def __getitem__(self, index):

 data_sr = self.dataset.iloc[index]
img_id = int(data_sr['ImageId'])
 x = data_sr['Image']
x = np.array([float(x)for x in x.split(' ')])
 x = x.reshape(( 96, 96))
img = np.stack(( x, x, x), axis=-1)/ 255.
 img = np.transpose(img,(2, 0, 1)).copy()
img_t = torch.from_numpy(img ).type(torch.FloatTensor)
 return img_t, img_id
def show_samples(self, indices, title=None, count=10):

 plt.figure(figsize=(count*3, 3))
display_indices = indices[:count]
if title:
plt.suptitle(title)
 for i, index in enumerate(display_indices):
x, y = self.__getitem__(index)
 x = np.asarray(x)
 plt.subplot(1, count, i + 1)
 plt.imshow(np.transpose(x,(1, 2, 0)))
 plt.title(f'Image Id {y}')
 plt.grid(False)
 plt.axis('off' )
class CatbModel(BaseModel):

 def train_model(self, train_set, val_set):
verbosity = 100 if self.verbose else 0
if self.task == "regression":
model = CatBoostRegressor(**self.params)
 elif self.task == "classification":
model = CatBoostClassifier(**self.params)
 model.fit(train_set['X'], train_set['y'], eval_set=(val_set['X'], val_set['y']),
verbose=verbosity, cat_features=self.categoricals)
 return model, model.get_feature_importance()
def convert_dataset(self, x_train, y_train, x_val, y_val):
train_set = {'X': x_train, 'y': y_train}
val_set = {'X': x_val, 'y': y_val}
return train_set, val_set
def get_params(self):
params = { 'task_type': "CPU",
'learning_rate': 0.01,
'iterations': 1000,
'random_seed': 42,
'use_best_model': True
}
if self.task == "regression":
params["loss_function"] = "RMSE"
elif self.task == "classification":
params["loss_function"] = "Logloss"
return params<normalization>
train_dataset = FacialKeypoiuntsTrainDataset('./training.csv')
 test_dataset = FacialKeypoiuntsTestDataset('./test.csv')
 train_plot_indices = np.random.choice(len(train_dataset), 10)
 test_plot_indices = np.random.choice(len(test_dataset), 10)
 train_dataset.show_samples(
 train_plot_indices, title='Samples from Facial Keypoints Train Dataset', count=7)
 test_dataset.show_samples(
 test_plot_indices, title='Samples from Facial Keypoints Test Dataset', count=7 )
class Mish(Layer):
def __init__(self, **kwargs):
super(Mish, self ).__init__(**kwargs)
 def build(self, input_shape):
super(Mish, self ).build(input_shape)
 def call(self, x):
return x * K.tanh(K.softplus(x))
def compute_output_shape(self, input_shape):
return input_shape
class LayerNormalization(keras.layers.Layer):
def __init__(self,
center=True,
scale=True,
epsilon=None,
gamma_initializer='ones',
beta_initializer='zeros',
gamma_regularizer=None,
beta_regularizer=None,
gamma_constraint=None,
beta_constraint=None,
**kwargs):

 super(LayerNormalization, self ).__init__(**kwargs)
 self.supports_masking = True
self.center = center
self.scale = scale
if epsilon is None:
epsilon = K.epsilon() * K.epsilon()
self.epsilon = epsilon
self.gamma_initializer = keras.initializers.get(gamma_initializer)
 self.beta_initializer = keras.initializers.get(beta_initializer)
 self.gamma_regularizer = keras.regularizers.get(gamma_regularizer)
 self.beta_regularizer = keras.regularizers.get(beta_regularizer)
 self.gamma_constraint = keras.constraints.get(gamma_constraint)
 self.beta_constraint = keras.constraints.get(beta_constraint)
 self.gamma, self.beta = None, None
def get_config(self):
config = {
'center': self.center,
'scale': self.scale,
'epsilon': self.epsilon,
'gamma_initializer': keras.initializers.serialize(self.gamma_initializer),
'beta_initializer': keras.initializers.serialize(self.beta_initializer),
'gamma_regularizer': keras.regularizers.serialize(self.gamma_regularizer),
'beta_regularizer': keras.regularizers.serialize(self.beta_regularizer),
'gamma_constraint': keras.constraints.serialize(self.gamma_constraint),
'beta_constraint': keras.constraints.serialize(self.beta_constraint),
}
base_config = super(LayerNormalization, self ).get_config()
return dict(list(base_config.items())+ list(config.items()))
def compute_output_shape(self, input_shape):
return input_shape
def compute_mask(self, inputs, input_mask=None):
return input_mask
def build(self, input_shape):
shape = input_shape[-1:]
if self.scale:
self.gamma = self.add_weight(
 shape=shape,
initializer=self.gamma_initializer,
regularizer=self.gamma_regularizer,
constraint=self.gamma_constraint,
name='gamma', 
)
 if self.center:
self.beta = self.add_weight(
 shape=shape,
initializer=self.beta_initializer,
regularizer=self.beta_regularizer,
constraint=self.beta_constraint,
name='beta', 
)
 super(LayerNormalization, self ).build(input_shape)
 def call(self, inputs, training=None):
mean = K.mean(inputs, axis=-1, keepdims=True)
 variance = K.mean(K.square(inputs - mean), axis=-1, keepdims=True)
 std = K.sqrt(variance + self.epsilon)
 outputs =(inputs - mean)/ std
if self.scale:
outputs *= self.gamma
if self.center:
outputs += self.beta
return outputs<train_model>
batch_size = 32
data_size = len(train_dataset)
 validation_fraction =.2
val_split_size = int(np.floor(validation_fraction * data_size))
indeces = list(range(data_size))
np.random.shuffle(indeces)
 val_indeces, train_indeces = indeces[:val_split_size], indeces[val_split_size:]
test_indeces = list(range(len(test_dataset)))
 print(f'train size = {len(train_indeces)}, validation size = {len(val_indeces)}')
 print(f'test size = {len(test_indeces)}')
 train_sampler = SubsetRandomSampler(train_indeces)
 val_sampler = SubsetRandomSampler(val_indeces)
 test_sampler = SubsetRandomSampler(test_indeces)
 train_loader = torch.utils.data.DataLoader(train_dataset,
batch_size=batch_size,
sampler=train_sampler)
 val_loader = torch.utils.data.DataLoader(train_dataset,
batch_size=batch_size,
sampler=val_sampler)
 test_loader = torch.utils.data.DataLoader(test_dataset,
batch_size=batch_size,
sampler=test_sampler )
class NeuralNetworkModel(BaseModel):

 def train_model(self, train_set, val_set):
inputs = []
embeddings = []
embedding_out_dim = self.params['embedding_out_dim']
n_neuron = self.params['hidden_units']
for i in self.categoricals:
input_ = Input(shape=(1,))
embedding = Embedding(int(np.absolute(self.train_df[i] ).max() + 1), embedding_out_dim, input_length=1 )(input_)
 embedding = Reshape(target_shape=(embedding_out_dim,))(embedding)
 inputs.append(input_)
 embeddings.append(embedding)
 input_numeric = Input(shape=(len(self.features)- len(self.categoricals),))
embedding_numeric = Dense(n_neuron )(input_numeric)
 embedding_numeric = Mish()(embedding_numeric)
 inputs.append(input_numeric)
 embeddings.append(embedding_numeric)
 x = Concatenate()(embeddings)
 for i in np.arange(self.params['hidden_layers'] - 1):
x = Dense(n_neuron //(2 *(i+1)) )(x)
 x = Mish()(x)
 x = Dropout(self.params['hidden_dropout'] )(x)
 x = LayerNormalization()(x)
 if self.task == "regression":
out = Dense(1, activation="linear", name = "out" )(x)
 loss = "mse"
elif self.task == "classification":
out = Dense(1, activation='sigmoid', name = 'out' )(x)
 loss = "binary_crossentropy"
model = Model(inputs=inputs, outputs=out)
 model.compile(loss=loss, optimizer=Adam(lr=1e-04, beta_1=0.9, beta_2=0.999, decay=1e-04))
er = EarlyStopping(patience=10, min_delta=1e-4, restore_best_weights=True, monitor='val_loss')
 ReduceLR = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=7, verbose=1, epsilon=1e-4, mode='min')
 model.fit(train_set['X'], train_set['y'], callbacks=[er, ReduceLR],
epochs=self.params['epochs'], batch_size=self.params['batch_size'],
validation_data=[val_set['X'], val_set['y']])
 fi = np.zeros(len(self.features))
return model, fi
def convert_dataset(self, x_train, y_train, x_val, y_val):
train_set = {'X': x_train, 'y': y_train}
val_set = {'X': x_val, 'y': y_val}
return train_set, val_set
def get_params(self):

 params = {
'input_dropout': 0.0,
'hidden_layers': 2,
'hidden_units': 128,
'embedding_out_dim': 4,
'hidden_activation': 'relu',
'hidden_dropout': 0.05,
'batch_norm': 'before_act',
'optimizer': {'type': 'adam', 'lr': 0.001},
'batch_size': 128,
'epochs': 80
}
return params<load_from_csv>
nn_model = models.resnet18(pretrained=True)
 nn_model.fc = nn.Linear(nn_model.fc.in_features, 30)
 nn_model = nn_model.type(torch.FloatTensor)
 nn_model = nn_model.to(device)
 *old_params, new_params = nn_model.parameters()
data_dict = {}
for i in glob.glob('/kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-womens-tournament/WDataFiles_Stage1/*'):
name = i.split('/')[-1].split('.')[0]
if name != 'WTeamSpellings':
data_dict[name] = pd.read_csv(i)
 else:
data_dict[name] = pd.read_csv(i, encoding='cp1252' )<feature_engineering>
def train_model(model, train_loader, val_loader, loss, optimizer, scheduler, num_epoch, plot_epoch):

 loss_history = []
train_rmse_history = []
val_rmse_history = []
best_model = None
best_val_rmse = None
indices = np.random.choice(batch_size, 10)
 for epoch in range(num_epoch):
print(f'Epoch {epoch + 1:2d} / {num_epoch:2d}', end=' ')
 model.train()
average_loss = 0
average_rmse = 0
for i_step, sample in enumerate(train_loader):
x, y = sample['img'], sample['landmarks']
x_gpu = x.to(device)
 y_gpu = y.to(device)
 prediction = model(x_gpu)
 loss_value = loss(prediction, y_gpu)
 optimizer.zero_grad()
loss_value.backward()
optimizer.step()
average_loss += loss_value.item()
rmse = mean_squared_error(
 y,
prediction.cpu().detach().numpy() ,
squared=False)
 average_rmse += rmse
average_loss = average_loss / i_step
train_rmse = average_rmse / i_step
val_rmse = compute_rmse(model, val_loader)
 loss_history.append(average_loss)
 train_rmse_history.append(train_rmse)
 val_rmse_history.append(val_rmse)
 print(f'Loss = {average_loss:.4f}, Train RMSE = {train_rmse:.4f}, Val RMSE = {val_rmse:.4f}')
 if best_val_rmse is None:
best_val_rmse = val_rmse
best_model = copy.deepcopy(model)
 if val_rmse < best_val_rmse:
best_val_rmse = val_rmse
best_model = copy.deepcopy(model)
 scheduler.step()
if(( epoch + 1)% plot_epoch)== 0:
plot_results(model, val_loader, indices, title=f'Examples for epoch {epoch + 1}')
 print(f' Best val RMSE = {best_val_rmse:.4f}')
 return loss_history, train_rmse_history, val_rmse_history, best_val_rmse, best_model
def compute_rmse(model, val_loader):

 average_rmse = 0
model.eval()
for i_step, sample in enumerate(val_loader):
x, y = sample['img'], sample['landmarks']
x_gpu = x.to(device)
 with torch.no_grad() :
prediction = model(x_gpu)
 rmse = mean_squared_error(
 y,
prediction.cpu().detach().numpy() ,
squared=False)
 average_rmse += rmse
val_rmse = float(average_rmse)/ i_step
return val_rmse
def plot_results(model, val_loader, indices, title=None, count=10):

 plt.figure(figsize=(count*3, 3))
display_indices = indices[:count]
if title:
plt.suptitle(title)
 model.eval()
for i_step, samples in enumerate(val_loader):
x_gpu, _ = samples['img'], samples['landmarks']
x_gpu = x_gpu.to(device)
 with torch.no_grad() :
prediction = model(x_gpu)
 ys = prediction.cpu().detach().numpy()
xs = x_gpu.cpu().detach().numpy()
for i, index in enumerate(display_indices):
x = xs[index]
y = ys[index]
y = y.reshape(( y.size // 2, 2))
plt.subplot(1, count, i + 1)
 if x.shape[0] == 3:
plt.imshow(np.transpose(x,(1, 2, 0)))
 else:
plt.imshow(x)
 plt.scatter(y[:, 0], y[:, 1], s=15, marker='.', c='r')
 plt.grid(False)
 plt.axis('off')
 plt.show()
break
data_dict['WNCAATourneySeeds']['Seed'] = data_dict['WNCAATourneySeeds']['Seed'].apply(lambda x: int(x[1:3]))
data_dict[fname].head()<load_from_csv>
loss = nn.MSELoss().to(device)
 optimizer = optim.Adam([
{'params': old_params, 'lr': 0.0001},
{'params': new_params}
], lr=0.001, weight_decay=0.01)
 scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=1.) 
(loss_history, train_rmse_history, val_rmse_history,
best_val_rmse, best_model)= train_model(nn_model, train_loader, val_loader, loss,
optimizer, scheduler, num_epoch=50, plot_epoch=3 )
test = pd.read_csv('.. /input/google-cloud-ncaa-march-madness-2020-division-1-womens-tournament/WSampleSubmissionStage1_2020.csv')
 print(test.shape)
 test.head()<feature_engineering>
def test_dataset_prediction(test_loader, submissions_data_file,
lookup_table_data_file, positions_name, model):

 submission = pd.read_csv(submissions_data_file)
 lookup_table = pd.read_csv(lookup_table_data_file)
 model.eval()
for i_step,(x, img_id)in enumerate(test_loader):
x_gpu = x.to(device)
 with torch.no_grad() :
prediction = model(x_gpu)
 prediction = np.asarray(prediction.cpu())
 for b_id in range(prediction.shape[0]):
for p_id in range(len(positions_name)) :
p_name = positions_name[p_id]
location = prediction[b_id, p_id]
row_id = lookup_table.loc[(
(lookup_table['FeatureName'] == p_name)& 
(lookup_table['ImageId'] == img_id[b_id].item())
)]['RowId'].to_numpy()
if row_id.size == 1:
submission['Location'][int(row_id[0])- 1] = location
return submission
test = test.drop(['Pred'], axis=1)
 test['Season'] = test['ID'].apply(lambda x: int(x.split('_')[0]))
test['WTeamID'] = test['ID'].apply(lambda x: int(x.split('_')[1]))
test['LTeamID'] = test['ID'].apply(lambda x: int(x.split('_')[2]))
test.head()<merge>
test_submissions = test_dataset_prediction(
 test_loader, '.. /input/facial-keypoints-detection/SampleSubmission.csv',
'.. /input/facial-keypoints-detection/IdLookupTable.csv',
train_dataset.positions_name, best_model)
 test_submissions.to_csv('./submission.csv', index=False )