def main_nn(num_epochs, working_device): model = pretrainedmodels.xception(num_classes=1000, pretrained='imagenet') model.last_linear.out_features = 4 print(model) model = nn.Sequential( nn.Conv2d(in_channels=5, out_channels=3, kernel_size=3, stride=3, padding=0, bias=False), model) if torch.cuda.is_available(): #model = torch.nn.DataParallel(model, device_ids=[0,1,2]) #multi gpu model.to(torch.device(working_device)) loss_function = nn.NLLLoss() #optimizer = optim.Adam(model.parameters()) params = model.state_dict() params.keys() for name, param in model.named_parameters(): if param.requires_grad and '1.layer1' in name: param.requires_grad = False if param.requires_grad and '1.layer2' in name: param.requires_grad = False optimizer = optim.Adam(filter(lambda p: p.requires_grad, model.parameters()), lr=0.001) return model, loss_function, optimizer
def get_xception(): model = pretrainedmodels.xception(num_classes=1000, pretrained="imagenet") model.last_linear = torch.nn.Sequential( torch.nn.Dropout(), nn.Linear(in_features=model.last_linear.in_features, out_features=config.NUM_CLASSES)) return model
def __init__(self,num_classes = 60,model_name='resnet50'): super(VA, self).__init__() self.num_classes = num_classes self.conv1 = nn.Conv2d(3, 128, kernel_size=5, stride=2, bias=False) self.bn1 = nn.BatchNorm2d(128) self.relu1 = nn.ReLU(inplace=True) self.conv2 = nn.Conv2d(128, 128, kernel_size=5, stride=2, bias=False) self.bn2 = nn.BatchNorm2d(128) self.relu2 = nn.ReLU(inplace=True) self.avepool = nn.MaxPool2d(7) self.fc = nn.Linear(6272, 6) if model_name=='resnet50': self.classifier = models.resnet50(pretrained=True) elif model_name=='resnext50_32x4d': self.classifier = models.resnext50_32x4d(pretrained=True) elif model_name=='resnext101_32x8d': self.classifier = models.resnext101_32x8d(pretrained=True) elif model_name=='wide_resnet50_2': self.classifier = models.wide_resnet50_2(pretrained=True) elif model_name=='wide_resnet101_2': self.classifier = models.wide_resnet101_2(pretrained=True) elif model_name=='xception': self.classifier = pretrainedmodels.xception(num_classes=1000, pretrained='imagenet') total_params = 0 for nname, pparameter in self.classifier.named_parameters(): if not pparameter.requires_grad: continue param = pparameter.numel() total_params+=param print(f"Total Trainable Params: {total_params}") self.init_weight()
def __init__(self, num_classes): super(Xception, self).__init__() self.name = "Xception" self.pretrained_model = model_zoo.xception() cfg.mean = self.pretrained_model.mean cfg.std = self.pretrained_model.std self.fc = nn.Linear(2048, num_classes)
def __init__(self, input_size=128, num_classes=340, pretrained='imagenet', dropout_rate=0.): super(GeneralizedXception, self).__init__() self.pretrained_model = xception(pretrained=pretrained) self.features = self.pretrained_model.features self.relu = nn.ReLU() self.avg_pool = nn.AvgPool2d(input_size // 32, stride=1, padding=0) self.dropout = nn.Dropout(p=dropout_rate) self.last_linear = nn.Linear(2048, num_classes)
def xception(): """ From: https://github.com/Cadene/pretrained-models.pytorch Interpretation of Inception modules in convolutional neural networks as being an intermediate step in-between regular convolution and the depthwise separable convolution operation https://arxiv.org/abs/1610.02357 Params 24M, size 87MB, Top-1 acc 79.000, Top-5 acc 94.500 """ return pretrainedmodels.xception(num_classes=1000, pretrained="imagenet")
def nets(model, num_class): if model == 'inceptionv4': model = ptm.inceptionv4(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, num_class) return model if model == 'senet154': model = ptm.senet154(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, num_class) return model if model == 'pnasnet': model = ptm.pnasnet5large(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, num_class) return model if model == 'xception': model = ptm.xception(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, num_class) return model if model == 'incepresv2': model = ptm.inceptionresnetv2(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, num_class) return model if model == 'resnet152': model = models.resnet152(pretrained=True) model.fc = nn.Linear(2048, num_class) return model if model == 'se_resxt101': model = ptm.se_resnext101_32x4d(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, num_class) return model if model == 'nasnet': model = ptm.nasnetalarge(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, num_class) return model if model == 'dpn': # 224 input size model = ptm.dpn107(num_classes=1000, pretrained='imagenet+5k') model.last_linear = nn.Conv2d(model.last_linear.in_channels, num_class, kernel_size=1, bias=True) return model if model == 'resnext101':# 320 input size model = torch.hub.load('facebookresearch/WSL-Images', 'resnext101_32x16d_wsl') model.fc = nn.Linear(2048, num_class) return model
def __init__(self, model_name, num_classes=2, dropout=0.0, pretrained=True): super(TransferModel, self).__init__() self.model_name = model_name if model_name == 'xception': self.image_size = 299 if pretrained: pretrained = 'imagenet' self.model = pretrainedmodels.xception(pretrained=pretrained) # Replace fc num_ftrs = self.model.last_linear.in_features if not dropout: self.model.last_linear = nn.Linear(num_ftrs, num_classes) else: print('Using dropout', dropout) self.model.last_linear = nn.Sequential( nn.Dropout(p=dropout), nn.Linear(num_ftrs, num_classes)) elif model_name == 'resnet50' or model_name == 'resnet18': self.image_size = 224 if model_name == 'resnet50': self.model = torchvision.models.resnet50(pretrained) if model_name == 'resnet18': self.model = torchvision.models.resnet18(pretrained) # Replace fc num_ftrs = self.model.fc.in_features if not dropout: self.model.fc = nn.Linear(num_ftrs, num_classes) else: self.model.fc = nn.Sequential(nn.Dropout(p=dropout), nn.Linear(num_ftrs, num_classes)) elif model_name == 'InceptionResnetV1': from facenet_pytorch import InceptionResnetV1 self.image_size = 160 if pretrained: pretrained = 'vggface2' self.model = InceptionResnetV1(pretrained=pretrained, classify=True, num_classes=2) elif model_name == 'SPPNet': from network.SPPNet import SPPNet self.image_size = 224 self.model = SPPNet(backbone=50, num_class=num_classes, pretrained=pretrained) elif model_name == 'ResNetXt': self.image_size = 224 self.model = torchvision.models.resnext50_32x4d( pretrained=pretrained) self.model.fc = nn.Linear(2048, num_classes) else: raise Exception('Choose valid model, e.g. resnet50')
def __init__(self): super().__init__() self.xception = xception() self.xception.eval() for p in self.xception.parameters(): p.requires_grad = False self.cnn1 = nn.Conv2d(in_channels=2048, out_channels=512, kernel_size=3, stride=1) self.bn = nn.BatchNorm2d(num_features=512) # B x 256 x 4 x 4 self.fc1 = nn.Linear(18432, 256) self.fc2 = nn.Linear(256, 1)
def getNetwork(args): if (args.net_type == 'alexnet'): net = models.alexnet(pretrained=args.finetune) file_name = 'alexnet' elif (args.net_type == 'vggnet'): if (args.depth == 11): net = models.vgg11(pretrained=args.finetune) elif (args.depth == 13): net = models.vgg13(pretrained=args.finetune) elif (args.depth == 16): net = models.vgg16(pretrained=args.finetune) elif (args.depth == 19): net = models.vgg19(pretrained=args.finetune) else: print( 'Error : VGGnet should have depth of either [11, 13, 16, 19]') sys.exit(1) file_name = 'vgg-%s' % (args.depth) elif (args.net_type == 'densenet'): if (args.depth == 121): net = models.densenet121(pretrained=args.finetune) elif (args.depth == 161): net = models.densenet161(pretrained=args.finetune) elif (args.depth == 169): net = models.densenet169(pretrained=args.finetune) file_name = 'densenet-%s' % (args.depth) elif (args.net_type == 'resnet'): net = networks.resnet(args.finetune, args.depth) file_name = 'resnet-%s' % (args.depth) elif (args.net_type == 'xception'): net = pretrainedmodels.xception(num_classes=1000, pretrained='imagenet') file_name = 'xception' elif (args.net_type == 'inception'): net = models.inception_v3(num_classes=1000, pretrained=args.finetune) file_name = 'inception' else: print( 'Error : Network should be either [alexnet / vggnet / resnet / densenet]' ) sys.exit(1) return net, file_name
def main_nn(working_device): model = pretrainedmodels.xception(num_classes=1000, pretrained='imagenet') model.last_linear.out_features = 4 print(model) model = nn.Sequential( nn.Conv2d(in_channels=5, out_channels=3, kernel_size=3, stride=3, padding=0, bias=False), model) if torch.cuda.is_available(): #model = torch.nn.DataParallel(model, device_ids=[0,1,2]) #multi gpu model.to(torch.device(working_device)) loss_function = nn.NLLLoss() optimizer = optim.Adam(model.parameters()) return model, loss_function, optimizer
def xception(num_classes, feature_extract, use_pretrained=True): """Funkcja zwracająca model xception :param num_classes: liczba szukanych cech :type num_classes: int :param feature_extract: czy ekstrachować cechy :type feature_extract: bool :param use_pretrained: czy używać wstępnie przetrenowanego modelu :type use_pretrained: bool :return: wygenerowny model,wielkość wejścia modelu,sugerowana średnia do normalizacji,sugerowane odchylenie standardowe do normalizacji :rtype: model, int, float, float """ model = pretrainedmodels.xception(num_classes=1000, pretrained='imagenet') set_parameter_requires_grad(model, feature_extract) num_ftrs = model.last_linear.in_features model.last_linear = nn.Sequential(nn.Linear(num_ftrs, num_classes), nn.Sigmoid()) input_size = 299 mean, std = [0.5, 0.5, 0.5], [0.5, 0.5, 0.5] return model, input_size, mean, std
def main(): # 随机种子 np.random.seed(666) torch.manual_seed(666) torch.cuda.manual_seed_all(666) random.seed(666) # 获取当前文件名,用于创建模型及结果文件的目录 file_name = os.path.basename(__file__).split('.')[0] # 创建保存模型和结果的文件夹 if not os.path.exists('./model/%s' % file_name): os.makedirs('./model/%s' % file_name) if not os.path.exists('./result/%s' % file_name): os.makedirs('./result/%s' % file_name) # 创建日志文件 if not os.path.exists('./result/%s.txt' % file_name): with open('./result/%s.txt' % file_name, 'w') as acc_file: pass with open('./result/%s.txt' % file_name, 'a') as acc_file: acc_file.write('\n%s %s\n' % (time.strftime( "%Y-%m-%d %H:%M:%S", time.localtime(time.time())), file_name)) # 默认使用PIL读图 def default_loader(path): # return Image.open(path) return Image.open(path).convert('RGB') # 训练集图片读取 class TrainDataset(Dataset): def __init__(self, label_list, transform=None, target_transform=None, loader=default_loader): imgs = [] for index, row in label_list.iterrows(): imgs.append((row['img_path'], row['label'])) self.imgs = imgs self.transform = transform self.target_transform = target_transform self.loader = loader def __getitem__(self, index): filename, label = self.imgs[index] img = self.loader(filename) if self.transform is not None: img = self.transform(img) return img, label def __len__(self): return len(self.imgs) # 验证集图片读取 class ValDataset(Dataset): def __init__(self, label_list, transform=None, target_transform=None, loader=default_loader): imgs = [] for index, row in label_list.iterrows(): imgs.append((row['img_path'], row['label'])) self.imgs = imgs self.transform = transform self.target_transform = target_transform self.loader = loader def __getitem__(self, index): filename, label = self.imgs[index] img = self.loader(filename) if self.transform is not None: img = self.transform(img) return img, label def __len__(self): return len(self.imgs) # 测试集图片读取 class TestDataset(Dataset): def __init__(self, label_list, transform=None, target_transform=None, loader=default_loader): imgs = [] for index, row in label_list.iterrows(): imgs.append((row['img_path'])) self.imgs = imgs self.transform = transform self.target_transform = target_transform self.loader = loader def __getitem__(self, index): filename = self.imgs[index] img = self.loader(filename) if self.transform is not None: img = self.transform(img) return img, filename def __len__(self): return len(self.imgs) # 数据增强:在给定角度中随机进行旋转 class FixedRotation(object): def __init__(self, angles): self.angles = angles def __call__(self, img): return fixed_rotate(img, self.angles) def fixed_rotate(img, angles): angles = list(angles) angles_num = len(angles) index = random.randint(0, angles_num - 1) return img.rotate(angles[index]) # 训练函数 def train(train_loader, model, criterion, optimizer, epoch): batch_time = AverageMeter() data_time = AverageMeter() losses = AverageMeter() acc = AverageMeter() # switch to train mode model.train() end = time.time() # 从训练集迭代器中获取训练数据 for i, (images, target) in enumerate(train_loader): # 评估图片读取耗时 data_time.update(time.time() - end) # 将图片和标签转化为tensor image_var = torch.tensor(images).cuda(async=True) label = torch.tensor(target).cuda(async=True) # 将图片输入网络,前传,生成预测值 y_pred = model(image_var) # 计算loss loss = criterion(y_pred, label) losses.update(loss.item(), images.size(0)) # 计算top1正确率 prec, PRED_COUNT = accuracy(y_pred.data, target, topk=(1, 1)) acc.update(prec, PRED_COUNT) # 对梯度进行反向传播,使用随机梯度下降更新网络权重 optimizer.zero_grad() loss.backward() optimizer.step() # 评估训练耗时 batch_time.update(time.time() - end) end = time.time() # 打印耗时与结果 if i % print_freq == 0: print('Epoch: [{0}][{1}/{2}]\t' 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' 'Data {data_time.val:.3f} ({data_time.avg:.3f})\t' 'Loss {loss.val:.4f} ({loss.avg:.4f})\t' 'Accuray {acc.val:.3f} ({acc.avg:.3f})'.format( epoch, i, len(train_loader), batch_time=batch_time, data_time=data_time, loss=losses, acc=acc)) # 验证函数 def validate(val_loader, model, criterion): batch_time = AverageMeter() losses = AverageMeter() acc = AverageMeter() # switch to evaluate mode model.eval() end = time.time() for i, (images, labels) in enumerate(val_loader): image_var = torch.tensor(images).cuda(async=True) target = torch.tensor(labels).cuda(async=True) # 图片前传。验证和测试时不需要更新网络权重,所以使用torch.no_grad(),表示不计算梯度 with torch.no_grad(): y_pred = model(image_var) loss = criterion(y_pred, target) # measure accuracy and record loss prec, PRED_COUNT = accuracy(y_pred.data, labels, topk=(1, 1)) losses.update(loss.item(), images.size(0)) acc.update(prec, PRED_COUNT) # measure elapsed time batch_time.update(time.time() - end) end = time.time() if i % print_freq == 0: print('TrainVal: [{0}/{1}]\t' 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' 'Loss {loss.val:.4f} ({loss.avg:.4f})\t' 'Accuray {acc.val:.3f} ({acc.avg:.3f})'.format( i, len(val_loader), batch_time=batch_time, loss=losses, acc=acc)) print(' * Accuray {acc.avg:.3f}'.format(acc=acc), '(Previous Best Acc: %.3f)' % best_precision, ' * Loss {loss.avg:.3f}'.format(loss=losses), 'Previous Lowest Loss: %.3f)' % lowest_loss) return acc.avg, losses.avg # 测试函数 def test(test_loader, model): csv_map = OrderedDict({'filename': [], 'probability': []}) # switch to evaluate mode model.eval() for i, (images, filepath) in enumerate(tqdm(test_loader)): # bs, ncrops, c, h, w = images.size() filepath = [os.path.basename(i) for i in filepath] image_var = torch.tensor(images, requires_grad=False) # for pytorch 0.4 with torch.no_grad(): y_pred = model(image_var) # 使用softmax函数将图片预测结果转换成类别概率 smax = nn.Softmax(1) smax_out = smax(y_pred) # 保存图片名称与预测概率 csv_map['filename'].extend(filepath) for output in smax_out: prob = ';'.join([str(i) for i in output.data.tolist()]) csv_map['probability'].append(prob) result = pd.DataFrame(csv_map) result['probability'] = result['probability'].map( lambda x: [float(i) for i in x.split(';')]) # 转换成提交样例中的格式 sub_filename, sub_label = [], [] prob_list = [] for index, row in result.iterrows(): sub_filename.append(row['filename']) pred_label = np.argmax(row['probability']) prob_list.append([row['filename']] + row['probability']) if pred_label == 0: sub_label.append('norm') else: sub_label.append('defect%d' % pred_label) # 生成结果文件,保存在result文件夹中,可用于直接提交 pdb.set_trace() submission = pd.DataFrame({ 'filename': sub_filename, 'label': sub_label }) submission.to_csv('./result/%s/submission.csv' % file_name, header=None, index=False) prob_map = pd.DataFrame(prob_list) prob_map.to_csv('./result/%s/prob_map.csv' % file_name, header=False, index=False) return # 保存最新模型以及最优模型 def save_checkpoint(state, is_best, is_lowest_loss, filename='./model/%s/checkpoint.pth.tar' % file_name): torch.save(state, filename) if is_best: shutil.copyfile(filename, './model/%s/model_best.pth.tar' % file_name) if is_lowest_loss: shutil.copyfile(filename, './model/%s/lowest_loss.pth.tar' % file_name) # 用于计算精度和时间的变化 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 # 学习率衰减:lr = lr / lr_decay def adjust_learning_rate(): nonlocal lr lr = lr / lr_decay return optim.Adam(model.parameters(), lr, weight_decay=weight_decay, amsgrad=True) # 计算top K准确率 def accuracy(y_pred, y_actual, topk=(1, )): """Computes the precision@k for the specified values of k""" final_acc = 0 maxk = max(topk) # for prob_threshold in np.arange(0, 1, 0.01): PRED_COUNT = y_actual.size(0) PRED_CORRECT_COUNT = 0 prob, pred = y_pred.topk(maxk, 1, True, True) # prob = np.where(prob > prob_threshold, prob, 0) for j in range(pred.size(0)): if int(y_actual[j]) == int(pred[j]): PRED_CORRECT_COUNT += 1 if PRED_COUNT == 0: final_acc = 0 else: final_acc = PRED_CORRECT_COUNT / PRED_COUNT return final_acc * 100, PRED_COUNT # 程序主体 # 设定GPU ID os.environ["CUDA_VISIBLE_DEVICES"] = '0, 1' # 小数据集上,batch size不易过大。如出现out of memory,应调小batch size batch_size = 24 # 进程数量,最好不要超过电脑最大进程数。windows下报错可以改为workers=0 workers = 0 # epoch数量,分stage进行,跑完一个stage后降低学习率进入下一个stage stage_epochs = [20, 10, 10] # 初始学习率 lr = 1e-4 # 学习率衰减系数 (new_lr = lr / lr_decay) lr_decay = 5 # 正则化系数 weight_decay = 1e-4 # 参数初始化 stage = 0 start_epoch = 0 total_epochs = sum(stage_epochs) best_precision = 0 lowest_loss = 100 # 设定打印频率,即多少step打印一次,用于观察loss和acc的实时变化 # 打印结果中,括号前面为实时loss和acc,括号内部为epoch内平均loss和acc print_freq = 1 # 验证集比例 val_ratio = 0.12 # 是否只验证,不训练 evaluate = False # 是否从断点继续跑 resume = False # 创建Xception模型 # xception.pretrained_settings['xception']['imagenet']['num_classes']=12 model = xception() model.last_linear = nn.Linear(2048, 12) model = torch.nn.DataParallel(model).cuda() # optionally resume from a checkpoint if resume: checkpoint_path = './model/%s/checkpoint.pth.tar' % file_name if os.path.isfile(checkpoint_path): print("=> loading checkpoint '{}'".format(checkpoint_path)) checkpoint = torch.load(checkpoint_path) start_epoch = checkpoint['epoch'] + 1 best_precision = checkpoint['best_precision'] lowest_loss = checkpoint['lowest_loss'] stage = checkpoint['stage'] lr = checkpoint['lr'] model.load_state_dict(checkpoint['state_dict']) # 如果中断点恰好为转换stage的点,需要特殊处理 if start_epoch in np.cumsum(stage_epochs)[:-1]: stage += 1 optimizer = adjust_learning_rate() model.load_state_dict( torch.load('./model/%s/model_best.pth.tar' % file_name)['state_dict']) print("=> loaded checkpoint (epoch {})".format( checkpoint['epoch'])) else: print("=> no checkpoint found at '{}'".format(checkpoint_path)) # 读取训练图片列表 all_data = pd.read_csv('data/label.csv') # 分离训练集和测试集,stratify参数用于分层抽样 train_data_list, val_data_list = train_test_split( all_data, test_size=val_ratio, random_state=666, stratify=all_data['label']) # 读取测试图片列表 test_data_list = pd.read_csv('data/test.csv') # 图片归一化,由于采用ImageNet预训练网络,因此这里直接采用ImageNet网络的参数 normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # 训练集图片变换,输入网络的尺寸为299*299 train_data = TrainDataset( train_data_list, transform=transforms.Compose([ transforms.Resize((320, 320)), transforms.ColorJitter(0.15, 0.15, 0.15, 0.075), transforms.RandomHorizontalFlip(), transforms.RandomGrayscale(), # transforms.RandomRotation(20), FixedRotation([0, 90, 180, 270]), transforms.RandomCrop(299), transforms.ToTensor(), normalize, ])) # 验证集图片变换 val_data = ValDataset(val_data_list, transform=transforms.Compose([ transforms.Resize((320, 320)), transforms.CenterCrop(299), transforms.ToTensor(), normalize, ])) # 测试集图片变换 test_data = TestDataset(test_data_list, transform=transforms.Compose([ transforms.Resize((320, 320)), transforms.CenterCrop(299), transforms.ToTensor(), normalize, ])) # 生成图片迭代器 train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True, pin_memory=True, num_workers=workers) val_loader = DataLoader(val_data, batch_size=batch_size * 2, shuffle=False, pin_memory=False, num_workers=workers) test_loader = DataLoader(test_data, batch_size=batch_size * 2, shuffle=False, pin_memory=False, num_workers=workers) # 使用交叉熵损失函数 criterion = nn.CrossEntropyLoss().cuda() # 优化器,使用带amsgrad的Adam optimizer = optim.Adam(model.parameters(), lr, weight_decay=weight_decay, amsgrad=True) if evaluate: pass validate(val_loader, model, criterion) else: # 开始训练 for epoch in range(start_epoch, total_epochs): # train for one epoch train(train_loader, model, criterion, optimizer, epoch) # evaluate on validation set precision, avg_loss = validate(val_loader, model, criterion) # 在日志文件中记录每个epoch的精度和loss with open('./result/%s.txt' % file_name, 'a') as acc_file: acc_file.write('Epoch: %2d, Precision: %.8f, Loss: %.8f\n' % (epoch, precision, avg_loss)) # 记录最高精度与最低loss,保存最新模型与最佳模型 is_best = precision > best_precision is_lowest_loss = avg_loss < lowest_loss best_precision = max(precision, best_precision) lowest_loss = min(avg_loss, lowest_loss) state = { 'epoch': epoch, 'state_dict': model.state_dict(), 'best_precision': best_precision, 'lowest_loss': lowest_loss, 'stage': stage, 'lr': lr, } save_checkpoint(state, is_best, is_lowest_loss) # 判断是否进行下一个stage if (epoch + 1) in np.cumsum(stage_epochs)[:-1]: stage += 1 optimizer = adjust_learning_rate() model.load_state_dict( torch.load('./model/%s/model_best.pth.tar' % file_name)['state_dict']) print('Step into next stage') with open('./result/%s.txt' % file_name, 'a') as acc_file: acc_file.write( '---------------Step into next stage----------------\n' ) # 记录线下最佳分数 with open('./result/%s.txt' % file_name, 'a') as acc_file: acc_file.write('* best acc: %.8f %s\n' % (best_precision, os.path.basename(__file__))) with open('./result/best_acc.txt', 'a') as acc_file: acc_file.write( '%s * best acc: %.8f %s\n' % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime( time.time())), best_precision, os.path.basename(__file__))) # 读取最佳模型,预测测试集,并生成可直接提交的结果文件 best_model = torch.load('./model/%s/checkpoint.pth.tar' % file_name) model.load_state_dict(best_model['state_dict']) test(test_loader=test_loader, model=model) # 释放GPU缓存 torch.cuda.empty_cache()
def __init__(self, num_classes, pretrained="xception-43020ad28.pth"): super().__init__() self.net = xception(pretrained=pretrained) self.avg_pool = AdaptiveConcatPool2d() self.net.last_linear = nn.Sequential(Flatten(), SEBlock(2048 * 2), nn.Linear(2048 * 2, num_classes))
def Model_builder(configer): model_name = configer.model['name'] No_classes = configer.dataset_cfg["id_cfg"]["num_classes"] model_pretrained = configer.model['pretrained'] model_dataparallel = configer.model["DataParallel"] model_gpu_replica = configer.model["Multi_GPU_replica"] gpu_ids = configer.train_cfg["gpu"] if model_name == "Inceptionv3": model = PM.inceptionv3(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "Xception": model = PM.xception(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "VGG_19": model = PM.vgg19(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "Resnet18": model = PM.resnet18(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "Resnet50": model = PM.resnet50(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "Resnet101": model = PM.resnet101(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "Resnet152": model = PM.resnet152(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "Resnet34": model = PM.resnet34(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "Densenet121": model = PM.densenet121(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "ResNeXt101-32": model = PM.resnext101_32x4d(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "ResNeXt101-64": model = PM.resnext101_64x4d(num_classes=1000, pretrained=model_pretrained) d = model.last_linear.in_features model.last_linear = nn.Linear(d, No_classes) elif model_name == "MobilenetV2": model = MobileNetV2(n_class=No_classes) else: raise ImportError("Model Architecture not supported") # Performing Data Parallelism if configured if model_dataparallel: model = torch.nn.DataParallel(model.to(device), device_ids=gpu_ids) elif model_gpu_replica: torch.distributed.init_process_group(backend='nccl', world_size=1, rank=1) model = torch.nn.DistributedDataParallel(model.to(device), device_ids=gpu_ids) else: model = model.to(device) print('---------- Model Loaded') return model
def __init__(self): super().__init__() self.base_model = pretrainedmodels.xception() self.base_model.conv1 = nn.Conv2d(1, 32, 3, 2, 0, bias=False)
#!/usr/bin/env python # coding=utf-8 import re import torch import wolframclient.serializers as wxf from pretrainedmodels import xception # manually fix this first model = xception(num_classes=1000, pretrained=False).cpu() net = list(model.modules()) params = model.state_dict() # remove `bn.num_batches_tracked` because it can broke the model npy = { key: value.numpy() for key, value in params.items() if not re.match('.*_tracked$', key) } wxf.export(npy, 'imagenet_xception.wxf', target_format='wxf') # torch.save(model, 'imagenet_xception.pth')
testdir = "../imgs_resized/test/" test_loader = data.DataLoader(TestImageFolder( testdir, transforms.Compose([ transforms.Scale(256), transforms.CenterCrop(224), transforms.ToTensor(), normalize, ])), batch_size=1, shuffle=False, num_workers=1, pin_memory=False) model = pretrainedmodels.xception(num_classes=1000) #model = models.squeezenet1_1() num_ftrs = model.last_linear.in_features model.last_linear = nn.Linear(num_ftrs, 6) #model.classifier = nn.Sequential( # nn.Dropout(p=0.5), # nn.Conv2d(512, 6, kernel_size=1), # nn.ReLU(inplace=True), # nn.AdaptiveAvgPool2d((1, 1)) # ) #model.num_classes = 6 model.load_state_dict(torch.load('best_model_xcep_cutout_full.pt')) model.cuda() model.eval()
def main(train_root, train_csv, val_root, val_csv, test_root, test_csv, epochs, aug, model_name, batch_size, num_workers, val_samples, test_samples, early_stopping_patience, limit_data, images_per_epoch, split_id, _run): assert(model_name in ('inceptionv4', 'resnet152', 'densenet161', 'senet154', 'pnasnet5large', 'nasnetalarge', 'xception', 'squeezenet', 'resnext', 'dpn', 'inceptionresnetv2', 'mobilenetv2')) cv2.setNumThreads(0) AUGMENTED_IMAGES_DIR = os.path.join(fs_observer.dir, 'images') CHECKPOINTS_DIR = os.path.join(fs_observer.dir, 'checkpoints') BEST_MODEL_PATH = os.path.join(CHECKPOINTS_DIR, 'model_best.pth') LAST_MODEL_PATH = os.path.join(CHECKPOINTS_DIR, 'model_last.pth') RESULTS_CSV_PATH = os.path.join('results', 'results.csv') EXP_NAME = _run.meta_info['options']['--name'] EXP_ID = _run._id for directory in (AUGMENTED_IMAGES_DIR, CHECKPOINTS_DIR): os.makedirs(directory) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") if model_name == 'inceptionv4': model = ptm.inceptionv4(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, 2) aug['size'] = 299 aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'resnet152': model = models.resnet152(pretrained=True) model.fc = nn.Linear(model.fc.in_features, 2) aug['size'] = 224 aug['mean'] = [0.485, 0.456, 0.406] aug['std'] = [0.229, 0.224, 0.225] elif model_name == 'densenet161': model = models.densenet161(pretrained=True) model.classifier = nn.Linear(model.classifier.in_features, 2) aug['size'] = 224 aug['mean'] = [0.485, 0.456, 0.406] aug['std'] = [0.229, 0.224, 0.225] elif model_name == 'senet154': model = ptm.senet154(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, 2) aug['size'] = model.input_size[1] aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'squeezenet': model = ptm.squeezenet1_1(num_classes=1000, pretrained='imagenet') model.last_conv = nn.Conv2d( 512, 2, kernel_size=(1, 1), stride=(1, 1)) aug['size'] = model.input_size[1] aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'pnasnet5large': model = ptm.pnasnet5large(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, 2) aug['size'] = model.input_size[1] aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'nasnetalarge': model = ptm.nasnetalarge(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, 2) aug['size'] = model.input_size[1] aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'xception': model = ptm.xception(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, 2) aug['size'] = model.input_size[1] aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'dpn': model = ptm.dpn131(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Conv2d(model.last_linear.in_channels, 2, kernel_size=1, bias=True) aug['size'] = model.input_size[1] aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'resnext': model = ptm.resnext101_64x4d(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, 2) aug['size'] = model.input_size[1] aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'inceptionresnetv2': model = ptm.inceptionresnetv2(num_classes=1000, pretrained='imagenet') model.last_linear = nn.Linear(model.last_linear.in_features, 2) aug['size'] = model.input_size[1] aug['mean'] = model.mean aug['std'] = model.std elif model_name == 'mobilenetv2': model = MobileNetV2() model.load_state_dict(torch.load('./auglib/models/mobilenet_v2.pth')) model.classifier = nn.Sequential( nn.Dropout(0.2), nn.Linear(model.last_channel, 2), ) aug['size'] = 224 aug['mean'] = [0.485, 0.456, 0.406] aug['std'] = [0.229, 0.224, 0.225] model.to(device) augs = Augmentations(**aug) model.aug_params = aug datasets = { 'samples': CSVDataset(train_root, train_csv, 'image_id', 'melanoma', transform=augs.tf_augment, add_extension='.jpg', limit=(400, 433)), 'train': CSVDataset(train_root, train_csv, 'image_id', 'melanoma', transform=augs.tf_transform, add_extension='.jpg', random_subset_size=limit_data), 'val': CSVDatasetWithName( val_root, val_csv, 'image_id', 'melanoma', transform=augs.tf_transform, add_extension='.jpg'), 'test': CSVDatasetWithName( test_root, test_csv, 'image_id', 'melanoma', transform=augs.tf_transform, add_extension='.jpg'), 'test_no_aug': CSVDatasetWithName( test_root, test_csv, 'image_id', 'melanoma', transform=augs.no_augmentation, add_extension='.jpg'), 'test_144': CSVDatasetWithName( test_root, test_csv, 'image_id', 'melanoma', transform=augs.inception_crop, add_extension='.jpg'), } dataloaders = { 'train': DataLoader(datasets['train'], batch_size=batch_size, shuffle=True, num_workers=num_workers, worker_init_fn=set_seeds), 'samples': DataLoader(datasets['samples'], batch_size=batch_size, shuffle=False, num_workers=num_workers, worker_init_fn=set_seeds), } save_images(datasets['samples'], to=AUGMENTED_IMAGES_DIR, n=32) sample_batch, _ = next(iter(dataloaders['samples'])) save_image(make_grid(sample_batch, padding=0), os.path.join(AUGMENTED_IMAGES_DIR, 'grid.jpg')) criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9, weight_decay=0.001) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, factor=0.1, min_lr=1e-5, patience=8) metrics = { 'train': pd.DataFrame(columns=['epoch', 'loss', 'acc', 'auc']), 'val': pd.DataFrame(columns=['epoch', 'loss', 'acc', 'auc']) } best_val_auc = 0.0 best_epoch = 0 epochs_without_improvement = 0 if images_per_epoch: batches_per_epoch = images_per_epoch // batch_size else: batches_per_epoch = None for epoch in range(epochs): print('train epoch {}/{}'.format(epoch+1, epochs)) epoch_train_result = train_epoch( device, model, dataloaders, criterion, optimizer, batches_per_epoch) metrics['train'] = metrics['train'].append( {**epoch_train_result, 'epoch': epoch}, ignore_index=True) print('train', epoch_train_result) epoch_val_result, _ = test_with_augmentation( model, datasets['val'], device, num_workers, val_samples) metrics['val'] = metrics['val'].append( {**epoch_val_result, 'epoch': epoch}, ignore_index=True) print('val', epoch_val_result) print('-' * 40) scheduler.step(epoch_val_result['loss']) if epoch_val_result['auc'] > best_val_auc: best_val_auc = epoch_val_result['auc'] best_val_result = epoch_val_result best_epoch = epoch epochs_without_improvement = 0 torch.save(model, BEST_MODEL_PATH) else: epochs_without_improvement += 1 if epochs_without_improvement > early_stopping_patience: last_val_result = epoch_val_result torch.save(model, LAST_MODEL_PATH) break if epoch == (epochs-1): last_val_result = epoch_val_result torch.save(model, LAST_MODEL_PATH) for phase in ['train', 'val']: metrics[phase].epoch = metrics[phase].epoch.astype(int) metrics[phase].to_csv(os.path.join(fs_observer.dir, phase + '.csv'), index=False) # Run testing # TODO: reduce code repetition test_result, preds = test_with_augmentation( torch.load(BEST_MODEL_PATH), datasets['test'], device, num_workers, test_samples) print('[best] test', test_result) test_noaug_result, preds_noaug = test_with_augmentation( torch.load(BEST_MODEL_PATH), datasets['test_no_aug'], device, num_workers, 1) print('[best] test (no augmentation)', test_noaug_result) test_result_last, preds_last = test_with_augmentation( torch.load(LAST_MODEL_PATH), datasets['test'], device, num_workers, test_samples) print('[last] test', test_result_last) test_noaug_result_last, preds_noaug_last = test_with_augmentation( torch.load(LAST_MODEL_PATH), datasets['test_no_aug'], device, num_workers, 1) print('[last] test (no augmentation)', test_noaug_result_last) # Save predictions preds.to_csv(os.path.join(fs_observer.dir, 'test-aug-best.csv'), index=False, columns=['image', 'label', 'score']) preds_noaug.to_csv(os.path.join(fs_observer.dir, 'test-noaug-best.csv'), index=False, columns=['image', 'label', 'score']) preds_last.to_csv(os.path.join(fs_observer.dir, 'test-aug-last.csv'), index=False, columns=['image', 'label', 'score']) preds_noaug_last.to_csv(os.path.join(fs_observer.dir, 'test-noaug-last.csv'), index=False, columns=['image', 'label', 'score']) # TODO: Avoid repetition. # use ordereddict, or create a pandas df before saving with open(RESULTS_CSV_PATH, 'a') as file: file.write(','.join(( EXP_NAME, str(EXP_ID), str(split_id), str(best_epoch), str(best_val_result['loss']), str(best_val_result['acc']), str(best_val_result['auc']), str(best_val_result['avp']), str(best_val_result['sens']), str(best_val_result['spec']), str(last_val_result['loss']), str(last_val_result['acc']), str(last_val_result['auc']), str(last_val_result['avp']), str(last_val_result['sens']), str(last_val_result['spec']), str(best_val_auc), str(test_result['auc']), str(test_result_last['auc']), str(test_result['acc']), str(test_result_last['acc']), str(test_result['spec']), str(test_result_last['spec']), str(test_result['sens']), str(test_result_last['sens']), str(test_result['avp']), str(test_result_last['avp']), str(test_noaug_result['auc']), str(test_noaug_result_last['auc']), str(test_noaug_result['acc']), str(test_noaug_result_last['acc']), str(test_noaug_result['spec']), str(test_noaug_result_last['spec']), str(test_noaug_result['sens']), str(test_noaug_result_last['sens']), str(test_noaug_result['avp']), str(test_noaug_result_last['avp']), )) + '\n') return (test_noaug_result['auc'], test_result['auc'], )
start_epoch = 0 total_epochs = sum(stage_epochs) best_precision = -1 lowest_loss = 100 # 设定打印频率,即多少step打印一次,用于观察loss和acc的实时变化 # 打印结果中,括号前面为实时loss和acc,括号内部为epoch内平均loss和acc print_freq = 1 # 验证集比例 val_ratio = 0.12 # 是否只验证,不训练 evaluate = False # 是否从断点继续跑 resume = False # 创建Xception模型 model = xception() model.last_linear = nn.Linear(2048, 28) model = torch.nn.DataParallel(model).cuda() # optionally resume from a checkpoint if resume: checkpoint_path = './model/%s/checkpoint.pth.tar' % file_name if os.path.isfile(checkpoint_path): print("=> loading checkpoint '{}'".format(checkpoint_path)) checkpoint = torch.load(checkpoint_path) start_epoch = checkpoint['epoch'] + 1 best_precision = checkpoint['best_precision'] lowest_loss = checkpoint['lowest_loss'] stage = checkpoint['stage'] lr = checkpoint['lr'] model.load_state_dict(checkpoint['state_dict'])
def __init__(self, num_classes): super(Xception, self).__init__() self.base = pretrainedmodels.xception() self.backbone = nn.Sequential(*list(self.base.children())[:-1]) self.head = nn.Linear(self.base.last_linear.in_features, num_classes)
return optimizer ### SECTION 4 : DEFINING MODEL ARCHITECTURE. # We use Resnet18 here. If you have more computational power, feel free to swap it with Resnet50, Resnet100 or Resnet152. # Since we are doing fine-tuning, or transfer learning we will use the pretrained net weights. In the last line, the number of classes has been specified. # Set the number of classes in the config file by setting the right value for NUM_CLASSES. ################ RESNET # model_ft = models.squeezenet1_1(pretrained=True) # model_ft = torch.hub.load( # 'moskomule/senet.pytorch', # 'se_resnet20', # num_classes=6) model_ft = pretrainedmodels.xception(num_classes=1000, pretrained='imagenet') # for param in model_ft.parameters(): # param.requires_grad = False #model_ft.classifier = nn.Sequential( # nn.Dropout(p=0.5), # nn.Conv2d(512, NUM_CLASSES, kernel_size=1), # nn.ReLU(inplace=True), # nn.AdaptiveAvgPool2d((1, 1)) # ) #model_ft.num_classes = NUM_CLASSES # num_ftrs = model_ft.fc.in_features # model_ft.fc = nn.Linear(num_ftrs, NUM_CLASSES) # num_ftrs = model_ft.classifier[6].in_features
def load_neural_network(self): if self.network_name == "vgg16": self.net = models.vgg16_bn(pretrained=False) num_ftrs = self.net.classifier[6].in_features self.net.classifier[6] = nn.Linear( num_ftrs, self.settings["number_of_classes"]) self.net.load_state_dict( torch.load(os.path.join(self.models_path, "VGG16_best.pth"))) elif self.network_name == "densenet": self.net = models.densenet161(pretrained=False) num_ftrs = self.net.classifier.in_features self.net.classifier = nn.Linear(num_ftrs, self.settings["number_of_classes"]) self.net.load_state_dict( torch.load(os.path.join(self.models_path, 'DenseNet_best.pth'))) elif self.network_name == "xception": self.net = pretrainedmodels.xception() num_ftrs = self.net.last_linear.in_features self.net.last_linear = nn.Linear( num_ftrs, self.settings["number_of_classes"]) self.net.load_state_dict( torch.load(os.path.join(self.models_path, 'Xception_best.pth'))) elif self.network_name == "wide_resnet50": self.net = models.wide_resnet50_2(pretrained=True) num_ftrs = self.net.fc.in_features self.net.fc = nn.Linear(num_ftrs, self.settings["number_of_classes"]) self.net.load_state_dict( torch.load( os.path.join(self.models_path, 'ResNetWide_best.pth'))) elif self.network_name == "resnext": self.net = models.resnext50_32x4d(pretrained=True) num_ftrs = self.net.fc.in_features self.net.fc = nn.Linear(num_ftrs, self.settings["number_of_classes"]) self.net.load_state_dict( torch.load(os.path.join(self.models_path, 'ResNext_best.pth'))) elif self.network_name == "inceptionresnetv2": self.net = models.wide_resnet50_2(pretrained=True) num_ftrs = self.net.fc.in_features self.net.fc = nn.Linear(num_ftrs, self.settings["number_of_classes"]) self.net.load_state_dict( torch.load( os.path.join(self.models_path, 'InceptionResNetv2_best.pth'))) elif self.network_name == "inceptionv4": self.net = pretrainedmodels.inceptionv4() self.net.avg_pool = nn.AvgPool2d(kernel_size=2, stride=2) num_ftrs = self.net.last_linear.in_features self.net.last_linear = nn.Linear( num_ftrs, self.settings["number_of_classes"]) self.net.load_state_dict( torch.load( os.path.join(self.models_path, 'InceptionV4_best.pth'))) else: self.net = None print("unknown neural network architecture") self.net.eval()