You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thank you for your great work!
I'm a little confused about the segmentation accuracy of the Human dataset, which is provided by PD-Mesh (Simplified inputs with hard ground truth at faces). I try to use DiffusionNet (xyz) on it, but the accuracy is only 81%.
I try to use hks as input, and the accuracy is only 79%.
I also try to adjust C_width, but it seems to have no effect. emmmmm..... I want to know what parameters I need to adjust....
The code for loading data and training: human_seg_dataset.py
import os
import sys
import numpy as np
import torch
from torch.utils.data import Dataset
import potpourri3d as pp3d
sys.path.append(os.path.join(os.path.dirname(__file__), "../../")) # add the path to the DiffusionNet src
import src.diffusion_net as diffusion_net
def is_mesh_file(filename):
return any(filename.endswith(extension) for extension in ['.obj', 'off'])
class HumanDataset(Dataset):
def __init__(self, root_dir, phase, k_eig=128, op_cache_dir=None):
self.k_eig = k_eig
self.root_dir = root_dir
self.cache_dir = os.path.join(root_dir, "cache")
self.op_cache_dir = op_cache_dir
self.dir = os.path.join(self.root_dir, phase)
self.paths = self.make_dataset(self.dir)
self.seg_paths = self.get_seg_files(self.paths, os.path.join(self.root_dir, 'seg'))
def __len__(self):
return len(self.paths)
def __getitem__(self, index):
path = self.paths[index]
label = np.loadtxt(open(self.seg_paths[index], 'r'), dtype='float64')
verts, faces = pp3d.read_mesh(path)
verts = torch.tensor(verts).float()
faces = torch.tensor(faces)
label = torch.tensor(label).long()
frames, mass, L, evals, evecs, gradX, gradY = diffusion_net.geometry.get_operators(verts, faces,
k_eig=self.k_eig,
op_cache_dir=self.op_cache_dir)
return verts, faces, frames, mass, L, evals, evecs, gradX, gradY, label
@staticmethod
def get_seg_files(paths, seg_dir, seg_ext='.eseg'):
segs = []
for path in paths:
segfile = os.path.join(seg_dir, os.path.splitext(os.path.basename(path))[0] + seg_ext)
assert (os.path.isfile(segfile))
segs.append(segfile)
return segs
@staticmethod
def make_dataset(path):
meshes = []
assert os.path.isdir(path), '%s is not a valid directory' % path
for root, _, fnames in sorted(os.walk(path)):
for fname in fnames:
if is_mesh_file(fname):
path = os.path.join(root, fname)
meshes.append(path)
return meshes
seg_human.py
import os
import sys
import argparse
import torch
from torch.utils.data import DataLoader
from tqdm import tqdm
sys.path.append(os.path.join(os.path.dirname(__file__), "../../")) # add the path to the DiffusionNet src
import src.diffusion_net as diffusion_net
from experiments.human_seg.human_seg_dataset import HumanDataset
# Parse a few args
parser = argparse.ArgumentParser()
parser.add_argument("--input_features", type=str, help="('xyz' or 'hks')", default='hks')
parser.add_argument("--features_width", type=int, choices={32, 64, 128, 256}, default=128)
parser.add_argument("--data_name", type=str, choices={'human'}, default='human')
parser.add_argument("--n_class", type=int, choices={8}, default=8)
args = parser.parse_args()
# system things
device = torch.device('cuda:0')
dtype = torch.float32
input_features = args.input_features # one of ['xyz', 'hks']
C_width = args.features_width
k_eig = 128
n_epoch = 200
lr = 1e-3
decay_every = 50
decay_rate = 0.5
augment_random_rotate = (input_features == 'xyz')
# === Load datasets
data_name = args.data_name # aliens vases chairs
base_path = os.path.dirname(__file__)
op_cache_dir = os.path.join(base_path, "data", "op_cache", data_name)
dataset_path = os.path.join(base_path, "data", data_name)
n_class = args.n_class
# Load the test dataset
test_dataset = HumanDataset(dataset_path, 'test', k_eig=k_eig, op_cache_dir=op_cache_dir)
test_loader = DataLoader(test_dataset, batch_size=None)
# Load the train dataset
train_dataset = HumanDataset(dataset_path, 'train', k_eig=k_eig, op_cache_dir=op_cache_dir)
train_loader = DataLoader(train_dataset, batch_size=None, shuffle=True)
# === Create the model
C_in={'xyz': 3, 'hks': 16}[input_features] # dimension of input features
model = diffusion_net.layers.DiffusionNet(C_in=C_in,
C_out=n_class,
C_width=C_width,
N_block=4,
last_activation=lambda x : torch.nn.functional.log_softmax(x, dim=-1),
outputs_at='faces',
dropout=True)
model = model.to(device)
# === Optimize
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
def train_epoch(epoch):
# Implement lr decay
if epoch > 0 and epoch % decay_every == 0:
global lr
lr *= decay_rate
for param_group in optimizer.param_groups:
param_group['lr'] = lr
# Set model to 'train' mode
model.train()
optimizer.zero_grad()
correct = 0
total_num = 0
for data in tqdm(train_loader):
# Get data
verts, faces, frames, mass, L, evals, evecs, gradX, gradY, labels = data
# Move to device
verts = verts.to(device)
faces = faces.to(device)
frames = frames.to(device)
mass = mass.to(device)
L = L.to(device)
evals = evals.to(device)
evecs = evecs.to(device)
gradX = gradX.to(device)
gradY = gradY.to(device)
labels = labels.to(device)
# Randomly rotate positions
if augment_random_rotate:
verts = diffusion_net.utils.random_rotate_points(verts)
# Construct features
if input_features == 'xyz':
features = verts
elif input_features == 'hks':
features = diffusion_net.geometry.compute_hks_autoscale(evals, evecs, 16)
# Apply the model
preds = model(features, mass, L=L, evals=evals, evecs=evecs, gradX=gradX, gradY=gradY, faces=faces)
# Evaluate loss
loss = torch.nn.functional.nll_loss(preds, labels)
loss.backward()
# track accuracy
pred_labels = torch.max(preds, dim=1).indices
this_correct = pred_labels.eq(labels).sum().item()
this_num = labels.shape[0]
correct += this_correct
total_num += this_num
# Step the optimizer
optimizer.step()
optimizer.zero_grad()
train_acc = correct / total_num
return train_acc
# Do an evaluation pass on the test dataset
def test():
model.eval()
correct = 0
total_num = 0
with torch.no_grad():
for data in tqdm(test_loader):
# Get data
verts, faces, frames, mass, L, evals, evecs, gradX, gradY, labels = data
# Move to device
verts = verts.to(device)
faces = faces.to(device)
frames = frames.to(device)
mass = mass.to(device)
L = L.to(device)
evals = evals.to(device)
evecs = evecs.to(device)
gradX = gradX.to(device)
gradY = gradY.to(device)
labels = labels.to(device)
# Construct features
if input_features == 'xyz':
features = verts
elif input_features == 'hks':
features = diffusion_net.geometry.compute_hks_autoscale(evals, evecs, 16)
# Apply the model
preds = model(features, mass, L=L, evals=evals, evecs=evecs, gradX=gradX, gradY=gradY, faces=faces)
# track accuracy
pred_labels = torch.max(preds, dim=1).indices
this_correct = pred_labels.eq(labels).sum().item()
this_num = labels.shape[0]
correct += this_correct
total_num += this_num
test_acc = correct / total_num
return test_acc
print("Training...")
for epoch in range(n_epoch):
train_acc = train_epoch(epoch)
test_acc = test()
print("Epoch {} - Train overall: {:06.3f}% Test overall: {:06.3f}%".format(epoch, 100*train_acc, 100*test_acc))
# Test
test_acc = test()
print("Overall test accuracy: {:06.3f}%".format(100*test_acc))
I'm sorry that this content is too much. Any hint on this problem is appreciated!
Thanks! Have a nice day!
The text was updated successfully, but these errors were encountered:
Thank you for your great work!
I'm a little confused about the segmentation accuracy of the Human dataset, which is provided by PD-Mesh (Simplified inputs with hard ground truth at faces). I try to use DiffusionNet (xyz) on it, but the accuracy is only 81%.
I try to use hks as input, and the accuracy is only 79%.
I also try to adjust C_width, but it seems to have no effect.
emmmmm..... I want to know what parameters I need to adjust....
The code for loading data and training:
human_seg_dataset.py
seg_human.py
I'm sorry that this content is too much. Any hint on this problem is appreciated!
Thanks! Have a nice day!
The text was updated successfully, but these errors were encountered: