mirror of
https://github.com/wassname/Flex-Convolution.git
synced 2026-09-09 11:14:10 +08:00
add pooling, transpose convolution to layers.py and update example.py
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
@@ -14,7 +14,7 @@ The following figure shows the *raw* network semantic segmentation prediction on
|
||||
<p align="center"> <img src=".github/flexconv.jpg" width="100%"> </p>
|
||||
|
||||
|
||||
This repository contains contains the source code of our FlexConv Layer from our 2018 ACCV paper "Flex-Convolution (Million-Scale Point-Cloud Learning Beyond Grid-Worlds)".
|
||||
This repository contains the source code of our FlexConv Layer from our 2018 ACCV paper "Flex-Convolution (Million-Scale Point-Cloud Learning Beyond Grid-Worlds)".
|
||||
|
||||
<p align="center"> <a href="https://www.youtube.com/watch?v=5ftWmuQXU_s"><img src="./.github/youtube.jpg" width="50%"></a> </p>
|
||||
|
||||
@@ -22,7 +22,7 @@ This repository contains contains the source code of our FlexConv Layer from our
|
||||
Example - Usage
|
||||
-------------------
|
||||
|
||||
We provide GPU-tailored cuda implementation of our novel FlexConv in TensorFlow.
|
||||
We provide GPU-tailored CUDA implementations of our novel FlexConv, FlexPool, FlexDeconv operations in TensorFlow.
|
||||
|
||||
```console
|
||||
user@host $ cd user_ops
|
||||
@@ -35,13 +35,13 @@ user@host $ python example.py
|
||||
Experiments
|
||||
-------------------
|
||||
|
||||
Deep learning on point-clouds is a complex matter and our codebase reflect that complexity.
|
||||
Deep learning on point-clouds is a complex matter and our codebase reflects that complexity.
|
||||
We are currently working on refactoring our research implementation to ease the usage. Therefore,
|
||||
`layers.py` contains a Keras/tf.layers compatible implementation. We will add the models later.
|
||||
|
||||
### Benchmark
|
||||
|
||||
We benchmarked the inference time of entire network on the 2D-3D-S dataset and with recent tests on V100, we were able to process ~18 Million Points.
|
||||
We benchmarked the inference time of *entire* network on the 2D-3D-S dataset and with a recent test on a NVIDIA V100 GPU, we were able to process ~18 Million Points.
|
||||
|
||||
<p align="center"> <img src=".github/inference_time.png" width="50%"> </p>
|
||||
|
||||
@@ -50,14 +50,14 @@ We benchmarked the inference time of entire network on the 2D-3D-S dataset and w
|
||||
|
||||
ShapeNet part segmentation results per category and mIoU (%) for different methods and inference speed (on a NVIDIA GeForce GTX 1080 Ti).
|
||||
|
||||
|| Airplane | Bag | Cap | Car | Chair | Earphones | Guitar | Knife | Lamp | Laptop | Motorbike | Mug | Pistol | Rocket | Skateboard | Table | mIoU | shapes/sec |
|
||||
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | --- | ---- | ---- | --- |
|
||||
|Kd-Network [4] | 80.1 | 74.6 | 74.3 | 70.3 | 88.6 | 73.5 | 90.2 | **87.2** | 81.0 | 94.9 | 57.4 | 86.7 | 78.1 | 51.8 | 69.9 | 80.3 | 77.4 | n.a.|
|
||||
|PointNet [1] | 83.4 | 78.7 | 82.5 | 74.9 | 89.6 | 73.0 | 91.5 | 85.9 | 80.8 | 95.3 | 65.2 | 93.0 | 81.2 | 57.9 | 72.8 | 80.6 | 80.4 | n.a. |
|
||||
|PointNet++ [2] | 82.4 | 79.0 | 87.7 | 77.3 | **90.8** | 71.8 | 91.0 | 85.9 | 83.7 | 95.3 | 71.6 | 94.1 | 81.3 | 58.7 | 76.4 | 82.6 | 81.9 | 2.7 |
|
||||
|SPLATNet3D [3] | 81.9 | 83.9 | 88.6 | **79.5** | 90.1 | 73.5 | 91.3 | 84.7 | **84.5** | 96.3 | 69.7 | 95.0 | 81.7 | 59.2 | 70.4 | 81.3 | 82.0 | 9.4 |
|
||||
|SGPN [5] | 80.4 | 78.6 | 78.8 | 71.5 | 88.6 | **78.0** | 90.9 | 83.0 | 78.8 | 95.8 | **77.8** | 93.8 | **87.4** | 60.1 | **92.3** | **89.4** | 82.8 | n.a. |
|
||||
Ours | **83.6** | **91.2** | **96.7** | **79.5** | 84.7 | 71.7 | **92.0** | 86.5 | 83.2 | **96.6** | 71.7 | **95.7** | 86.1 | **74.8** | 81.4 | 84.5 | **85.0** | **489.3** |
|
||||
| | mIoU | shapes/sec | Airplane | Bag | Cap | Car | Chair | Earphones | Guitar | Knife | Lamp | Laptop | Motorbike | Mug | Pistol | Rocket | Skateboard | Table |
|
||||
| ---- | ---- | --- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | --- | ---- |
|
||||
| Kd-Network [4] | 77.4 | n.a. | 80.1 | 74.6 | 74.3 | 70.3 | 88.6 | 73.5 | 90.2 | **87.2** | 81.0 | 94.9 | 57.4 | 86.7 | 78.1 | 51.8 | 69.9 | 80.3 |
|
||||
| PointNet [1] | 80.4 | n.a. | 83.4 | 78.7 | 82.5 | 74.9 | 89.6 | 73.0 | 91.5 | 85.9 | 80.8 | 95.3 | 65.2 | 93.0 | 81.2 | 57.9 | 72.8 | 80.6 |
|
||||
| PointNet++ [2] | 81.9 | 2.7 | 82.4 | 79.0 | 87.7 | 77.3 | **90.8** | 71.8 | 91.0 | 85.9 | 83.7 | 95.3 | 71.6 | 94.1 | 81.3 | 58.7 | 76.4 | 82.6 |
|
||||
| SPLATNet3D [3] | 82.0 | 9.4 | 81.9 | 83.9 | 88.6 | **79.5** | 90.1 | 73.5 | 91.3 | 84.7 | **84.5** | 96.3 | 69.7 | 95.0 | 81.7 | 59.2 | 70.4 | 81.3 |
|
||||
| SGPN [5] | 82.8 | n.a. | 80.4 | 78.6 | 78.8 | 71.5 | 88.6 | **78.0** | 90.9 | 83.0 | 78.8 | 95.8 | **77.8** | 93.8 | **87.4** | 60.1 | **92.3** | **89.4** |
|
||||
| Ours | **85.0** | **489.3** | **83.6** | **91.2** | **96.7** | **79.5** | 84.7 | 71.7 | **92.0** | 86.5 | 83.2 | **96.6** | 71.7 | **95.7** | 86.1 | **74.8** | 81.4 | 84.5 |
|
||||
|
||||

|
||||
|
||||
@@ -65,14 +65,14 @@ Ours | **83.6** | **91.2** | **96.7** | **79.5** | 84.
|
||||
|
||||
Class specific average precision (AP) on the 2D-3D-S dataset.
|
||||
|
||||
| | Table | Chair | Sofa | Bookcase | Board | Ceiling | Floor | Wall | Beam | Col. | Wind. | Door | mAP |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
Armeni [6] | 46.02 | 16.15 | 6.78 | 54.71 | 3.91 | 71.61 | 88.70 | 72.86 | 66.67 | **91.77** | 25.92 | 54.11 | 49.93|
|
||||
Armeni [6] | 39.87 | 11.43 | 4.91 | **57.76** | 3.73 | 50.74 | 80.48 | 65.59 | 68.53 | 85.08 | 21.17 | 45.39 | 44.19|
|
||||
PointNet [1] | 46.67 | 33.80 | 4.76 | n.a. | 11.72 | n.a. | n.a. | n.a. | n.a. | n.a. | n.a. | n.a. | n.a. |
|
||||
SGPN [5] | 46.90 | 40.77 | 6.38 | 47.61 | 11.05 | 79.44 | 66.29 | **88.77** | **77.98** | 60.71 | **66.62** | **56.75** | 54.35 |
|
||||
Ours | 66.03 | 51.75 | 15.59 | 39.03 | 43.50 | 87.20 | 96.00 | 65.53 | 54.76 | 52.74 | 55.34 | 35.81 | 55.27|
|
||||
Ours** | **67.02** | **52.75** | **16.61** | 39.26 | **47.68** | **87.33** | **96.10** | 65.52 | 56.83 | 55.10 | 57.66 | 36.76 | **56.55**|
|
||||
| | mAP | Table | Chair | Sofa | Bookcase | Board | Ceiling | Floor | Wall | Beam | Col. | Wind. | Door |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| Armeni [6] | 49.93 | 46.02 | 16.15 | 6.78 | 54.71 | 3.91 | 71.61 | 88.70 | 72.86 | 66.67 | **91.77** | 25.92 | 54.11 |
|
||||
| Armeni [6] | 44.19 | 39.87 | 11.43 | 4.91 | **57.76** | 3.73 | 50.74 | 80.48 | 65.59 | 68.53 | 85.08 | 21.17 | 45.39 |
|
||||
| PointNet [1] | n.a. | 46.67 | 33.80 | 4.76 | n.a. | 11.72 | n.a. | n.a. | n.a. | n.a. | n.a. | n.a. | n.a. |
|
||||
| SGPN [5] | 54.35 | 46.90 | 40.77 | 6.38 | 47.61 | 11.05 | 79.44 | 66.29 | **88.77** | **77.98** | 60.71 | **66.62** | **56.75** |
|
||||
| Ours | 55.27 | 66.03 | 51.75 | 15.59 | 39.03 | 43.50 | 87.20 | 96.00 | 65.53 | 54.76 | 52.74 | 55.34 | 35.81 |
|
||||
| Ours** | **56.55** | **67.02** | **52.75** | **16.61** | 39.26 | **47.68** | **87.33** | **96.10** | 65.52 | 56.83 | 55.10 | 57.66 | 36.76 |
|
||||
|
||||
|
||||

|
||||
|
||||
+32
-11
@@ -19,29 +19,50 @@
|
||||
|
||||
|
||||
"""
|
||||
Demonstration of using FlexConvolution Layer.
|
||||
Demonstration of using FlexConvolution, FlexPooling Layer.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
from layers import flex_convolution
|
||||
from tabulate import tabulate
|
||||
from layers import flex_convolution, flex_convolution_transpose, flex_pooling
|
||||
|
||||
B, Din, Dout, Dp, N, K = 1, 2, 4, 3, 10, 5
|
||||
B, Din, Dout, Dout2, Dp, N, N2, K, K2 = 1, 2, 4, 8, 3, 10, 5, 5, 3
|
||||
|
||||
features = np.random.randn(B, Din, N).astype(np.float32)
|
||||
positions = np.random.randn(B, Dp, N).astype(np.float32)
|
||||
neighbors = np.random.randint(0, N, [B, K, N]).astype(np.int32)
|
||||
neighbors2 = np.random.randint(0, N, [B, K2, N2]).astype(np.int32)
|
||||
|
||||
features = tf.convert_to_tensor(features, name='features')
|
||||
positions = tf.convert_to_tensor(positions, name='positions')
|
||||
neighbors = tf.convert_to_tensor(neighbors, name='neighbors')
|
||||
neighbors2 = tf.convert_to_tensor(neighbors2, name='neighbors2')
|
||||
|
||||
net = [features]
|
||||
# use our FlexConv similar to a traditional convolution layer
|
||||
net.append(flex_convolution(net[-1], positions, neighbors, Dout))
|
||||
# pool and sub-sampling are different operations
|
||||
net.append(flex_pooling(net[-1], neighbors))
|
||||
|
||||
# when ordering the points beforehand sub-sampling is simply
|
||||
features = net[-1][:, :, :N2]
|
||||
positions = positions[:, :, :N2]
|
||||
|
||||
net.append(features)
|
||||
# we didn't notice any improvements using the transposed version vs. pooling
|
||||
net.append(flex_convolution_transpose(net[-1], positions, neighbors2, Dout2))
|
||||
# of course any commonly used arguments work here as well
|
||||
net.append(flex_convolution(net[-1], positions,
|
||||
neighbors2, Dout2, trainable=False))
|
||||
|
||||
features = tf.convert_to_tensor(features)
|
||||
positions = tf.convert_to_tensor(positions)
|
||||
neighbors = tf.convert_to_tensor(neighbors)
|
||||
|
||||
features2 = flex_convolution(features, positions, neighbors, Dout)
|
||||
features3 = flex_convolution(features2, positions, neighbors, Dout, trainable=False)
|
||||
|
||||
with tf.Session() as sess:
|
||||
sess.run(tf.global_variables_initializer())
|
||||
sess.run(features2)
|
||||
sess.run(features3)
|
||||
sess.run(net[-1])
|
||||
|
||||
print(tf.trainable_variables())
|
||||
print(tabulate([[v.name, v.shape] for v in tf.trainable_variables()],
|
||||
headers=["Name", "Shape"]))
|
||||
|
||||
print(tabulate([[n.name, n.shape] for n in net], headers=["Name", "Shape"]))
|
||||
|
||||
@@ -29,18 +29,88 @@ from tensorflow.python.util.tf_export import tf_export
|
||||
from tensorflow.python.framework import tensor_shape
|
||||
from tensorflow.python.framework import ops
|
||||
|
||||
flex_pooling = _flex_pooling
|
||||
flex_convolution_transpose = _flex_convolution_transpose
|
||||
|
||||
all = ['FlexPooling', 'FlexConvolution', 'FlexConvolutionTranspose',
|
||||
'flex_pooling', 'flex_convolution', 'flex_convolution_transpose']
|
||||
|
||||
|
||||
def _remove_dim(x, axis):
|
||||
shape = x.shape.as_list()
|
||||
assert shape[axis] == 1
|
||||
del shape[axis]
|
||||
return tf.reshape(x, shape)
|
||||
def _remove_dim(x, axis=2):
|
||||
return tf.squeeze(x, axis=axis)
|
||||
|
||||
|
||||
@tf_export('keras.layers.Dense')
|
||||
@tf_export('keras.layers.FlexPooling')
|
||||
class FlexPooling(Layer):
|
||||
"""flex pooling layer.
|
||||
|
||||
This layer performs a max-pooling operation over elements in arbitrary
|
||||
neighborhoods. When `data_format` is 'simple', the input shape should
|
||||
have rank 3, otherwise rank 4 and dimension 2 should be 1.
|
||||
|
||||
Remarks:
|
||||
In contrast to traditional pooling, this operation has no option for
|
||||
sub-sampling.
|
||||
|
||||
Arguments:
|
||||
features: A `Tensor` of the format [B, Din, (1), N].
|
||||
neighborhoods: A `Tensor` of the format [B, K, (1), N] (tf.int32).
|
||||
name: A string, the name of the layer.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
features,
|
||||
neighborhoods,
|
||||
data_format='simple',
|
||||
name=None):
|
||||
|
||||
super(FlexPooling, self).__init__(name=name)
|
||||
self.features = features
|
||||
self.neighborhoods = neighborhoods
|
||||
self.data_format = data_format
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
return tensor_shape.TensorShape(input_shape)
|
||||
|
||||
def build(self, input_shape):
|
||||
self.built = True
|
||||
|
||||
def call(self, inputs):
|
||||
if not isinstance(inputs, list):
|
||||
raise ValueError('A flexconv layer should be called '
|
||||
'on a list of inputs.')
|
||||
|
||||
features = ops.convert_to_tensor(inputs[0], dtype=self.dtype)
|
||||
neighborhoods = ops.convert_to_tensor(inputs[1], dtype=tf.int32)
|
||||
|
||||
if self.data_format == 'expanded':
|
||||
features = _remove_dim(inputs[0], 2)
|
||||
neighborhoods = _remove_dim(inputs[1], 2)
|
||||
else:
|
||||
features = inputs[0]
|
||||
neighborhoods = inputs[1]
|
||||
|
||||
y, _ = _flex_pooling(features, neighborhoods)
|
||||
|
||||
if self.data_format == 'expanded':
|
||||
y = tf.expand_dims(y, axis=2)
|
||||
|
||||
return y
|
||||
|
||||
|
||||
def flex_pooling(features,
|
||||
neighborhoods,
|
||||
data_format='simple',
|
||||
name=None):
|
||||
|
||||
layer = FlexPooling(features,
|
||||
neighborhoods,
|
||||
data_format=data_format,
|
||||
name=name)
|
||||
|
||||
return layer.apply([features, neighborhoods])
|
||||
|
||||
|
||||
@tf_export('keras.layers.FlexConvolution')
|
||||
class FlexConvolution(Layer):
|
||||
"""flex convolution layer.
|
||||
|
||||
@@ -49,6 +119,8 @@ class FlexConvolution(Layer):
|
||||
If `use_feature_bias` is True (and a `features_bias_initializer` is provided),
|
||||
a bias vector is created and added to the outputs after te convolution.
|
||||
Finally, if `activation` is not `None`, it is applied to the outputs as well.
|
||||
When `data_format` is 'simple', the input shape should have rank 3,
|
||||
otherwise rank 4 and dimension 2 should be 1.
|
||||
|
||||
Remarks:
|
||||
In contrast to traditional convolutions, this operation has two
|
||||
@@ -120,7 +192,6 @@ class FlexConvolution(Layer):
|
||||
else:
|
||||
features = self.features
|
||||
positions = self.positions
|
||||
|
||||
[B, Din, N] = features.shape
|
||||
Din = int(Din)
|
||||
N = int(N)
|
||||
@@ -213,3 +284,108 @@ def flex_convolution(features,
|
||||
name=name)
|
||||
|
||||
return layer.apply([features, positions, neighborhoods])
|
||||
|
||||
|
||||
@tf_export('keras.layers.FlexConvolutionTranspose')
|
||||
class FlexConvolutionTranspose(FlexConvolution):
|
||||
"""flex convolution-transpose layer.
|
||||
|
||||
This layer applies a transpose convolution to elements in arbitrary
|
||||
neighborhoods.
|
||||
If `use_feature_bias` is True (and a `features_bias_initializer` is provided),
|
||||
a bias vector is created and added to the outputs after te convolution.
|
||||
Finally, if `activation` is not `None`, it is applied to the outputs as well.
|
||||
When `data_format` is 'simple', the input shape should have rank 3,
|
||||
otherwise rank 4 and dimension 2 should be 1.
|
||||
|
||||
Remarks:
|
||||
In contrast to traditional transposed convolutions, this operation has two
|
||||
bias terms:
|
||||
- bias term when dynamically computing the weight [Din, Dout]
|
||||
- bias term which is added tot the features [Dout]
|
||||
|
||||
Arguments:
|
||||
features: A `Tensor` of the format [B, Din, (1), N].
|
||||
positions: A `Tensor` of the format [B, Dp, (1), N].
|
||||
neighborhoods: A `Tensor` of the format [B, K, (1), N] (tf.int32).
|
||||
filters: Integer, the dimensionality of the output space (i.e. the number
|
||||
of filters in the convolution).
|
||||
activation: Activation function. Set it to None to maintain a
|
||||
linear activation.
|
||||
kernel_initializer: An initializer for the convolution kernel.
|
||||
position_bias_initializer: An initializer for the bias vector within
|
||||
the convolution. If None, the default initializer will be used.
|
||||
features_bias_initializer: An initializer for the bias vector after
|
||||
the convolution. If None, the default initializer will be used.
|
||||
use_feature_bias: Boolean, whether the layer uses a bias.
|
||||
data_format: A string, one of `simple` (default) or `expaned`.
|
||||
If `simple` the shapes are [B, Din, N], when `expanded` the shapes
|
||||
are assumed to be [B, Din, 1, N] to match `channels_first` in trad
|
||||
convolutions.
|
||||
trainable: Boolean, if `True` also add variables to the graph collection
|
||||
`GraphKeys.TRAINABLE_VARIABLES` (see `tf.Variable`).
|
||||
name: A string, the name of the layer.
|
||||
|
||||
"""
|
||||
|
||||
def call(self, inputs):
|
||||
|
||||
if not isinstance(inputs, list):
|
||||
raise ValueError('A flexconv layer should be called '
|
||||
'on a list of inputs.')
|
||||
|
||||
features = ops.convert_to_tensor(inputs[0], dtype=self.dtype)
|
||||
positions = ops.convert_to_tensor(inputs[1], dtype=self.dtype)
|
||||
neighborhoods = ops.convert_to_tensor(inputs[2], dtype=tf.int32)
|
||||
|
||||
if self.data_format == 'expanded':
|
||||
features = _remove_dim(inputs[0], 2)
|
||||
positions = _remove_dim(inputs[1], 2)
|
||||
neighborhoods = _remove_dim(inputs[2], 2)
|
||||
else:
|
||||
features = inputs[0]
|
||||
positions = inputs[1]
|
||||
neighborhoods = inputs[2]
|
||||
|
||||
y = _flex_convolution_transpose(features, positions, neighborhoods,
|
||||
self.position_theta, self.position_bias)
|
||||
|
||||
if self.use_feature_bias:
|
||||
y = tf.add(y, self.feature_bias)
|
||||
|
||||
if self.activation is not None:
|
||||
y = self.activation(y)
|
||||
|
||||
if self.data_format == 'expanded':
|
||||
y = tf.expand_dims(y, axis=2)
|
||||
|
||||
return y
|
||||
|
||||
|
||||
def flex_convolution_transpose(features,
|
||||
positions,
|
||||
neighborhoods,
|
||||
filters,
|
||||
activation=None,
|
||||
kernel_initializer=None,
|
||||
position_bias_initializer=tf.zeros_initializer(),
|
||||
features_bias_initializer=tf.zeros_initializer(),
|
||||
use_feature_bias=True,
|
||||
data_format='simple',
|
||||
trainable=True,
|
||||
name=None):
|
||||
|
||||
layer = FlexConvolutionTranspose(features,
|
||||
positions,
|
||||
neighborhoods,
|
||||
filters,
|
||||
activation=activation,
|
||||
kernel_initializer=kernel_initializer,
|
||||
position_bias_initializer=position_bias_initializer,
|
||||
features_bias_initializer=features_bias_initializer,
|
||||
use_feature_bias=use_feature_bias,
|
||||
data_format=data_format,
|
||||
trainable=trainable,
|
||||
name=name)
|
||||
|
||||
return layer.apply([features, positions, neighborhoods])
|
||||
|
||||
@@ -10,7 +10,7 @@ project( FlexConv )
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
|
||||
|
||||
find_package(CUDA 9 REQUIRED)
|
||||
find_package(CUDA REQUIRED)
|
||||
find_package(TensorFlow REQUIRED)
|
||||
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ else()
|
||||
# However, only TensorFlow versions 1.9, 1.10 support all header files
|
||||
# for custom ops.
|
||||
set(_TensorFlow_KNOWN_VERSIONS ${TensorFlow_ADDITIONAL_VERSIONS}
|
||||
"1.9" "1.9.0" "1.10" "1.10.0")
|
||||
"1.9" "1.9.0" "1.10" "1.10.0", "1.11", "1.11.0")
|
||||
set(_TensorFlow_TEST_VERSIONS)
|
||||
|
||||
if(TF_FIND_VERSION)
|
||||
@@ -270,4 +270,4 @@ SET(TensorFlow_INCLUDE_DIR ${TensorFlow_INCLUDE_DIR} CACHE PATH "path to tensorf
|
||||
SET(TensorFlow_VERSION ${TensorFlow_VERSION} CACHE INTERNAL "The Python executable Version")
|
||||
SET(TensorFlow_ABI ${TensorFlow_ABI} CACHE STRING "The Python executable Version")
|
||||
SET(TensorFlow_LIBRARY ${TensorFlow_LIBRARY} CACHE PATH "The Python executable Version")
|
||||
SET(TensorFlow_FOUND ${TensorFlow_FOUND} CACHE BOOL "The Python executable Version")
|
||||
SET(TensorFlow_FOUND ${TensorFlow_FOUND} CACHE BOOL "The Python executable Version")
|
||||
|
||||
@@ -41,9 +41,8 @@ flex_pool_grad = _flex_pooling_op_so.flex_pool_grad
|
||||
flex_deconv = _flex_deconvolution_op_so.flex_deconv
|
||||
flex_deconv_grad = _flex_deconvolution_op_so.flex_deconv_grad
|
||||
|
||||
|
||||
# pylint: disable=redefined-builtin
|
||||
|
||||
|
||||
def flex_convolution(features,
|
||||
position,
|
||||
neighborhood,
|
||||
|
||||
Reference in New Issue
Block a user