Kaggle competition: Cassava Leaf Disease Classification
<SOS> metric: CategorizationAccuracy Kaggle data source: cassava-leaf-disease-classification<data_type_conversions>
!pip install.. /input/timm031/timm-0.3.1-py3-none-any.whl
sub = 0
if sub==0:
!pip install --upgrade pip adabound
pil2tensor = transforms.ToTensor()
class HWIDataset(FilesDataset):
def __init__(self, fnames, path, transform):
self.train_df = train_df
super().__init__(fnames, transform, path)
 def get_x(self, i):
img_cr = make_bbox_image(os.path.join(self.path, self.fnames[i])).convert("RGB")
 img = pil2tensor(img_cr ).numpy().transpose(1, 2, 0)
 try:
img = cv2.resize(img,(self.sz, self.sz))
except Exception as e:
print(self.fnames[i])
 print(str(e))
return img
def get_y(self, i):
if(self.path == TEST): return 0
return self.train_df.loc[self.fnames[i]]['Id']
def get_c(self):
return len(unique_labels)
<categorify>
import numpy as np
import pandas as pd
import timm
import os
import matplotlib.pyplot as plt
import cv2
import sys
from sklearn import model_selection, metrics
import torch
from PIL import Image
from tensorflow.keras import models, layers
from PIL import ImageEnhance, ImageOps
import pdb
import torchvision.transforms as transforms
import adabound
import random
class RandomLighting(Transform):
def __init__(self, b, c, tfm_y=TfmType.NO):
super().__init__(tfm_y)
 self.b, self.c = b, c
def set_state(self):
self.store.b_rand = rand0(self.b)
 self.store.c_rand = rand0(self.c)
 def do_transform(self, x, is_y):
if is_y and self.tfm_y != TfmType.PIXEL: return x
b = self.store.b_rand
c = self.store.c_rand
c = -1 /(c - 1)if c < 0 else c + 1
x = lighting(x, b, c)
 return x
def get_data(sz, batch_size):

 aug_tfms = [RandomRotateZoom(deg=20, zoom=2, stretch=1),
RandomLighting(0.2, 0.2, tfm_y=TfmType.NO),
RandomBlur(blur_strengths=3,tfm_y=TfmType.NO),
RandomFlip(tfm_y=TfmType.NO)]
tfms = tfms_from_model(arch, sz, crop_type=CropType.NO, tfm_y=TfmType.NO,
aug_tfms=aug_tfms)
 ds = ImageData.get_ds(HWIDataset,(tr_n[:-(len(tr_n)% batch_size)], TRAIN), 
(val_n, TRAIN), tfms, test=(test_names, TEST))
md = ImageData("./", ds, batch_size, num_workers=num_workers, classes=None)
 return md 
<load_from_zip>
BASE_DIR = '.. /input/cassava-leaf-disease-classification'
TRAIN_PATH = BASE_DIR+"/train_images/"
TEST_PATH = BASE_DIR+"/test_images/"
!wget http://files.fast.ai/models/weights.tgz
!tar -zxvf weights.tgz
!mkdir /opt/conda/lib/python3.6/site-packages/fastai/weights/
!cp weights/resnext_50_32x4d.pth /opt/conda/lib/python3.6/site-packages/fastai/weights/
!rm -rf weights weights.tgz<load_pretrained>
def read_image(path,label):
image_data = cv2.imread(path)
 plt.title('label:{}'.format(label))
plt.imshow(image_data)
 return image_data
class CassavaDataset(torch.utils.data.Dataset):

 def __init__(self, df, data_path, mode="train", transforms=None):
super().__init__()
self.df_data = df.values
self.data_path = data_path
self.transforms = transforms
self.mode = mode
self.data_dir = "train_images" if mode == "train" else "test_images"
def __len__(self):
return len(self.df_data)
 def __getitem__(self, index):
img_name, label = self.df_data[index]
img = Image.open(img_name ).convert("RGB")
 if self.transforms is not None:
img = self.transforms(img)
 return img, label
class CassvaImgClassifier(torch.nn.Module):
def __init__(self, model_arch, n_class, pretrained=False):
super().__init__()
self.model = timm.create_model(model_arch, pretrained=pretrained)
 n_features = self.model.classifier.in_features
self.model.classifier = torch.nn.Linear(n_features, n_class)
 def forward(self, x):
x = self.model(x)
 return x
class CassavaNet(torch.nn.Module):
def __init__(self,model_name):
super().__init__()
backbone = timm.create_model(model_name, pretrained=True)
 n_features = backbone.fc.in_features
self.backbone = torch.nn.Sequential(*backbone.children())[:-2]
self.classifier = torch.nn.Linear(n_features, 5)
 self.pool = torch.nn.AdaptiveAvgPool2d(( 1, 1))
def forward_features(self, x):
x = self.backbone(x)
 return x
def forward(self, x):
feats = self.forward_features(x)
 x = self.pool(feats ).view(x.size(0), -1)
 x = self.classifier(x)
 return x, feats
image_size = 384
batch_size = 16
md = get_data(image_size, batch_size)
 extra_fc_layers_size = []
learn = ConvLearner.pretrained(arch, md, xtra_fc=extra_fc_layers_size)
 learn.opt_fn = optim.Adam<set_options>
def train(net, epoch, trainLoader, optimizer, criterion):
sum_loss = 0
total = 0
correct = 0
net.train()
for i, data in enumerate(trainLoader, 0):
length = len(data)
 input, target = data
input, target = input.to(device), target.to(device)
 optimizer.zero_grad()
output= net(input)
 loss = criterion(output, target)
 loss.backward()
optimizer.step()
sum_loss += loss.item()
_, predicted = torch.max(output.data, 1)
 total += target.size(0)
 correct += predicted.eq(target.data ).cpu().sum()
if i % 49 == 0 and i != 0:
log_string('[epoch:%d, batch:%d] Loss: %.03f | Acc: %.3f%% ' %(
 epoch + 1, i + 1, sum_loss / total, 100.* float(correct)/ float(total)))
 log_string('[epoch:%d] Loss: %.03f | Acc: %.3f%% ' %(
 epoch + 1, sum_loss / total, 100.* float(correct)/ float(total)))
 return float(correct)/ float(total)
 def valid(net, EPOCH, validLoader):
total = 0
correct = 0
net.eval()
with torch.no_grad() :
correct = 0
total = 0
for data in validLoader:
net.eval()
images, labels = data
images, labels = images.to(device), labels.to(device)
 outputs = net(images)
 _, predicted = torch.max(outputs.data, 1)
 total += labels.size(0)
 correct +=(predicted == labels ).cpu().sum()
log_string('测试分类准确率为：%.3f%%' %(100.* float(correct)/ float(total)))
 return float(correct)/ float(total)
 def log_string(out_str):
LOG_FOUT.write(out_str + '
')
 LOG_FOUT.flush()
print(out_str )
md.is_multi, md.is_reg<init_hyperparams>
lr = 1e-4
BATCH_SIZE=8
IMG_SIZE=512
EPOCH=10
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 df = pd.read_csv(os.path.join(BASE_DIR,'train.csv'))
df.image_id = df.image_id.apply(lambda x : TRAIN_PATH+x)
 LOG_FOUT = open(os.path.join('./', 'log_train.txt'), 'w')
 if os.path.exists('./models')==0:
os.mkdir('./models' )
print('Number of layer groups:', len(learn.get_layer_groups()), '\t(first 2 groups is pretrained backbone)')
 print('This is our extra thin on top of the backbone Resnet50 architecture:')
 learn.get_layer_groups() [2]<train_model>
def one_epoch(fold):
log_string('fold:%d, batch_size:%d,lr:%f,fold_epech:%d,device:%s' %(fold , BATCH_SIZE,lr,2,device))
folds= StratifiedKFold(n_splits=fold ).split(df['image_id'],df['label'])
 acc_train_all= []
acc_valid_all= []
best_acc = 0
for i,(train_index,valid_index)in enumerate(folds):
train_df = df.loc[train_index,:].reset_index(drop=True)
 valid_df = df.loc[valid_index,:].reset_index(drop=True)
 train_dataset = CassavaDataset(train_df,BASE_DIR,transforms=transforms.Compose([
transforms.RandomResizedCrop(IMG_SIZE),
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomVerticalFlip(p=0.5),
transforms.RandomRotation(45),
transforms.ColorJitter(brightness=0.1,contrast=0.1),
transforms.ToTensor() ,
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
]))
valid_dataset = CassavaDataset(valid_df,BASE_DIR,transforms=transforms.Compose([
transforms.CenterCrop(IMG_SIZE),
transforms.ToTensor() ,
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
]))
trainLoader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=BATCH_SIZE,shuffle=True)
 validLoader = torch.utils.data.DataLoader(dataset=valid_dataset,batch_size=BATCH_SIZE)
 acc= train(net, i, trainLoader, optimizer, criterion)
 acc_train_all.append(acc)
 acc= valid(net ,i, validLoader)
 acc_valid_all.append(acc)
 if acc > best_acc:
best_acc = acc
torch.save(net, './models/efficientnetb4_fold5_2.pth')
 scheduler.step()
plt.plot(acc_train_all)
 plt.plot(acc_valid_all)
 plt.ylabel('Accuracy')
 plt.xlabel('Epoch')
 plt.legend(['Train', 'Valid'], loc='upper left')
 plt.show()
base_lr = 1e-4
fc_lr = 1e-3
lrs = [base_lr, base_lr, fc_lr]
learn.fit(lrs=lrs, n_cycle=2, cycle_len=None)
 learn.unfreeze()
learn.fit(lrs, n_cycle=9, cycle_len=None)
 learn.save(MODEL_PATH )<define_variables>
best_th = 0.4<prepare_output>
def test_one(model_name , file_name):
net = CassvaImgClassifier(model_name,5, False)
 net.to(device)
 net.load_state_dict(torch.load(filename ).state_dict())
 net.eval()
preds = []
submit = pd.read_csv(os.path.join(BASE_DIR, "sample_submission.csv"))
for image_id in submit.image_id:
img = Image.open(BASE_DIR+"/test_images/"+image_id ).convert("RGB")
 img = transform1(img ).unsqueeze(0 ).to(device)
 pred = net(img)
 pred = pred.cpu().detach().numpy().astype('int')
 preds.extend(pred)
 return preds
<save_to_csv><EOS> 
file_name = ['a','b','c']
model_name = ['a','b','c']
transform1 = transforms.Compose([
transforms.CenterCrop(IMG_SIZE),
transforms.ToTensor() ,
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
 all_preds = []
for i in range(3):
all_preds.append(test_one(model_name[i],file_name[i]))
submit['label'] = np.argmax(np.mean(all_preds, axis=0), axis=1)
 submit.to_csv('submission.csv', index = False )