1. 程式人生 > 實用技巧 >稀疏張量基礎

稀疏張量基礎

稀疏張量基礎

稀疏張量是稀疏矩陣的高維擴充套件,其中非零元素表示為一組索引和關聯值。

Data Generation

可以通過提取非零元素直接生成資料。本文展示了一個簡單的2D陣列,其中心有5個非零元素。

data = [

[0, 0, 2.1, 0, 0],

[0, 1, 1.4, 3, 0],

[0, 0, 4.0, 0, 0]

]

def to_sparse_coo(data):

# An intuitive way to extract coordinates and features

coords, feats = [], []

for i, row in enumerate(data):

for

j, val in enumerate(row):

if val != 0:

coords.append([i, j])

feats.append([val])

return torch.IntTensor(coords), torch.FloatTensor(feats)

to_sparse_coo(data)

注意,將座標與特徵一起提取。這是一個簡單的示例,效率很低而且是人為的。在許多實際應用中,不太可能獲得離散座標。

稀疏張量初始化

流水線的下一步是初始化稀疏張量。AMinkowskiEngine.SparseTensor需要具有批次索引的座標;導致張量稀疏D+1維空間尺寸(如果原始座標具有D維尺寸)。

coords0, feats0 = to_sparse_coo(data_batch_0)

coords1, feats1 = to_sparse_coo(data_batch_1)

coords, feats = ME.utils.sparse_collate(

coords=[coords0, coords1], feats=[feats0, feats1])

這裡使用了MinkowskiEngine.utils.sparse_collate函式,但是可以使用MinkowskiEngine.utils.batched_coordinates將座標列表轉換為MinkowskiEngine.SparseTensor

相容座標。

連續座標的稀疏張量

在許多情況下,神經網路中使用的座標是連續的。稀疏張量網路中使用的稀疏張量是在離散座標系中定義的。要將連續座標中的特徵轉換為離散座標,提供了特徵平均功能,可將連續座標中的特徵轉換為離散座標。可以為此簡單地使用稀疏張量初始化。例如,

sinput = ME.SparseTensor(
 feats=torch.from_numpy(colors), # Convert to a tensor
 coords=ME.utils.batched_coordinates([coordinates / voxel_size]), # coordinates must be defined in a integer grid. If the scale
 quantization_mode=ME.SparseTensorQuantizationMode.UNWEIGHTED_AVERAGE # when used with continuous coordinates, average features in the same coordinate
)
logits = model(sinput).slice(sinput)

稀疏張量演算法

可以將初始化的稀疏張量與簡單的前饋神經網路一起使用,但是在許多情況下,需要執行一些非常規的運算元,這就是為什麼來使用此庫的原因。這裡,提供了一些簡單的運算元,這些運算元允許沿特徵維的稀疏張量和級聯之間的二進位制運算。

# sparse tensors
A = ME.SparseTensor(coords=coords, feats=feats)
B = ME.SparseTensor(
 coords=new_coords,
 feats=new_feats,
 coords_manager=A.coords_man, # must share the same coordinate manager
 force_creation=True # must force creation since tensor stride [1] exists
)

C = A + B
C = A - B
C = A * B
C = A / B

在這裡,建立兩個具有不同稀疏模式的稀疏張量。強制第二個稀疏張量B共享座標管理器coords_man。允許在兩個稀疏張量之間共享計算圖。目前的語義相當醜陋,但將來會隱藏起來。

如果新增兩個稀疏張量,將新增兩個功能。如果存在一個非零元素,但在特定座標上的另一個稀疏張量上沒有,將不存在的值設為0,因為稀疏張量僅儲存非零元素。根據定義,未指定的任何內容均為0。其他所有二進位制運算元也是如此。

對於區域性運算元,強制座標具有相同的稀疏模式。

# in place operations
# Note that it requires the same coords_key (no need to feed coords)
D = ME.SparseTensor(
 # coords=coords, not required
 feats=feats,
 coords_manager=A.coords_man, # must share the same coordinate manager
 coords_key=A.coords_key # For inplace, must share the same coords key
)

A += D
A -= D
A *= D
A /= D

注意,對稀疏張量D使用相同的coords_key。如果嘗試使用帶有不同coords_key的稀疏張量,將給一個斷言錯誤。

功能串聯

如果兩個稀疏張量共享相同的coords_key可以沿特徵維連線們。

# If you have two or more sparse tensors with the same coords_key, you can concatenate features
E = ME.cat(A, D)

分批分解

稀疏張量的內部結構將批處理中的所有非零元素摺疊為座標矩陣和特徵矩陣。要分解輸出,可以使用幾個函式和屬性。

coords0, feats0 = to_sparse_coo(data_batch_0)
coords1, feats1 = to_sparse_coo(data_batch_1)
coords, feats = ME.utils.sparse_collate(
 coords=[coords0, coords1], feats=[feats0, feats1])

# sparse tensors
A = ME.SparseTensor(coords=coords, feats=feats)
conv = ME.MinkowskiConvolution(
 in_channels=1, out_channels=2, kernel_size=3, stride=2, dimension=2)
B = conv(A)

# Extract features and coordinates per batch index
coords = B.decomposed_coordinates
feats = B.decomposed_features
coords, feats = B.decomposed_coordinates_and_features

# To specify a batch index
batch_index = 1
coords = B.coordinates_at(batch_index)
feats = B.features_at(batch_index)