refactor: 将子模块转为普通目录,移除外部 git 依赖
Sync to site1 / sync (push) Has been cancelled

- 移除 JEPA/lejepa-identifiability 子模块 gitlink
- 移除 research/multiply/MultiPLY 子模块 gitlink
- 删除 .gitmodules(不再有外部 URL 依赖)
- 两个目录内容作为普通文件纳入主仓库追踪
- 删除各自内部 .git 目录,消除嵌套 git 仓库
This commit is contained in:
gaojie
2026-06-05 17:14:01 +08:00
parent cb629f18a1
commit c66855adfc
208 changed files with 23296 additions and 9 deletions
@@ -0,0 +1,214 @@
from torch.utils.data.distributed import DistributedSampler
from torch.utils.data import Dataset, DataLoader
import os
import orjson
import torch
import random
from itertools import chain
from easydict import EasyDict
import json
import numpy as np
from PIL import Image
SCENE_TOKEN = "<scene>"
VISUAL_TOKEN = "<visual>"
TEMP_TOKEN = "<temperature>"
TACTILE_TOKEN = "<tactile>"
SOUND_TOKEN = "<sound>"
AMBIENT_TOKEN = "<ambient>"
GET_VISUAL_TOKEN = "<observe>"
GET_TACTILE_TOKEN = "<touch>"
GET_SOUND_TOKEN = "<hit>"
SELECT_TOKEN = "<select>"
NAV_TOKEN = "<nav>"
PICK_TOKEN = "<pick-up>"
PICK_DOWN_TOKEN = "<pick-down>"
EXPLORE_TOKEN = "<look-around>"
class MultisensoryDataset(Dataset):
def __init__(
self, json_path,
tokenizer, max_length: int,
scene_token=SCENE_TOKEN,
visual_token=VISUAL_TOKEN,
tactile_token=TACTILE_TOKEN,
sound_token=SOUND_TOKEN,
get_visual_token=GET_VISUAL_TOKEN,
get_tactile_token=GET_TACTILE_TOKEN,
get_sound_token=GET_SOUND_TOKEN,
):
assert os.path.exists(json_path)
self.items = orjson.loads(open(json_path).read())
self.tokenizer = tokenizer
self.scene_token = scene_token
self.visual_token = visual_token
self.tactile_token = tactile_token
self.sound_token = sound_token
self.get_visual_token = get_visual_token
self.get_tactile_token = get_tactile_token
self.get_sound_token = get_sound_token
self.scene_token_id = self.tokenizer(self.scene_token).input_ids[-1]
self.visual_token_id = self.tokenizer(self.visual_token).input_ids[-1]
self.tactile_token_id = self.tokenizer(self.tactile_token).input_ids[-1]
self.sound_token_id = self.tokenizer(self.sound_token).input_ids[-1]
self.get_sound_token_id = self.tokenizer(self.get_sound_token).input_ids[-1]
self.max_length = max_length
def __len__(self):
return len(self.items)
def _get_text_dict(self, item):
return dict(
question="Is the bed soft or hard?",
answer="soft",
)
def _get_scene_feature(self, item):
if "scene" in item:
features = []
folder = item["scene"]
bboxes = json.load(open(os.path.join("./dataset/bboxes", folder+".json")))
path = os.path.join("./dataset/feature_dict", folder)
k = 0
for bbox in bboxes:
if "id" in bbox:
if not str(bbox["id"]) + ".pt" in os.listdir(path): continue
feature = torch.load(os.path.join(path, str(bbox['id']) + ".pt"), map_location=torch.device('cpu')).unsqueeze(0)
else:
feature = torch.load(os.path.join(path, str(10000+k) + ".pt"), map_location=torch.device('cpu')).unsqueeze(0)
k += 1
features.append(feature)
features = torch.cat(features)
return features
else:
return torch.randn(256, 1024)
def _get_visual_feature(self, item):
if "visual" in item:
visual = 10000 + int(item["visual"])
folder = item["scene"]
path = os.path.join("./datasetg/feature_dict", folder)
feature = torch.load(os.path.join(path, str(visual) + ".pt"), map_location=torch.device('cpu')).unsqueeze(0)
return feature
else:
return torch.randn(256, 1024)
def _get_tactile_feature(self, item):
if "tactile_reading" in item:
tactile_reading = torch.load(os.path.join("./dataset/data5", item["tactile_reading"], "marker4.pt"), map_location=torch.device('cpu'))
tactile_reading = tactile_reading.mean(1)
return tactile_reading
def _get_temperature_feature(self, item):
if "temperature" in item:
if item["temperature"] in item:
temperature = torch.load(os.path.join("./dataset/data4", item["temperature_reading"], "temp.png"), map_location=torch.device('cpu'))
return temperature
return torch.randn(random.randint(1, 4), 1024)
def _get_sound_feature(self, item):
if "impact_sound" in item:
impact_sound = torch.load(os.path.join("./dataset", "impact_sound_" + str(item["impact_sound"]) + "_0", "impact_sound", "0.pt")).unsqueeze(0)
return impact_sound
elif "scene_id" in item:
sound = torch.load(os.path.join("./dataset/audioset/embedding", item["scene_id"]+".pt"))
return sound
else:
return torch.randn(random.randint(1, 4), 1024)
def collate_wrapper(self, batch):
max_length = max(b.length for b in batch)
max_scene_length = max(b.scene_feature.shape[0] for b in batch)
scene_feature = torch.zeros((len(batch), max_scene_length, 1024))
prediction = torch.zeros((len(batch), max_scene_length))
for (j,b) in enumerate(batch):
scene_feature[j, :b.scene_feature.shape[0]] = b.scene_feature
prediction[j, :b.scene_feature.shape[0]] = b.prediction
return EasyDict(
input_ids=torch.cat([b.input_ids for b in batch])[...,:max_length],
attention_mask=torch.cat([b.attention_mask for b in batch])[...,:max_length],
scene_feature=scene_feature,
visual_feature=torch.cat([b.visual_feature for b in batch]),
tactile_feature=torch.cat([b.tactile_feature for b in batch]),
temperature_feature=torch.cat([b.temperature_feature for b in batch]),
sound_feature=torch.cat([b.sound_feature for b in batch]),
scene_insert_loc=list(chain.from_iterable([[[batch_idx, x] for x in b.scene_insert_loc] for batch_idx, b in enumerate(batch)])),
visual_insert_loc=list(chain.from_iterable([[[batch_idx, x] for x in b.visual_insert_loc] for batch_idx, b in enumerate(batch)])),
tactile_insert_loc=list(chain.from_iterable([[[batch_idx, x] for x in b.tactile_insert_loc] for batch_idx, b in enumerate(batch)])),
sound_insert_loc=list(chain.from_iterable([[[batch_idx, x] for x in b.sound_insert_loc] for batch_idx, b in enumerate(batch)])),
prediction = prediction,
max_scene_length = torch.tensor([b.scene_feature.shape[0] for b in batch])
)
def __getitem__(self, idx):
try:
current_item = self.items[idx]
scene_feature = self._get_scene_feature(current_item)
text_dict = self._get_text_dict(current_item)
visual_feature = self._get_visual_feature(current_item)
tactile_feature = self._get_tactile_feature(current_item)
sound_feature = self._get_sound_feature(current_item)
text = f'Question: {current_item["question"]} Answer: {current_item["answer"]} {self.tokenizer.eos_token}'.replace(self.tactile_token, self.tactile_token*len(tactile_feature)).replace(self.scene_token, self.scene_token*len(scene_feature)).replace(self.sound_token, self.sound_token*len(sound_feature)).replace(self.visual_token, self.visual_token*len(visual_feature))
assert self.max_length > len(scene_feature) # make sure that scene feature is never truncated
text = self.tokenizer(text, return_tensors="pt", max_length=self.max_length, truncation=True, padding='max_length')
input_ids = text["input_ids"]
length = torch.nonzero(input_ids).shape[0]
attention_mask = text["attention_mask"]
scene_insert_loc = (input_ids == self.scene_token_id).nonzero()[:1, 1].reshape(-1).tolist()
visual_insert_loc = (input_ids == self.visual_token_id).nonzero()[:, 1].reshape(-1).tolist()
tactile_insert_loc = (input_ids == self.tactile_token_id).nonzero()[:, 1].reshape(-1).tolist()
temperature_insert_loc = (input_ids == self.temperature_token_id).nonzero()[:, 1].reshape(-1).tolist()
sound_insert_loc = (input_ids == self.sound_token_id).nonzero()[:, 1].reshape(-1).tolist()
visual_feature = visual_feature[:len(visual_insert_loc)]
tactile_feature = tactile_feature[:len(tactile_insert_loc)]
temperature_feature = temperature_feature[:len(temperature_insert_loc)]
sound_feature = sound_feature[:len(sound_insert_loc)]
if "prediction" in current_item:
prediction = current_item['prediction']
else:
prediction = [-1 for tok in range(len(scene_feature))]
prediction = torch.tensor(current_item['prediction'])
prediction[prediction>0] = 1
prediction = prediction.float()
return EasyDict(
text=text,
input_ids=input_ids,
length=length,
attention_mask=attention_mask,
scene_feature=scene_feature,
visual_feature=visual_feature,
tactile_feature=tactile_feature,
temperature_feature=temperature_feature,
sound_feature=sound_feature,
scene_insert_loc=scene_insert_loc,
visual_insert_loc=visual_insert_loc,
tactile_insert_loc=tactile_insert_loc,
sound_insert_loc=sound_insert_loc,
prediction = prediction
)
except:
# print ("cannot find feature %d"%idx)
return self.__getitem__(idx-1)