交叉验证
from __future__ import print_function
import os
import time
import torch
import random
import warnings
import torchvision
import numpy as np
import pandas as pd
from tqdm import tqdm
from config import config
from datetime import datetime
from torch import nn,optim
from torch.utils.data import DataLoader
from torch.optim import lr_scheduler
from sklearn.model_selection import train_test_split
from timeit import default_timer as timer
from sklearn.metrics import f1_score,accuracy_score
import torch.nn.functional as F
from warmup_scheduler import GradualWarmupScheduler
from sklearn.model_selection import KFold, StratifiedKFold
from utils import *
from multimodal import *
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
random.seed(2050)
np.random.seed(2050)
torch.manual_seed(2050)
torch.cuda.manual_seed_all(2050)
torch.backends.cudnn.benchmark = True
warnings.filterwarnings('ignore')
os.makedirs("./submit_txt/", exist_ok=True)
os.makedirs("./logs/", exist_ok=True)
log = Logger()
log.open("logs/%s_log_train.txt"%config.model_name, mode="a")
log.write("\n----------------------------------------------- [START %s] %s\n\n" % (datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '-' * 51))
log.write(' |------------ Train -------|----------- Valid ---------|----------Best Results---|------------|\n')
log.write('mode iter epoch | acc loss f1_macro | acc loss f1_macro | acc loss f1_macro | time |\n')
log.write('-------------------------------------------------------------------------------------------------------------------------|\n')
def gen_txt(pred_npy, ckpt, fold, best_what):#生成txt
submit1 = pd.read_csv(config.test_csv)
submit1['Predicted'] = np.argmax(pred_npy, 1)
submit1.drop('Target', axis=1, inplace=True)
submit1.Predicted = submit1.Predicted.apply(lambda x: "00" + str(int(x) + 1))
submit1.Id = submit1.Id.apply(lambda x: str(x).zfill(6))
submit1 = submit1.sort_values('Id', ascending=True)
submit1.to_csv("./submit_txt/%s_submit_%s_fold%s.txt" % (ckpt["model_name"], best_what, str(fold)), sep='\t', index=None, header=None)
def train(train_loader,model,criterion,optimizer,epoch,valid_metrics,best_results,start):
losses = AverageMeter()
f1 = AverageMeter()
acc = AverageMeter()
model.train()
for i, (images, visits, target) in enumerate(train_loader):
visits = visits.to(device)
images = images.to(device)
indx_target = target.clone()
target = torch.from_numpy(np.array(target)).long().to(device)
#### --------- mixup --------------
if config.mix_up:
alpha = config.alpha
lam = np.random.beta(alpha, alpha)
index = torch.randperm(images.size(0)).cuda()
images = lam * images + (1 - lam) * images[index, :]
visits = lam * visits + (1 - lam) * visits[index, :]
targets_a, targets_b = target, target[index]
output, features = model(images, visits)
loss = lam * criterion(output, targets_a) + (1 - lam) * criterion(output, targets_b)
else:
output, features = model(images, visits)
loss = criterion(output, target)
psnr = 0
losses.update(loss.item(),images.size(0))
f1_batch = f1_score(target.cpu().data.numpy(),np.argmax(F.softmax(output).cpu().data.numpy(),axis=1),average='macro')
acc_score = accuracy_score(target.cpu().data.numpy(),np.argmax(F.softmax(output).cpu().data.numpy(),axis=1))
f1.update(f1_batch,images.size(0))
acc.update(acc_score,images.size(0))
optimizer.zero_grad()
loss.backward()
optimizer.step()
print('\r',end='',flush=True)
message = '%s %5.1f %6.1f | %0.3f %0.3f %0.3f | %0.3f %0.3f %0.4f | %s %s %s | %s | %.2fdB' % (\
"train", i/len(train_loader) + epoch, epoch,
acc.avg, losses.avg, f1.avg,
valid_metrics[0], valid_metrics[1],valid_metrics[2],
str(best_results[0])[:8],str(best_results[1])[:8],str(best_results[2])[:8],
time_to_str((timer() - start),'min'), psnr)
print(message , end='',flush=True)
log.write("\n")
return [acc.avg, losses.avg, f1.avg]
def evaluate(val_loader,model,criterion,epoch,train_metrics,best_results,start):
losses = AverageMeter()
f1 = AverageMeter()
acc= AverageMeter()
model.to(device)
model.eval()
with torch.no_grad():
for i, (images, visits, target) in enumerate(val_loader):
images = images.to(device)
visits = visits.to(device)
indx_target = target.clone()
target = torch.from_numpy(np.array(target)).long().to(device)
if len(images.size())==5: ### tta
bs, ncrops, c_i, h_i, w_i = images.size()
if len(visits.size()) == 4: bs, c_v, h_v, w_v = visits.size()
if len(visits.size()) == 5: bs, ncrops, c_v, h_v, w_v = visits.size()
images = images.reshape(-1, c_i, h_i, w_i)
visits = visits.reshape(-1, c_v, h_v, w_v).contiguous()
output, features = model(images, visits)
output = output.view(bs, ncrops, -1).mean(1)
else:
output, features = model(images,visits)
loss = criterion(output,target)
psnr = 0
losses.update(loss.item(),images.size(0))
f1_batch = f1_score(target.cpu().data.numpy(),np.argmax(F.softmax(output).cpu().data.numpy(),axis=1),average='macro')
acc_score=accuracy_score(target.cpu().data.numpy(),np.argmax(F.softmax(output).cpu().data.numpy(),axis=1))
f1.update(f1_batch,images.size(0))
acc.update(acc_score,images.size(0))
print('\r',end='',flush=True)
message = '%s %5.1f %6.1f | %0.3f %0.3f %0.3f | %0.3f %0.3f %0.4f | %s %s %s | %s | %.2fdB' % (\
"val", i/len(val_loader) + epoch, epoch,
acc.avg,losses.avg,f1.avg,
train_metrics[0], train_metrics[1],train_metrics[2],
str(best_results[0])[:8],str(best_results[1])[:8],str(best_results[2])[:8],
time_to_str((timer() - start),'min'),psnr)
print(message, end='',flush=True)
log.write("\n")
return [acc.avg, losses.avg, f1.avg]
def test(test_loader, model, fold, ckpt, best_what, if_gen_txt):
save_dir = os.path.join('./preds_9', config.model_name)
os.makedirs(save_dir, exist_ok=True)
predicts = []
model.to(device)
model.eval()
for i, (image, visit, _) in tqdm(enumerate(test_loader)):
with torch.no_grad():
image = image.to(device)
visit = visit.to(device)
if len(image.size()) == 5:
bs, ncrops, c_i, h_i, w_i = image.size()
if len(visit.size()) == 4: bs, c_v, h_v, w_v = visit.size()
if len(visit.size()) == 5: bs, ncrops, c_v, h_v, w_v = visit.size()
image = image.reshape(-1, c_i, h_i, w_i)
visit = visit.reshape(-1, c_v, h_v, w_v).contiguous()
output, features = model(image,visit)
y_pred = output.view(bs, ncrops, -1).mean(1)
else: y_pred, _ = model(image,visit)
y_pred=F.softmax(y_pred).cpu().data.numpy()
predicts.append(y_pred)
pred_npy = np.concatenate(predicts)
save_name = '%s_val_%.4f_fold%d_%s.npy'%(ckpt["model_name"], ckpt["best_acc"], fold, best_what)
save_path = os.path.join(save_dir, save_name)
np.save(save_path, pred_npy)
if if_gen_txt:
gen_txt(pred_npy, ckpt, fold, best_what)
def test_ensemble_loss_acc(test_loader, fold, ckpt, best_what, if_gen_txt):
save_dir = os.path.join('./preds_9', config.model_name)
os.makedirs(save_dir, exist_ok=True)
loss_pred = np.load('%s/%s_val_%.4f_fold%d_%s.npy'
%(save_dir, ckpt[0]["model_name"], ckpt[0]["best_acc"], fold, 'best_loss'))
acc_pred = np.load('%s/%s_val_%.4f_fold%d_%s.npy'
%(save_dir, ckpt[1]["model_name"], ckpt[1]["best_acc"], fold, 'best_acc'))
pred_npy = (loss_pred + acc_pred) / 2
save_name = '%s_val_fold%d_%s.npy'%(ckpt[0]["model_name"], fold, best_what)
save_path = os.path.join(save_dir, save_name)
np.save(save_path, pred_npy)
if if_gen_txt:
gen_txt(pred_npy, ckpt[0], fold, best_what)
def training(train_data_list, val_data_list, test_files, fold):
os.makedirs(os.path.join(config.weights, config.model_name) + os.sep + str(fold), exist_ok=True)
os.makedirs(config.best_models, exist_ok=True)
### ---------- get model ------------------------------------------
model = FF3DNet(drop=0.5)
### ---------- set lr, opt, loss ------------------------------------------
img_params = list(map(id, model.img_encoder.parameters()))
rest_params = filter(lambda p: id(p) not in img_params, model.parameters())
params = [{'params': rest_params, 'lr': config.lr},
{'params': model.img_encoder.parameters(), 'lr': config.lr * 3},
]
optimizer = torch.optim.SGD(params, momentum=0.9, weight_decay=1e-4)
scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=config.epochs - 5, eta_min=config.lr / 100)
scheduler_warmup = GradualWarmupScheduler(optimizer, multiplier=10, total_epoch=5, after_scheduler=scheduler)
criterion = nn.CrossEntropyLoss().to(device)
if torch.cuda.device_count() > 1:
model = nn.DataParallel(model)
model.to(device)
best_results = [0, np.inf, 0]
val_metrics = [0, np.inf, 0]
### ---------- load dataset ------------------------------------------
train_gen = MultiModalDataset(train_data_list, config.train_data, config.train_vis, mode="train")
train_loader = DataLoader(train_gen, batch_size=config.batch_size, shuffle=True, pin_memory=True, num_workers=4)
val_gen = MultiModalDataset(val_data_list, config.train_data, config.train_vis, augument=False, mode="val")
val_loader = DataLoader(val_gen, batch_size=config.batch_size, shuffle=False, pin_memory=True, num_workers=4)
test_gen = MultiModalDataset(test_files, config.test_data, config.test_vis, augument=False, mode="test")
test_loader = DataLoader(test_gen, 20, shuffle=False, pin_memory=True, num_workers=4)
# --- train, val, test -------------------------
resume =False
start = timer()
if resume:
checkpoint_loss = torch.load('checkpoints/best_models/0616_coslr_55_fold_0_model_best_loss.pth.tar')
model.load_state_dict(checkpoint_loss["state_dict"])
test(test_loader, model, fold, checkpoint_loss, 'best_loss', False)
checkpoint_acc = torch.load('checkpoints/best_models/0616_coslr_55_fold_0_model_best_acc.pth.tar')
model.load_state_dict(checkpoint_acc["state_dict"])
test(test_loader, model, fold, checkpoint_acc, 'best_acc', False)
test_ensemble_loss_acc(test_loader, fold, [checkpoint_loss, checkpoint_acc], 'ensemble', True)
else:
### ---------- train loop ----------------
for epoch in range(0, config.epochs):
scheduler_warmup.step(metrics=val_metrics[0])
for param_group in optimizer.param_groups:
log.write(str(param_group['lr'])+'\n')
train_metrics = train(train_loader, model, criterion, optimizer, epoch, val_metrics, best_results, start)
# val_metrics_tta = evaluate(val_loader_tta,model,criterion,epoch,train_metrics,best_results,start)
val_metrics = evaluate(val_loader, model, criterion, epoch, train_metrics, best_results, start)
is_best_acc = val_metrics[0] > best_results[0]
best_results[0] = max(val_metrics[0], best_results[0])
is_best_loss = val_metrics[1] < best_results[1]
best_results[1] = min(val_metrics[1], best_results[1])
is_best_f1 = val_metrics[2] > best_results[2]
best_results[2] = max(val_metrics[2], best_results[2])
save_checkpoint({
"epoch": epoch + 1,
"model_name": config.model_name,
"state_dict": model.state_dict(),
"best_acc": best_results[0],
"best_loss": best_results[1],
"optimizer": optimizer.state_dict(),
"fold": fold,
"best_f1": best_results[2],
}, is_best_acc, is_best_loss, is_best_f1, fold)
print('\r', end='', flush=True)
log.write(
'%s %5.1f %6.1f | %0.3f %0.3f %0.3f | %0.3f %0.3f %0.3f | %s %s %s | %s' % ( \
"best", epoch, epoch,
train_metrics[0], train_metrics[1], train_metrics[2],
val_metrics[0], val_metrics[1], val_metrics[2],
str(best_results[0])[:8], str(best_results[1])[:8], str(best_results[2])[:8],
time_to_str((timer() - start), 'min'))
)
log.write("\n")
time.sleep(0.01)
### ---------- per fold ensemble best loss ckpt and best acc ckpt
checkpoint_loss = torch.load('checkpoints/best_models/%s_fold_%s_model_best_loss.pth.tar'% (config.model_name, str(fold)))
model.load_state_dict(checkpoint_loss["state_dict"])
test(test_loader, model, fold, checkpoint_loss, 'best_loss', False)
checkpoint_acc = torch.load('checkpoints/best_models/%s_fold_%s_model_best_acc.pth.tar'% (config.model_name, str(fold)))
model.load_state_dict(checkpoint_acc["state_dict"])
test(test_loader, model, fold, checkpoint_acc, 'best_acc', False)
test_ensemble_loss_acc(test_loader, fold, [checkpoint_loss, checkpoint_acc], 'ensemble', not config.k_fold)
### ----------- last kfold ensemble all before k ensemble ckpts
if config.k_fold and fold == config.num_kf:
mean_npy = np.zeros([10000, 9])
for i in range(1, config.num_kf+1):
checkpoint = torch.load('checkpoints/best_models/%s_fold_%s_model_best_loss.pth.tar'% (config.model_name, str(i)))
loss_pred = np.load('preds_9/%s/%s_val_fold%s_%s.npy'% (checkpoint["model_name"], checkpoint["model_name"], str(i), 'ensemble'))
mean_npy += loss_pred
mean_npy = mean_npy/config.num_kf
np.save('preds_9/%s/%s_val_fold%s_%s.npy'% (checkpoint["model_name"], checkpoint["model_name"], 'cv', 'ensemble'), mean_npy)
gen_txt(mean_npy, checkpoint, 'cv', 'ensemble')
def main():
fold = 0
all_files = pd.read_csv(config.train_csv)
test_files = pd.read_csv(config.test_csv)
### -------- kfold or not kfold ---------------
if not config.k_fold:
train_data_list, val_data_list = train_test_split(all_files, test_size=0.1, random_state = 2050)
training(train_data_list, val_data_list, test_files, fold)
else:
kf = StratifiedKFold(n_splits=config.num_kf, shuffle=True)
for train_index, test_index in kf.split(all_files, all_files.loc[:,"Target"]):
fold +=1
message_start_kf = "*" * 50 + " KFold_%d " % fold + "*" * 50+'\n'
log.write(message_start_kf)
train_data_list = all_files.loc[train_index]
val_data_list = all_files.loc[test_index]
training(train_data_list, val_data_list, test_files, fold)
if __name__ == "__main__":
main()
import os
import random
import pathlib
import cv2
import numpy as np
import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms as T
import pretrainedmodels
from config import config
from preprocess import *
random.seed(2050)
np.random.seed(2050)
torch.manual_seed(2050)
torch.cuda.manual_seed_all(2050)
class FCViewer(nn.Module):
def forward(self, x):
return x.view(x.size(0), -1)
class MultiModalDataset(Dataset):
def __init__(self, images_df, base_path, vis_path, augument=True, mode="train"):
if not isinstance(base_path, pathlib.Path):
base_path = pathlib.Path(base_path)
if not isinstance(vis_path, pathlib.Path):
vis_path = pathlib.Path(vis_path)
self.images_df = images_df.copy() # csv
self.augument = augument
self.vis_path = vis_path # vist npy path
self.images_df.Id = self.images_df.Id.apply(lambda x: base_path / str(x).zfill(6))
self.mode = mode
def __len__(self):
return len(self.images_df)
def __getitem__(self, index):
if not self.mode == "test":
y = self.images_df.iloc[index].Target
else:
y = str(self.images_df.iloc[index].Id.absolute())
### ------- image process --------------
X = self.read_images(index)
if self.augument:
X = process_image_iaa(X)
X = T.Compose([T.ToPILImage(), # pic (Tensor or numpy.ndarray): Image to be converted to PIL Image.
T.ToTensor(), # Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor.
])(X)
else:
if self.mode == "tta":
X = T.Compose([T.ToPILImage(),
T.TenCrop(80), # this is a list of PIL Images
T.Lambda(lambda crops: torch.stack([T.Compose([T.Resize(100),
T.ColorJitter(),
T.ToTensor()])(crop) for crop in crops]))
# returns a 4D tensor
])(X)
else:
X = T.Compose([T.ToPILImage(), # pic (Tensor or numpy.ndarray): Image to be converted to PIL Image.
T.ToTensor(), # Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor.
])(X)
### ------- vsiit process --------------
visit = self.read_npy(index) # 24x182
def norm(visit): # convert ori float npy to 0_1 to then to uint8
visit = visit.astype(np.float)
max = np.max(visit)
min = np.min(visit)
visit = (visit - min) / (max - min)
visit = (255 * visit).astype(np.uint8)
return visit, max, min
def denorm(visit, max, min): # convert normed uint8 to ~ori
visit = visit.astype(np.float) / 255
visit = visit * (max - min) + min
return visit
def std(visit): # distribution to gauss(0,1)
visit = visit.astype(np.float)
return (visit - visit.mean()) / visit.std()
def Rand_5channels(choice):
# rand = np.random.choice(6, 3)
# return [choice[i] for i in list(rand)]
return [random.choice([choice[0], choice[5]]),
random.choice([choice[1], choice[6]]),
random.choice([choice[2], choice[7]]),
random.choice([choice[3], choice[8]]),
random.choice([choice[4], choice[9]])]
visit = visit.reshape((24, 182, 1))
visit_l1 = visit / (np.sum(visit, 0, keepdims=True) + 1e-5)
visit_l2 = visit / (np.sum(visit ** 2, 0, keepdims=True) ** 0.5 + 1e-5)
visit_log = np.log1p(visit)
visit, max, min = norm(visit)
visit_0_1 = visit.astype(np.float) / 255.0
visit_std = std(visit)
def gen_new_visit(visit):
visit_denorm_l1 = denorm(visit, max, min) / (np.sum(denorm(visit, max, min), 0, keepdims=True) + 1e-5)
visit_denorm_l2 = denorm(visit, max, min) / (np.sum(denorm(visit, max, min) ** 2, 0, keepdims=True) ** 0.5 + 1e-5)
visit_denorm_log = np.log1p(denorm(visit, max, min))
visit_denorm_0_1 = norm(denorm(visit, max, min))[0].astype(np.float) / 255.0 # important?
visit_denorm_std = std(visit)
choices = [visit_log, visit_0_1, visit_std, visit_l1, visit_l2,
visit_denorm_log, visit_denorm_0_1, visit_denorm_std, visit_denorm_l1, visit_denorm_l2]
cat_list = Rand_5channels(choices)
visit = np.concatenate(cat_list, 2)
visit = T.ToTensor()(visit)
return visit
if self.augument:
visit = process_image_visit(visit)
visit = gen_new_visit(visit)
else:
if self.mode == "tta":
vst_list = []
visit_befor_aug = visit
for i in range(10):
visit = process_image_visit(visit_befor_aug)
visit = gen_new_visit(visit)
vst_list.append(visit)
visit = torch.stack(vst_list)
else:
visit = np.concatenate([visit_log, visit_0_1, visit_std, visit_l1, visit_l2], 2)
visit = T.ToTensor()(visit)
return X.float(), visit.float(), y
def read_images(self, index):
row = self.images_df.iloc[index]
filename = str(row.Id.absolute())
images = cv2.imread(filename + '.png')
return images
def read_npy(self, index):
row = self.images_df.iloc[index]
filename = os.path.basename(str(row.Id.absolute()))
pth = os.path.join(str(self.vis_path.absolute()), filename + '.npy')
visit = np.load(pth)
return visit
class FF3DNet(nn.Module):
def __init__(self, drop):
super().__init__()
img_model = pretrainedmodels.__dict__['resnet50'](num_classes=1000, pretrained='imagenet') # seresnext101
self.img_encoder = list(img_model.children())[:-2]
self.img_encoder.append(nn.AdaptiveAvgPool2d(1))
self.img_encoder = nn.Sequential(*self.img_encoder,
FCViewer(),
nn.Dropout(drop),
nn.Linear(2048, 256),
)
self.visit_conv = visit_Convnet()
#### cat 512->9
cat_dim = 256 + 256
self.ff_encoder = nn.Sequential(FCViewer(),
nn.ReLU(),
nn.Dropout(drop),
nn.Linear(cat_dim, cat_dim),
nn.ReLU(),
nn.Dropout(drop),
nn.Linear(cat_dim, config.num_classes)
)
def forward(self, x_img, x_vis):
x1 = self.img_encoder(x_img)
x2 = self.visit_conv(x_vis)
x3 = torch.cat([x1, x2], 1)
out = self.ff_encoder(x3)
return out, [x3, None]
class VisitConvNet(nn.Module):
def __init__(self):
super(VisitConvNet, self).__init__()
k = 1
layer1_1 = []
layer1_1.append(nn.Conv2d(5, 64 * k, kernel_size=(6, 1), stride=(6, 1)))
layer1_1.append(nn.BatchNorm2d(64 * k))
layer1_1.append(nn.ReLU())
layer1_1.append(nn.Conv2d(64 * k, 64 * k, kernel_size=(1, 7), stride=(1, 7)))
layer1_1.append(nn.BatchNorm2d(64 * k))
layer1_1.append(nn.ReLU())
self.cell_1_1 = nn.Sequential(*layer1_1)
layer1_2 = []
layer1_2.append(nn.Conv2d(5, 64 * k, kernel_size=(1, 7), stride=(1, 7), padding=(0, 0)))
layer1_2.append(nn.BatchNorm2d(64 * k))
layer1_2.append(nn.ReLU())
layer1_2.append(nn.Conv2d(64 * k, 64 * k, kernel_size=(6, 1), stride=(6, 1), padding=(0, 0)))
layer1_2.append(nn.BatchNorm2d(64 * k))
layer1_2.append(nn.ReLU())
self.cell_1_2 = nn.Sequential(*layer1_2)
layer1_3 = []
layer1_3.append(nn.Conv2d(5, 64 * k, kernel_size=(6, 5), stride=(6, 1), padding=(0, 2)))
layer1_3.append(nn.BatchNorm2d(64 * k))
layer1_3.append(nn.ReLU())
layer1_3.append(nn.Conv2d(64 * k, 64 * k, kernel_size=(5, 7), stride=(1, 7), padding=(2, 0)))
layer1_3.append(nn.BatchNorm2d(64 * k))
layer1_3.append(nn.ReLU())
self.cell_1_3 = nn.Sequential(*layer1_3)
layer1_4 = []
layer1_4.append(nn.Conv2d(5, 64 * k, kernel_size=(5, 7), stride=(1, 7), padding=(2, 0)))
layer1_4.append(nn.BatchNorm2d(64 * k))
layer1_4.append(nn.ReLU())
layer1_4.append(nn.Conv2d(64 * k, 64 * k, kernel_size=(6, 5), stride=(6, 1), padding=(0, 2)))
layer1_4.append(nn.BatchNorm2d(64 * k))
layer1_4.append(nn.ReLU())
self.cell_1_4 = nn.Sequential(*layer1_4)
layer2_1 = []
layer2_1.append(nn.Conv2d(256 * k, 256 * k, kernel_size=(3, 1), stride=(1, 1), padding=(1, 0)))
layer2_1.append(nn.BatchNorm2d(256 * k))
layer2_1.append(nn.ReLU())
layer2_1.append(nn.Dropout(0.1))
layer2_1.append(nn.Conv2d(256 * k, 256 * k, kernel_size=(1, 3), stride=(1, 1), padding=(0, 1)))
layer2_1.append(nn.BatchNorm2d(256 * k))
layer2_1.append(nn.ReLU())
layer2_1.append(nn.Dropout(0.1))
self.cell_2_1 = nn.Sequential(*layer2_1)
layer2_2 = []
layer2_2.append(nn.Conv2d(256 * k, 256 * k, kernel_size=(1, 1), stride=(1, 1), padding=(0, 0)))
layer2_2.append(nn.BatchNorm2d(256 * k))
layer2_2.append(nn.ReLU())
layer2_2.append(nn.Dropout(0.1))
layer2_2.append(nn.Conv2d(256 * k, 256 * k, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)))
layer2_2.append(nn.BatchNorm2d(256 * k))
layer2_2.append(nn.ReLU())
layer2_2.append(nn.Dropout(0.1))
self.cell_2_2 = nn.Sequential(*layer2_2)
layer3_1 = []
layer3_1.append(nn.Conv2d(512 * k, 512 * k, kernel_size=(3, 1), stride=(1, 1), padding=(1, 0)))
layer3_1.append(nn.BatchNorm2d(512 * k))
layer3_1.append(nn.ReLU())
layer3_1.append(nn.Dropout(0.2))
layer3_1.append(nn.Conv2d(512 * k, 512 * k, kernel_size=(1, 3), stride=(1, 1), padding=(0, 1)))
layer3_1.append(nn.BatchNorm2d(512 * k))
layer3_1.append(nn.ReLU())
layer3_1.append(nn.Dropout(0.2))
self.cell_3_1 = nn.Sequential(*layer3_1)
layer4_1 = []
layer4_1.append(nn.Conv2d(512 * k, 512 * k, kernel_size=(3, 1), stride=(1, 1), padding=(1, 0)))
layer4_1.append(nn.BatchNorm2d(512 * k))
layer4_1.append(nn.ReLU())
layer4_1.append(nn.Dropout(0.2))
layer4_1.append(nn.Conv2d(512 * k, 512 * k, kernel_size=(1, 3), stride=(1, 1), padding=(0, 1)))
layer4_1.append(nn.BatchNorm2d(512 * k))
layer4_1.append(nn.ReLU())
layer4_1.append(nn.Dropout(0.2))
self.cell_4_1 = nn.Sequential(*layer4_1)
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
elif isinstance(m, nn.BatchNorm2d):
nn.init.constant_(m.weight, 1)
nn.init.constant_(m.bias, 0)
fc_dim = 4 * 26 * 512 * k
self.fc = nn.Sequential(FCViewer(),
nn.Dropout(0.5),
nn.Linear(fc_dim, 512),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(512, 256)
)
def forward(self, x):
x1_1 = self.cell_1_1(x)
x1_2 = self.cell_1_2(x)
x1_3 = self.cell_1_3(x)
x1_4 = self.cell_1_4(x)
x_in = torch.cat([x1_1, x1_2, x1_3, x1_4], 1)
x_out_1 = self.cell_2_1(x_in)
x_out_2 = self.cell_2_2(x_in)
x_in = torch.cat([x_out_1, x_out_2], 1)
x_out = self.cell_3_1(x_in)
x_in = x_in + x_out
x_out = self.cell_4_1(x_in)
x_in = x_in + x_out
out = self.fc(x_in)
return out
def visit_Convnet():
return VisitConvNet()
import os
import sys
import torch
import shutil
from config import config
# save best acc and best loss model
def save_checkpoint(state, is_best_acc,is_best_loss,is_best_f1,fold):
filename = config.weights + config.model_name + os.sep +str(fold) + os.sep + "checkpoint.pth.tar"
torch.save(state, filename)
if is_best_acc:
shutil.copyfile(filename,"%s/%s_fold_%s_model_best_acc.pth.tar"%(config.best_models,config.model_name,str(fold)))
if is_best_loss:
shutil.copyfile(filename,"%s/%s_fold_%s_model_best_loss.pth.tar"%(config.best_models,config.model_name,str(fold)))
# if is_best_f1:
# shutil.copyfile(filename,"%s/%s_fold_%s_model_best_f1.pth.tar"%(config.best_models,config.model_name,str(fold)))
# evaluate meters
class AverageMeter(object):
"""Computes and stores the average and current value"""
def __init__(self):
self.reset()
def reset(self):
self.val = 0
self.avg = 0
self.sum = 0
self.count = 0
def update(self, val, n=1):
self.val = val
self.sum += val * n
self.count += n
self.avg = self.sum / self.count
# print logger
class Logger(object):
def __init__(self):
self.terminal = sys.stdout #stdout
self.file = None
def open(self, file, mode=None):
if mode is None: mode ='w'
self.file = open(file, mode)
def write(self, message, is_terminal=1, is_file=1 ):
if '\r' in message: is_file=0
if is_terminal == 1:
self.terminal.write(message)
self.terminal.flush()
#time.sleep(1)
if is_file == 1:
self.file.write(message)
self.file.flush()
def flush(self):
# this flush method is needed for python 3 compatibility.
# this handles the flush command by doing nothing.
# you might want to specify some extra behavior here.
pass
def get_learning_rate(optimizer):
lr=[]
for param_group in optimizer.param_groups:
lr +=[ param_group['lr'] ]
#assert(len(lr)==1) #we support only one param_group
lr = lr[0]
return lr
def time_to_str(t, mode='min'):
if mode=='min':
t = int(t)/60
hr = t//60
min = t%60
return '%2d hr %02d min'%(hr,min)
elif mode=='sec':
t = int(t)
min = t//60
sec = t%60
return '%2d min %02d sec'%(min,sec)
else:
raise NotImplementedError
#coding=utf-8
import warnings
class DefaultConfigs(object):
env='default'
model_name = "0626_debug"
train_data = "./data/train/" # where is your train images data
test_data = "./data/test/" # your test data
train_vis="./data/npy/train_visit" # where is your train visits data
test_vis="./data/npy/test_visit"
load_model_path = None
weights = "./checkpoints/"
best_models = "./checkpoints/best_models/"
train_csv = "./preliminary/train.csv"
test_csv = "./preliminary/test.csv"
num_kf = 10
k_fold = False
mix_up = False
num_classes = 9
lr = 0.0004
batch_size = 96
epochs = 60
step =20
alpha = 0.5
def parse(self, kwargs):
"""
update config by kwargs
"""
for k, v in kwargs.items():
if not hasattr(self, k):
warnings.warn("Warning: opt has not attribut %s" % k)
setattr(self, k, v)
print('user config:')
for k, v in self.__class__.__dict__.items():
if not k.startswith('__'):
print(k, getattr(self, k))
DefaultConfigs.parse = parse
config = DefaultConfigs()
progress.py
import imgaug as ia
from imgaug import augmenters as iaa
def process_image_iaa(img):
sometimes = lambda aug: iaa.Sometimes(0.5, aug)
seq = iaa.Sequential([
sometimes(iaa.Crop(percent=(0, 0.2))),
sometimes(iaa.GammaContrast((0.5, 1.5))),
sometimes(iaa.Sharpen(alpha=(0, 0.5), lightness=(0.8, 1.2))),
sometimes(iaa.Affine(
scale={"x": (0.8, 1.2), "y": (0.8, 1.2)},# scale images to 80-120% of their size, individually per axis
translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}, # translate by -20 to +20 percent (per axis)
rotate=(-45, 45), # rotate by -45 to +45 degrees
shear=(-16, 16), # shear by -16 to +16 degrees
order=[0, 1], # use nearest neighbour or bilinear interpolation (fast)
cval=(0, 255), # if mode is constant, use a cval between 0 and 255
mode=ia.ALL # use any of scikit-image's warping modes (see 2nd image from the top for examples)
)),
iaa.Fliplr(0.5),
iaa.Flipud(0.5),
iaa.SomeOf((0, 4), [
iaa.Affine(rotate=90),
iaa.Affine(rotate=180),
iaa.Affine(rotate=270),
]),
sometimes(iaa.OneOf([
iaa.GaussianBlur((0, 0.5)), # blur images with a sigma between 0 and 3.0
iaa.AverageBlur(k=(2, 5)), # blur image using local means with kernel sizes between 2 and 7
iaa.MedianBlur(k=(3, 5)), # blur image using local medians with kernel sizes between 2 and 7
])),
], random_order=True)
image_aug = seq.augment_image(img)
return image_aug
def process_image_visit(vst):
sometimes = lambda aug: iaa.Sometimes(0.5, aug)
seq = iaa.Sequential([
sometimes(iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.02 * 255), per_channel=0.5)),
sometimes(iaa.GammaContrast((0.5, 1.5))), ########### we add to equalization
sometimes(iaa.Sharpen(alpha=(0, 0.5), lightness=(0.8, 1.2))),
sometimes(iaa.Add((-5, 5), per_channel=0.5)), # change brightness of images (by -10 to 10 of original value)
sometimes(iaa.OneOf([
iaa.GaussianBlur((0, 0.5)), # blur images with a sigma between 0 and 3.0
# iaa.AverageBlur(k=(2, 5)), # blur image using local means with kernel sizes between 2 and 7
# iaa.MedianBlur(k=(3, 5)), # blur image using local medians with kernel sizes between 2 and 7
])),
], random_order=True)
visit_aug = seq.augment_image(vst)
return visit_aug