Kaggle competition: What's Cooking?
train_transform = transforms.Compose([
transforms.RandomHorizontalFlip() ,
transforms.ColorJitter(brightness=0.2, contrast=0.1, saturation=0.1),
transforms.RandomAffine(0.1),
transforms.RandomGrayscale() ,
transforms.RandomRotation(10),
transforms.ToTensor() ,
transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])
 ] )<categorify>
for t in ['train','test']:
with zipfile.ZipFile(".. /input/whats-cooking/{}.json.zip".format(t),"r")as z:
z.extractall(".")
 with open('./train.json')as data_file:
data = pd.read_json(data_file)
 with open('./test.json')as test_file:
test = pd.read_json(test_file )
valid_transform = transforms.Compose([
transforms.ToTensor() ,
transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])
 ] )<define_variables>
data['cuisine'].value_counts()
image_path = base_path/'train'/'train'
image_size =(224, 224)
 bs = 64<create_dataframe>
tfidf = TfidfVectorizer(vocabulary=ingredient_vocab)
 dct = {' ': '_', '
ingredients_data = data['ingredients'].map(lambda lst: '
ingredients_data = ingredients_data.map(lambda st: ''.join(c if c not in dct else dct[c] for c in st))
tfidf_data = tfidf.fit_transform(ingredients_data)
 ingredients_test = test['ingredients'].map(lambda lst: '
ingredients_test = ingredients_test.map(lambda st: ''.join(c if c not in dct else dct[c] for c in st))
tfidf_test = tfidf.fit_transform(ingredients_test)
cac_dataset = CactusDataset(df_data, image_path, image_size, transform=train_transform )<load_pretrained>
XGBC = xgb.XGBClassifier(objective='multi:softmax', num_class=20, tree_method='auto' )
sample_loader = torch.utils.data.DataLoader(cac_dataset, batch_size=8, shuffle=True)
 images, labels = next(iter(sample_loader))<prepare_x_and_y>
X = df_data['id']
y = df_data['has_cactus']<split>
params = {'objective': 'multi:softmax', 'num_class': 20, 'max_depth': 6, 'n_estimators': 300, 'learning_rate': 0.1, 'tree_method': 'auto'}
X_train, X_val, y_train, y_val = train_test_split(X, y,
stratify=y,
test_size=0.20, shuffle=True )<create_dataframe>
XGBC = xgb.XGBClassifier(params)
 XGBC.fit(tfidf_data, data['cuisine'], eval_metric='merror' )
df_train = pd.DataFrame({'id': X_train.values, 'has_cactus':y_train.values})
 df_val = pd.DataFrame({'id':X_val.values, 'has_cactus':y_val.values} )<create_dataframe>
XGBC.save_model("model")
 XGBC = xgb.XGBClassifier(params)
 XGBC.load_model("model" )
cac_dataset_train = CactusDataset(df_train, image_path, image_size, transform=train_transform)
 cac_dataset_valid = CactusDataset(df_val, image_path, image_size, transform=valid_transform )<load_pretrained>
pred = XGBC.predict(tfidf_test )
train_loader = torch.utils.data.DataLoader(cac_dataset_train, batch_size=32, shuffle=True)
 valid_loader = torch.utils.data.DataLoader(cac_dataset_valid, batch_size=32, shuffle=True )<choose_model_class>
ans = pd.DataFrame()
ans['id'] = test['id']
ans['cuisine'] = pred
ans.head()
def get_base_model(model_name, num_classes, pretrained=True, unfreeze=True, to_gpu=True):
if model_name == "resnet":
model = models.resnet152(pretrained=pretrained)
 input_features = model.fc.in_features
fc_custom = nn.Linear(input_features, num_classes)
 model.fc = fc_custom
elif model_name == "densenet":
model = models.densenet121(pretrained=pretrained)
 input_features = model.classifier.in_features
fc_custom = nn.Linear(input_features, num_classes)
 model.classifier = fc_custom
if unfreeze:
for param in model.parameters() :
param.requires_grad = True
if to_gpu:
model = model.to(device)
 return model<load_pretrained>
ans.to_csv("submission_1.csv", index=False )
model = get_base_model("resnet", 2 )<choose_model_class>
params = {'objective': 'multi:softmax', 'num_class': 20, 'max_depth': 6, 'n_estimators': 300, 'learning_rate': 0.1, 'tree_method': 'auto'}
XGBC = xgb.XGBClassifier(params)
 XGBC.fit(tfidf_data, data['cuisine'], eval_metric='merror')
 XGBC.save_model("model")
 XGBC = xgb.XGBClassifier(params)
 XGBC.load_model("model" )
criterion = nn.CrossEntropyLoss()
optimizer = optmim.SGD([
{'params': model.layer1.parameters() , 'lr': 1e-6},
{'params': model.layer2.parameters() , 'lr': 1e-5},
{'params': model.layer3.parameters() , 'lr': 1e-4},
{'params': model.layer4.parameters() , 'lr': 1e-4},
{'params': model.fc.parameters() , 'lr': 1e-3}
], lr=1e-3)
<compute_test_metric>
LR = LogisticRegression(max_iter=500)
 LR.fit(tfidf_data, data['cuisine'] )
def get_auc_score(y_true, y_pred):
y_true = np.array([item for sublist in y_true for item in sublist])
 y_pred = np.array([item for sublist in y_pred for item in sublist])
 return roc_auc_score(y_true, y_pred )<define_variables>
SVC = LinearSVC()
SVC.fit(tfidf_data, data['cuisine'] )
n_epochs = 50<train_model>
XGB_pred = XGBC.predict(tfidf_test)
 LR_pred = LR.predict(tfidf_test)
 SVC_pred = SVC.predict(tfidf_test)
 predictions = pd.DataFrame()
predictions['XGB'] = XGB_pred
predictions['LR'] = LR_pred
predictions['SVC'] = SVC_pred
def train_model(model, dataloaders, criterion, optimizer, epochs=50):
start_time = time.time()
best_model_wts = copy.deepcopy(model.state_dict())
 best_acc = 0.0
best_loss = np.Inf
metrics = defaultdict(list)
 losses = defaultdict(list)
 for epoch_no in range(epochs):
print("*" * 100)
 print(f"Starting epoch no {epoch_no+1}")
 for phase in ['train','valid']:
y_true = list()
y_pred = list()
if phase == 'train':
model.train()
else:
model.eval()
running_loss = 0.0
running_corrects = 0
for inputs, labels in dataloaders[phase]:
inputs = inputs.to(device)
 labels = labels.to(device)
 optimizer.zero_grad()
with torch.set_grad_enabled(phase == 'train'):
outputs = model(inputs)
 idxs, preds = torch.max(outputs, 1)
 loss = criterion(outputs, labels)
 if phase == 'train':
loss.backward()
optimizer.step()
probs = torch.nn.functional.softmax(outputs, dim=1)[:, 1]
running_loss += loss.item() * inputs.size(0)
 running_corrects += torch.sum(preds == labels.data)
 y_true.append(list(labels.data.cpu().numpy()))
y_pred.append(list(probs.detach().cpu().numpy()))
auc_score = get_auc_score(y_true, y_pred)
 epoch_loss = running_loss / len(dataloaders[phase].dataset)
 epoch_acc = float(running_corrects)/ len(dataloaders[phase].dataset)
 if phase == 'valid' and epoch_loss < best_loss:
print(f"Validation loss decreased from {best_loss} to {epoch_loss}.Saving Model ")
 best_loss = epoch_loss
checkpoint = {'model': model,
'state_dict': model.state_dict() ,
'optimizer' : optimizer.state_dict()
}
torch.save(checkpoint, 'model_resnet_50_v2.pth')
 best_model_wts = copy.deepcopy(model.state_dict())
 print(f"Ending epoch no {epoch_no+1} with below stats")
 print(f"-------------Stats for {phase}-------------")
 print(f"Loss: {epoch_loss}...Accuracy: {epoch_acc}")
 print(f"AUC for {phase} is {auc_score}")
 metrics[phase].append(epoch_acc)
 losses[phase].append(epoch_loss)
 time_elapsed = time.time() - start_time
print(f"Total time taken in training: {time_elapsed / 60} minutes")
 model.load_state_dict(best_model_wts)
 return model, metrics, losses 
<load_from_csv>
rows = predictions['XGB'].size
LR_SVC_match = predictions['SVC'] == predictions['LR']
print(sum(LR_SVC_match)/ rows)
 overruling =(predictions['SVC'] == predictions['LR'])&(predictions['XGB'] != predictions['LR'])
 print(sum(overruling)/ rows )
df_submission = pd.read_csv(base_path/'sample_submission.csv' )<load_pretrained>
ens_pred = predictions['XGB'].copy()
for i in range(rows):
if(overruling[i]):
ens_pred[i] = predictions['SVC'][i]
def load_model(checkpoint_path):
checkpoint = torch.load(checkpoint_path)
 model = checkpoint['model']
model.load_state_dict(checkpoint['state_dict'])
 model.cpu()
for parameter in model.parameters() :
parameter.requires_grad = False
model.eval()
return model<load_pretrained>
ans = pd.DataFrame()
ans['id'] = test['id']
ans['cuisine'] = ens_pred
ans.head()
model = load_model('model_resnet_50_v2.pth' )<define_variables>
ans.to_csv("submission_2.csv", index=False )