Kaggle competition: Plant Pathology 2020 - FGVC7
<SOS> metric: MCAUC Kaggle data source: plant-pathology-2020-fgvc7<save_to_csv>
!pip install -q efficientnet_pytorch
ensemble_final.to_csv('ensemble_final.csv', index=False )<set_options>
base_path = Path('/kaggle/input/plant-pathology-2020-fgvc7/' )
warnings.filterwarnings('ignore')
<define_variables>
def get_tag(row):
if row.healthy:
return "healthy"
if row.multiple_diseases:
return "multiple_diseases"
if row.rust:
return "rust"
if row.scab:
return "scab"
def seed_everything(seed = 34):
os.environ['PYTHONHASHSEED']=str(seed)
 tf.random.set_seed(seed)
 np.random.seed(seed)
 random.seed(seed)
 seed_everything()<load_from_csv>
def transform_data(train_labels):
train_labels.image_id = [image_id+'.jpg' for image_id in train_labels.image_id]
train_labels['tag'] = [get_tag(train_labels.iloc[idx])for idx in train_labels.index]
train_labels.drop(columns=['healthy', 'multiple_diseases', 'rust', 'scab'], inplace=True )
train = pd.read_json('/kaggle/input/stanford-covid-vaccine/train.json', lines=True)
 test = pd.read_json('/kaggle/input/stanford-covid-vaccine/test.json', lines=True)
 sample_sub = pd.read_csv('/kaggle/input/stanford-covid-vaccine/sample_submission.csv' )<randomize_order>
train_labels = pd.read_csv(base_path/"train.csv")
 path = base_path/"images"
print(f"Samples with signal_to_noise greater than 1: {len(train.loc[(train['signal_to_noise'] > 1)])}")
 print(f"Samples with SN_filter = 1: {len(train.loc[(train['SN_filter'] == 1)])}" )<define_variables>
transform_data(train_labels)
 train_labels = train_labels.set_index("image_id" )
target_cols = ['reactivity', 'deg_Mg_pH10', 'deg_pH10', 'deg_Mg_50C', 'deg_50C']<define_variables>
tfms = get_transforms(max_rotate=30.,flip_vert=True )
token2int = {x:i for i, x in enumerate('().ACGUBEHIMSX')}<categorify>
src =(ImageList.from_folder(path)
.filter_by_func(lambda fname: "Train" in fname.name)
.split_by_rand_pct() 
.label_from_func(lambda o: train_labels.loc[o.name]['tag']))
def preprocess_inputs(df, cols=['sequence', 'structure', 'predicted_loop_type']):
return np.transpose(
 np.array(
 df[cols] 
.applymap(lambda seq: [token2int[x] for x in seq])
.values 
.tolist() 
), 
(0, 2, 1)
 )<compute_test_metric>
def get_data(size, bs):
data =(src.transform(tfms, size=size)
.databunch(bs=bs)
.normalize())
 return data
def rmse(y_actual, y_pred):
mse = tf.keras.losses.mean_squared_error(y_actual, y_pred)
 return K.sqrt(mse)
 def mcrmse(y_actual, y_pred, num_scored=len(target_cols)) :
score = 0
for i in range(num_scored):
score += rmse(y_actual[:, :, i], y_pred[:, :, i])/ num_scored
return score<define_variables>
def getModelEff(model_name = 'efficientnet-b4'):
model = EfficientNet.from_pretrained(model_name)
 if model_name == 'efficientnet-b4':
model._fc = nn.Linear(1792,4)
 elif model_name == 'efficientnet-b3':
model._fc = nn.Linear(1536,4)
 return model
train_inputs = preprocess_inputs(train)
 train_labels = np.array(train[target_cols].values.tolist() ).transpose(( 0, 2, 1))<choose_model_class>
archs = {
"resnet50": {
"model": models.resnet50,
"epochs_1": 10,
"epochs_2": 10,
"epochs_3": 10,
"epochs_4": 10,
"max_lr_s1": 0.003,
"max_lr_s2": slice(1e-5, 3e-4),
"max_lr_s1_448": 0.003,
"max_lr_s2_448":slice(1e-5, 3e-4)
 },
"dense121": {
"model": models.densenet121,
"epochs_1": 6,
"epochs_2": 5,
"epochs_3": 6,
"epochs_4": 3,
"max_lr_s1": 0.003,
"max_lr_s2": slice(1e-5, 3e-4),
"max_lr_s1_448": 0.003,
"max_lr_s2_448":slice(1e-5, 1e-4)
 },
"dense161": {
"model": models.densenet161,
"epochs_1": 8,
"epochs_2": 5,
"epochs_3": 7,
"epochs_4": 4,
"max_lr_s1": 1e-3,
"max_lr_s2": slice(1e-5, 1e-4),
"max_lr_s1_448": 0.003,
"max_lr_s2_448":slice(1e-5, 3e-4)
 },
"eff-b3": {
"model": getModelEff('efficientnet-b3'),
"epochs_1": 7,
"epochs_2": 3,
"epochs_3": 5,
"epochs_4": 2,
"max_lr_s1": 1e-3,
"max_lr_s2": slice(1e-5, 1e-4),
"max_lr_s1_448": 1e-3,
"max_lr_s2_448":slice(1e-5, 3e-4)
 },
"eff-b4": {
"model": getModelEff('efficientnet-b4'),
"epochs_1": 10,
"epochs_2": 5,
"epochs_3": 8,
"epochs_4": 5,
"max_lr_s1": 3e-3,
"max_lr_s2": slice(1e-5, 3e-4),
"max_lr_s1_448": 1e-3,
"max_lr_s2_448":slice(1e-5, 1e-4)
 }
}
def gru_layer(hidden_dim, dropout):
return tf.keras.layers.Bidirectional(
 tf.keras.layers.GRU(hidden_dim,
dropout=dropout,
return_sequences=True,
kernel_initializer='orthogonal'))
def lstm_layer(hidden_dim, dropout):
return tf.keras.layers.Bidirectional(
 tf.keras.layers.LSTM(hidden_dim,
dropout=dropout,
return_sequences=True,
kernel_initializer='orthogonal'))
def build_model(gru=False, lstm=False, seq_len=107, pred_len=68, dropout=0.4,
embed_dim=100, hidden_dim=128, layers=3):
inputs = tf.keras.layers.Input(shape=(seq_len, 3))
embed = tf.keras.layers.Embedding(input_dim=len(token2int), output_dim=embed_dim )(inputs)
 reshaped = tf.reshape(
 embed, shape=(-1, embed.shape[1], embed.shape[2] * embed.shape[3]))
hidden = tf.keras.layers.SpatialDropout1D (.2 )(reshaped)
 if gru:
for _ in range(layers):
hidden = gru_layer(hidden_dim, dropout )(hidden)
 elif lstm:
for _ in range(layers):
hidden = lstm_layer(hidden_dim, dropout )(hidden)
 truncated = hidden[:, :pred_len]
out = tf.keras.layers.Dense(5, activation='linear' )(truncated)
 model = tf.keras.Model(inputs=inputs, outputs=out)
 adam = tf.optimizers.Adam()
radam = tfa.optimizers.RectifiedAdam()
lookahead = tfa.optimizers.Lookahead(adam, sync_period=6)
 ranger = tfa.optimizers.Lookahead(radam, sync_period=6)
 model.compile(optimizer=adam, loss=mcrmse)
 return model<define_variables>
archs = {
"resnet152": {
"model_name": "resnet152",
"model": models.resnet152,
"stages": [{
"name_s1": "stage-1_lr",
"epochs_s1": 10,
"max_lr_s1": 1e-3,
"name_s2": "stage-2_lr",
"epochs_s2": 10,
"max_lr_s2": slice(1e-5, 1e-4),
"size": 224,
"bs": 20
},
{
"name_s1": "stage-1_mr",
"epochs_s1": 10,
"max_lr_s1": 1e-3,
"name_s2": "stage-2_mr",
"epochs_s2": 10,
"max_lr_s2": slice(1e-5, 1e-4),
"size": 448,
"bs": 10
},
{
"name_s1": "stage-1_hr",
"epochs_s1": 10,
"max_lr_s1": 1e-3,
"name_s2": "stage-2_hr",
"epochs_s2": 10,
"max_lr_s2": slice(1e-5, 1e-4),
"size": 896,
"bs": 5
}]
}
}
FOLDS = 4
EPOCHS = 120
REPEATS = 1
BATCH_SIZE = 64
VERBOSE = 2
SEED = 34<define_variables>
def train_model(arch):
model_name = arch["model_name"]
print(arch)
 for i, stage in enumerate(arch["stages"]):
print(f"traing {model_name} on {stage['name_s1']}")
 data = get_data(size=stage["size"], bs=stage["bs"])
 if model_name.startswith("eff"):
learner = Learner(data, arch["model"], metrics=error_rate ).to_fp16()
learner.split(lambda m:(arch._conv_head,))
else:
learner = cnn_learner(data, arch["model"], metrics=error_rate ).to_fp16()
learner.model_dir = "/kaggle/working"
if i != 0:
learner.load(f"{arch['stages'][i-1]['name_s2']}_{model_name}")
 print(f"lr for {model_name} {stage['name_s1']}")
 learner.lr_find()
learner.recorder.plot(suggestion=True)
 learner.fit_one_cycle(stage['epochs_s1'], max_lr=stage['max_lr_s1'])
 learner.save(f"{stage['name_s1']}_{model_name}")
 print(f"lr for {model_name} {stage['name_s2']}")
 learner.unfreeze()
learner.lr_find()
learner.recorder.plot(suggestion=True)
 learner.fit_one_cycle(stage['epochs_s2'], max_lr=stage['max_lr_s2'])
 learner.save(f"{stage['name_s2']}_{model_name}")
 del data
gc.collect()
if i == len(arch["stages"])-1:
return learner
learner.destroy()
torch.cuda.empty_cache()
public_df = test.query("seq_length == 107" ).copy()
private_df = test.query("seq_length == 130" ).copy()
public_inputs = preprocess_inputs(public_df)
 private_inputs = preprocess_inputs(private_df )<train_model>
def create_results() :
test_images = ImageList.from_folder(base_path/"images")
 test_images.filter_by_func(lambda x: x.name.startswith("Test"))
for model_name in archs:
arch = archs[model_name]
learner = train_model(arch)
 test_df = pd.read_csv(base_path/"test.csv")
 test_df['healthy'] = [0.0 for _ in test_df.index]
test_df['multiple_diseases'] = [0.0 for _ in test_df.index]
test_df['rust'] = [0.0 for _ in test_df.index]
test_df['scab'] = [0.0 for _ in test_df.index]
test_df = test_df.set_index('image_id')
 for item in tqdm(test_images.items):
name = item.name[:-4]
img = open_image(item)
 preds = learner.predict(img)[2]
test_df.loc[name]['healthy'] = preds[0]
test_df.loc[name]['multiple_diseases'] = preds[1]
test_df.loc[name]['rust'] = preds[2]
test_df.loc[name]['scab'] = preds[3]
test_df.to_csv(f"/kaggle/working/{model_name}_result.csv")
 learner.destroy()
torch.cuda.empty_cache()