sparsepixels 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sparsepixels-0.2.0/sparsepixels.egg-info → sparsepixels-0.2.1}/PKG-INFO +2 -4
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/README.md +1 -3
- sparsepixels-0.2.1/pyproject.toml +24 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/setup.cfg +1 -1
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/sparsepixels/layers.py +25 -24
- {sparsepixels-0.2.0 → sparsepixels-0.2.1/sparsepixels.egg-info}/PKG-INFO +2 -4
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/tests/test_model.py +2 -5
- sparsepixels-0.2.0/pyproject.toml +0 -3
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/LICENSE +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/notebook/utils.py +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/setup.py +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/sparsepixels/__init__.py +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/sparsepixels/img/logo.png +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/sparsepixels.egg-info/SOURCES.txt +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/sparsepixels.egg-info/dependency_links.txt +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/sparsepixels.egg-info/requires.txt +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/sparsepixels.egg-info/top_level.txt +0 -0
- {sparsepixels-0.2.0 → sparsepixels-0.2.1}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sparsepixels
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Efficient convolution for sparse data on FPGAs
|
|
5
5
|
Home-page: https://github.com/hftsoi/sparse-pixels
|
|
6
6
|
Author: Ho Fung Tsoi
|
|
@@ -53,7 +53,6 @@ import keras
|
|
|
53
53
|
from keras.layers import Flatten, Activation, ReLU
|
|
54
54
|
from hgq.layers import QConv2D, QDense
|
|
55
55
|
from hgq.config import QuantizerConfigScope, LayerConfigScope
|
|
56
|
-
from hgq.quantizer.config import QuantizerConfig
|
|
57
56
|
from sparsepixels.layers import InputReduce, QConv2DSparse, AveragePooling2DSparse
|
|
58
57
|
```
|
|
59
58
|
|
|
@@ -71,8 +70,7 @@ with (
|
|
|
71
70
|
x, keep_mask = InputReduce(n_max_pixels=20, threshold=0.1, name='input_reduce')(x_in)
|
|
72
71
|
|
|
73
72
|
# Sparse convolution
|
|
74
|
-
x = QConv2DSparse(filters=3, kernel_size=3, name='conv1', padding='same', strides=1,
|
|
75
|
-
bq_conf=QuantizerConfig('default', 'bias'))([x, keep_mask])
|
|
73
|
+
x = QConv2DSparse(filters=3, kernel_size=3, name='conv1', padding='same', strides=1)([x, keep_mask])
|
|
76
74
|
x = ReLU(name='relu1')(x)
|
|
77
75
|
|
|
78
76
|
# Sparse pooling
|
|
@@ -35,7 +35,6 @@ import keras
|
|
|
35
35
|
from keras.layers import Flatten, Activation, ReLU
|
|
36
36
|
from hgq.layers import QConv2D, QDense
|
|
37
37
|
from hgq.config import QuantizerConfigScope, LayerConfigScope
|
|
38
|
-
from hgq.quantizer.config import QuantizerConfig
|
|
39
38
|
from sparsepixels.layers import InputReduce, QConv2DSparse, AveragePooling2DSparse
|
|
40
39
|
```
|
|
41
40
|
|
|
@@ -53,8 +52,7 @@ with (
|
|
|
53
52
|
x, keep_mask = InputReduce(n_max_pixels=20, threshold=0.1, name='input_reduce')(x_in)
|
|
54
53
|
|
|
55
54
|
# Sparse convolution
|
|
56
|
-
x = QConv2DSparse(filters=3, kernel_size=3, name='conv1', padding='same', strides=1,
|
|
57
|
-
bq_conf=QuantizerConfig('default', 'bias'))([x, keep_mask])
|
|
55
|
+
x = QConv2DSparse(filters=3, kernel_size=3, name='conv1', padding='same', strides=1)([x, keep_mask])
|
|
58
56
|
x = ReLU(name='relu1')(x)
|
|
59
57
|
|
|
60
58
|
# Sparse pooling
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.ruff]
|
|
6
|
+
target-version = "py310"
|
|
7
|
+
line-length = 120
|
|
8
|
+
|
|
9
|
+
[tool.ruff.lint]
|
|
10
|
+
select = [
|
|
11
|
+
"E",
|
|
12
|
+
"F",
|
|
13
|
+
"I",
|
|
14
|
+
"W",
|
|
15
|
+
"UP",
|
|
16
|
+
]
|
|
17
|
+
ignore = [
|
|
18
|
+
"E402",
|
|
19
|
+
"F403",
|
|
20
|
+
"F405",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[tool.ruff.lint.isort]
|
|
24
|
+
known-first-party = ["sparsepixels"]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import keras
|
|
2
|
-
from keras import ops
|
|
3
|
-
from keras.layers import AveragePooling2D, MaxPooling2D
|
|
4
2
|
from hgq.layers import QConv2D
|
|
5
3
|
from hgq.quantizer import Quantizer
|
|
6
4
|
from hgq.quantizer.config import QuantizerConfig
|
|
5
|
+
from keras import ops
|
|
6
|
+
from keras.layers import AveragePooling2D, MaxPooling2D
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class InputReduce(keras.layers.Layer):
|
|
@@ -37,10 +37,12 @@ class InputReduce(keras.layers.Layer):
|
|
|
37
37
|
|
|
38
38
|
def get_config(self):
|
|
39
39
|
config = super().get_config()
|
|
40
|
-
config.update(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
config.update(
|
|
41
|
+
{
|
|
42
|
+
"n_max_pixels": self.n_max_pixels,
|
|
43
|
+
"threshold": self.threshold,
|
|
44
|
+
}
|
|
45
|
+
)
|
|
44
46
|
return config
|
|
45
47
|
|
|
46
48
|
|
|
@@ -60,7 +62,8 @@ class RemoveDilatedPixels(keras.layers.Layer):
|
|
|
60
62
|
class QConv2DSparse(keras.layers.Layer):
|
|
61
63
|
def __init__(self, *conv_args, **conv_kwargs):
|
|
62
64
|
super().__init__(name=conv_kwargs.get("name", None))
|
|
63
|
-
self.
|
|
65
|
+
self._use_bias = conv_kwargs.pop("use_bias", True)
|
|
66
|
+
self._bq_conf = conv_kwargs.pop("bq_conf", None) or QuantizerConfig("default", "bias")
|
|
64
67
|
|
|
65
68
|
conv_kwargs["use_bias"] = False
|
|
66
69
|
conv_kwargs.setdefault("enable_iq", False)
|
|
@@ -68,17 +71,15 @@ class QConv2DSparse(keras.layers.Layer):
|
|
|
68
71
|
self.masker = RemoveDilatedPixels()
|
|
69
72
|
|
|
70
73
|
def build(self, input_shape):
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
if self._use_bias:
|
|
75
|
+
self.sparse_bias = self.add_weight(
|
|
76
|
+
name="sparse_bias",
|
|
77
|
+
shape=(self.conv.filters,),
|
|
78
|
+
initializer="zeros",
|
|
79
|
+
trainable=True,
|
|
80
|
+
)
|
|
78
81
|
self._bq = Quantizer(self._bq_conf, name=f"{self.name}_bq")
|
|
79
82
|
self._bq.build((self.conv.filters,))
|
|
80
|
-
else:
|
|
81
|
-
self._bq = None
|
|
82
83
|
super().build(input_shape)
|
|
83
84
|
|
|
84
85
|
def call(self, inputs, **kwargs):
|
|
@@ -86,13 +87,11 @@ class QConv2DSparse(keras.layers.Layer):
|
|
|
86
87
|
x = self.masker((x, keep_mask))
|
|
87
88
|
y = self.conv(x, **kwargs)
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
b =
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
non_zero = ops.cast(y != 0, y.dtype)
|
|
95
|
-
y = y + b * non_zero
|
|
90
|
+
if self._use_bias:
|
|
91
|
+
b = self._bq(self.sparse_bias)
|
|
92
|
+
b = ops.reshape(b, (1, 1, 1, -1))
|
|
93
|
+
non_zero = ops.cast(y != 0, y.dtype)
|
|
94
|
+
y = y + b * non_zero
|
|
96
95
|
|
|
97
96
|
y = self.masker((y, keep_mask))
|
|
98
97
|
return y
|
|
@@ -100,14 +99,16 @@ class QConv2DSparse(keras.layers.Layer):
|
|
|
100
99
|
def get_config(self):
|
|
101
100
|
cfg = super().get_config()
|
|
102
101
|
cfg["conv_config"] = self.conv.get_config()
|
|
102
|
+
cfg["use_bias"] = self._use_bias
|
|
103
103
|
cfg["bq_conf"] = self._bq_conf
|
|
104
104
|
return cfg
|
|
105
105
|
|
|
106
106
|
@classmethod
|
|
107
107
|
def from_config(cls, config):
|
|
108
108
|
conv_cfg = config.pop("conv_config")
|
|
109
|
+
use_bias = config.pop("use_bias", True)
|
|
109
110
|
bq_conf = config.pop("bq_conf", None)
|
|
110
|
-
return cls(**conv_cfg, bq_conf=bq_conf)
|
|
111
|
+
return cls(**conv_cfg, use_bias=use_bias, bq_conf=bq_conf)
|
|
111
112
|
|
|
112
113
|
|
|
113
114
|
class AveragePooling2DSparse(keras.layers.Layer):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sparsepixels
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Efficient convolution for sparse data on FPGAs
|
|
5
5
|
Home-page: https://github.com/hftsoi/sparse-pixels
|
|
6
6
|
Author: Ho Fung Tsoi
|
|
@@ -53,7 +53,6 @@ import keras
|
|
|
53
53
|
from keras.layers import Flatten, Activation, ReLU
|
|
54
54
|
from hgq.layers import QConv2D, QDense
|
|
55
55
|
from hgq.config import QuantizerConfigScope, LayerConfigScope
|
|
56
|
-
from hgq.quantizer.config import QuantizerConfig
|
|
57
56
|
from sparsepixels.layers import InputReduce, QConv2DSparse, AveragePooling2DSparse
|
|
58
57
|
```
|
|
59
58
|
|
|
@@ -71,8 +70,7 @@ with (
|
|
|
71
70
|
x, keep_mask = InputReduce(n_max_pixels=20, threshold=0.1, name='input_reduce')(x_in)
|
|
72
71
|
|
|
73
72
|
# Sparse convolution
|
|
74
|
-
x = QConv2DSparse(filters=3, kernel_size=3, name='conv1', padding='same', strides=1,
|
|
75
|
-
bq_conf=QuantizerConfig('default', 'bias'))([x, keep_mask])
|
|
73
|
+
x = QConv2DSparse(filters=3, kernel_size=3, name='conv1', padding='same', strides=1)([x, keep_mask])
|
|
76
74
|
x = ReLU(name='relu1')(x)
|
|
77
75
|
|
|
78
76
|
# Sparse pooling
|
|
@@ -2,7 +2,6 @@ import keras
|
|
|
2
2
|
from keras.layers import Flatten, Activation, AveragePooling2D, ReLU
|
|
3
3
|
from hgq.layers import QConv2D, QDense
|
|
4
4
|
from hgq.config import QuantizerConfigScope, LayerConfigScope
|
|
5
|
-
from hgq.quantizer.config import QuantizerConfig
|
|
6
5
|
from sparsepixels.layers import InputReduce, QConv2DSparse, AveragePooling2DSparse
|
|
7
6
|
|
|
8
7
|
|
|
@@ -19,13 +18,11 @@ def build_cnn(is_sparse, n_max_pixels=None):
|
|
|
19
18
|
x = x_in
|
|
20
19
|
|
|
21
20
|
if is_sparse:
|
|
22
|
-
x = QConv2DSparse(filters=1, kernel_size=7, name='conv1', padding='same', strides=1,
|
|
23
|
-
bq_conf=QuantizerConfig('default', 'bias'))([x, keep_mask])
|
|
21
|
+
x = QConv2DSparse(filters=1, kernel_size=7, name='conv1', padding='same', strides=1)([x, keep_mask])
|
|
24
22
|
x = ReLU(name='relu1')(x)
|
|
25
23
|
x, keep_mask = AveragePooling2DSparse(4, name='pool1')([x, keep_mask])
|
|
26
24
|
|
|
27
|
-
x = QConv2DSparse(filters=3, kernel_size=5, name='conv2', padding='same', strides=1,
|
|
28
|
-
bq_conf=QuantizerConfig('default', 'bias'))([x, keep_mask])
|
|
25
|
+
x = QConv2DSparse(filters=3, kernel_size=5, name='conv2', padding='same', strides=1)([x, keep_mask])
|
|
29
26
|
x = ReLU(name='relu2')(x)
|
|
30
27
|
x, keep_mask = AveragePooling2DSparse(2, name='pool2')([x, keep_mask])
|
|
31
28
|
else:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|