Về số liệu tập cách thức trọng tổ, trọng viết Dataset hàm số
Dataset nguyên mã
classDataset(object):
"""An abstract class representing a Dataset.
All other datasets should subclass it. All subclasses should override
``__len__``, that provides the size of the dataset, and ``__getitem__``,
supporting integer inde xing in range from 0 to len(self) exclusive.
"""
def__getitem__(self,index):
raiseNotImplementedError
def__len__(self):
raiseNotImplementedError
def__add__(self,other):
returnConcatDataset([self,other])
Toàn bộ mặt khác số liệu tập loại đều phải kế thừa cái này loại, bên trong__len__, __getitem__
Cần thiết muốn trọng viết.def
__getitem__(self, idx)
idx là căn cứ__len__
Chiều dài trong phạm vi tùy cơ sinh thành.
Nguyên học tập episode cách thức
Ở COCO2014 số liệu tập trung hoa cái episode cách thức dùng để nguyên huấn luyện.
Đầu tiêncreat_batch
classVQAFineTuneDataset(Dataset):
'''
minival.json, train.json... Đều là loại này cách thức
{
"answer_type": "other",
"img_id": "COCO_train2014_000000458752",
"label": {
"net": 1
},
"question_id": 458752000,
"question_type": "what is this",
"sent": "What is this photo taken looking through?"
}
'''
def__init__(self,split='train',raw_dataset=None,rank=-1,topk=-1,verbose=True,args=None,mode='train',n_way=2,k_shot=1,k_query=5):
super().__init__()
self.raw_dataset=raw_dataset
self.topk=topk
self.verbose=verbose
self.args=args
self.mode=mode
self.n_way=n_way# n-way 2
self.k_shot=k_shot# k-shot 1
self.k_query=k_query# for evaluation 5
# Loading datasets to data
self.sources=split
ifself.verbose:
print('Data sources: ',self.sources)#['train']
model_path='/HDD/liuyuanyuan/t5-base'
TRANSFORMERS_OFFLINE=1
if't5'inself.args.backbone:
ifself.args.use_vision:
self.tokenizer=FewVLMTokenizerFast.from_pretrained(
#args.backbone, # t5-base
model_path,
else:
self.tokenizer=T5TokenizerFast.from_pretrained(
args.backbone,
self.answer_normalizer=VQAEvaluator()
self.img_ids_to_source={}# phóng hình ảnh nơi phát ra img_ids_to_source[ "COCO_val2014_000000393225" ]='source'
data_info_dicts=[]# toàn bộ tin tức đều bỏ vào đi
data_info_path=dataset_dir.joinpath(f'mscoco2014/annotations/captions_{self.sources}2014.json')# /HDD/liuyuanyuan/ VQAv2/train.json
withopen(data_info_path)asf:
_data_info_dicts=json.load(f)
for_din_data_info_dicts['images']:#_d là từng cái {},{},{}
if'vg_qa_full'==self.sources:
self.img_ids_to_source[_d['file_name']]='vg'
elif'train2014'in_d['file_name']:
self.img_ids_to_source[_d['file_name']]='train2014'
elif'val2014'in_d['file_name']:
self.img_ids_to_source[_d['file_name']]='val2014'
else:
self.img_ids_to_source[_d['file_name']]=self.sources
_d['source']=self.sources
data_info_dicts.extend(_data_info_dicts['images'])#[]
ifself.verbose:
print(f "Loaded{len(_data_info_dicts['images'])}data from ",self.sources)
data=data_info_dicts# thả train.json từ điển
self.n_gpus=torch.cuda.device_count()
self.rank=rank
ifself.topk>0:
data=data[:self.topk]
ifself.verbose:
print(f "Use only{self.topk}data ")
self.data=data
# if args.subsample and split == 'train':#m mỗi lần quấy rầy lấy dùng để hơi điều cái mấy cái hàng mẫu ---16, 32, 64...
# random.seed(args.dataseed)
# random.shuffle(self.data)# quấy rầy
# if 'train' in split and mode == 'train':
# self.data = self.data[:args.num_data]#[:32]
# elif 'train' in split and mode == 'val':
# self.data = self.data[args.num_data:2*args.num_data]#[32:64]# vì sao nghiệm chứng cùng train hơi điều thời điểm hàng mẫu số lượng giống nhau đâu??
ifself.verbose:
print("# all sentences:",len(self.data))# thí nghiệm thời điểm lấy toàn bộ
self.n_boxes=args.n_boxes
self.source_to_h5={
'train':coco_feature_dir.joinpath(f'train2014_obj36.h5'),
'minival':coco_feature_dir.joinpath(f'val2014_obj36.h5'),
'nominival':coco_feature_dir.joinpath(f'val2014_obj36.h5'),
'test':coco_feature_dir.joinpath(f'test2015_obj36.h5'),
'vg':dataset_dir.joinpath('VG/features').joinpath('vg_gqa_obj36.h5'),
'train2014':coco_feature_dir.joinpath(f'train2014_obj36.h5'),
'val2014':coco_feature_dir.joinpath(f'val2014_obj36.h5'),
}
# tân thêm
fromparse_cocoimportget_coco_categories_to_img_caps
json_data=get_coco_categories_to_img_caps(mode)
self.data_pkl=[]# thả toàn bộ (Caption,image_id/[class_id])
self.img2caption={}
self.category_name=[]
fori,(category_name,cap_imgs)inenumerate(json_data.items()):
cap_imgs=[(x[0],x[1],category_name)forxincap_imgs]
self.data_pkl.append(cap_imgs)
forcaption,image,_incap_imgs:
self.img2caption[image]=caption
# print( "self.data_pkl:",self.data_pkl)# caption đánh số
# print( "self.img2caption:",self.img2caption)# từ điển hình thức [id]=caption
self.cls_num=len(self.data_pkl)# 80 cái loại
def__len__(self):
returnlen(self.data)
defcreate_batch(self,batchsz,mode):
"""
create batch for meta-learning.
×episode× here means batch, and it means how many sets we want to retain.
:param episodes: batch size
:return:
"""
self.support_x_batch=[]# support set batch
self.query_x_batch=[]# query set batch
# Creating of tasks; batchsz is the num. of iterations when sampling from the task distribution
importos,pickle
sup_data_path=f "datasets/COCO2014/{mode}/support_20000.pkl "
que_data_path=f "datasets/COCO2014/{mode}/query_20000.pkl "
ifos.path.exists(sup_data_path):
withopen(sup_data_path,'rb')asfile:
self.support_x_batch=pickle.load(file)
ifos.path.exists(que_data_path):
withopen(que_data_path,'rb')asfile:
self.query_x_batch=pickle.load(file)
#------------------ dùng để bảo tồn số liệu đến pkl------------------------
forbinrange(batchsz):# for each batch 20000
# 1.select n_way classes randomly
selected_cls=np.random.choice(self.cls_num,self.n_way,replace=False)# tuyển hai cái loại tức 2-way
np.random.shuffle(selected_cls)
support_x=[]# 2 cái hàng mẫu
query_x=[]# 10 cái hàng mẫu
forclsinselected_cls:
# 2. select k_shot + k_query for each class
selected_imgs_idx=np.random.choice(len(self.data_pkl[cls]),self.k_shot+self.k_query,False)
np.random.shuffle(selected_imgs_idx)
indexDtrain=np.array(selected_imgs_idx[:self.k_shot])# idx for Dtrain
indexDtest=np.array(selected_imgs_idx[self.k_shot:])# idx for Dtest
support_x.append(
np.array(self.data_pkl[cls])[indexDtrain].tolist())# get all images filename for current Dtrain
query_x.append(np.array(self.data_pkl[cls])[indexDtest].tolist())
random.shuffle(support_x)
random.shuffle(query_x)
# nơi này là Caption,image_id
self.support_x_batch.append(support_x)# append set to current sets tổng cộng có 10000 cái task, mỗi cái task có 2
self.query_x_batch.append(query_x)# append sets to current sets
# nếu không đem create——batch tồn, mỗi lần thêm tái, nếu không quá chậm
ifnotos.path.exists(sup_data_path):
withopen(sup_data_path,'wb')asfile:
pickle.dump(self.support_x_batch,file)
withopen(que_data_path,'wb')asfile:
pickle.dump(self.query_x_batch,file)
print("write over",self.mode)
#---------------------------------------------------------------------------------------
deftask_split(self,index):
''' đem hình ảnh dựa theo episode hình thức phân chia
Cuối cùng được đến một cái task, từ support2 cái hàng mẫu,query10 cái hàng mẫu tạo thành
'''
print("self.mode",self.mode)
self.create_batch(20000,self.mode)
out_dict={}
self.setsz=self.n_way*self.k_shot
print("index:",index)# tùy cơ một ít index như: 7250, 9540, 7727, 2979
# bắt được hình ảnh cụ thể địa chỉ
flatten_support_x=[f "COCO_{self.mode}2014_{int(img_id):012d}"# thông qua hình ảnh id tổ hợp ra hình ảnh địa chỉ ---2ge
forsublistinself.support_x_batch[index]for_,img_id,_insublist]
flatten_query_x=[f "COCO_{self.mode}2014_{int(img_id):012d}"# ---10ge
forsublistinself.query_x_batch[index]for_,img_id,_insublist]
# print( "---flatten_support_x:",flatten_support_x)
###### Image ###### thông qua như vậy COCO_train2014_000000458752 id lấy ra hình ảnh
fori,idxinenumerate(flatten_support_x):# 2ge
# datum = self.data[idx] # tồn train.json từ điển các loại đồ vật
ifself.args.use_vision:
img_id=idx# đơn trương hình ảnh id COCO_train2014_000000458752
print("---idx",idx)
out_dict['img_id'].append(img_id)
#....
fori,idxinenumerate(flatten_query_x):# 10ge
# datum = self.data[idx] # tồn train.json từ điển các loại đồ vật
ifself.args.use_vision:
img_id=idx# đơn trương hình ảnh id COCO_train2014_000000458752
out_dict['img_id'].append(img_id)
#....
#
########### mã hóa text#########
forsublistinself.support_x_batch[index]:# (category_name,caption, img_id) có 2 cái
forcaption,img_id,category_nameinsublist:
# không cần Caption, sửa dùng category
#
sent='What is in the image?'
input_ids=self.tokenizer.encode(f'{sent}<extra_id_0>',max_length=20,truncation=True)# Q là token
#.....
#
forsublistinself.query_x_batch[index]:# 10 cái
forcaption,img_id,category_nameinsublist:
#
sent='What is in the image?'
input_ids=self.tokenizer.encode(f'{sent}<extra_id_0>',max_length=20,truncation=True)# Q là token
#.....
#
returnout_dict
def__getitem__(self,idx):
# được đến idx sau ở đã phân chia tốt support cùng query trung dựa theo idx trực tiếp lấy
out_dict={}
out_dict=self.task_split(idx)
out_dict['args']=self.args
returnout_dict
defcollate_fn(self,batch):# tại đây hình thành batch
batch_entry={}
args=batch[0]['args']
B=len(batch[0])# 1
S_W_L=max(entryforentryinbatch[0]['input_length'])# 9
input_ids=torch.ones(B,S_W_L,dtype=torch.long)*self.tokenizer.pad_token_id
# print( "***input_ids:",input_ids.size())# [12,9]
ifargs.use_vision:
V_L=len(batch[0]['boxes'][0])# 12
feat_dim=batch[0]['vis_feats'][0].shape[-1]# 2048
boxes=torch.zeros(B,V_L,4,dtype=torch.float)
vis_feats=torch.zeros(B,V_L,feat_dim,dtype=torch.float)
# print( "***box,vis_feats:",boxes.size(),vis_feats.size())# [12,36,4][12,36,2048]
# if 'target' in batch[0]:
# # targets = []
# targets = torch.zeros(B, len(batch[0]['target']), dtype=torch.float)
if'target_ids'inbatch[0]:
T_W_L=max(entryforentryinbatch[0]['target_length'])
target_ids=torch.ones(B,T_W_L,dtype=torch.long)*self.tokenizer.pad_token_id
# print( "**target_ids",target_ids.size())#[12,3]
# bắt đầu chỉnh hợp
fori,entryinenumerate(batch[0]['input_ids']):
input_ids[i,:S_W_L]=entry
ifargs.use_vision:
fori,entryinenumerate(batch[0]['boxes']):
boxes[i]+=entry
fori,entryinenumerate(batch[0]['vis_feats']):
vis_feats[i]+=entry
if'target_ids'inbatch[0]:
fori,entryinenumerate(batch[0]['target_ids']):
print("***target_ids,entry",target_ids.size(),entry.size())
print("**entry",entry)
target_ids[i,:batch[0]['target_length'][i]]=entry
# print( "**target_ids", target_ids.size())#[12,3]
# print( "**input_id",input_ids.size())
if'target_ids'inbatch[0]:
word_mask=target_ids!=self.tokenizer.pad_token_id
target_ids[~word_mask]=-100
batch_entry['target_ids']=target_ids
if'target'inbatch[0]:
# targets = torch.stack(targets, dim=0)
batch_entry['targets']=targets
ifargs.use_vision:
batch_entry['boxes']=boxes
batch_entry['vis_feats']=vis_feats
# batch_entry['img_id'] = img_ids
# batch_entry['img_paths'] = img_paths
batch_entry['input_ids']=input_ids
batch_entry['sent']=batch[0]['sent']
batch_entry['answers']=batch[0]['answer']
batch_entry['scores']=batch[0]['score']
batch_entry['labels']=batch[0]['label']
batch_entry['args']=args
batch_entry['task']='coco'
# print( "**__** batch_entry",batch_entry)
returnbatch_entry