稀疏2d卷积模型搭建
稀疏2d卷积
输入
-
1.sparse_shape = torch.LongTensor([87, 87])
-
2.input = scn.InputBatch(2, spase_shape) # dimension sparse shape
-
3.输入稀疏张量
# add_sample的一种方式 input.add_sample() location = torch.LongTensor([y, x]) featureVector = torch.FloatTensor([2]) input.set_location(location, featureVector, 0) # 另一种方式 input.add_sample() locations.append([y, x]) features.append([1]) locations = torch.LongTensor(locations) features = torch.FloatTensor(features) input.set_locations(locations, features, 0)
-
另外一种方法:
self.inputLayer = scn.InputLayer(2, self.spatial_size, 2) # dimension, spatial_size, mode input = self.inputLayer(x) # 这里有一个问题,这个x是什么样的呢?也有坐标和features # 其中变量x是一个(coors, features, batch_size)的一个元组。
model搭建
model1 = scn.Sequential().add(
scn.SubmanifoldConvolution(2, 1, 8, 3, False)
).add(
scn.SubmanifoldConvolution(2, 8, 16, 3, False)
).add(
scn.SubmanifoldConvolution(2, 16, 32, 3, False)
).add(
scn.BatchNormalization(32)
).add(
scn.Convolution(2, 32, 32, 3, 2, False),
).add(
scn.SparseToDense(2, 32)
)
# 稀疏2d卷积模型
import torch
import torch.nn as nn
import sparseconvnet as scn
from data import get_iterators
# two-dimensional SparseConvNet
class Model(nn.Module):
def __init__(self):
nn.Module.__init__(self)
self.sparseModel = scn.Sequential(
scn.SubmanifoldConvolution(2, 3, 8, 3, False),
scn.MaxPooling(2, 3, 2),
scn.SparseResNet(2, 8, [ # dimension,输入通道数,['basic block',输出通道数,]
['b', 8, 2, 1],
['b', 16, 2, 2],
['b', 24, 2, 2],
['b', 32, 2, 2]]),
scn.Convolution(2, 32, 64, 5, 1, False),
scn.BatchNormReLU(64),
scn.SparseToDense(2, 64))
self.spatial_size= self.sparseModel.input_spatial_size(torch.LongTensor([1, 1]))
self.inputLayer = scn.InputLayer(2,self.spatial_size,2)
self.linear = nn.Linear(64, 183)
def forward(self, x):
x = self.inputLayer(x)
x = self.sparseModel(x)
x = x.view(-1, 64)
x = self.linear(x)
return x
model = Model()
print('model: ', model)
## 稀疏卷积 ResNet结构实现
def SparseResNet(dimension, nInputPlanes, layers):
"""
pre-activated ResNet
e.g. layers = {{'basic',16,2,1}, {'basic',32,2}}
"""
nPlanes = nInputPlanes
m = scn.Sequential()
def residual(nIn, nOut, stride):
if stride > 1:
return scn.Convolution(dimension, nIn, nOut, 3, stride, False)
elif nIn != nOut:
return scn.NetworkInNetwork(nIn, nOut, False)
else:
return scn.Identity()
for blockType, n, reps, stride in layers:
for rep in range(reps):
if blockType[0] == 'b': # basic block
if rep == 0:
m.add(scn.BatchNormReLU(nPlanes))
m.add(
scn.ConcatTable().add(
scn.Sequential().add(
scn.SubmanifoldConvolution(
dimension,
nPlanes,
n,
3,
False) if stride == 1 else scn.Convolution(
dimension,
nPlanes,
n,
3,
stride,
False)) .add(
scn.BatchNormReLU(n)) .add(
scn.SubmanifoldConvolution(
dimension,
n,
n,
3,
False))) .add(
residual(
nPlanes,
n,
stride)))
else:
m.add(
scn.ConcatTable().add(
scn.Sequential().add(
scn.BatchNormReLU(nPlanes)) .add(
scn.SubmanifoldConvolution(
dimension,
nPlanes,
n,
3,
False)) .add(
scn.BatchNormReLU(n)) .add(
scn.SubmanifoldConvolution(
dimension,
n,
n,
3,
False))) .add(
scn.Identity()))
nPlanes = n
m.add(scn.AddTable())
m.add(scn.BatchNormReLU(nPlanes))
return m
将稀疏转成稠密张量
- scn.SparseToDense(2, 32)
总结
稀疏卷积网络的搭建基本就是这个样子。我觉得难点还是具体的实现。