Skip to content

Commit a9076f1

Browse files
committed
Merge branch 'patch-op-names' into r0.1
2 parents a116402 + 12b5053 commit a9076f1

35 files changed

+1735
-80
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Try those commands below:
6868
Addons provides `make code-format` command to format your changes
6969
automatically, don't forget to use it before pushing your codes.
7070

71-
Please see our [Style Guide](SYLE_GUIDE.md) for more details.
71+
Please see our [Style Guide](STYLE_GUIDE.md) for more details.
7272

7373
## Code Testing
7474
#### CI Testing

README.md

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# TensorFlow Addons
22

3+
[![PyPI Status Badge](https://badge.fury.io/py/tensorflow-addons.svg)](https://pypi.org/project/tensorflow-addons/)
4+
[![Gitter chat](https://img.shields.io/badge/chat-on%20gitter-46bc99.svg)](https://gitter.im/tensorflow/sig-addons)
5+
6+
### Official Builds
7+
8+
| Build Type | Status |
9+
| --- | --- |
10+
| **Linux Py2 CPU** | [![Status](https://storage.googleapis.com/tensorflow-kokoro-build-badges/addons/ubuntu-py2.svg)](https://storage.googleapis.com/tensorflow-kokoro-build-badges/addons/ubuntu-py2.html) |
11+
| **Linux Py3 CPU** | [![Status](https://storage.googleapis.com/tensorflow-kokoro-build-badges/addons/ubuntu-py3.svg)](https://storage.googleapis.com/tensorflow-kokoro-build-badges/addons/ubuntu-py3.html) |
12+
| **Linux Py2 GPU** | [![Status](https://storage.googleapis.com/tensorflow-kokoro-build-badges/addons/ubuntu-gpu-py2.svg)](https://storage.googleapis.com/tensorflow-kokoro-build-badges/addons/ubuntu-gpu-py2.html) |
13+
| **Linux Py3 GPU** | [![Status](https://storage.googleapis.com/tensorflow-kokoro-build-badges/addons/ubuntu-gpu-py3.svg)](https://storage.googleapis.com/tensorflow-kokoro-build-badges/addons/ubuntu-gpu-py3.html) |
14+
315
TensorFlow Addons is a repository of contributions that conform to
416
well-established API patterns, but implement new functionality
517
not available in core TensorFlow. TensorFlow natively supports
@@ -13,9 +25,14 @@ developments that cannot be integrated into core TensorFlow
1325
| Sub-Package | Addon | Reference |
1426
|:----------------------- |:----------- |:---------------------------- |
1527
| tfa.activations | Sparsemax | https://arxiv.org/abs/1602.02068 |
28+
| tfa.image | adjust_hsv_in_yiq | |
29+
| tfa.image | random_hsv_in_yiq | |
1630
| tfa.image | transform | |
31+
| tfa.layers | GroupNormalization | https://arxiv.org/abs/1803.08494 |
32+
| tfa.layers | InstanceNormalization | https://arxiv.org/abs/1607.08022 |
33+
| tfa.layers | LayerNormalization | https://arxiv.org/abs/1607.06450 |
1734
| tfa.layers | Maxout | https://arxiv.org/abs/1302.4389 |
18-
| tfa.layers | PoinareNormalize | https://arxiv.org/abs/1705.08039 |
35+
| tfa.layers | PoincareNormalize | https://arxiv.org/abs/1705.08039 |
1936
| tfa.layers | WeightNormalization | https://arxiv.org/abs/1602.07868 |
2037
| tfa.losses | LiftedStructLoss | https://arxiv.org/abs/1511.06452 |
2138
| tfa.losses | SparsemaxLoss | https://arxiv.org/abs/1602.02068 |
@@ -33,9 +50,9 @@ the list we adhere to:
3350

3451

3552
1) [Layers](tensorflow_addons/layers/README.md)
36-
1) [Optimizers](tensorflow_addons/optimizers/README.md)
37-
1) [Losses](tensorflow_addons/losses/README.md)
38-
1) [Custom Ops](tensorflow_addons/custom_ops/README.md)
53+
2) [Optimizers](tensorflow_addons/optimizers/README.md)
54+
3) [Losses](tensorflow_addons/losses/README.md)
55+
4) [Custom Ops](tensorflow_addons/custom_ops/README.md)
3956

4057
#### Periodic Evaluation
4158
Based on the nature of this repository, there will be contributions that
@@ -44,7 +61,6 @@ maintainable, SIG-Addons will perform periodic reviews and deprecate
4461
contributions which will be slated for removal. More information will
4562
be available after we submit a formal request for comment.
4663

47-
4864
## Examples
4965
See [`tensorflow_addons/examples/`](tensorflow_addons/examples/)
5066
for end-to-end examples of various addons.
@@ -56,6 +72,15 @@ To install the latest version, run the following:
5672
pip install tensorflow-addons
5773
```
5874

75+
**Note:** You will also need [TensorFlow 2.0 or higher](https://www.tensorflow.org/alpha).
76+
77+
To use addons:
78+
79+
```python
80+
import tensorflow as tf
81+
import tensorflow_addons as tfa
82+
```
83+
5984
#### Installing from Source
6085
You can also install from source. This requires the [Bazel](
6186
https://bazel.build/) build system.

tensorflow_addons/activations/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ py_library(
1717

1818
py_test(
1919
name = "sparsemax_py_test",
20-
size = "small",
20+
size = "medium",
2121
srcs = [
2222
"python/sparsemax_test.py",
2323
],

tensorflow_addons/activations/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ must:
1919
#### Testing Requirements
2020
* Simple unittests that demonstrate the layer is behaving as expected.
2121
* When applicable, run all unittests with TensorFlow's
22-
`@run_all_in_graph_and_eager_modes` decorator.
22+
`@run_in_graph_and_eager_modes` (for test method)
23+
or `run_all_in_graph_and_eager_modes` (for TestCase subclass)
24+
decorator.
2325
* Add a `py_test` to this sub-package's BUILD file.
2426

2527
#### Documentation Requirements

tensorflow_addons/custom_ops/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ must:
2020
* Simple unittests that demonstrate the custom op is behaving as
2121
expected.
2222
* When applicable, run all unittests with TensorFlow's
23-
`@run_all_in_graph_and_eager_modes` decorator.
23+
`@run_in_graph_and_eager_modes` (for test method)
24+
or `run_all_in_graph_and_eager_modes` (for TestCase subclass)
25+
decorator.
2426
* Add a `py_test` to the custom-op's BUILD file.
2527

2628
#### Documentation Requirements

tensorflow_addons/custom_ops/image/BUILD

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ licenses(["notice"]) # Apache 2.0
22

33
package(default_visibility = ["//visibility:public"])
44

5+
cc_binary(
6+
name = "python/_distort_image_ops.so",
7+
srcs = [
8+
"cc/kernels/adjust_hsv_in_yiq_op.cc",
9+
"cc/kernels/adjust_hsv_in_yiq_op.h",
10+
"cc/ops/distort_image_ops.cc",
11+
],
12+
linkshared = 1,
13+
deps = [
14+
"@local_config_tf//:libtensorflow_framework",
15+
"@local_config_tf//:tf_header_lib",
16+
],
17+
copts = ["-pthread", "-std=c++11", "-D_GLIBCXX_USE_CXX11_ABI=0"]
18+
)
19+
20+
521
cc_binary(
622
name = "python/_image_ops.so",
723
srcs = [
@@ -26,18 +42,34 @@ py_library(
2642
srcs = ([
2743
"__init__.py",
2844
"python/__init__.py",
45+
"python/distort_image_ops.py",
2946
"python/transform.py",
3047
]),
3148
data = [
49+
":python/_distort_image_ops.so",
3250
":python/_image_ops.so",
51+
"//tensorflow_addons/utils:utils_py",
3352
],
3453
srcs_version = "PY2AND3",
3554
)
3655

56+
py_test(
57+
name = "distort_image_ops_test",
58+
size = "small",
59+
srcs = [
60+
"python/distort_image_ops_test.py",
61+
],
62+
main = "python/distort_image_ops_test.py",
63+
deps = [
64+
":images_ops_py",
65+
],
66+
srcs_version = "PY2AND3"
67+
)
68+
3769
# TODO: use cuda_py_test later.
3870
py_test(
3971
name = "transform_ops_test",
40-
size = "small",
72+
size = "medium",
4173
srcs = [
4274
"python/transform_test.py",
4375
],

tensorflow_addons/custom_ops/image/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@
1717
from __future__ import division
1818
from __future__ import print_function
1919

20+
from tensorflow_addons.custom_ops.image.python.distort_image_ops import adjust_hsv_in_yiq
21+
from tensorflow_addons.custom_ops.image.python.distort_image_ops import random_hsv_in_yiq
2022
# Transforms
2123
from tensorflow_addons.custom_ops.image.python.transform import transform
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
==============================================================================*/
15+
16+
#if GOOGLE_CUDA
17+
#define EIGEN_USE_GPU
18+
#endif // GOOGLE_CUDA
19+
20+
#include <memory>
21+
22+
#include "tensorflow/core/framework/register_types.h"
23+
#include "tensorflow/core/framework/tensor.h"
24+
#include "tensorflow/core/framework/tensor_shape.h"
25+
#include "tensorflow/core/lib/core/status.h"
26+
#include "tensorflow/core/platform/logging.h"
27+
#include "tensorflow/core/util/work_sharder.h"
28+
#include "tensorflow_addons/custom_ops/image/cc/kernels/adjust_hsv_in_yiq_op.h"
29+
30+
namespace tensorflow {
31+
32+
typedef Eigen::ThreadPoolDevice CPUDevice;
33+
typedef Eigen::GpuDevice GPUDevice;
34+
35+
class AdjustHsvInYiqOpBase : public OpKernel {
36+
protected:
37+
explicit AdjustHsvInYiqOpBase(OpKernelConstruction* context)
38+
: OpKernel(context) {}
39+
40+
struct ComputeOptions {
41+
const Tensor* input = nullptr;
42+
Tensor* output = nullptr;
43+
const Tensor* delta_h = nullptr;
44+
const Tensor* scale_s = nullptr;
45+
const Tensor* scale_v = nullptr;
46+
int64 channel_count = 0;
47+
};
48+
49+
virtual void DoCompute(OpKernelContext* context,
50+
const ComputeOptions& options) = 0;
51+
52+
void Compute(OpKernelContext* context) override {
53+
const Tensor& input = context->input(0);
54+
const Tensor& delta_h = context->input(1);
55+
const Tensor& scale_s = context->input(2);
56+
const Tensor& scale_v = context->input(3);
57+
OP_REQUIRES(context, input.dims() >= 3,
58+
errors::InvalidArgument("input must be at least 3-D, got shape",
59+
input.shape().DebugString()));
60+
OP_REQUIRES(context, TensorShapeUtils::IsScalar(delta_h.shape()),
61+
errors::InvalidArgument("delta_h must be scalar: ",
62+
delta_h.shape().DebugString()));
63+
OP_REQUIRES(context, TensorShapeUtils::IsScalar(scale_s.shape()),
64+
errors::InvalidArgument("scale_s must be scalar: ",
65+
scale_s.shape().DebugString()));
66+
OP_REQUIRES(context, TensorShapeUtils::IsScalar(scale_v.shape()),
67+
errors::InvalidArgument("scale_v must be scalar: ",
68+
scale_v.shape().DebugString()));
69+
auto channels = input.dim_size(input.dims() - 1);
70+
OP_REQUIRES(
71+
context, channels == kChannelSize,
72+
errors::InvalidArgument("input must have 3 channels but instead has ",
73+
channels, " channels."));
74+
75+
Tensor* output = nullptr;
76+
OP_REQUIRES_OK(context,
77+
context->allocate_output(0, input.shape(), &output));
78+
79+
if (input.NumElements() > 0) {
80+
const int64 channel_count = input.NumElements() / channels;
81+
ComputeOptions options;
82+
options.input = &input;
83+
options.delta_h = &delta_h;
84+
options.scale_s = &scale_s;
85+
options.scale_v = &scale_v;
86+
options.output = output;
87+
options.channel_count = channel_count;
88+
DoCompute(context, options);
89+
}
90+
}
91+
};
92+
93+
template <class Device>
94+
class AdjustHsvInYiqOp;
95+
96+
template <>
97+
class AdjustHsvInYiqOp<CPUDevice> : public AdjustHsvInYiqOpBase {
98+
public:
99+
explicit AdjustHsvInYiqOp(OpKernelConstruction* context)
100+
: AdjustHsvInYiqOpBase(context) {}
101+
102+
void DoCompute(OpKernelContext* context,
103+
const ComputeOptions& options) override {
104+
const Tensor* input = options.input;
105+
Tensor* output = options.output;
106+
const int64 channel_count = options.channel_count;
107+
auto input_data = input->shaped<float, 2>({channel_count, kChannelSize});
108+
const float delta_h = options.delta_h->scalar<float>()();
109+
const float scale_s = options.scale_s->scalar<float>()();
110+
const float scale_v = options.scale_v->scalar<float>()();
111+
auto output_data = output->shaped<float, 2>({channel_count, kChannelSize});
112+
float tranformation_matrix[kChannelSize * kChannelSize] = {0};
113+
internal::compute_tranformation_matrix<kChannelSize * kChannelSize>(
114+
delta_h, scale_s, scale_v, tranformation_matrix);
115+
const int kCostPerChannel = 10;
116+
const DeviceBase::CpuWorkerThreads& worker_threads =
117+
*context->device()->tensorflow_cpu_worker_threads();
118+
Shard(worker_threads.num_threads, worker_threads.workers, channel_count,
119+
kCostPerChannel, [&input_data, &output_data, &tranformation_matrix](
120+
int64 start_channel, int64 end_channel) {
121+
// Applying projection matrix to input RGB vectors.
122+
const float* p = input_data.data() + start_channel * kChannelSize;
123+
float* q = output_data.data() + start_channel * kChannelSize;
124+
for (int i = start_channel; i < end_channel; i++) {
125+
for (int q_index = 0; q_index < kChannelSize; q_index++) {
126+
q[q_index] = 0;
127+
for (int p_index = 0; p_index < kChannelSize; p_index++) {
128+
q[q_index] +=
129+
p[p_index] *
130+
tranformation_matrix[q_index + kChannelSize * p_index];
131+
}
132+
}
133+
p += kChannelSize;
134+
q += kChannelSize;
135+
}
136+
});
137+
}
138+
};
139+
140+
REGISTER_KERNEL_BUILDER(
141+
Name("AdjustHsvInYiq").Device(DEVICE_CPU).TypeConstraint<float>("T"),
142+
AdjustHsvInYiqOp<CPUDevice>);
143+
144+
#if GOOGLE_CUDA
145+
template <>
146+
class AdjustHsvInYiqOp<GPUDevice> : public AdjustHsvInYiqOpBase {
147+
public:
148+
explicit AdjustHsvInYiqOp(OpKernelConstruction* context)
149+
: AdjustHsvInYiqOpBase(context) {}
150+
151+
void DoCompute(OpKernelContext* ctx, const ComputeOptions& options) override {
152+
const int64 number_of_elements = options.input->NumElements();
153+
if (number_of_elements <= 0) {
154+
return;
155+
}
156+
const float* delta_h = options.delta_h->flat<float>().data();
157+
const float* scale_s = options.scale_s->flat<float>().data();
158+
const float* scale_v = options.scale_v->flat<float>().data();
159+
functor::AdjustHsvInYiqGPU()(ctx, options.channel_count, options.input,
160+
delta_h, scale_s, scale_v, options.output);
161+
}
162+
};
163+
164+
REGISTER_KERNEL_BUILDER(
165+
Name("AdjustHsvInYiq").Device(DEVICE_GPU).TypeConstraint<float>("T"),
166+
AdjustHsvInYiqOp<GPUDevice>);
167+
#endif
168+
169+
} // namespace tensorflow

0 commit comments

Comments
 (0)