Commit f6e15d2f authored by Benjamin Thomas Graham's avatar Benjamin Thomas Graham
Browse files

Fixes

parent b862d6a2
...@@ -4,5 +4,7 @@ ...@@ -4,5 +4,7 @@
# #
# This source code is licensed under the BSD-style license found in the # This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
#export TORCH_CUDA_ARCH_LIST="6.0;6.1;6.2;7.0;7.5"
rm -rf build/ dist/ sparseconvnet.egg-info rm -rf build/ dist/ sparseconvnet.egg-info
python setup.py install && python examples/hello-world.py python setup.py install && python examples/hello-world.py
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
# This source code is licensed under the BSD-style license found in the # This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
#export TORCH_CUDA_ARCH_LIST="6.0;6.1;6.2;7.0;7.5"
rm -rf build/ dist/ sparseconvnet.egg-info sparseconvnet_SCN*.so rm -rf build/ dist/ sparseconvnet.egg-info sparseconvnet_SCN*.so
python setup.py develop python setup.py develop && python examples/hello-world.py
python examples/hello-world.py
...@@ -14,8 +14,7 @@ if torch.cuda.is_available(): ...@@ -14,8 +14,7 @@ if torch.cuda.is_available():
this_dir = os.path.dirname(os.path.realpath(__file__)) this_dir = os.path.dirname(os.path.realpath(__file__))
torch_dir = os.path.dirname(torch.__file__) torch_dir = os.path.dirname(torch.__file__)
conda_include_dir = '/'.join(torch_dir.split('/')[:-4]) + '/include' conda_include_dir = '/'.join(torch_dir.split('/')[:-4]) + '/include'
extra = {'cxx': ['-std=c++14', '-fopenmp'], 'nvcc': ['-std=c++14', '-Xcompiler', '-fopenmp']}
extra = {'cxx': ['-std=c++11', '-fopenmp'], 'nvcc': ['-std=c++11', '-Xcompiler', '-fopenmp']}
setup( setup(
name='sparseconvnet', name='sparseconvnet',
...@@ -29,12 +28,12 @@ setup( ...@@ -29,12 +28,12 @@ setup(
CUDAExtension('sparseconvnet.SCN', CUDAExtension('sparseconvnet.SCN',
[ [
'sparseconvnet/SCN/cuda.cu', 'sparseconvnet/SCN/sparseconvnet_cuda.cpp', 'sparseconvnet/SCN/pybind.cpp'], 'sparseconvnet/SCN/cuda.cu', 'sparseconvnet/SCN/sparseconvnet_cuda.cpp', 'sparseconvnet/SCN/pybind.cpp'],
include_dirs=[conda_include_dir, this_dir+'/sparseconvnet/SCN/'], include_dirs=[this_dir+'/sparseconvnet/SCN/'],
extra_compile_args=extra) extra_compile_args=extra)
if torch.cuda.is_available() else if torch.cuda.is_available() else
CppExtension('sparseconvnet.SCN', CppExtension('sparseconvnet.SCN',
['sparseconvnet/SCN/pybind.cpp', 'sparseconvnet/SCN/sparseconvnet_cpu.cpp'], ['sparseconvnet/SCN/pybind.cpp', 'sparseconvnet/SCN/sparseconvnet_cpu.cpp'],
include_dirs=[conda_include_dir, this_dir+'/sparseconvnet/SCN/'], include_dirs=[this_dir+'/sparseconvnet/SCN/'],
extra_compile_args=extra['cxx'])], extra_compile_args=extra['cxx'])],
cmdclass={'build_ext': BuildExtension}, cmdclass={'build_ext': BuildExtension},
zip_safe=False, zip_safe=False,
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
// mode 0==guaranteed unique 1==overwrite, 2=keep, 3=sum, 4=mean // mode 0==guaranteed unique 1==overwrite, 2=keep, 3=sum, 4=mean
template <Int dimension> template <Int dimension>
void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
Int nInputRows, Int nInputColumns, Int batchSize, Int mode, Int nInputRows, Int nInputColumns, Int batchSize, Int mode,
Int &nActive) { Int &nActive) {
assert(nActive == 0); assert(nActive == 0);
assert(rules.size() == 0); assert(rules.size() == 0);
assert(SGs.size() == 0); assert(SGs.size() == 0);
...@@ -37,21 +37,21 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -37,21 +37,21 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
SGs.resize(1); SGs.resize(1);
auto &sg = SGs[0]; auto &sg = SGs[0];
for (Int i = 0; i < nInputRows; ++i) { for (Int i = 0; i < nInputRows; ++i) {
for (Int j = 0; j < dimension; j++) for (Int j = 0; j < dimension; j++)
p[j] = coords[j]; p[j] = coords[j];
coords += dimension; coords += dimension;
sg.mp[p] = i; sg.mp[p] = i;
} }
} else { // nInputColumns == dimension + 1 } else { // nInputColumns == dimension + 1
Int idx; Int idx;
for (Int i = 0; i < nInputRows; ++i) { for (Int i = 0; i < nInputRows; ++i) {
for (Int j = 0; j < dimension; j++) for (Int j = 0; j < dimension; j++)
p[j] = coords[j]; p[j] = coords[j];
idx = coords[dimension]; idx = coords[dimension];
coords += dimension + 1; coords += dimension + 1;
if (idx + 1 >= (Int)SGs.size()) if (idx + 1 >= (Int)SGs.size())
SGs.resize(idx + 1); SGs.resize(idx + 1);
SGs[idx].mp[p] = i; SGs[idx].mp[p] = i;
} }
} }
return; return;
...@@ -64,10 +64,10 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -64,10 +64,10 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
auto &sg = SGs[0]; auto &sg = SGs[0];
for (Int i = 0; i < nInputRows; ++i) { for (Int i = 0; i < nInputRows; ++i) {
for (Int j = 0; j < dimension; j++) for (Int j = 0; j < dimension; j++)
p[j] = coords[j]; p[j] = coords[j];
coords += dimension; coords += dimension;
if (sg.mp.insert(make_pair(p, nActive)).second) { if (sg.mp.insert(make_pair(p, nActive)).second) {
outputRows.resize(++nActive); outputRows.resize(++nActive);
} }
outputRows[sg.mp[p]].push_back(i); outputRows[sg.mp[p]].push_back(i);
} }
...@@ -75,15 +75,15 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -75,15 +75,15 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
Int idx; Int idx;
for (Int i = 0; i < nInputRows; ++i) { for (Int i = 0; i < nInputRows; ++i) {
for (Int j = 0; j < dimension; j++) for (Int j = 0; j < dimension; j++)
p[j] = coords[j]; p[j] = coords[j];
idx = coords[dimension]; idx = coords[dimension];
coords += dimension + 1; coords += dimension + 1;
if (idx + 1 >= (Int)SGs.size()) if (idx + 1 >= (Int)SGs.size())
SGs.resize(idx + 1); SGs.resize(idx + 1);
auto &sg = SGs[idx]; auto &sg = SGs[idx];
if (sg.mp.insert(make_pair(p, nActive)).second) { if (sg.mp.insert(make_pair(p, nActive)).second) {
outputRows.resize(++nActive); outputRows.resize(++nActive);
} }
outputRows[sg.mp[p]].push_back(i); outputRows[sg.mp[p]].push_back(i);
} }
} }
...@@ -113,9 +113,9 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -113,9 +113,9 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
for (auto &row : outputRows) { for (auto &row : outputRows) {
rule.push_back(row.size()); rule.push_back(row.size());
for (auto &r : row) for (auto &r : row)
rule.push_back(r); rule.push_back(r);
rule.resize((rule.size() + maxActive) / (maxActive + 1) * rule.resize((rule.size() + maxActive) / (maxActive + 1) *
(maxActive + 1)); (maxActive + 1));
} }
} }
} }
...@@ -133,7 +133,7 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -133,7 +133,7 @@ void inputLayerRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
// 4=mean // 4=mean
template <Int dimension> template <Int dimension>
void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
Int batchSize, Int length, Int mode, Int &nActive) { Int batchSize, Int length, Int mode, Int &nActive) {
assert(nActive == 0); assert(nActive == 0);
assert(rules.size() == 0); assert(rules.size() == 0);
assert(SGs.size() == 0); assert(SGs.size() == 0);
...@@ -155,10 +155,10 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -155,10 +155,10 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
auto c = coords + I * length * dimension; auto c = coords + I * length * dimension;
Point<dimension> p; Point<dimension> p;
for (Int l = 0; l < length; ++l) { for (Int l = 0; l < length; ++l) {
for (Int j = 0; j < dimension; ++j) for (Int j = 0; j < dimension; ++j)
p[j] = c[j]; p[j] = c[j];
c += dimension; c += dimension;
sg.mp[p] = l; sg.mp[p] = l;
} }
} }
return; return;
...@@ -178,30 +178,30 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -178,30 +178,30 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
Point<dimension> p; Point<dimension> p;
if (mode == 1) { if (mode == 1) {
for (Int l = 0; l < length; ++l, ++i) { for (Int l = 0; l < length; ++l, ++i) {
for (Int j = 0; j < dimension; ++j) for (Int j = 0; j < dimension; ++j)
p[j] = *c++; p[j] = *c++;
if (p[0] >= 0) { if (p[0] >= 0) {
if (sg.mp.insert(make_pair(p, nAct)).second) { if (sg.mp.insert(make_pair(p, nAct)).second) {
nAct++; nAct++;
ors.push_back(i); ors.push_back(i);
} else { } else {
ors[sg.mp[p]] = i; ors[sg.mp[p]] = i;
} }
} }
} }
} }
if (mode == 2) { if (mode == 2) {
for (Int l = 0; l < length; ++l, ++i) { for (Int l = 0; l < length; ++l, ++i) {
for (Int j = 0; j < dimension; ++j) for (Int j = 0; j < dimension; ++j)
p[j] = *c++; p[j] = *c++;
if (p[0] >= 0) { if (p[0] >= 0) {
if (sg.mp.insert(make_pair(p, nAct)).second) { if (sg.mp.insert(make_pair(p, nAct)).second) {
nAct++; nAct++;
ors.push_back(i); ors.push_back(i);
} }
} }
} }
} }
} }
for (I = 0; I < batchSize; I++) { for (I = 0; I < batchSize; I++) {
...@@ -216,17 +216,15 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -216,17 +216,15 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
rules[0].push_back(length); rules[0].push_back(length);
rules[0].push_back(nActive); rules[0].push_back(nActive);
auto &rule = rules[1]; auto &rule = rules[1];
if (mode == 1) { rule.resize(2 * nActive);
rule.resize(2 * nActive);
#pragma omp parallel for private(I) #pragma omp parallel for private(I)
for (I = 0; I < batchSize; I++) { for (I = 0; I < batchSize; I++) {
auto &ors = outputRows[I]; auto &ors = outputRows[I];
auto rr = &rule[SGs[I].ctr * 2]; auto rr = &rule[SGs[I].ctr * 2];
for (auto &row : ors) { for (auto &row : ors) {
rr[0] = 1; rr[0] = 1;
rr[1] = row; rr[1] = row;
rr += 2; rr += 2;
}
} }
} }
return; return;
...@@ -245,15 +243,15 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -245,15 +243,15 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
Int i = I * length; Int i = I * length;
Point<dimension> p; Point<dimension> p;
for (Int l = 0; l < length; ++l, ++i) { for (Int l = 0; l < length; ++l, ++i) {
for (Int j = 0; j < dimension; ++j) for (Int j = 0; j < dimension; ++j)
p[j] = *c++; p[j] = *c++;
if (p[0] >= 0) { if (p[0] >= 0) {
if (sg.mp.insert(make_pair(p, nAct)).second) { if (sg.mp.insert(make_pair(p, nAct)).second) {
nAct++; nAct++;
ors.resize(nAct); ors.resize(nAct);
} }
ors[sg.mp[p]].push_back(i); ors[sg.mp[p]].push_back(i);
} }
} }
} }
...@@ -264,8 +262,8 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -264,8 +262,8 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
Int maxActive = 1; Int maxActive = 1;
if (mode >= 3) if (mode >= 3)
for (auto &ors : outputRows) for (auto &ors : outputRows)
for (auto &row : ors) for (auto &row : ors)
maxActive = std::max(maxActive, (Int)row.size()); maxActive = std::max(maxActive, (Int)row.size());
rules.resize(2); rules.resize(2);
rules[0].push_back(mode); rules[0].push_back(mode);
...@@ -280,10 +278,10 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords, ...@@ -280,10 +278,10 @@ void blRules(SparseGrids<dimension> &SGs, RuleBook &rules, long *coords,
auto &ors = outputRows[I]; auto &ors = outputRows[I];
auto rr = &rule[SGs[I].ctr * (maxActive + 1)]; auto rr = &rule[SGs[I].ctr * (maxActive + 1)];
for (auto &row : ors) { for (auto &row : ors) {
rr[0] = row.size(); rr[0] = row.size();
for (Int i = 0; i < (Int)row.size(); ++i) for (Int i = 0; i < (Int)row.size(); ++i)
rr[i + 1] = row[i]; rr[i + 1] = row[i];
rr += 1 + maxActive; rr += 1 + maxActive;
} }
} }
} }
......
...@@ -15,7 +15,7 @@ class BatchNormalization(Module): ...@@ -15,7 +15,7 @@ class BatchNormalization(Module):
Parameters: Parameters:
nPlanes : number of input planes nPlanes : number of input planes
eps : small number used to stabilise standard deviation calculation eps : small number used to stabilise standard deviation calculation
momentum : for calculating running average for testing (default 0.9) momentum : for calculating running average for testing (default 0.99)
affine : only 'true' is supported at present (default 'true') affine : only 'true' is supported at present (default 'true')
noise : add multiplicative and additive noise during training if >0. noise : add multiplicative and additive noise during training if >0.
leakiness : Apply activation def inplace: 0<=leakiness<=1. leakiness : Apply activation def inplace: 0<=leakiness<=1.
...@@ -25,7 +25,7 @@ class BatchNormalization(Module): ...@@ -25,7 +25,7 @@ class BatchNormalization(Module):
self, self,
nPlanes, nPlanes,
eps=1e-4, eps=1e-4,
momentum=0.9, momentum=0.99,
affine=True, affine=True,
leakiness=1): leakiness=1):
Module.__init__(self) Module.__init__(self)
...@@ -72,7 +72,7 @@ class BatchNormalization(Module): ...@@ -72,7 +72,7 @@ class BatchNormalization(Module):
class BatchNormReLU(BatchNormalization): class BatchNormReLU(BatchNormalization):
def __init__(self, nPlanes, eps=1e-4, momentum=0.9): def __init__(self, nPlanes, eps=1e-4, momentum=0.99):
BatchNormalization.__init__(self, nPlanes, eps, momentum, True, 0) BatchNormalization.__init__(self, nPlanes, eps, momentum, True, 0)
def __repr__(self): def __repr__(self):
...@@ -82,7 +82,7 @@ class BatchNormReLU(BatchNormalization): ...@@ -82,7 +82,7 @@ class BatchNormReLU(BatchNormalization):
class BatchNormLeakyReLU(BatchNormalization): class BatchNormLeakyReLU(BatchNormalization):
def __init__(self, nPlanes, eps=1e-4, momentum=0.9, leakiness=0.333): def __init__(self, nPlanes, eps=1e-4, momentum=0.99, leakiness=0.333):
BatchNormalization.__init__(self, nPlanes, eps, momentum, True, leakiness) BatchNormalization.__init__(self, nPlanes, eps, momentum, True, leakiness)
def __repr__(self): def __repr__(self):
...@@ -166,7 +166,7 @@ class MeanOnlyBNLeakyReLU(Module): ...@@ -166,7 +166,7 @@ class MeanOnlyBNLeakyReLU(Module):
""" """
Parameters: Parameters:
nPlanes : number of input planes nPlanes : number of input planes
momentum : for calculating running average for testing (default 0.9) momentum : for calculating running average for testing (default 0.99)
leakiness : Apply activation def inplace: 0<=leakiness<=1. leakiness : Apply activation def inplace: 0<=leakiness<=1.
0 for ReLU, values in (0,1) for LeakyReLU, 1 for no activation def. 0 for ReLU, values in (0,1) for LeakyReLU, 1 for no activation def.
""" """
...@@ -175,7 +175,7 @@ class MeanOnlyBNLeakyReLU(Module): ...@@ -175,7 +175,7 @@ class MeanOnlyBNLeakyReLU(Module):
nPlanes, nPlanes,
affine=True, affine=True,
leakiness=1, leakiness=1,
momentum=0.9): momentum=0.99):
Module.__init__(self) Module.__init__(self)
self.nPlanes = nPlanes self.nPlanes = nPlanes
self.momentum = momentum self.momentum = momentum
......
...@@ -318,7 +318,7 @@ def FullConvolutionalNetIntegratedLinear(dimension, reps, nPlanes, nClasses=-1, ...@@ -318,7 +318,7 @@ def FullConvolutionalNetIntegratedLinear(dimension, reps, nPlanes, nClasses=-1,
return x+nPlanes return x+nPlanes
def foo(m,np): def foo(m,np):
for _ in range(reps): for _ in range(reps):
if residual_blocks: #ResNet style blocks if residual: #ResNet style blocks
m.add(scn.ConcatTable() m.add(scn.ConcatTable()
.add(scn.Identity()) .add(scn.Identity())
.add(scn.Sequential() .add(scn.Sequential()
...@@ -333,7 +333,7 @@ def FullConvolutionalNetIntegratedLinear(dimension, reps, nPlanes, nClasses=-1, ...@@ -333,7 +333,7 @@ def FullConvolutionalNetIntegratedLinear(dimension, reps, nPlanes, nClasses=-1,
def bar(m,nPlanes,bias): def bar(m,nPlanes,bias):
m.add(scn.BatchNormLeakyReLU(nPlanes,leakiness=leakiness)) m.add(scn.BatchNormLeakyReLU(nPlanes,leakiness=leakiness))
m.add(scn.NetworkInNetwork(nPlanes,nClasses,bias)) #accumulte softmax input, only one set of biases m.add(scn.NetworkInNetwork(nPlanes,nClasses,bias)) #accumulte softmax input, only one set of biases
def baz(depth,nPlanes): def baz(nPlanes):
m=scn.Sequential() m=scn.Sequential()
foo(m,nPlanes[0]) foo(m,nPlanes[0])
if len(nPlanes)==1: if len(nPlanes)==1:
...@@ -348,4 +348,4 @@ def FullConvolutionalNetIntegratedLinear(dimension, reps, nPlanes, nClasses=-1, ...@@ -348,4 +348,4 @@ def FullConvolutionalNetIntegratedLinear(dimension, reps, nPlanes, nClasses=-1,
scn.UnPooling(dimension, downsample[0], downsample[1])) scn.UnPooling(dimension, downsample[0], downsample[1]))
m.add(ConcatTable(a,b)) m.add(ConcatTable(a,b))
m.add(scn.AddTable()) m.add(scn.AddTable())
return baz(depth,nPlanes) return baz(nPlanes)
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
import torch, torch.utils.checkpoint import torch, torch.utils.checkpoint
from .utils import checkpoint101
class Sequential(torch.nn.Sequential): class Sequential(torch.nn.Sequential):
def input_spatial_size(self, out_size): def input_spatial_size(self, out_size):
...@@ -12,6 +13,14 @@ class Sequential(torch.nn.Sequential): ...@@ -12,6 +13,14 @@ class Sequential(torch.nn.Sequential):
out_size = self._modules[m].input_spatial_size(out_size) out_size = self._modules[m].input_spatial_size(out_size)
return out_size return out_size
def __add__(self, x):
r = Sequential()
for m in self:
r.append(m)
for m in x:
r.append(m)
return r
def add(self, module): def add(self, module):
self._modules[str(len(self._modules))] = module self._modules[str(len(self._modules))] = module
return self return self
......
...@@ -127,7 +127,7 @@ def batch_location_tensors(location_tensors): ...@@ -127,7 +127,7 @@ def batch_location_tensors(location_tensors):
def prepare_BLInput(l,f): def prepare_BLInput(l,f):
with torch.no_grad(): with torch.no_grad():
n=max([x.size(0) for x in l]) n=max([x.size(0) for x in l])
L=torch.empty(len(l),n,l[0].size(1)).fill_(-1) L=torch.empty(len(l),n,l[0].size(1),dtype=torch.int64).fill_(-1)
F=torch.zeros(len(l),n,f[0].size(1)) F=torch.zeros(len(l),n,f[0].size(1))
for i, (ll, ff) in enumerate(zip(l,f)): for i, (ll, ff) in enumerate(zip(l,f)):
L[i,:ll.size(0),:].copy_(ll) L[i,:ll.size(0),:].copy_(ll)
...@@ -156,6 +156,9 @@ def checkpoint_restore(model,exp_name,name2,use_cuda=True,epoch=0): ...@@ -156,6 +156,9 @@ def checkpoint_restore(model,exp_name,name2,use_cuda=True,epoch=0):
def is_power2(num): def is_power2(num):
return num != 0 and ((num & (num - 1)) == 0) return num != 0 and ((num & (num - 1)) == 0)
def is_square(num):
return int(num**0.5+0.5)**2==num
def has_only_one_nonzero_digit(num): #https://oeis.org/A037124 def has_only_one_nonzero_digit(num): #https://oeis.org/A037124
return num != 0 and (num/10**math.floor(math.log(num,10))).is_integer() return num != 0 and (num/10**math.floor(math.log(num,10))).is_integer()
...@@ -291,9 +294,37 @@ def matplotlib_planes(ax, positions,colors): ...@@ -291,9 +294,37 @@ def matplotlib_planes(ax, positions,colors):
pass pass
ax.set_axis_off() ax.set_axis_off()
def visdom_scatter(vis, xyz, rgb, win='3d', markersize=3): def visdom_scatter(vis, xyz, rgb, win='3d', markersize=3, title=''):
rgb=rgb.detach()
rgb-=rgb.min()
rgb/=rgb.max()/255+1e-10
rgb=rgb.floor().cpu().numpy()
vis.scatter( vis.scatter(
xyz, xyz.detach().cpu().numpy(),
opts={'markersize': markersize,'markercolor': rgb}, opts={'markersize': markersize,'markercolor': rgb, 'title': title},
win=win) win=win)
def ply_scatter(name, xyz, rgb):
rgb=rgb.detach()
rgb-=rgb.min()
rgb/=rgb.max()/255+1e-10
rgb=rgb.floor().cpu().numpy()
with open(name+'.ply','w') as f:
print("""ply
format ascii 1.0
element vertex %d
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
end_header"""%(xyz.size(0)), file = f)
for (x,y,z),(r,g,b) in zip(xyz,rgb):
print('%d %d %d %d %d %d'%(x,y,z,r,g,b),file=f)
class VerboseIdentity(torch.nn.Module):
def forward(self, x):
print(x)
return x
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment