[add]上传训练benchmark by z00560161

This commit is contained in:
liang_chaoming@huawei.com
2020-10-19 20:22:23 +08:00
parent 22b83024f5
commit 82522e2f61
1225 changed files with 345421 additions and 0 deletions
@@ -0,0 +1,81 @@
import torch.utils.data as data
import os
from PIL import Image
import numpy as np
import pickle
import copy
class AttDataset(data.Dataset):
"""
person attribute dataset interface
"""
def __init__(
self,
dataset,
partition,
split='train',
partition_idx=0,
transform=None,
target_transform=None,
**kwargs):
if os.path.exists( dataset ):
file = open(dataset, 'rb')
self.dataset = pickle.load(file)
else:
print (dataset + ' does not exist in dataset.')
raise ValueError
if os.path.exists( partition ):
part = open(partition, 'rb')
self.partition = pickle.load(part)
else:
print (partition + ' does not exist in dataset.')
raise ValueError
if split not in self.partition:
print (split + ' does not exist in dataset.')
raise ValueError
if partition_idx > len(self.partition[split])-1:
print ('partition_idx is out of range in partition.')
raise ValueError
self.transform = transform
self.target_transform = target_transform
# create image, label based on the selected partition and dataset split
self.root_path = self.dataset['root']
self.att_name = [self.dataset['att_name'][i] for i in self.dataset['selected_attribute']]
self.image = []
self.label = []
for idx in self.partition[split][partition_idx]:
self.image.append(self.dataset['image'][idx])
label_tmp = np.array(self.dataset['att'][idx])[self.dataset['selected_attribute']].tolist()
self.label.append(label_tmp)
def __getitem__(self, index):
"""
Args:
index (int): Index
Returns:
tuple: (image, target) where target is the index of the target class
"""
imgname, target = self.image[index], self.label[index]
# load image and labels
imgname = os.path.join(self.dataset['root'], imgname)
img = Image.open(imgname)
if self.transform is not None:
img = self.transform( img )
# default no transform
target = np.array(target).astype(np.float32)
target[target == 0] = -1
target[target == 2] = 0
if self.target_transform is not None:
target = self.transform( target )
return img, target
# useless for personal batch sampler
def __len__(self):
return len(self.image)
@@ -0,0 +1,65 @@
import torch
import numpy as np
import numbers
__all__ = ["AddPad", "AddCrop"]
class AddCrop(object):
def __init__(self, size):
self.size = size # two
assert len(self.size) == 2
def __repr__(self):
return self.__class__.__name__ + '(size={0})'.format(self.size)
def __call__(self, img):
shape = img.shape # 3*H*W
h_high = shape[1] - self.size[0]
w_high = shape[2] - self.size[1]
h_start = np.random.randint(low=0, high=h_high)
w_start = np.random.randint(low=0, high=w_high)
return img[:, h_start: h_start+self.size[0], w_start: w_start+self.size[1]]
class AddPad(object):
def __init__(self, padding, fill=0):
self.padding = padding
self.fill = fill
if isinstance(self.padding, numbers.Number):
self.pad_l = int(self.padding)
self.pad_r = int(self.padding)
self.pad_u = int(self.padding)
self.pad_d = int(self.padding)
elif isinstance(self.padding, (list, tuple)) and len(self.padding) == 4:
self.pad_l = int(self.padding[0])
self.pad_r = int(self.padding[1])
self.pad_u = int(self.padding[2])
self.pad_d = int(self.padding[3])
else:
print ("The type of padding is not right.")
raise ValueError
if self.pad_l <0 or self.pad_r < 0 or self.pad_u < 0 or self.pad_d < 0:
raise ValueError
if isinstance(self.fill, numbers.Number):
self.fill_value = [self.fill]
elif isinstance(self.fill, list):
self.fill_value = self.fill
def __repr__(self):
return self.__class__.__name__ + '(padding={0})'.format(self.padding)
def __call__(self, img):
"""
Args:
img: a 3-dimensional torch tensor with shape [R,G,B]*H*W
Returns:
img: a 3-dimensional padded tensor with shape [R,G,B]*H'*W'
"""
if not (self.pad_l or self.pad_r or self.pad_u or self.pad_d):
return img
shape = img.shape
img_ = torch.rand(shape[0], shape[1]+self.pad_u+self.pad_d, \
shape[2]+self.pad_l+self.pad_r)
for i in range(shape[0]):
img_[i, 0:self.pad_u, :] = self.fill_value[i%len(self.fill_value)]
img_[i, -(self.pad_d+1):-1, :] = self.fill_value[i%len(self.fill_value)]
img_[i, :, 0:self.pad_l] = self.fill_value[i%len(self.fill_value)]
img_[i, :, -(self.pad_r+1):-1] = self.fill_value[i%len(self.fill_value)]
img_[i, self.pad_u:self.pad_u+shape[1], self.pad_l:self.pad_l+shape[2]] = img[i, :, :]
return img_
@@ -0,0 +1,81 @@
import torch
import torch.nn as nn
import torch.nn.init as init
import torch.nn.functional as F
from torch.autograd import Variable
import numpy as np
from .resnet import resnet50
class DeepMAR_ResNet50(nn.Module):
def __init__(
self,
**kwargs
):
super(DeepMAR_ResNet50, self).__init__()
# init the necessary parameter for netwokr structure
if 'num_att' in kwargs:
self.num_att = kwargs['num_att']
else:
self.num_att = 35
if 'last_conv_stride' in kwargs:
self.last_conv_stride = kwargs['last_conv_stride']
else:
self.last_conv_stride = 2
if 'drop_pool5' in kwargs:
self.drop_pool5 = kwargs['drop_pool5']
else:
self.drop_pool5 = True
if 'drop_pool5_rate' in kwargs:
self.drop_pool5_rate = kwargs['drop_pool5_rate']
else:
self.drop_pool5_rate = 0.5
if 'pretrained' in kwargs:
self.pretrained = kwargs['pretrained']
else:
self.pretrained = True
self.base = resnet50(pretrained=self.pretrained, last_conv_stride=self.last_conv_stride)
self.classifier = nn.Linear(2048, self.num_att)
init.normal_(self.classifier.weight, std=0.001)
init.constant_(self.classifier.bias, 0)
def forward(self, x):
x = self.base(x)
x = F.avg_pool2d(x, x.shape[2:])
# x = x.view(x.size(0), -1)
x = torch.flatten(x, 1)
if self.drop_pool5:
# x = x.to("cpu")
x = F.dropout(x, p=self.drop_pool5_rate, training=self.training)
# x = x.to("npu")
x = self.classifier(x)
return x
class DeepMAR_ResNet50_ExtractFeature(object):
"""
A feature extraction function
"""
def __init__(self, model, **kwargs):
self.model = model
def __call__(self, imgs):
old_train_eval_model = self.model.training
# set the model to be eval
self.model.eval()
# imgs should be Variable
if not isinstance(imgs, Variable):
print ('imgs should be type: Variable')
raise ValueError
# compute output
score = self.model(imgs)
score = score.data.cpu().numpy()
# set the model to be training
self.model.train(old_train_eval_model)
return score
@@ -0,0 +1,217 @@
import torch.nn as nn
import math
import torch.utils.model_zoo as model_zoo
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101',
'resnet152']
model_urls = {
'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',
}
def conv3x3(in_planes, out_planes, stride=1):
"""3x3 convolution with padding"""
return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
padding=1, bias=False)
class BasicBlock(nn.Module):
expansion = 1
def __init__(self, inplanes, planes, stride=1, downsample=None):
super(BasicBlock, self).__init__()
self.conv1 = conv3x3(inplanes, planes, stride)
self.bn1 = nn.BatchNorm2d(planes)
self.relu = nn.ReLU(inplace=True)
self.conv2 = conv3x3(planes, planes)
self.bn2 = nn.BatchNorm2d(planes)
self.downsample = downsample
self.stride = stride
def forward(self, x):
residual = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
if self.downsample is not None:
residual = self.downsample(x)
out += residual
out = self.relu(out)
return out
class Bottleneck(nn.Module):
expansion = 4
def __init__(self, inplanes, planes, stride=1, downsample=None):
super(Bottleneck, self).__init__()
self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
self.bn3 = nn.BatchNorm2d(planes * 4)
self.relu = nn.ReLU(inplace=True)
self.downsample = downsample
self.stride = stride
def forward(self, x):
residual = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.bn3(out)
if self.downsample is not None:
residual = self.downsample(x)
out += residual
out = self.relu(out)
return out
class ResNet(nn.Module):
def __init__(self, block, layers, last_conv_stride=2):
self.inplanes = 64
super(ResNet, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,
bias=False)
self.bn1 = nn.BatchNorm2d(64)
self.relu = nn.ReLU(inplace=True)
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
self.layer1 = self._make_layer(block, 64, layers[0])
self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
self.layer4 = self._make_layer(block, 512, layers[3], stride=last_conv_stride)
for m in self.modules():
if isinstance(m, nn.Conv2d):
n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
m.weight.data.normal_(0, math.sqrt(2. / n))
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1)
m.bias.data.zero_()
def _make_layer(self, block, planes, blocks, stride=1):
downsample = None
if stride != 1 or self.inplanes != planes * block.expansion:
downsample = nn.Sequential(
nn.Conv2d(self.inplanes, planes * block.expansion,
kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(planes * block.expansion),
)
layers = []
layers.append(block(self.inplanes, planes, stride, downsample))
self.inplanes = planes * block.expansion
for i in range(1, blocks):
layers.append(block(self.inplanes, planes))
return nn.Sequential(*layers)
def forward(self, x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.maxpool(x)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
return x
def remove_fc(state_dict):
""" Remove the fc layer parameter from state_dict. """
for key, value in list(state_dict.items()):
if key.startswith('fc.'):
del state_dict[key]
return state_dict
def resnet18(pretrained=False, **kwargs):
"""Constructs a ResNet-18 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs)
if pretrained:
model.load_state_dict(remove_fc(model_zoo.load_url(model_urls['resnet18'])))
return model
def resnet34(pretrained=False, **kwargs):
"""Constructs a ResNet-34 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(BasicBlock, [3, 4, 6, 3], **kwargs)
if pretrained:
model.load_state_dict(remove_fc(model_zoo.load_url(model_urls['resnet34'])))
return model
def resnet50(pretrained=False, **kwargs):
"""Constructs a ResNet-50 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)
if pretrained:
model.load_state_dict(remove_fc(model_zoo.load_url(model_urls['resnet50'])))
return model
def resnet101(pretrained=False, **kwargs):
"""Constructs a ResNet-101 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs)
if pretrained:
model.load_state_dict(remove_fc(model_zoo.load_url(model_urls['resnet101'])))
return model
def resnet152(pretrained=False, **kwargs):
"""Constructs a ResNet-152 model.
Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
"""
model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs)
if pretrained:
model.load_state_dict(remove_fc(model_zoo.load_url(model_urls['resnet152'])))
return model
@@ -0,0 +1,105 @@
import os
import torch
from torch.autograd import Variable
import numpy as np
import copy
import time
import sys
def extract_feat(feat_func, dataset, device_id, **kwargs):
"""
extract feature for images
"""
test_loader = torch.utils.data.DataLoader(
dataset=dataset, batch_size=32,
num_workers=32, pin_memory=True,
drop_last=True)
# extract feature for all the images of test/val identities
start_time = time.time()
total_eps = len(test_loader)
N = len(dataset.image)
start = 0
with torch.no_grad():
for ep, (imgs, labels) in enumerate(test_loader):
# imgs_var = Variable(imgs).cuda()
# imgs_var = Variable(imgs)
imgs_var = Variable(imgs).to(device_id)
feat_tmp = feat_func(imgs_var)
batch_size = feat_tmp.shape[0]
if ep == 0:
feat = np.zeros((N, int(feat_tmp.size/batch_size)))
feat[start:start+batch_size, :] = feat_tmp.reshape((batch_size, -1))
start += batch_size
end_time = time.time()
print('{} batches done, total {:.2f}s'.format(total_eps, end_time-start_time))
return feat
# attribute recognition evaluation
def attribute_evaluate(feat_func, dataset, device_id, **kwargs):
print ("extracting features for attribute recognition")
pt_result = extract_feat(feat_func, dataset, device_id)
# obain the attributes from the attribute dictionary
print ("computing attribute recognition result")
N = pt_result.shape[0]
L = pt_result.shape[1]
gt_result = np.zeros(pt_result.shape)
# get the groundtruth attributes
for idx, label in enumerate(dataset.label):
gt_result[idx, :] = label
pt_result[pt_result>=0] = 1
pt_result[pt_result<0] = 0
return attribute_evaluate_lidw(gt_result, pt_result)
def attribute_evaluate_lidw(gt_result, pt_result):
"""
Input:
gt_result, pt_result, N*L, with 0/1
Output:
result
a dictionary, including label-based and instance-based evaluation
label-based: label_pos_acc, label_neg_acc, label_acc
instance-based: instance_acc, instance_precision, instance_recall, instance_F1
"""
# obtain the label-based and instance-based accuracy
# compute the label-based accuracy
if gt_result.shape != pt_result.shape:
print ('Shape beteen groundtruth and predicted results are different')
# compute the label-based accuracy
result = {}
gt_pos = np.sum((gt_result == 1).astype(float), axis=0)
gt_neg = np.sum((gt_result == 0).astype(float), axis=0)
pt_pos = np.sum((gt_result == 1).astype(float) * (pt_result == 1).astype(float), axis=0)
pt_neg = np.sum((gt_result == 0).astype(float) * (pt_result == 0).astype(float), axis=0)
label_pos_acc = 1.0*pt_pos/gt_pos
label_neg_acc = 1.0*pt_neg/gt_neg
label_acc = (label_pos_acc + label_neg_acc)/2
result['label_pos_acc'] = label_pos_acc
result['label_neg_acc'] = label_neg_acc
result['label_acc'] = label_acc
# compute the instance-based accuracy
# precision
gt_pos = np.sum((gt_result == 1).astype(float), axis=1)
pt_pos = np.sum((pt_result == 1).astype(float), axis=1)
floatersect_pos = np.sum((gt_result == 1).astype(float)*(pt_result == 1).astype(float), axis=1)
union_pos = np.sum(((gt_result == 1)+(pt_result == 1)).astype(float),axis=1)
# avoid empty label in predicted results
cnt_eff = float(gt_result.shape[0])
for iter, key in enumerate(gt_pos):
if key == 0:
union_pos[iter] = 1
pt_pos[iter] = 1
gt_pos[iter] = 1
cnt_eff = cnt_eff - 1
continue
if pt_pos[iter] == 0:
pt_pos[iter] = 1
instance_acc = np.sum(floatersect_pos/union_pos)/cnt_eff
instance_precision = np.sum(floatersect_pos/pt_pos)/cnt_eff
instance_recall = np.sum(floatersect_pos/gt_pos)/cnt_eff
floatance_F1 = 2*instance_precision*instance_recall/(instance_precision+instance_recall)
result['instance_acc'] = instance_acc
result['instance_precision'] = instance_precision
result['instance_recall'] = instance_recall
result['instance_F1'] = floatance_F1
return result
@@ -0,0 +1,347 @@
import os
import pickle
import datetime
import time
# from contextlib import contextmanger
import torch
from torch.autograd import Variable
import random
import numpy as np
import torch.backends.cudnn as cudnn
def time_str(fmt=None):
if fmt is None:
fmt = '%Y-%m-%d_%H:%M:%S'
return datetime.datetime.today().strftime(fmt)
def str2bool(v):
return v.lower() in ("yes", "true", "1")
def is_iterable(obj):
return hasattr(obj, '__len__')
def to_scalar(vt):
"""
transform a 1-length pytorch Variable or Tensor to scalar
"""
if isinstance(vt, Variable):
return vt.data.cpu().numpy().flatten()[0]
if torch.is_tensor(vt):
return vt.cpu().numpy().flatten()[0]
raise TypeError('Input should be a variable or tensor')
def set_seed(rand_seed):
np.random.seed( rand_seed )
random.seed( rand_seed )
torch.backends.cudnn.enabled = True
torch.manual_seed( rand_seed )
torch.cuda.manual_seed( rand_seed )
def seed_everything(seed):
random.seed(seed)
os.environ['PYTHONHASHSEED'] = str(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
cudnn.deterministic = True
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
def may_mkdir(fname):
if not os.path.exists(os.path.dirname(os.path.abspath(fname))):
os.makedirs(os.path.dirname(os.path.abspath(fname)))
class AverageMeter(object):
"""
Computes and stores the average and current value
"""
def __init__(self):
self.val = 0
self.avg = 0
self.sum = 0
self.count = 0
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 = float(self.sum) / (self.count + 1e-10)
class RunningAverageMeter(object):
"""
Computes and stores the running average and current value
"""
def __init__(self, hist=0.99):
self.val = None
self.avg = None
self.hist = hist
def reset(self):
self.val = None
self.avg = None
def update(self, val):
if self.avg is None:
self.avg = val
else:
self.avg = self.avg * self.hist + val * (1 - self.hist)
self.val = val
class RecentAverageMeter(object):
"""
Stores and computes the average of recent values
"""
def __init__(self, hist_size=100):
self.hist_size = hist_size
self.fifo = []
self.val = 0
def reset(self):
self.fifo = []
self.val = 0
def update(self, val):
self.val = val
self.fifo.append(val)
if len(self.fifo) > self.hist_size:
del self.fifo[0]
@property
def avg(self):
assert len(self.fifo) > 0
return float(sum(self.fifo)) / len(self.fifo)
class ReDirectSTD(object):
"""
overwrites the sys.stdout or sys.stderr
Args:
fpath: file path
console: one of ['stdout', 'stderr']
immediately_visiable: False
Usage example:
ReDirectSTD('stdout.txt', 'stdout', False)
ReDirectSTD('stderr.txt', 'stderr', False)
"""
def __init__(self, fpath=None, console='stdout', immediately_visiable=False):
import sys
import os
assert console in ['stdout', 'stderr']
self.console = sys.stdout if console == "stdout" else sys.stderr
self.file = fpath
self.f = None
self.immediately_visiable = immediately_visiable
if fpath is not None:
# Remove existing log file
if os.path.exists(fpath):
os.remove(fpath)
if console == 'stdout':
sys.stdout = self
else:
sys.stderr = self
def __del__(self):
self.close()
def __enter__(self):
pass
def __exit__(self, **args):
self.close()
def write(self, msg):
self.console.write(msg)
if self.file is not None:
if not os.path.exists(os.path.dirname(os.path.abspath(self.file))):
os.mkdir(os.path.dirname(os.path.abspath(self.file)))
if self.immediately_visiable:
with open(self.file, 'a') as f:
f.write(msg)
else:
if self.f is None:
self.f = open(self.file, 'w')
self.f.write(msg)
def flush(self):
self.console.flush()
if self.f is not None:
self.f.flush()
import os
os.fsync(self.f.fileno())
def close(self):
self.console.close()
if self.f is not None:
self.f.close()
def find_index(seq, item):
for i, x in enumerate(seq):
if item == x:
return i
return -1
def set_devices(sys_device_ids):
"""
Args:
sys_device_ids: a tuple; which GPUs to use
e.g. sys_device_ids = (), only use cpu
sys_device_ids = (3,), use the 4-th gpu
sys_device_ids = (0, 1, 2, 3,), use the first 4 gpus
sys_device_ids = (0, 2, 4,), use the 1, 3 and 5 gpus
"""
import os
visiable_devices = ''
for i in sys_device_ids:
visiable_devices += '{}, '.format(i)
os.environ['CUDA_VISIBLE_DEVICES'] = visiable_devices
# Return wrappers
# Models and user defined Variables/Tensors would be transferred to
# the first device
device_id = 0 if len(sys_device_ids) > 0 else -1
def transfer_optims(optims, device_id=-1):
for optim in optims:
if isinstance(optim, torch.optim.Optimizer):
transfer_optim_state(optim.state, device_id=device_id)
def transfer_optim_state(state, device_id=-1):
for key, val in state.items():
if isinstance(val, dict):
transfer_optim_state(val, device_id=device_id)
elif isinstance(val, Variable):
raise RuntimeError("Oops, state[{}] is a Variable!".format(key))
elif isinstance(val, torch.nn.Parameter):
raise RuntimeError("Oops, state[{}] is a Parameter!".format(key))
else:
try:
if device_id == -1:
state[key] = val.cpu()
else:
#state[key] = val.cuda(device=device_id)
state[key] = val.npu(device=device_id)
except:
pass
def load_state_dict(model, src_state_dict):
"""
copy parameter from src_state_dict to model
Arguments:
model: A torch.nn.Module object
src_state_dict: a dict containing parameters and persistent buffers
"""
from torch.nn import Parameter
dest_state_dict = model.state_dict()
for name, param in src_state_dict.items():
if name not in dest_state_dict:
continue
if isinstance(param, Parameter):
param = param.data
try:
dest_state_dict[name].copy_(param)
except Exception:
print("Warning: Error occurs when copying '{}'".format(name))
src_missing = set(dest_state_dict.keys()) - set(src_state_dict.keys())
if len(src_missing) > 0:
print ("Keys not found in source state_dict: ")
for n in src_missing:
print('\t', n)
dest_missint = set(src_state_dict.keys()) - set(dest_state_dict.keys())
if len(dest_missint):
print ("Keys not found in destination state_dict: ")
for n in dest_missint:
print('\t', n)
def load_ckpt(modules_optims, ckpt_file, load_to_cpu=True, verbose=True):
"""
load state_dict of module & optimizer from file
Args:
modules_optims: A two-element list which contains module and optimizer
ckpt_file: the check point file
load_to_cpu: Boolean, whether to transform tensors in model & optimizer to cpu type
"""
map_location = (lambda storage, loc: storage) if load_to_cpu else None
ckpt = torch.load(ckpt_file, map_location=map_location)
for m, sd in zip(modules_optims, ckpt['state_dicts']):
m.load_state_dict(sd)
if verbose:
print("Resume from ckpt {}, \nepoch: {}, scores: {}".format(
ckpt_file, ckpt['ep'], ckpt['scores']))
return ckpt['ep'], ckpt['scores']
def save_ckpt(modules_optims, ep, scores, ckpt_file):
"""
save state_dict of modules/optimizers to file
Args:
modules_optims: a two-element list which contains a module and a optimizer
ep: the current epoch number
scores: the performance of current module
ckpt_file: the check point file path
Note:
torch.save() reserves device type and id of tensors to save.
So when loading ckpt, you have to inform torch.load() to load these tensors
to cpu or your desired gpu, if you change devices.
"""
state_dicts = [m.state_dict() for m in modules_optims]
ckpt = dict(state_dicts = state_dicts,
ep = ep,
scores = scores)
if not os.path.exists(os.path.dirname(os.path.abspath(ckpt_file))):
os.mkdir(os.path.dirname(os.path.abspath(ckpt_file)))
torch.save(ckpt, ckpt_file)
def adjust_lr_staircase(param_groups, base_lrs, ep, decay_at_epochs, factor):
""" Multiplied by a factor at the beging of specified epochs. Different
params groups specify thier own base learning rates.
Args:
param_groups: a list of params
base_lrs: starting learning rate, len(base_lrs) = len(params_groups)
ep: current epoch, ep >= 1
decay_at_epochs: a list or tuple; learning rates are multiplied by a factor
at the begining of these epochs
factor: a number in range (0, 1)
Example:
base_lrs = [0.1, 0.01]
decay_at_epochs = [51, 101]
factor = 0.1
Note:
It is meant to be called at the begining of an epoch
"""
assert len(base_lrs) == len(param_groups), \
'You should specify base lr for each param group.'
assert ep >= 1, "Current epoch number should be >= 1"
if ep not in decay_at_epochs:
return
ind = find_index(decay_at_epochs, ep)
for i, (g, base_lr) in enumerate(zip(param_groups, base_lrs)):
g['lr'] = base_lr * factor ** (ind + 1)
print('=====> Param group {}: lr adjusted to {:.10f}'
.format(i, g['lr']).rstrip('0'))
def adjust_lr(optimizer, ep, finetuned_params_lr):
"""Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
# lr = args.lr * (0.1 ** (ep// 30))
lr = finetuned_params_lr * (0.96 ** (ep // 8)) #decreasing the learning rate by 4% every 8 epoch
for param_group in optimizer.param_groups:
param_group['lr'] = lr
def may_set_mode(maybe_modules, mode):
"""
maybe_modules, an object or a list of objects.
"""
assert mode in ['train', 'eval']
if not is_iterable(maybe_modules):
maybe_modules = [maybe_modules]
for m in maybe_modules:
if isinstance(m, torch.nn.Module):
if mode == 'train':
m.train()
else:
m.eval()
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

@@ -0,0 +1,141 @@
import sys
import os
import numpy as np
import random
import math
import torch
import torchvision.transforms as transforms
from torch.autograd import Variable
from torch.nn.parallel import DataParallel
import pickle
import time
import argparse
from PIL import Image, ImageFont, ImageDraw
from baseline.model.DeepMAR import DeepMAR_ResNet50
from baseline.utils.utils import str2bool
from baseline.utils.utils import save_ckpt, load_ckpt
from baseline.utils.utils import load_state_dict
from baseline.utils.utils import set_devices
from baseline.utils.utils import set_seed
class Config(object):
def __init__(self):
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--sys_device_ids', type=eval, default=(0,))
parser.add_argument('--set_seed', type=str2bool, default=False)
# model
parser.add_argument('--resize', type=eval, default=(224, 224))
parser.add_argument('--last_conv_stride', type=int, default=2, choices=[1,2])
# demo image
parser.add_argument('--demo_image', type=str, default='./dataset/demo/demo_image.png')
## dataset parameter
parser.add_argument('--dataset', type=str, default='peta',
choices=['peta','rap', 'pa100k'])
# utils
parser.add_argument('--load_model_weight', type=str2bool, default=True)
parser.add_argument('--model_weight_file', type=str, default='./exp/deepmar_resnet50/peta/partition0/run1/model/ckpt_epoch150.pth')
args = parser.parse_args()
# gpu ids
self.sys_device_ids = args.sys_device_ids
# random
self.set_seed = args.set_seed
if self.set_seed:
self.rand_seed = 0
else:
self.rand_seed = None
self.resize = args.resize
self.mean = [0.485, 0.456, 0.406]
self.std = [0.229, 0.224, 0.225]
# utils
self.load_model_weight = args.load_model_weight
self.model_weight_file = args.model_weight_file
if self.load_model_weight:
if self.model_weight_file == '':
print ('Please input the model_weight_file if you want to load model weight')
raise ValueError
# dataset
datasets = dict()
datasets['peta'] = './dataset/peta/peta_dataset.pkl'
datasets['rap'] = './dataset/rap/rap_dataset.pkl'
datasets['pa100k'] = './dataset/pa100k/pa100k_dataset.pkl'
if args.dataset in datasets:
dataset = pickle.load(open(datasets[args.dataset]))
else:
print ('%s does not exist.'%(args.dataset))
raise ValueError
self.att_list = [dataset['att_name'][i] for i in dataset['selected_attribute']]
# demo image
self.demo_image = args.demo_image
# model
model_kwargs = dict()
model_kwargs['num_att'] = len(self.att_list)
model_kwargs['last_conv_stride'] = args.last_conv_stride
self.model_kwargs = model_kwargs
### main function ###
cfg = Config()
# dump the configuration to log.
import pprint
print('-' * 60)
print('cfg.__dict__')
pprint.pprint(cfg.__dict__)
print('-' * 60)
# set the random seed
if cfg.set_seed:
set_seed( cfg.rand_seed )
# init the gpu ids
set_devices(cfg.sys_device_ids)
# dataset
normalize = transforms.Normalize(mean=cfg.mean, std=cfg.std)
test_transform = transforms.Compose([
transforms.Resize(cfg.resize),
transforms.ToTensor(),
normalize,])
### Att model ###
model = DeepMAR_ResNet50(**cfg.model_kwargs)
# load model weight if necessary
if cfg.load_model_weight:
map_location = (lambda storage, loc:storage)
ckpt = torch.load(cfg.model_weight_file, map_location=map_location)
model.load_state_dict(ckpt['state_dicts'][0])
model.cuda()
model.eval()
# load one image
img = Image.open(cfg.demo_image)
img_trans = test_transform( img )
img_trans = torch.unsqueeze(img_trans, dim=0)
img_var = Variable(img_trans).cuda()
score = model(img_var).data.cpu().numpy()
# show the score in command line
for idx in range(len(cfg.att_list)):
if score[0, idx] >= 0:
print ('%s: %.2f'%(cfg.att_list[idx], score[0, idx]))
# show the score in the image
img = img.resize(size=(256, 512), resample=Image.BILINEAR)
draw = ImageDraw.Draw(img)
positive_cnt = 0
for idx in range(len(cfg.att_list)):
if score[0, idx] >= 0:
txt = '%s: %.2f'%(cfg.att_list[idx], score[0, idx])
draw.text((10, 10 + 10*positive_cnt), txt, (255, 0, 0))
positive_cnt += 1
img.save('./dataset/demo/demo_image_result.png')
@@ -0,0 +1,483 @@
import sys
import os
import numpy as np
import random
import math
import torch
import torch.optim as optim
import torchvision.transforms as transforms
import torch.nn.functional as F
import torch.backends.cudnn as cudnn
from torch.autograd import Variable
from torch.nn.parallel import DataParallel
import pickle
import time
import argparse
import pdb
import sys
from torch.utils.tensorboard import SummaryWriter
from baseline.dataset import add_transforms
from baseline.dataset.Dataset import AttDataset
from baseline.model.DeepMAR import DeepMAR_ResNet50
from baseline.model.DeepMAR import DeepMAR_ResNet50_ExtractFeature
from baseline.utils.evaluate import attribute_evaluate
from baseline.utils.utils import str2bool
from baseline.utils.utils import transfer_optim_state
from baseline.utils.utils import time_str
from baseline.utils.utils import save_ckpt, load_ckpt
from baseline.utils.utils import load_state_dict
from baseline.utils.utils import ReDirectSTD
from baseline.utils.utils import adjust_lr_staircase
from baseline.utils.utils import adjust_lr
from baseline.utils.utils import set_devices
from baseline.utils.utils import AverageMeter
from baseline.utils.utils import to_scalar
from baseline.utils.utils import may_set_mode
from baseline.utils.utils import may_mkdir
from baseline.utils.utils import set_seed
from baseline.utils.utils import seed_everything
# Apex
import numpy as np
from apex import amp
import torch.npu
from benchmark_log import hwlog
from benchmark_log.basic_utils import get_environment_info
from benchmark_log.basic_utils import get_model_parameter
hwlog.ROOT_DIR = os.path.split(os.path.abspath(__file__))[0]
cpu_info, npu_info, framework_info, os_info, benchmark_version = get_environment_info("pytorch")
config_info = get_model_parameter("pytorch_config")
initinal_data = {"base_lr": 0.1, "dataset": "imagenet", "optimizer": "SGD", "loss_scale": 1024}
hwlog.remark_print(key=hwlog.CPU_INFO, value=cpu_info)
hwlog.remark_print(key=hwlog.NPU_INFO, value=npu_info)
hwlog.remark_print(key=hwlog.OS_INFO, value=os_info)
hwlog.remark_print(key=hwlog.FRAMEWORK_INFO, value=framework_info)
hwlog.remark_print(key=hwlog.BENCHMARK_VERSION, value=benchmark_version)
hwlog.remark_print(key=hwlog.CONFIG_INFO, value=config_info)
hwlog.remark_print(key=hwlog.BASE_LR, value=initinal_data.get("base_lr"))
hwlog.remark_print(key=hwlog.DATASET, value=initinal_data.get("dataset"))
hwlog.remark_print(key=hwlog.OPT_NAME, value=initinal_data.get("optimizer"))
hwlog.remark_print(key=hwlog.LOSS_SCALE, value=initinal_data.get("loss_scale"))
CALCULATE_DEVICE = "npu:7"
PRINT_DEVICE = "cpu"
class Config(object):
def __init__(self):
parser = argparse.ArgumentParser()
parser.add_argument('--npu', type=int, default=0, help='NPU id to use.')
parser.add_argument('--set_seed', type=str2bool, default=False)
## dataset parameter
parser.add_argument('--dataset', type=str, default='peta',
choices=['peta','rap', 'pa100k', 'rap2'])
parser.add_argument('--save_dir', type=str, default='/home/zhusiyi/dataset/peta/')
parser.add_argument('--split', type=str, default='trainval',
choices=['trainval', 'train'])
parser.add_argument('--test_split', type=str, default='test')
parser.add_argument('--partition_idx', type=int, default=0)
parser.add_argument('--resize', type=eval, default=(224, 224))
parser.add_argument('--mirror', type=str2bool, default=True)
parser.add_argument('--batch_size', type=int, default=32)
parser.add_argument('--workers', type=int, default=2)
# model
parser.add_argument('--num_att', type=int, default=35)
parser.add_argument('--pretrained', type=str2bool, default=True)
parser.add_argument('--last_conv_stride', type=int, default=2, choices=[1,2])
parser.add_argument('--drop_pool5', type=str2bool, default=True)
parser.add_argument('--drop_pool5_rate', type=float, default=0.5)
parser.add_argument('--sgd_weight_decay', type=float, default=0.0005)
parser.add_argument('--sgd_momentum', type=float, default=0.9)
parser.add_argument('--new_params_lr', type=float, default=0.001)
parser.add_argument('--finetuned_params_lr', type=float, default=0.001)
parser.add_argument('--staircase_decay_at_epochs', type=eval,
default=(51, ))
parser.add_argument('--staircase_decay_multiple_factor', type=float,
default=0.1)
parser.add_argument('--total_epochs', type=int, default=150)
parser.add_argument('--weighted_entropy', type=str2bool, default=True)
# utils
parser.add_argument('--resume', type=str2bool, default=False)
parser.add_argument('--ckpt_file', type=str, default='')
parser.add_argument('--load_model_weight', type=str2bool, default=False)
parser.add_argument('--model_weight_file', type=str, default='')
parser.add_argument('--test_only', type=str2bool, default=False)
parser.add_argument('--exp_dir', type=str, default='')
parser.add_argument('--exp_subpath', type=str, default='deepmar_resnet50')
parser.add_argument('--log_to_file', type=str2bool, default=True)
parser.add_argument('--steps_per_log', type=int, default=20)
parser.add_argument('--epochs_per_val', type=int, default=10)
parser.add_argument('--epochs_per_save', type=int, default=50)
parser.add_argument('--run', type=int, default=1)
# apex
parser.add_argument('--amp', default=False, action='store_true',
help='use amp to train the model')
parser.add_argument('--loss_scale', default=-1., type=float,
help='loss scale using in amp, default -1 means dynamic')
parser.add_argument('--opt_level', default='O1', type=str,
help='opt level using in amp, default O1 means FP16')
args = parser.parse_args()
# gpu ids
self.npu = args.npu
# random
self.set_seed = args.set_seed
if self.set_seed:
self.seed = 0
else:
self.seed = None
# amp
self.amp = args.amp
self.loss_scale = args.loss_scale
self.opt_level = args.opt_level
# run time index
self.run = args.run
# Dataset #
datasets = dict()
#datasets['peta'] = '/home/zhusiyi/dataset/peta/peta_dataset.pkl'
#datasets['peta'] = os.path.join(os.path.abspath(os.path.dirname(__file__)),'dataset/peta/peta_dataset.pkl')
datasets['peta'] = args.save_dir + '/peta_dataset.pkl'
partitions = dict()
#partitions['peta'] = '/home/zhusiyi/dataset/peta/peta_partition.pkl'
#partitions['peta'] = os.path.join(os.path.abspath(os.path.dirname(__file__)),'dataset/peta/peta_partition.pkl')
partitions['peta'] = args.save_dir + '/peta_partition.pkl'
self.dataset_name = args.dataset
if args.dataset not in datasets or args.dataset not in partitions:
print ("Please select the right dataset name.")
raise ValueError
else:
self.dataset = datasets[args.dataset]
self.partition = partitions[args.dataset]
self.partition_idx = args.partition_idx
self.split = args.split
self.test_split = args.test_split
self.resize = args.resize
self.mirror = args.mirror
self.mean = [0.485, 0.456, 0.406]
self.std = [0.229, 0.224, 0.225]
self.batch_size = args.batch_size
self.workers = args.workers
# optimization
self.sgd_momentum = args.sgd_momentum
self.sgd_weight_decay = args.sgd_weight_decay
self.new_params_lr = args.new_params_lr
self.finetuned_params_lr = args.finetuned_params_lr
self.staircase_decay_at_epochs = args.staircase_decay_at_epochs
self.staircase_decay_multiple_factor = args.staircase_decay_multiple_factor
self.total_epochs = args.total_epochs
self.weighted_entropy = args.weighted_entropy
# utils
self.resume = args.resume
self.ckpt_file = args.ckpt_file
if self.resume:
if self.ckpt_file == '':
print ('Please input the ckpt_file if you want to resume training')
raise ValueError
self.load_model_weight = args.load_model_weight
self.model_weight_file = args.model_weight_file
if self.load_model_weight:
if self.model_weight_file == '':
print ('Please input the model_weight_file if you want to load model weight')
raise ValueError
self.test_only = args.test_only
self.exp_dir = args.exp_dir
self.exp_subpath = args.exp_subpath
self.log_to_file = args.log_to_file
self.steps_per_log = args.steps_per_log
self.epochs_per_val = args.epochs_per_val
self.epochs_per_save = args.epochs_per_save
self.run = args.run
# for model
model_kwargs = dict()
model_kwargs['num_att'] = args.num_att
model_kwargs['last_conv_stride'] = args.last_conv_stride
model_kwargs['drop_pool5'] = args.drop_pool5
model_kwargs['drop_pool5_rate'] = args.drop_pool5_rate
self.model_kwargs = model_kwargs
# for evaluation
self.test_kwargs = dict()
if self.exp_dir == '':
self.exp_dir = os.path.join('exp',
'{}'.format(self.exp_subpath),
'{}'.format(self.dataset_name),
'partition{}'.format(self.partition_idx),
'run{}'.format(self.run))
self.stdout_file = os.path.join(self.exp_dir, \
'log', 'stdout_{}.txt'.format(time_str()))
self.stderr_file = os.path.join(self.exp_dir, \
'log', 'stderr_{}.txt'.format(time_str()))
may_mkdir(self.stdout_file)
### main function ###
cfg = Config()
# log
if cfg.log_to_file:
ReDirectSTD(cfg.stdout_file, 'stdout', False)
ReDirectSTD(cfg.stderr_file, 'stderr', False)
# dump the configuration to log.
import pprint
print('-' * 60)
print('cfg.__dict__')
pprint.pprint(cfg.__dict__)
print('-' * 60)
# set the random seed
print(cfg.seed)
if cfg.set_seed:
set_seed(cfg.seed)
seed_everything(cfg.seed)
# init the npu ids
CALCULATE_DEVICE = "npu:{}".format(cfg.npu)
torch.npu.set_device(CALCULATE_DEVICE)
# dataset
normalize = transforms.Normalize(mean=cfg.mean, std=cfg.std)
transform = transforms.Compose([
transforms.Resize(cfg.resize),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(), # 3*H*W, [0, 1]
normalize,]) # normalize with mean/std
# by a subset of attributes
train_set = AttDataset(
dataset = cfg.dataset,
partition = cfg.partition,
split = cfg.split,
partition_idx= cfg.partition_idx,
transform = transform)
num_att = len(train_set.dataset['selected_attribute'])
cfg.model_kwargs['num_att'] = num_att
train_loader = torch.utils.data.DataLoader(
dataset = train_set,
batch_size = cfg.batch_size,
shuffle = True,
num_workers = cfg.workers,
pin_memory = True,
drop_last = True)
test_transform = transforms.Compose([
transforms.Resize(cfg.resize),
transforms.ToTensor(),
normalize,])
test_set = AttDataset(
dataset = cfg.dataset,
partition = cfg.partition,
split = cfg.test_split,
partition_idx = cfg.partition_idx,
transform = test_transform)
### Att model ###
model = DeepMAR_ResNet50(**cfg.model_kwargs)
# Optimizer
finetuned_params = []
new_params = []
for n, p in model.named_parameters():
if n.find('classifier') >=0:
new_params.append(p)
else:
finetuned_params.append(p)
param_groups = [{'params': finetuned_params, 'lr': cfg.finetuned_params_lr},
{'params': new_params, 'lr': cfg.new_params_lr}]
optimizer = optim.SGD(
param_groups,
momentum = cfg.sgd_momentum,
weight_decay = cfg.sgd_weight_decay)
model = model.to(CALCULATE_DEVICE)
# apex
if cfg.amp:
# Initialization
model, optimizer = amp.initialize(model, optimizer, opt_level=cfg.opt_level, loss_scale=cfg.loss_scale)
print("=> Using amp mode.")
# using the weighted cross entropy loss
if cfg.weighted_entropy:
rate = np.array(train_set.partition['weight_' + cfg.split][cfg.partition_idx])
rate = rate[train_set.dataset['selected_attribute']].tolist()
else:
rate = None
# compute the weight of positive and negative
if rate is None:
weight_pos = [1 for i in range(num_att)]
weight_neg = [1 for i in range(num_att)]
else:
if len(rate) != num_att:
print ("the length of rate should be equal to %d" % (num_att))
raise ValueError
weight_pos = []
weight_neg = []
for idx, v in enumerate(rate):
weight_pos.append(math.exp(1.0 - v))
weight_neg.append(math.exp(v))
# bind the model and optimizer
modules_optims = [model, optimizer]
# load model weight if necessary
if cfg.load_model_weight:
map_location = (lambda storage, loc:storage)
ckpt = torch.load(cfg.model_weight_file, map_location=map_location)
model.load_state_dict(ckpt['state_dicts'][0], strict=False)
# print(ckpt['state_dicts'][0])
### Resume or not ###
if cfg.resume:
# store the model, optimizer, epoch
start_epoch, scores = load_ckpt(modules_optims, cfg.ckpt_file)
else:
start_epoch = 0
model = torch.nn.DataParallel(model)
# model_w.cuda()
transfer_optim_state(state=optimizer.state, device_id=cfg.npu)
# cudnn.benchmark = True
# for evaluation
feat_func_att = DeepMAR_ResNet50_ExtractFeature(model=model)
def attribute_evaluate_subfunc(feat_func, test_set, device_id, **test_kwargs):
""" evaluate the attribute recognition precision """
result = attribute_evaluate(feat_func, test_set, device_id, **test_kwargs)
print ('-' * 60)
print ('Evaluation on %s set:' % (cfg.test_split))
print ('Label-based evaluation: \n mA: %.4f'%(np.mean(result['label_acc'])))
print ('Instance-based evaluation: \n Acc: %.4f, Prec: %.4f, Rec: %.4f, F1: %.4f' \
%(result['instance_acc'], result['instance_precision'], result['instance_recall'], result['instance_F1']))
print ('-' * 60)
hwlog.remark_print(key=hwlog.ACC, value="{:.4f}".format(result['instance_acc']))
hwlog.remark_print(key=hwlog.PREC, value="{:.4f}".format(result['instance_precision']))
hwlog.remark_print(key=hwlog.REC, value="{:.4f}".format(result['instance_recall']))
hwlog.remark_print(key=hwlog.F1, value="{:.4f}".format(result['instance_recall']))
return result['instance_acc']
# print the model into log
# test only
if cfg.test_only:
print ('test with feat_func_att')
attribute_evaluate_subfunc(feat_func_att, test_set, **cfg.test_kwargs)
sys.exit(0)
# writer = SummaryWriter(os.path.join('runs/deepmar', str(cfg.npu)))
# training
for epoch in range(start_epoch, cfg.total_epochs):
if cfg.seed is not None:
cfg.seed += 1
seed_everything(cfg.seed)
# adjust the learning rate
adjust_lr_staircase(
optimizer.param_groups,
[cfg.finetuned_params_lr, cfg.new_params_lr],
epoch + 1,
cfg.staircase_decay_at_epochs,
cfg.staircase_decay_multiple_factor)
# adjust_lr(optimizer,epoch+1,cfg.finetuned_params_lr)n
may_set_mode(modules_optims, 'train')
# recording loss
loss_meter = AverageMeter()
dataset_L = len(train_loader) # crop batch data
ep_st = time.time()
ep_st_mark=ep_st
# runing every batch data
for step, (imgs, targets) in enumerate(train_loader):
step_st = time.time()
# measure data loading time
data_time = step_st-ep_st
imgs_var = Variable(imgs)
targets_var = Variable(targets)
# compute the weight
weights = torch.zeros(targets_var.shape)
for i in range(targets_var.shape[0]):
for j in range(targets_var.shape[1]):
if targets_var.data.cpu()[i, j] == -1:
weights[i, j] = weight_neg[j]
elif targets_var.data.cpu()[i, j] == 1:
weights[i, j] = weight_pos[j]
else:
weights[i, j] = 0
targets_var[targets_var == -1] = 0
targets_var = targets_var.to(CALCULATE_DEVICE)
imgs_var = imgs_var.to(CALCULATE_DEVICE)
weights = weights.to(CALCULATE_DEVICE)
score = model(imgs_var)
criterion = torch.nn.BCEWithLogitsLoss(weight=Variable(weights)).to(CALCULATE_DEVICE)
loss = criterion(score, targets_var) * num_att
optimizer.zero_grad()
if cfg.amp:
with amp.scale_loss(loss, optimizer) as scaled_loss:
scaled_loss.backward()
else:
loss.backward()
optimizer.step()
############
# step log #
############
loss_meter.update(to_scalar(loss))
# one batch time using backward calculation
batch_time = time.time() - ep_st # include data load time
ep_st = time.time()
fps = cfg.batch_size / batch_time
# do not include data load time
if (step + 1) % cfg.steps_per_log == 0 or (step + 1) % len(train_loader) == 0:
log = '{}, Step {}/{} in Ep {}, {:.2f}s, datatime:{:.6f}, batchtime:{:.6f}, FPS:{:.2f}, loss:{:.4f}'.format( \
time_str(), step + 1, dataset_L, epoch + 1, time.time() - step_st, data_time, batch_time, fps, loss_meter.val)
print(log)
hwlog.remark_print(key=hwlog.FPS, value='{:.2f}'.format(fps))
##############
# epoch log #
##############
epoch_time = time.time() - ep_st_mark
log = 'Ep{}, {:.2f}s, loss {:.4f}'.format(
epoch+1, epoch_time, loss_meter.avg)
print(log)
# writer.add_scalar('Train/Time', epoch_time, epoch+1)
# writer.add_scalar('Train/Loss', loss_meter.avg, epoch+1)
# writer.add_scalar('Train/LR', optimizer.param_groups[0]['lr'], epoch+1)
# model ckpt
if (epoch + 1) % cfg.epochs_per_save == 0 or epoch+1 == cfg.total_epochs:
ckpt_file = os.path.join(cfg.exp_dir, 'model', 'ckpt_epoch%d.pth'%(epoch+1))
save_ckpt(modules_optims, epoch+1, 0, ckpt_file)
##########################
# test on validation set #
##########################
if (epoch + 1) % cfg.epochs_per_val == 0 or epoch+1 == cfg.total_epochs:
print ('att test with feat_func_att')
res = attribute_evaluate_subfunc(feat_func_att, test_set, CALCULATE_DEVICE, **cfg.test_kwargs)
# writer.add_scalar('Val/Acc', res, epoch)
@@ -0,0 +1,587 @@
import os
import random
import math
import torch
import torch.optim as optim
import torchvision.transforms as transforms
import torch.nn.functional as F
import torch.backends.cudnn as cudnn
from torch.autograd import Variable
from torch.nn.parallel import DataParallel
import pickle
import time
import argparse
import pdb
import sys
from torch.utils.tensorboard import SummaryWriter
from baseline.dataset import add_transforms
from baseline.dataset.Dataset import AttDataset
from baseline.model.DeepMAR import DeepMAR_ResNet50
from baseline.model.DeepMAR import DeepMAR_ResNet50_ExtractFeature
from baseline.utils.evaluate import attribute_evaluate
from baseline.utils.utils import str2bool
from baseline.utils.utils import transfer_optim_state
from baseline.utils.utils import time_str
from baseline.utils.utils import save_ckpt, load_ckpt
from baseline.utils.utils import load_state_dict
from baseline.utils.utils import ReDirectSTD
from baseline.utils.utils import adjust_lr_staircase
from baseline.utils.utils import adjust_lr
from baseline.utils.utils import set_devices
from baseline.utils.utils import AverageMeter
from baseline.utils.utils import to_scalar
from baseline.utils.utils import may_set_mode
from baseline.utils.utils import may_mkdir
from baseline.utils.utils import set_seed
from baseline.utils.utils import seed_everything
import torch.distributed as dist
import torch.multiprocessing as mp
import torch.utils.data.distributed
# Apex
import numpy as np
from apex import amp
import torch.npu
from benchmark_log import hwlog
from benchmark_log.basic_utils import get_environment_info
from benchmark_log.basic_utils import get_model_parameter
class Config(object):
def __init__(self):
parser = argparse.ArgumentParser()
parser.add_argument('--sys_device_ids', type=eval, default=6)
parser.add_argument('--npu', default=None, type=int, help='NPU id to use.')
parser.add_argument('--set_seed', type=str2bool, default=False)
## dataset parameter
parser.add_argument('--dataset', type=str, default='peta',
choices=['peta','rap', 'pa100k', 'rap2'])
parser.add_argument('--save_dir', type=str, default='/home/zhusiyi/dataset/peta/')
parser.add_argument('--split', type=str, default='trainval',
choices=['trainval', 'train'])
parser.add_argument('--test_split', type=str, default='test')
parser.add_argument('--partition_idx', type=int, default=0)
parser.add_argument('--resize', type=eval, default=(224, 224))
parser.add_argument('--mirror', type=str2bool, default=True)
parser.add_argument('--batch_size', type=int, default=32)
parser.add_argument('--workers', type=int, default=2)
# model
parser.add_argument('--num_att', type=int, default=35)
parser.add_argument('--pretrained', type=str2bool, default=True)
parser.add_argument('--last_conv_stride', type=int, default=2, choices=[1,2])
parser.add_argument('--drop_pool5', type=str2bool, default=True)
parser.add_argument('--drop_pool5_rate', type=float, default=0.5)
parser.add_argument('--sgd_weight_decay', type=float, default=0.0005)
parser.add_argument('--sgd_momentum', type=float, default=0.9)
parser.add_argument('--new_params_lr', type=float, default=0.001)
parser.add_argument('--finetuned_params_lr', type=float, default=0.001)
parser.add_argument('--staircase_decay_at_epochs', type=eval,
default=(51, ))
parser.add_argument('--staircase_decay_multiple_factor', type=float,
default=0.1)
parser.add_argument('--total_epochs', type=int, default=150)
parser.add_argument('--weighted_entropy', type=str2bool, default=True)
# utils
parser.add_argument('--resume', type=str2bool, default=False)
parser.add_argument('--ckpt_file', type=str, default='')
parser.add_argument('--load_model_weight', type=str2bool, default=False)
parser.add_argument('--model_weight_file', type=str, default='')
parser.add_argument('--test_only', type=str2bool, default=False)
parser.add_argument('--exp_dir', type=str, default='')
parser.add_argument('--exp_subpath', type=str, default='deepmar_resnet50')
parser.add_argument('--log_to_file', type=str2bool, default=True)
parser.add_argument('--steps_per_log', type=int, default=20)
parser.add_argument('--epochs_per_val', type=int, default=10)
parser.add_argument('--epochs_per_save', type=int, default=50)
parser.add_argument('--run', type=int, default=1)
# apex
parser.add_argument('--amp', default=False, action='store_true',
help='use amp to train the model')
parser.add_argument('--loss_scale', default=-1., type=float,
help='loss scale using in amp, default -1 means dynamic')
parser.add_argument('--opt_level', default='O1', type=str,
help='opt level using in amp, default O1 means FP16')
# distributed
parser.add_argument('--addr', default='90.90.176.152', type=str,
help='master addr')
parser.add_argument('--world_size', default=-1, type=int,
help='number of nodes for distributed training')
parser.add_argument('--rank', default=-1, type=int,
help='node rank for distributed training')
parser.add_argument('--dist_url', default='tcp://224.66.41.62:23456', type=str,
help='url used to set up distributed training')
parser.add_argument('--dist_backend', default='nccl', type=str,
help='distributed backend')
parser.add_argument('--multiprocessing_distributed', action='store_true',
help='Use multi-processing distributed training to launch '
'N processes per node, which has N NPUs. This is the '
'fastest way to use PyTorch for either single node or '
'multi node data parallel training')
parser.add_argument('--npus_per_node', default=None, type=int,
help='number of npus to use for distributed train on each node')
args = parser.parse_args()
# gpu ids
# self.sys_device_ids = args.sys_device_ids
self.npus_per_node=args.npus_per_node
self.npu = args.npu
# random
self.set_seed = args.set_seed
if self.set_seed:
self.seed = 0
else:
self.seed = None
# amp
self.amp = args.amp
self.loss_scale = args.loss_scale
self.opt_level = args.opt_level
# run time index
self.run = args.run
# Dataset #
datasets = dict()
datasets['peta'] = args.save_dir + '/peta_dataset.pkl'
partitions = dict()
partitions['peta'] = args.save_dir + '/peta_partition.pkl'
self.dataset_name = args.dataset
if args.dataset not in datasets or args.dataset not in partitions:
print ("Please select the right dataset name.")
raise ValueError
else:
self.dataset = datasets[args.dataset]
self.partition = partitions[args.dataset]
self.partition_idx = args.partition_idx
self.split = args.split
self.test_split = args.test_split
self.resize = args.resize
self.mirror = args.mirror
self.mean = [0.485, 0.456, 0.406]
self.std = [0.229, 0.224, 0.225]
self.batch_size = args.batch_size
self.workers = args.workers
# optimization
self.sgd_momentum = args.sgd_momentum
self.sgd_weight_decay = args.sgd_weight_decay
self.new_params_lr = args.new_params_lr
self.finetuned_params_lr = args.finetuned_params_lr
self.staircase_decay_at_epochs = args.staircase_decay_at_epochs
self.staircase_decay_multiple_factor = args.staircase_decay_multiple_factor
self.total_epochs = args.total_epochs
self.weighted_entropy = args.weighted_entropy
# distributed
self.addr = args.addr
self.world_size = args.world_size
self.rank = args.rank
self.dist_url = args.dist_url
self.dist_backend = args.dist_backend
self.multiprocessing_distributed = args.multiprocessing_distributed
# utils
self.resume = args.resume
self.ckpt_file = args.ckpt_file
if self.resume:
if self.ckpt_file == '':
print ('Please input the ckpt_file if you want to resume training')
raise ValueError
self.load_model_weight = args.load_model_weight
self.model_weight_file = args.model_weight_file
if self.load_model_weight:
if self.model_weight_file == '':
print ('Please input the model_weight_file if you want to load model weight')
raise ValueError
self.test_only = args.test_only
self.exp_dir = args.exp_dir
self.exp_subpath = args.exp_subpath
self.log_to_file = args.log_to_file
self.steps_per_log = args.steps_per_log
self.epochs_per_val = args.epochs_per_val
self.epochs_per_save = args.epochs_per_save
self.run = args.run
# for model
model_kwargs = dict()
model_kwargs['num_att'] = args.num_att
model_kwargs['last_conv_stride'] = args.last_conv_stride
model_kwargs['drop_pool5'] = args.drop_pool5
model_kwargs['drop_pool5_rate'] = args.drop_pool5_rate
self.model_kwargs = model_kwargs
# for evaluation
self.test_kwargs = dict()
if self.exp_dir == '':
self.exp_dir = os.path.join('exp',
'{}'.format(self.exp_subpath),
'{}'.format(self.dataset_name),
'partition{}'.format(self.partition_idx),
'run{}'.format(self.run))
self.stdout_file = os.path.join(self.exp_dir, \
'log', 'stdout_{}.txt'.format(time_str()))
self.stderr_file = os.path.join(self.exp_dir, \
'log', 'stderr_{}.txt'.format(time_str()))
may_mkdir(self.stdout_file)
def main():
### main function ###
# pdb.set_trace()
cfg = Config()
# log
if cfg.log_to_file:
ReDirectSTD(cfg.stdout_file, 'stdout', False)
ReDirectSTD(cfg.stderr_file, 'stderr', False)
# dump the configuration to log.
import pprint
print('-' * 60)
print('cfg.__dict__')
pprint.pprint(cfg.__dict__)
print('-' * 60)
os.environ['KERNEL_NAME_ID'] = str(0)
print("+++++++++++++++++++++++++++KERNEL_NAME_ID:",os.environ['KERNEL_NAME_ID'])
# set the random seed
print(cfg.seed)
if cfg.set_seed:
set_seed(cfg.seed)
seed_everything(cfg.seed)
os.environ['MASTER_ADDR'] = cfg.addr
os.environ['MASTER_PORT'] = '29501'
if cfg.dist_url == "env://" and cfg.world_size == -1:
cfg.world_size = int(os.environ["WORLD_SIZE"])
npus_per_node=cfg.npus_per_node
#npus_per_node = torch.npu.device_count()
if cfg.multiprocessing_distributed:
# Since we have ngpus_per_node processes per node, the total world_size needs to be adjusted accordingly
cfg.world_size = npus_per_node * cfg.world_size # world_size means nums of all devices or nums of processes
mp.spawn(main_worker, nprocs=npus_per_node, args=(npus_per_node, cfg))
def main_worker(npu, npus_per_node, cfg):
cfg.npu = npu
print("[npu id:", npu, "]", "+++++++++++++++++++++++++++ before set KERNEL_NAME_ID:", os.environ['KERNEL_NAME_ID'])
os.environ['KERNEL_NAME_ID'] = str(npu)
print("[npu id:", npu, "]", "+++++++++++++++++++++++++++KERNEL_NAME_ID:", os.environ['KERNEL_NAME_ID'])
if npu is not None:
print("[npu id:", npu, "]", "Use NPU: {} for training".format(npu))
if cfg.dist_url == "env://" and cfg.rank == -1:
cfg.rank = int(os.environ["RANK"])
if cfg.multiprocessing_distributed:
# For multiprocessing distributed training, rank needs to be the
# global rank among all the processes
#cfg.rank = cfg.rank * npus_per_node + npu
cfg.rank = npu
print("rank:",cfg.rank)
dist.init_process_group(backend=cfg.dist_backend, #init_method=cfg.dist_url,
world_size=cfg.world_size, rank=cfg.rank)
CALCULATE_DEVICE = 'npu:{}'.format(npu)
print(CALCULATE_DEVICE)
torch.npu.set_device(CALCULATE_DEVICE)
# DistributedDataParallel, we need to divide the batch size
# ourselves based on the total number of NPUs we have
cfg.batch_size = int(cfg.batch_size / npus_per_node)
cfg.workers = int((cfg.workers + npus_per_node - 1) / npus_per_node)
print("batchsize:", cfg.batch_size)
print("workers", cfg.workers)
# dataset
normalize = transforms.Normalize(mean=cfg.mean, std=cfg.std)
transform = transforms.Compose([
transforms.Resize(cfg.resize),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(), # 3*H*W, [0, 1]
normalize,]) # normalize with mean/std
# by a subset of attributes
train_set = AttDataset(
dataset = cfg.dataset,
partition = cfg.partition,
split = cfg.split,
partition_idx= cfg.partition_idx,
transform = transform)
num_att = len(train_set.dataset['selected_attribute'])
cfg.model_kwargs['num_att'] = num_att
distributed = cfg.world_size > 1 or cfg.multiprocessing_distributed
if distributed:
train_sampler = torch.utils.data.distributed.DistributedSampler(train_set)
else:
train_sampler = None
train_loader = torch.utils.data.DataLoader(
dataset = train_set,
batch_size = cfg.batch_size,
shuffle=(train_sampler is None),
num_workers = cfg.workers,
pin_memory = True,
sampler=train_sampler,
drop_last = True)
test_transform = transforms.Compose([
transforms.Resize(cfg.resize),
transforms.ToTensor(),
normalize,])
test_set = AttDataset(
dataset = cfg.dataset,
partition = cfg.partition,
split = cfg.test_split,
partition_idx = cfg.partition_idx,
transform = test_transform)
### Att model ###
model = DeepMAR_ResNet50(**cfg.model_kwargs)
# Optimizer
finetuned_params = []
new_params = []
for n, p in model.named_parameters():
if n.find('classifier') >=0:
new_params.append(p)
else:
finetuned_params.append(p)
param_groups = [{'params': finetuned_params, 'lr': cfg.finetuned_params_lr},
{'params': new_params, 'lr': cfg.new_params_lr}]
optimizer = optim.SGD(
param_groups,
momentum = cfg.sgd_momentum,
weight_decay = cfg.sgd_weight_decay)
# model = model.cuda()
model = model.to(CALCULATE_DEVICE)
# apex
if cfg.amp:
# Initialization
model, optimizer = amp.initialize(model, optimizer, opt_level=cfg.opt_level, loss_scale=cfg.loss_scale)
print("=> Using amp mode.")
# Wrap the model after set_devices, data parallel
# model_w = torch.nn.DataParallel(model)
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[cfg.npu], broadcast_buffers=False)
# using the weighted cross entropy loss
if cfg.weighted_entropy:
rate = np.array(train_set.partition['weight_' + cfg.split][cfg.partition_idx])
rate = rate[train_set.dataset['selected_attribute']].tolist()
else:
rate = None
# compute the weight of positive and negative
if rate is None:
weight_pos = [1 for i in range(num_att)]
weight_neg = [1 for i in range(num_att)]
else:
if len(rate) != num_att:
print ("the length of rate should be equal to %d" % (num_att))
raise ValueError
weight_pos = []
weight_neg = []
for idx, v in enumerate(rate):
weight_pos.append(math.exp(1.0 - v))
weight_neg.append(math.exp(v))
# bind the model and optimizer
modules_optims = [model, optimizer]
# load model weight if necessary
if cfg.load_model_weight:
map_location = (lambda storage, loc:storage)
ckpt = torch.load(cfg.model_weight_file, map_location=map_location)
model.load_state_dict(ckpt['state_dicts'][0], strict=False)
### Resume or not ###
if cfg.resume:
# store the model, optimizer, epoch
start_epoch, scores = load_ckpt(modules_optims, cfg.ckpt_file)
else:
start_epoch = 0
#model = torch.nn.DataParallel(model)
#transfer_optim_state(state=optimizer.state, device_id=npu)
# cudnn.benchmark = True
# for evaluation
feat_func_att = DeepMAR_ResNet50_ExtractFeature(model=model)
# print the model into log
# print (model)
# test only
if cfg.test_only:
print ('test with feat_func_att')
attribute_evaluate_subfunc(feat_func_att, test_set, **cfg.test_kwargs)
sys.exit(0)
# writer = SummaryWriter('runs/deepmar/6')
# training
for epoch in range(start_epoch, cfg.total_epochs):
if cfg.seed is not None:
cfg.seed += 1
seed_everything(cfg.seed)
if distributed:
train_sampler.set_epoch(epoch)
# adjust the learning rate
adjust_lr_staircase(
optimizer.param_groups,
[cfg.finetuned_params_lr, cfg.new_params_lr],
epoch + 1,
cfg.staircase_decay_at_epochs,
cfg.staircase_decay_multiple_factor)
# adjust_lr(optimizer,epoch+1,cfg.finetuned_params_lr)n
may_set_mode(modules_optims, 'train')
# recording loss
loss_meter = AverageMeter()
dataset_L = len(train_loader) # crop batch data
ep_st = time.time()
ep_st_mark=ep_st
# runing every batch data
for step, (imgs, targets) in enumerate(train_loader):
step_st = time.time()
# measure data loading time
data_time = step_st-ep_st
imgs_var = Variable(imgs)
targets_var = Variable(targets)
# if 'npu' in CALCULATE_DEVICE:
# targets = targets.to(torch.int32)
# imgs, targets = imgs.to(CALCULATE_DEVICE, non_blocking=True), targets.to(CALCULATE_DEVICE, non_blocking=True)
# compute the weight
weights = torch.zeros(targets_var.shape)
for i in range(targets_var.shape[0]):
for j in range(targets_var.shape[1]):
if targets_var.data.cpu()[i, j] == -1:
weights[i, j] = weight_neg[j]
elif targets_var.data.cpu()[i, j] == 1:
weights[i, j] = weight_pos[j]
else:
weights[i, j] = 0
# loss for the attribute classification, average over the batch size
targets_var[targets_var == -1] = 0
targets_var = targets_var.to(CALCULATE_DEVICE)
imgs_var = imgs_var.to(CALCULATE_DEVICE)
weights = weights.to(CALCULATE_DEVICE)
score = model(imgs_var)
criterion = torch.nn.BCEWithLogitsLoss(weight=Variable(weights)).to(CALCULATE_DEVICE)
loss = criterion(score, targets_var) * num_att
optimizer.zero_grad()
if cfg.amp:
with amp.scale_loss(loss, optimizer) as scaled_loss:
scaled_loss.backward()
else:
loss.backward()
# for name, parms in model.named_parameters():
# print('-->name:', name, ' -->grad_value_max:', torch.max(parms.grad), ' -->grad_value_min:',
# torch.min(parms.grad))
optimizer.step()
############
# step log #
############
loss_meter.update(to_scalar(loss))
# one batch time using backward calculation
batch_time = time.time() - ep_st # include data load time
ep_st = time.time()
fps = npus_per_node*cfg.batch_size / batch_time
# do not include data load time
if (step + 1) % cfg.steps_per_log == 0 or (step + 1) % len(train_loader) == 0:
log = '{}, Step {}/{} in Ep {}, {:.2f}s, datatime:{:.6f}, batchtime:{:.6f}, FPS:{:.2f}, loss:{:.4f}'.format( \
time_str(), step + 1, dataset_L, epoch + 1, time.time() - step_st, data_time, batch_time, fps, loss_meter.val)
print(log)
hwlog.remark_print(key=hwlog.FPS, value='{:.2f}'.format(fps))
##############
# epoch log #
##############
epoch_time = time.time() - ep_st_mark
log = 'Ep{}, {:.2f}s, loss {:.4f}'.format(
epoch+1, epoch_time, loss_meter.avg)
print(log)
# writer.add_scalar('Train/Time', epoch_time, epoch+1)
# writer.add_scalar('Train/Loss', loss_meter.avg, epoch+1)
# # writer.add_scalar('Train/Acc', res['instance_acc'], epoch+1)
# writer.add_scalar('Train/LR', optimizer.param_groups[0]['lr'], epoch+1)
# model ckpt
if (epoch + 1) % cfg.epochs_per_save == 0 or epoch+1 == cfg.total_epochs:
ckpt_file = os.path.join(cfg.exp_dir, 'model', 'ckpt_epoch%d.pth'%(epoch+1))
save_ckpt(modules_optims, epoch+1, 0, ckpt_file)
##########################
# test on validation set #
##########################
if (epoch + 1) % cfg.epochs_per_val == 0 or epoch+1 == cfg.total_epochs:
print ('att test with feat_func_att')
res = attribute_evaluate_subfunc(feat_func_att, test_set, CALCULATE_DEVICE, cfg, **cfg.test_kwargs)
# writer.add_scalar('Val/Acc', res, epoch)
# writer.close()
def attribute_evaluate_subfunc(feat_func, test_set, device_id, cfg, **test_kwargs):
""" evaluate the attribute recognition precision """
result = attribute_evaluate(feat_func, test_set, device_id, **test_kwargs)
print ('-' * 60)
print ('Evaluation on %s set:' % (cfg.test_split))
print ('Label-based evaluation: \n mA: %.4f'%(np.mean(result['label_acc'])))
print ('Instance-based evaluation: \n Acc: %.4f, Prec: %.4f, Rec: %.4f, F1: %.4f' \
%(result['instance_acc'], result['instance_precision'], result['instance_recall'], result['instance_F1']))
print ('-' * 60)
hwlog.remark_print(key=hwlog.ACC, value="{:.4f}".format(result['instance_acc']))
hwlog.remark_print(key=hwlog.PREC, value="{:.4f}".format(result['instance_precision']))
hwlog.remark_print(key=hwlog.REC, value="{:.4f}".format(result['instance_recall']))
hwlog.remark_print(key=hwlog.F1, value="{:.4f}".format(result['instance_recall']))
return result['instance_acc']
# intermediate variable
inter_feature = {}
inter_gradient = {}
def make_hook(name, flag):
if flag == 'forward':
def hook(m, input, output):
inter_feature[name] = input
return hook
elif flag == 'backward':
def hook(m, input, output):
inter_gradient[name] = output
return hook
else:
assert False
if __name__ == '__main__':
hwlog.ROOT_DIR = os.path.split(os.path.abspath(__file__))[0]
cpu_info, npu_info, framework_info, os_info, benchmark_version = get_environment_info("pytorch")
config_info = get_model_parameter("pytorch_config")
initinal_data = {"base_lr": 0.1, "dataset": "imagenet", "optimizer": "SGD", "loss_scale": 1024}
hwlog.remark_print(key=hwlog.CPU_INFO, value=cpu_info)
hwlog.remark_print(key=hwlog.NPU_INFO, value=npu_info)
hwlog.remark_print(key=hwlog.OS_INFO, value=os_info)
hwlog.remark_print(key=hwlog.FRAMEWORK_INFO, value=framework_info)
hwlog.remark_print(key=hwlog.BENCHMARK_VERSION, value=benchmark_version)
hwlog.remark_print(key=hwlog.CONFIG_INFO, value=config_info)
hwlog.remark_print(key=hwlog.BASE_LR, value=initinal_data.get("base_lr"))
hwlog.remark_print(key=hwlog.DATASET, value=initinal_data.get("dataset"))
hwlog.remark_print(key=hwlog.OPT_NAME, value=initinal_data.get("optimizer"))
hwlog.remark_print(key=hwlog.LOSS_SCALE, value=initinal_data.get("loss_scale"))
main()
@@ -0,0 +1,96 @@
import os
import numpy as np
import random
import cPickle as pickle
from scipy.io import loadmat
np.random.seed(0)
random.seed(0)
def make_dir(path):
if os.path.exists(path):
pass
else:
os.mkdir(path)
def generate_data_description(save_dir):
"""
create a dataset description file, which consists of images, labels
"""
dataset = dict()
dataset['description'] = 'pa100k'
dataset['root'] = './dataset/pa100k/data/'
dataset['image'] = []
dataset['att'] = []
dataset['att_name'] = []
dataset['selected_attribute'] = range(26)
# load ANNOTATION.MAT
data = loadmat(open('./dataset/pa100k/annotation.mat', 'r'))
for idx in range(26):
dataset['att_name'].append(data['attributes'][idx][0][0])
for idx in range(80000):
dataset['image'].append(data['train_images_name'][idx][0][0])
dataset['att'].append(data['train_label'][idx, :].tolist())
for idx in range(10000):
dataset['image'].append(data['val_images_name'][idx][0][0])
dataset['att'].append(data['val_label'][idx, :].tolist())
for idx in range(10000):
dataset['image'].append(data['test_images_name'][idx][0][0])
dataset['att'].append(data['test_label'][idx, :].tolist())
with open(os.path.join(save_dir, 'pa100k_dataset.pkl'), 'w+') as f:
pickle.dump(dataset, f)
def create_trainvaltest_split(traintest_split_file):
"""
create a dataset split file, which consists of index of the train/val/test splits
"""
partition = dict()
partition['trainval'] = []
partition['train'] = []
partition['val'] = []
partition['test'] = []
partition['weight_trainval'] = []
partition['weight_train'] = []
# load ANNOTATION.MAT
data = loadmat(open('./dataset/pa100k/annotation.mat', 'r'))
train = range(80000)
val = [i+80000 for i in range(10000)]
test = [i+90000 for i in range(10000)]
trainval = train + val
partition['train'].append(train)
partition['val'].append(val)
partition['trainval'].append(trainval)
partition['test'].append(test)
# weight
train_label = data['train_label'].astype('float32')
trainval_label = np.concatenate((data['train_label'], data['val_label']), axis=0).astype('float32')
weight_train = np.mean(train_label==1, axis=0).tolist()
weight_trainval = np.mean(trainval_label==1, axis=0).tolist()
partition['weight_trainval'].append(weight_trainval)
partition['weight_train'].append(weight_train)
with open(traintest_split_file, 'w+') as f:
pickle.dump(partition, f)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="pa100k dataset")
parser.add_argument(
'--save_dir',
type=str,
default='./dataset/pa100k/')
parser.add_argument(
'--traintest_split_file',
type=str,
default="./dataset/pa100k/pa100k_partition.pkl")
args = parser.parse_args()
save_dir = args.save_dir
traintest_split_file = args.traintest_split_file
generate_data_description(save_dir)
create_trainvaltest_split(traintest_split_file)
@@ -0,0 +1,84 @@
import os
import numpy as np
import random
import pickle
from scipy.io import loadmat
np.random.seed(0)
random.seed(0)
def make_dir(path):
if os.path.exists(path):
pass
else:
os.mkdir(path)
def generate_data_description(save_dir):
"""
create a dataset description file, which consists of images, labels
"""
dataset = dict()
dataset['description'] = 'peta'
dataset['root'] = save_dir + '/images/'
dataset['image'] = []
dataset['att'] = []
dataset['att_name'] = []
dataset['selected_attribute'] = range(35)
# load PETA.MAT
data = loadmat(save_dir + '/PETA.mat')
for idx in range(105):
dataset['att_name'].append(data['peta'][0][0][1][idx,0][0])
for idx in range(19000):
dataset['image'].append('%05d.png'%(idx+1))
dataset['att'].append(data['peta'][0][0][0][idx, 4:].tolist())
with open(os.path.join(save_dir, 'peta_dataset.pkl'), 'wb') as f:
pickle.dump(dataset, f)
def create_trainvaltest_split(traintest_split_file):
"""
create a dataset split file, which consists of index of the train/val/test splits
"""
partition = dict()
partition['trainval'] = []
partition['train'] = []
partition['val'] = []
partition['test'] = []
partition['weight_trainval'] = []
partition['weight_train'] = []
# load PETA.MAT
data = loadmat(save_dir + '/PETA.mat')
for idx in range(5):
train = (data['peta'][0][0][3][idx][0][0][0][0][:,0]-1).tolist()
val = (data['peta'][0][0][3][idx][0][0][0][1][:,0]-1).tolist()
test = (data['peta'][0][0][3][idx][0][0][0][2][:,0]-1).tolist()
trainval = train + val
partition['train'].append(train)
partition['val'].append(val)
partition['trainval'].append(trainval)
partition['test'].append(test)
# weight
weight_trainval = np.mean(data['peta'][0][0][0][trainval, 4:].astype('float32')==1, axis=0).tolist()
weight_train = np.mean(data['peta'][0][0][0][train, 4:].astype('float32')==1, axis=0).tolist()
partition['weight_trainval'].append(weight_trainval)
partition['weight_train'].append(weight_train)
with open(traintest_split_file, 'wb') as f:
pickle.dump(partition, f)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="peta dataset")
parser.add_argument(
'--save_dir',
type=str,
default='/home/zhusiyi/dataset/peta/')
parser.add_argument(
'--traintest_split_file',
type=str,
default="/home/zhusiyi/dataset/peta/peta_partition.pkl")
args = parser.parse_args()
save_dir = args.save_dir
traintest_split_file = args.traintest_split_file
generate_data_description(save_dir)
create_trainvaltest_split(traintest_split_file)
@@ -0,0 +1,76 @@
import os
import numpy as np
import random
import cPickle as pickle
from scipy.io import loadmat
np.random.seed(0)
random.seed(0)
def make_dir(path):
if os.path.exists(path):
pass
else:
os.mkdir(path)
def generate_data_description(save_dir):
"""
create a dataset description file, which consists of images, labels
"""
dataset = dict()
dataset['description'] = 'rap'
dataset['root'] = './dataset/rap/RAP_dataset/'
dataset['image'] = []
dataset['att'] = []
dataset['att_name'] = []
dataset['selected_attribute'] = range(51)
# load Rap_annotation.mat
data = loadmat(open('./dataset/rap/RAP_annotation/RAP_annotation.mat', 'r'))
for idx in range(51):
dataset['att_name'].append(data['RAP_annotation'][0][0][6][idx][0][0])
for idx in range(41585):
dataset['image'].append(data['RAP_annotation'][0][0][5][idx][0][0])
dataset['att'].append(data['RAP_annotation'][0][0][1][idx, :].tolist())
with open(os.path.join(save_dir, 'rap_dataset.pkl'), 'w+') as f:
pickle.dump(dataset, f)
def create_trainvaltest_split(traintest_split_file):
"""
create a dataset split file, which consists of index of the train/val/test splits
"""
partition = dict()
partition['trainval'] = []
partition['test'] = []
partition['weight_trainval'] = []
# load RAP_annotation.mat
data = loadmat(open('./dataset/rap/RAP_annotation/RAP_annotation.mat', 'r'))
for idx in range(5):
trainval = (data['RAP_annotation'][0][0][0][idx][0][0][0][0][0,:]-1).tolist()
test = (data['RAP_annotation'][0][0][0][idx][0][0][0][1][0,:]-1).tolist()
partition['trainval'].append(trainval)
partition['test'].append(test)
# weight
weight_trainval = np.mean(data['RAP_annotation'][0][0][1][trainval, :].astype('float32')==1, axis=0).tolist()
partition['weight_trainval'].append(weight_trainval)
with open(traintest_split_file, 'w+') as f:
pickle.dump(partition, f)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="rap dataset")
parser.add_argument(
'--save_dir',
type=str,
default='./dataset/rap/')
parser.add_argument(
'--traintest_split_file',
type=str,
default="./dataset/rap/rap_partition.pkl")
args = parser.parse_args()
save_dir = args.save_dir
traintest_split_file = args.traintest_split_file
generate_data_description(save_dir)
create_trainvaltest_split(traintest_split_file)
@@ -0,0 +1,86 @@
import os
import numpy as np
import random
import cPickle as pickle
from scipy.io import loadmat
np.random.seed(0)
random.seed(0)
def make_dir(path):
if os.path.exists(path):
pass
else:
os.mkdir(path)
def generate_data_description(save_dir):
"""
create a dataset description file, which consists of images, labels
"""
dataset = dict()
dataset['description'] = 'rap2'
dataset['root'] = './dataset/rap2/RAP_dataset/'
dataset['image'] = []
dataset['att'] = []
dataset['att_name'] = []
# load RAP_annotation.mat
data = loadmat(open('./dataset/rap2/RAP_annotation/RAP_annotation.mat', 'r'))
dataset['selected_attribute'] = (data['RAP_annotation'][0][0][3][0,:]-1).tolist()
for idx in range(152):
dataset['att_name'].append(data['RAP_annotation'][0][0][2][idx][0][0])
for idx in range(84928):
dataset['image'].append(data['RAP_annotation'][0][0][0][idx][0][0])
dataset['att'].append(data['RAP_annotation'][0][0][1][idx, :].tolist())
with open(os.path.join(save_dir, 'rap2_dataset.pkl'), 'w+') as f:
pickle.dump(dataset, f)
def create_trainvaltest_split(traintest_split_file):
"""
create a dataset split file, which consists of index of the train/val/test splits
"""
partition = dict()
partition['train'] = []
partition['val'] = []
partition['trainval'] = []
partition['test'] = []
partition['weight_train'] = []
partition['weight_trainval'] = []
# load RAP_annotation.mat
data = loadmat(open('./dataset/rap2/RAP_annotation/RAP_annotation.mat', 'r'))
for idx in range(5):
train = (data['RAP_annotation'][0][0][4][0, idx][0][0][0][0,:]-1).tolist()
val = (data['RAP_annotation'][0][0][4][0, idx][0][0][1][0,:]-1).tolist()
test = (data['RAP_annotation'][0][0][4][0, idx][0][0][2][0,:]-1).tolist()
trainval = train + val
partition['trainval'].append(trainval)
partition['train'].append(train)
partition['val'].append(val)
partition['test'].append(test)
# weight
weight_train = np.mean(data['RAP_annotation'][0][0][1][train, :].astype('float32')==1, axis=0).tolist()
weight_trainval = np.mean(data['RAP_annotation'][0][0][1][trainval, :].astype('float32')==1, axis=0).tolist()
partition['weight_train'].append(weight_train)
partition['weight_trainval'].append(weight_trainval)
with open(traintest_split_file, 'w+') as f:
pickle.dump(partition, f)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="rap2 dataset")
parser.add_argument(
'--save_dir',
type=str,
default='./dataset/rap2/')
parser.add_argument(
'--traintest_split_file',
type=str,
default="./dataset/rap2/rap2_partition.pkl")
args = parser.parse_args()
save_dir = args.save_dir
traintest_split_file = args.traintest_split_file
generate_data_description(save_dir)
create_trainvaltest_split(traintest_split_file)