Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
ResNet50_tensorflow
Commits
ca552843
"...git@developer.sourcefind.cn:yaoht/yolox_migraphx.git" did not exist on "04e4e7631f85c99155e526342d40fb5d8eb96640"
Unverified
Commit
ca552843
authored
Sep 16, 2021
by
Srihari Humbarwadi
Committed by
GitHub
Sep 16, 2021
Browse files
Merge branch 'panoptic-segmentation' into panoptic-segmentation
parents
7e2f7a35
6b90e134
Changes
283
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
458 additions
and
160 deletions
+458
-160
research/seq_flow_lite/tf_ops/projection_util.h
research/seq_flow_lite/tf_ops/projection_util.h
+36
-23
research/seq_flow_lite/tf_ops/repo.bzl
research/seq_flow_lite/tf_ops/repo.bzl
+1
-1
research/seq_flow_lite/tf_ops/sequence_string_projection.cc
research/seq_flow_lite/tf_ops/sequence_string_projection.cc
+41
-9
research/seq_flow_lite/tf_ops/sequence_string_projection_op_v2.cc
.../seq_flow_lite/tf_ops/sequence_string_projection_op_v2.cc
+15
-1
research/seq_flow_lite/tf_ops/text_distorter.h
research/seq_flow_lite/tf_ops/text_distorter.h
+0
-1
research/seq_flow_lite/tf_ops/tf_custom_ops.cc
research/seq_flow_lite/tf_ops/tf_custom_ops.cc
+0
-54
research/seq_flow_lite/tflite_ops/BUILD
research/seq_flow_lite/tflite_ops/BUILD
+14
-0
research/seq_flow_lite/tflite_ops/expected_value.cc
research/seq_flow_lite/tflite_ops/expected_value.cc
+2
-2
research/seq_flow_lite/tflite_ops/expected_value.h
research/seq_flow_lite/tflite_ops/expected_value.h
+2
-2
research/seq_flow_lite/tflite_ops/layer_norm.cc
research/seq_flow_lite/tflite_ops/layer_norm.cc
+100
-4
research/seq_flow_lite/tflite_ops/layer_norm.h
research/seq_flow_lite/tflite_ops/layer_norm.h
+2
-2
research/seq_flow_lite/tflite_ops/layer_norm_test.cc
research/seq_flow_lite/tflite_ops/layer_norm_test.cc
+37
-35
research/seq_flow_lite/tflite_ops/quantization_util.h
research/seq_flow_lite/tflite_ops/quantization_util.h
+2
-2
research/seq_flow_lite/tflite_ops/registerer.cc
research/seq_flow_lite/tflite_ops/registerer.cc
+49
-0
research/seq_flow_lite/tflite_ops/sequence_string_projection.cc
...ch/seq_flow_lite/tflite_ops/sequence_string_projection.cc
+6
-4
research/seq_flow_lite/tflite_ops/sequence_string_projection.h
...rch/seq_flow_lite/tflite_ops/sequence_string_projection.h
+2
-2
research/seq_flow_lite/tflite_ops/sequence_string_projection_test.cc
...q_flow_lite/tflite_ops/sequence_string_projection_test.cc
+27
-14
research/seq_flow_lite/tflite_ops/tf_tflite_diff_test_util.cc
...arch/seq_flow_lite/tflite_ops/tf_tflite_diff_test_util.cc
+7
-2
research/seq_flow_lite/tflite_ops/tf_tflite_diff_test_util.h
research/seq_flow_lite/tflite_ops/tf_tflite_diff_test_util.h
+2
-2
research/seq_flow_lite/trainer_v2.py
research/seq_flow_lite/trainer_v2.py
+113
-0
No files found.
research/seq_flow_lite/tf_ops/projection_util.h
View file @
ca552843
...
@@ -21,23 +21,26 @@ limitations under the License.
...
@@ -21,23 +21,26 @@ limitations under the License.
#include "libutf/utf.h"
#include "libutf/utf.h"
constexpr
int
kFirstCapOffset
=
3
;
inline
constexpr
int
kFirstCapOffset
=
3
;
constexpr
int
kAllCapsOffset
=
4
;
inline
constexpr
int
kAllCapsOffset
=
4
;
constexpr
int
kWordNoveltyOffset
=
1
;
inline
constexpr
int
kWordNoveltyOffset
=
1
;
constexpr
int
kDocSizeOffset
=
2
;
inline
constexpr
int
kDocSizeOffset
=
2
;
const
char
kMurmurHash
[]
=
"murmur"
;
inline
constexpr
char
kMurmurHash
[]
=
"murmur"
;
const
char
kXfixHash8
[]
=
"xfixhash8"
;
inline
constexpr
char
kXfixHash8
[]
=
"xfixhash8"
;
const
char
kXfixHash16
[]
=
"xfixhash16"
;
inline
constexpr
char
kXfixHash16
[]
=
"xfixhash16"
;
const
char
kXfixHash32
[]
=
"xfixhash32"
;
inline
constexpr
char
kXfixHash32
[]
=
"xfixhash32"
;
const
char
kUnicodeHash8
[]
=
"unicodehash8"
;
inline
constexpr
char
kUnicodeHash8
[]
=
"unicodehash8"
;
const
char
kUnicodeHash16
[]
=
"unicodehash16"
;
inline
constexpr
char
kUnicodeHash16
[]
=
"unicodehash16"
;
// A base class that specifies the interface for a hash engine used by the
// projection operator.
class
HashEngine
{
class
HashEngine
{
public:
public:
virtual
void
GetHashCodes
(
const
std
::
string
&
word
,
// Takes a string token `word` and a `feature_size` (measured in bits) and
std
::
vector
<
uint64_t
>*
hash_codes
,
// returns hash codes that represent the token.
int
feature_size
)
=
0
;
virtual
std
::
vector
<
uint64_t
>
GetHashCodes
(
const
std
::
string
&
word
,
int
feature_size
)
=
0
;
virtual
~
HashEngine
()
{}
virtual
~
HashEngine
()
{}
};
};
...
@@ -50,13 +53,12 @@ class Hasher {
...
@@ -50,13 +53,12 @@ class Hasher {
const
std
::
string
&
hash_type
=
kMurmurHash
);
const
std
::
string
&
hash_type
=
kMurmurHash
);
static
bool
SupportedHashType
(
const
std
::
string
&
hash_type
);
static
bool
SupportedHashType
(
const
std
::
string
&
hash_type
);
bool
GetHashCodes
(
const
std
::
string
&
word
,
bool
GetHashCodes
(
const
std
::
string
&
word
,
std
::
vector
<
uint64_t
>
*
hash_codes
)
{
std
::
vector
<
uint64_t
>
&
hash_codes
)
{
if
(
!
hash_engine_
)
return
false
;
if
(
!
hash_engine_
)
return
false
;
if
(
word
.
empty
())
{
if
(
word
.
empty
())
{
*
hash_codes
=
null_hash_codes_
;
hash_codes
=
null_hash_codes_
;
}
else
{
}
else
{
hash_codes
->
clear
();
hash_codes
=
hash_engine_
->
GetHashCodes
(
word
,
feature_size_
);
hash_engine_
->
GetHashCodes
(
word
,
hash_codes
,
feature_size_
);
}
}
return
true
;
return
true
;
}
}
...
@@ -64,8 +66,13 @@ class Hasher {
...
@@ -64,8 +66,13 @@ class Hasher {
private:
private:
explicit
Hasher
(
int
feature_size
,
HashEngine
*
hash_engine
);
explicit
Hasher
(
int
feature_size
,
HashEngine
*
hash_engine
);
const
std
::
string
empty_string_
=
"<null>"
;
const
std
::
string
empty_string_
=
"<null>"
;
// Size of the projection feature which represents the number of bits of
// hash codes that will be generated by this class.
const
int
feature_size_
;
const
int
feature_size_
;
// The hash engine used by this class.
std
::
unique_ptr
<
HashEngine
>
hash_engine_
;
std
::
unique_ptr
<
HashEngine
>
hash_engine_
;
// Hash codes for empty text is precaculated and stored below to speed
// up projection.
std
::
vector
<
uint64_t
>
null_hash_codes_
;
std
::
vector
<
uint64_t
>
null_hash_codes_
;
};
};
...
@@ -90,7 +97,8 @@ class ProjectionUnicodeHandler {
...
@@ -90,7 +97,8 @@ class ProjectionUnicodeHandler {
}
}
// Performs language independent lower case and returns a string with
// Performs language independent lower case and returns a string with
// supported unicode segments.
// supported unicode segments and two additional flags first_cap and all_caps
// which when true indicate the text is Firstcap or ALLCAPS.
std
::
string
LowerCaseUTF8WithSupportedUnicodes
(
std
::
string
LowerCaseUTF8WithSupportedUnicodes
(
const
std
::
pair
<
const
char
*
,
size_t
>&
source
,
bool
*
first_cap
=
nullptr
,
const
std
::
pair
<
const
char
*
,
size_t
>&
source
,
bool
*
first_cap
=
nullptr
,
bool
*
all_caps
=
nullptr
)
const
;
bool
*
all_caps
=
nullptr
)
const
;
...
@@ -126,14 +134,19 @@ class ProjectionUnicodeHandler {
...
@@ -126,14 +134,19 @@ class ProjectionUnicodeHandler {
int
max_tokens
);
int
max_tokens
);
private:
private:
// Parses and extracts supported unicode segments from a utf8 string.
// Parses and extracts supported or allowed unicode segments, also referred
// to as vocabulary, from a utf8 string.
void
InitializeVocabulary
(
const
std
::
string
&
vocabulary
);
void
InitializeVocabulary
(
const
std
::
string
&
vocabulary
);
// A variable that maps a valid Unicode rune to its index in valid character
// vocabulary.
std
::
unordered_map
<
Rune
,
int
>
valid_chars_
;
std
::
unordered_map
<
Rune
,
int
>
valid_chars_
;
// Controls whether to exclude non-alphabetic, non-space characters from the
// output text.
bool
exclude_nonalphaspace_unicodes_
;
bool
exclude_nonalphaspace_unicodes_
;
};
};
static
constexpr
size_t
kEntireString
=
SIZE_MAX
;
inline
constexpr
size_t
kEntireString
=
SIZE_MAX
;
static
constexpr
size_t
kAllTokens
=
SIZE_MAX
;
inline
constexpr
size_t
kAllTokens
=
SIZE_MAX
;
std
::
vector
<
std
::
string
>
SplitBySpace
(
const
char
*
input_ptr
,
size_t
len
,
std
::
vector
<
std
::
string
>
SplitBySpace
(
const
char
*
input_ptr
,
size_t
len
,
size_t
max_input
,
size_t
max_tokens
);
size_t
max_input
,
size_t
max_tokens
);
...
...
research/seq_flow_lite/tf_ops/repo.bzl
View file @
ca552843
...
@@ -198,7 +198,7 @@ cc_library(
...
@@ -198,7 +198,7 @@ cc_library(
),
),
includes = ["tensorflow_includes"],
includes = ["tensorflow_includes"],
deps = [
deps = [
"@eigen_archive//:eigen",
"@eigen_archive//:eigen
3
",
"@protobuf_archive//:includes",
"@protobuf_archive//:includes",
"@zlib_includes//:includes",
"@zlib_includes//:includes",
"@snappy_includes//:includes",
"@snappy_includes//:includes",
...
...
research/seq_flow_lite/tf_ops/sequence_string_projection.cc
View file @
ca552843
...
@@ -12,16 +12,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
...
@@ -12,16 +12,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
See the License for the specific language governing permissions and
limitations under the License.
limitations under the License.
==============================================================================*/
==============================================================================*/
#include "tf_ops/projection_normalizer_util.h" // seq_flow_lite
#include "tf_ops/projection_tokenizer_util.h" // seq_flow_lite
#include "tf_ops/projection_util.h" // seq_flow_lite
#include "tf_ops/text_distorter.h" // seq_flow_lite
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_map.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/framework/shape_inference.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tf_ops/projection_normalizer_util.h" // seq_flow_lite
#include "tf_ops/projection_tokenizer_util.h" // seq_flow_lite
#include "tf_ops/projection_util.h" // seq_flow_lite
#include "tf_ops/text_distorter.h" // seq_flow_lite
using
::
tensorflow
::
int32
;
using
::
tensorflow
::
int32
;
using
::
tensorflow
::
int64
;
using
::
tensorflow
::
int64
;
...
@@ -51,10 +51,11 @@ float* AllocateTensor(OpKernelContext* ctx, const std::string& tensor_name,
...
@@ -51,10 +51,11 @@ float* AllocateTensor(OpKernelContext* ctx, const std::string& tensor_name,
return
&
tensor
->
flat
<
float
>
()(
0
);
return
&
tensor
->
flat
<
float
>
()(
0
);
}
}
// OpKernel for the sequence string projection op.
class
SequenceStringProjectionOp
:
public
OpKernel
{
class
SequenceStringProjectionOp
:
public
OpKernel
{
public:
public:
explicit
SequenceStringProjectionOp
(
OpKernelConstruction
*
context
)
explicit
SequenceStringProjectionOp
(
OpKernelConstruction
*
context
)
:
OpKernel
(
context
)
{
:
OpKernel
(
context
)
,
philox_
(
171
),
generator_
(
&
philox_
)
{
OP_REQUIRES_OK
(
context
,
context
->
GetAttr
(
"feature_size"
,
&
feature_size_
));
OP_REQUIRES_OK
(
context
,
context
->
GetAttr
(
"feature_size"
,
&
feature_size_
));
std
::
string
hashtype
;
std
::
string
hashtype
;
OP_REQUIRES_OK
(
context
,
context
->
GetAttr
(
"hashtype"
,
&
hashtype
));
OP_REQUIRES_OK
(
context
,
context
->
GetAttr
(
"hashtype"
,
&
hashtype
));
...
@@ -159,7 +160,10 @@ class SequenceStringProjectionOp : public OpKernel {
...
@@ -159,7 +160,10 @@ class SequenceStringProjectionOp : public OpKernel {
}
}
const
int64
seq_len
=
const
int64
seq_len
=
static_cast
<
int64
>
(
bos_tag_
+
words
.
size
()
+
eos_tag_
);
static_cast
<
int64
>
(
bos_tag_
+
words
.
size
()
+
eos_tag_
);
CHECK_GT
(
seq_len
,
0
);
CHECK_GT
(
seq_len
,
0
)
<<
"Projection models expect input text to have at-least one valid "
"token. If empty text is a valid input for your model, please set "
"add_bos_tag to true."
;
max_seq_len
=
std
::
max
(
max_seq_len
,
seq_len
);
max_seq_len
=
std
::
max
(
max_seq_len
,
seq_len
);
words_batches
.
emplace_back
(
std
::
move
(
words
));
words_batches
.
emplace_back
(
std
::
move
(
words
));
}
}
...
@@ -208,7 +212,7 @@ class SequenceStringProjectionOp : public OpKernel {
...
@@ -208,7 +212,7 @@ class SequenceStringProjectionOp : public OpKernel {
CHECK_EQ
(
eos_tag_
,
1
);
CHECK_EQ
(
eos_tag_
,
1
);
word
=
kEndTokenTSP
;
word
=
kEndTokenTSP
;
}
}
hasher_
->
GetHashCodes
(
word
,
&
hash_codes
);
hasher_
->
GetHashCodes
(
word
,
hash_codes
);
for
(
int
hindex
=
0
,
k
=
0
;
hindex
<
hash_codes
.
size
();
hindex
++
)
{
for
(
int
hindex
=
0
,
k
=
0
;
hindex
<
hash_codes
.
size
();
hindex
++
)
{
auto
hash
=
hash_codes
[
hindex
];
auto
hash
=
hash_codes
[
hindex
];
for
(
int
kmax
=
std
::
min
(
k
+
increment
,
feature_size_
);
k
<
kmax
;)
{
for
(
int
kmax
=
std
::
min
(
k
+
increment
,
feature_size_
);
k
<
kmax
;)
{
...
@@ -229,7 +233,7 @@ class SequenceStringProjectionOp : public OpKernel {
...
@@ -229,7 +233,7 @@ class SequenceStringProjectionOp : public OpKernel {
doc_size_feature
;
doc_size_feature
;
}
}
if
(
add_first_cap_feature_
>
0.0
f
)
{
if
(
add_first_cap_feature_
>
0.0
f
)
{
if
(
text_distorter_
->
BernouilleSample
(
add_first_cap_feature_
)
)
{
if
(
generator_
.
RandFloat
()
<=
add_first_cap_feature_
)
{
projection
[
offset0
+
feature_size_
-
kFirstCapOffset
]
=
projection
[
offset0
+
feature_size_
-
kFirstCapOffset
]
=
first_cap
?
1.0
:
-
1.0
;
first_cap
?
1.0
:
-
1.0
;
}
else
{
}
else
{
...
@@ -237,7 +241,7 @@ class SequenceStringProjectionOp : public OpKernel {
...
@@ -237,7 +241,7 @@ class SequenceStringProjectionOp : public OpKernel {
}
}
}
}
if
(
add_all_caps_feature_
>
0.0
f
)
{
if
(
add_all_caps_feature_
>
0.0
f
)
{
if
(
text_distorter_
->
BernouilleSample
(
add_all_caps_feature_
)
)
{
if
(
generator_
.
RandFloat
()
<=
add_all_caps_feature_
)
{
projection
[
offset0
+
feature_size_
-
kAllCapsOffset
]
=
projection
[
offset0
+
feature_size_
-
kAllCapsOffset
]
=
all_caps
?
1.0
:
-
1.0
;
all_caps
?
1.0
:
-
1.0
;
}
else
{
}
else
{
...
@@ -252,21 +256,49 @@ class SequenceStringProjectionOp : public OpKernel {
...
@@ -252,21 +256,49 @@ class SequenceStringProjectionOp : public OpKernel {
}
}
private:
private:
// Objects used for random number generator.
tensorflow
::
random
::
PhiloxRandom
philox_
;
tensorflow
::
random
::
SimplePhilox
generator_
;
// Dimensionality of the ternary vector for each token in the text.
int32
feature_size_
;
int32
feature_size_
;
// An object used to hash tokens in the text.
std
::
unique_ptr
<
Hasher
>
hasher_
;
std
::
unique_ptr
<
Hasher
>
hasher_
;
// An object used for distorting text before projection.
std
::
unique_ptr
<
TextDistorter
>
text_distorter_
;
std
::
unique_ptr
<
TextDistorter
>
text_distorter_
;
// An object used for manipulating unicode in the text. It performs tasks such
// as retaining only whitelisted unicodes in the text tokens and lowercasing
// them.
std
::
unique_ptr
<
ProjectionUnicodeHandler
>
unicode_handler_
;
std
::
unique_ptr
<
ProjectionUnicodeHandler
>
unicode_handler_
;
// An object used for normalizing tokens in the text. This performs tasks
// such as identifying repeated characters and replace them with a single
// instance.
std
::
unique_ptr
<
ProjectionNormalizer
>
projection_normalizer_
;
std
::
unique_ptr
<
ProjectionNormalizer
>
projection_normalizer_
;
// Character whitelist used by the projection operator.
std
::
string
vocabulary_
;
std
::
string
vocabulary_
;
// Size of the character whitelist.
int
vocabulary_size_
;
int
vocabulary_size_
;
// Maximum number of splits allowed in the text. The number of tokens in text
// post segmentation will be utmost max_splits_ + 1.
int32
max_splits_
;
int32
max_splits_
;
// A flag that indicates how to segment text. When true text is segmented by
// space. Otherwise it is segmented on unicode boundaries.
bool
split_on_space_
;
bool
split_on_space_
;
// When true include an end of sentence token in the projection.
int
eos_tag_
;
int
eos_tag_
;
// When true include a begin of sentence token in the projection.
int
bos_tag_
;
int
bos_tag_
;
// Number of bits used to capture word novelty. See tensorflow op
// documentation below for details.
int
word_novelty_bits_
;
int
word_novelty_bits_
;
// Number of levels used to capture document size. See tensorflow op
// documentation below for details.
int
doc_size_levels_
;
int
doc_size_levels_
;
// Distance between levels used for word novelty.
float
word_novelty_offset_
;
float
word_novelty_offset_
;
// Adds boolean feature to indicate first_cap text with the below probability.
float
add_first_cap_feature_
;
float
add_first_cap_feature_
;
// Adds boolean feature to indicate all_cap text with the below probability.
float
add_all_caps_feature_
;
float
add_all_caps_feature_
;
};
};
...
...
research/seq_flow_lite/tf_ops/sequence_string_projection_op_v2.cc
View file @
ca552843
...
@@ -40,6 +40,8 @@ constexpr char kEndTokenTSP[] = "<EOS>";
...
@@ -40,6 +40,8 @@ constexpr char kEndTokenTSP[] = "<EOS>";
constexpr
float
kMappingTable
[
4
]
=
{
0
,
1
,
-
1
,
0
};
constexpr
float
kMappingTable
[
4
]
=
{
0
,
1
,
-
1
,
0
};
constexpr
int
kIncrement
=
32
;
constexpr
int
kIncrement
=
32
;
// Version 2 OpKernel for the sequence string projection op.
// Template T can be int32 or int64.
template
<
typename
T
>
template
<
typename
T
>
class
SequenceStringProjectionOpV2
:
public
OpKernel
{
class
SequenceStringProjectionOpV2
:
public
OpKernel
{
public:
public:
...
@@ -136,7 +138,7 @@ class SequenceStringProjectionOpV2 : public OpKernel {
...
@@ -136,7 +138,7 @@ class SequenceStringProjectionOpV2 : public OpKernel {
}
else
{
}
else
{
word
=
kEndTokenTSP
;
word
=
kEndTokenTSP
;
}
}
hasher_
->
GetHashCodes
(
word
,
&
hash_codes
);
hasher_
->
GetHashCodes
(
word
,
hash_codes
);
for
(
int
hindex
=
0
,
k
=
0
;
hindex
<
hash_codes
.
size
();
hindex
++
)
{
for
(
int
hindex
=
0
,
k
=
0
;
hindex
<
hash_codes
.
size
();
hindex
++
)
{
auto
hash
=
hash_codes
[
hindex
];
auto
hash
=
hash_codes
[
hindex
];
for
(
int
kmax
=
std
::
min
(
k
+
kIncrement
,
feature_size_
);
k
<
kmax
;)
{
for
(
int
kmax
=
std
::
min
(
k
+
kIncrement
,
feature_size_
);
k
<
kmax
;)
{
...
@@ -153,13 +155,25 @@ class SequenceStringProjectionOpV2 : public OpKernel {
...
@@ -153,13 +155,25 @@ class SequenceStringProjectionOpV2 : public OpKernel {
}
}
private:
private:
// Dimensionality of the ternary vector for each token in the text.
int32
feature_size_
;
int32
feature_size_
;
// An object used to hash tokens in the text.
std
::
unique_ptr
<
Hasher
>
hasher_
;
std
::
unique_ptr
<
Hasher
>
hasher_
;
// An object used for distorting text before projection.
std
::
unique_ptr
<
TextDistorter
>
text_distorter_
;
std
::
unique_ptr
<
TextDistorter
>
text_distorter_
;
// An object used for manipulating unicode in the text. It performs tasks such
// as retaining only whitelisted unicodes in the text tokens and lowercasing
// them.
std
::
unique_ptr
<
ProjectionUnicodeHandler
>
unicode_handler_
;
std
::
unique_ptr
<
ProjectionUnicodeHandler
>
unicode_handler_
;
// An object used for normalizing tokens in the text. This performs tasks
// such as identifying repeated characters and replace them with a single
// instance.
std
::
unique_ptr
<
ProjectionNormalizer
>
projection_normalizer_
;
std
::
unique_ptr
<
ProjectionNormalizer
>
projection_normalizer_
;
// Character whitelist used by the projection operator.
std
::
string
vocabulary_
;
std
::
string
vocabulary_
;
// When true include an end of sentence token in the projection.
int
eos_tag_
;
int
eos_tag_
;
// When true include a begin of sentence token in the projection.
int
bos_tag_
;
int
bos_tag_
;
};
};
...
...
research/seq_flow_lite/tf_ops/text_distorter.h
View file @
ca552843
...
@@ -32,7 +32,6 @@ class TextDistorter {
...
@@ -32,7 +32,6 @@ class TextDistorter {
assert
(
distortion_probability_
<=
1.0
);
assert
(
distortion_probability_
<=
1.0
);
}
}
std
::
string
DistortText
(
icu
::
UnicodeString
*
uword
);
std
::
string
DistortText
(
icu
::
UnicodeString
*
uword
);
bool
BernouilleSample
(
float
p
)
{
return
(
generator_
.
RandFloat
()
<=
p
);
}
private:
private:
tensorflow
::
random
::
PhiloxRandom
philox_
;
tensorflow
::
random
::
PhiloxRandom
philox_
;
...
...
research/seq_flow_lite/tf_ops/tf_custom_ops.cc
View file @
ca552843
...
@@ -20,30 +20,6 @@ limitations under the License.
...
@@ -20,30 +20,6 @@ limitations under the License.
using
::
tensorflow
::
int32
;
using
::
tensorflow
::
int32
;
class
PoolingOp
:
public
tensorflow
::
OpKernel
{
public:
explicit
PoolingOp
(
tensorflow
::
OpKernelConstruction
*
context
)
:
tensorflow
::
OpKernel
(
context
)
{}
void
Compute
(
tensorflow
::
OpKernelContext
*
ctx
)
override
{}
};
REGISTER_KERNEL_BUILDER
(
Name
(
"PoolingOp"
).
Device
(
::
tensorflow
::
DEVICE_CPU
),
PoolingOp
);
REGISTER_OP
(
"PoolingOp"
)
.
Input
(
"multiplier: float32"
)
.
Input
(
"constant: float32"
)
.
Input
(
"forward: float32"
)
.
Output
(
"state: float32"
)
.
SetShapeFn
([](
::
tensorflow
::
shape_inference
::
InferenceContext
*
c
)
{
c
->
set_output
(
0
,
c
->
input
(
0
));
return
tensorflow
::
Status
::
OK
();
})
.
Doc
(
R"doc(
Dummy pooling op.
)doc"
);
class
ExpectedValueOp
:
public
tensorflow
::
OpKernel
{
class
ExpectedValueOp
:
public
tensorflow
::
OpKernel
{
public:
public:
explicit
ExpectedValueOp
(
tensorflow
::
OpKernelConstruction
*
context
)
explicit
ExpectedValueOp
(
tensorflow
::
OpKernelConstruction
*
context
)
...
@@ -93,33 +69,3 @@ REGISTER_OP("LayerNorm")
...
@@ -93,33 +69,3 @@ REGISTER_OP("LayerNorm")
.
Doc
(
R"doc(
.
Doc
(
R"doc(
Dummy layer norm op.
Dummy layer norm op.
)doc"
);
)doc"
);
class
UniformCausalAttnOp
:
public
tensorflow
::
OpKernel
{
public:
explicit
UniformCausalAttnOp
(
tensorflow
::
OpKernelConstruction
*
context
)
:
tensorflow
::
OpKernel
(
context
)
{}
void
Compute
(
tensorflow
::
OpKernelContext
*
ctx
)
override
{}
};
REGISTER_KERNEL_BUILDER
(
Name
(
"UniformCausalAttn"
).
Device
(
::
tensorflow
::
DEVICE_CPU
),
UniformCausalAttnOp
);
REGISTER_OP
(
"UniformCausalAttn"
)
.
Input
(
"input: float32"
)
.
Input
(
"time_step: int32"
)
.
Input
(
"selected_beams: int32"
)
.
Attr
(
"feature_size: int"
)
.
Attr
(
"beam_size: int"
)
.
Output
(
"output: float32"
)
.
SetShapeFn
([](
::
tensorflow
::
shape_inference
::
InferenceContext
*
c
)
{
auto
batch_size
=
c
->
Dim
(
c
->
input
(
0
),
0
);
int32
feature_size
;
TF_RETURN_IF_ERROR
(
c
->
GetAttr
(
"feature_size"
,
&
feature_size
));
c
->
set_output
(
0
,
c
->
MakeShape
({
batch_size
,
1
,
feature_size
}));
return
tensorflow
::
Status
::
OK
();
})
.
Doc
(
R"doc(
Dummy uniform causal attn op.
)doc"
);
research/seq_flow_lite/tflite_ops/BUILD
View file @
ca552843
# TFLite ops for sequence string projection.
# TFLite ops for sequence string projection.
load
(
"@org_tensorflow//tensorflow:tensorflow.bzl"
,
"pybind_extension"
)
load
(
"@org_tensorflow//tensorflow/lite:build_def.bzl"
,
"tflite_copts"
)
load
(
"@org_tensorflow//tensorflow/lite:build_def.bzl"
,
"tflite_copts"
)
licenses
([
"notice"
])
licenses
([
"notice"
])
...
@@ -100,3 +101,16 @@ cc_test(
...
@@ -100,3 +101,16 @@ cc_test(
"@flatbuffers"
,
"@flatbuffers"
,
],
],
)
)
pybind_extension
(
name
=
"registerer"
,
srcs
=
[
"registerer.cc"
],
module_name
=
"registerer"
,
deps
=
[
":expected_value"
,
":layer_norm"
,
":sequence_string_projection"
,
"@org_tensorflow//tensorflow/lite:framework"
,
"@pybind11"
,
],
)
research/seq_flow_lite/tflite_ops/expected_value.cc
View file @
ca552843
...
@@ -18,7 +18,7 @@ limitations under the License.
...
@@ -18,7 +18,7 @@ limitations under the License.
#include "tflite_ops/quantization_util.h" // seq_flow_lite
#include "tflite_ops/quantization_util.h" // seq_flow_lite
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
ops
{
namespace
ops
{
namespace
custom
{
namespace
custom
{
...
@@ -156,4 +156,4 @@ TfLiteRegistration* Register_EXPECTED_VALUE() {
...
@@ -156,4 +156,4 @@ TfLiteRegistration* Register_EXPECTED_VALUE() {
}
// namespace custom
}
// namespace custom
}
// namespace ops
}
// namespace ops
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
research/seq_flow_lite/tflite_ops/expected_value.h
View file @
ca552843
...
@@ -17,7 +17,7 @@ limitations under the License.
...
@@ -17,7 +17,7 @@ limitations under the License.
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/kernels/register.h"
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
ops
{
namespace
ops
{
namespace
custom
{
namespace
custom
{
...
@@ -25,6 +25,6 @@ TfLiteRegistration* Register_EXPECTED_VALUE();
...
@@ -25,6 +25,6 @@ TfLiteRegistration* Register_EXPECTED_VALUE();
}
// namespace custom
}
// namespace custom
}
// namespace ops
}
// namespace ops
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
#endif // TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_EXPECTED_VALUE_H_
#endif // TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_EXPECTED_VALUE_H_
research/seq_flow_lite/tflite_ops/layer_norm.cc
View file @
ca552843
...
@@ -17,10 +17,10 @@ limitations under the License.
...
@@ -17,10 +17,10 @@ limitations under the License.
#include <unordered_set>
#include <unordered_set>
#include <vector>
#include <vector>
#include "tflite_ops/quantization_util.h" // seq_flow_lite
#include "tensorflow/lite/kernels/kernel_util.h"
#include "tensorflow/lite/kernels/kernel_util.h"
#include "tflite_ops/quantization_util.h" // seq_flow_lite
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
ops
{
namespace
ops
{
namespace
custom
{
namespace
custom
{
...
@@ -213,6 +213,102 @@ TfLiteStatus FlexibleLayerNorm(const TfLiteTensor* input, const float scale,
...
@@ -213,6 +213,102 @@ TfLiteStatus FlexibleLayerNorm(const TfLiteTensor* input, const float scale,
return
kTfLiteOk
;
return
kTfLiteOk
;
}
}
/*
* Layer normalization is optimized as follows in integer arithmetic
*
* Algorithm
* *********
* Subscript i \in {1, ..., N}, Inputs q_i, Outputs oq_i.
*
* x_i = (q_i - input_zero_point) * input_scale
* mean = sum_i x_i / N
* var = sum_i (x_i * x_i / N) - mean * mean
* std = sqrt(var + tolerance)
* xni = (xi - mean) / std
* yi = xni * scale + offset
* o_i = round(y_i / output_scale + output_zero_point)
* oq_i = clamp(o_i, 0, 255)
*
* Optimizations
* *************
* Applying linear expansion
* x_i = q_i * input_scale - input_zero_point * input_scale
* or x_i = m * qi + c
* mean = m * mean_q + c
* Variance is not affected by a constant shift to input
* var = m^2 * var_q
* std = m * sqrt(var_q + tolerance)
* Expanding xi, mean, std in equation for xni
* xni = (m * qi + c - m * mean_q - c) / m * sqrt(var_q + tolerance)
* Simplifying
* xni = (qi - mean_q) / sqrt(var_q + tolerance)
* Setting inv_std_qi = 1 / sqrt(var_q + tolerance)
* xni = qi * inv_std_qi - mean_q * inv_std_qi
* yi = qi * inv_std_qi * scale - mean_q * inv_std_qi * scale + offset
* o_i = round(qi * inv_std_qi * scale / output_scale
* - mean_q * inv_std_qi * scale / output_scale
* + offset / output_scale
* + output_zero_point)
* Setting
* static_bias = offset / output_scale + output_zero_point
* static_scale = scale / output_scale
* o_i = round(qi * inv_std_qi * static_scale
* - mean_q * inv_std_qi * static_scale
* + static_bias)
* Setting
* dynamic_scale = inv_std_qi * static_scale
* dynamic_bias = static_bias - mean_q * dynamic_scale
* o_i = round(qi * dynamic_scale + dynamic_bias)
* oq_i = clamp(round(qi * dynamic_scale + dynamic_bias), 0, 255)
*
* This results in the below optimized implementation. The strategy is to first
* compute first and second order summary statistics for qi in a loop,
* then compute mean_q, var_q and then dynamic_scale/dynamic_bias. This
* allows one to compute oqi quickly in a tight loop.
* */
TfLiteStatus
IntegerLayerNorm
(
const
TfLiteTensor
*
input
,
const
float
scale
,
const
float
offset
,
TfLiteTensor
*
output
)
{
const
int
input_rank
=
input
->
dims
->
size
;
const
int
num_features
=
input
->
dims
->
data
[
input_rank
-
1
];
const
int
time_steps
=
static_cast
<
int
>
(
GetNumberOfSteps
(
input
)
/
num_features
);
const
float
out_inverse_scale
=
1.0
f
/
output
->
params
.
scale
;
const
float
static_scale
=
scale
*
out_inverse_scale
;
const
float
static_bias
=
static_cast
<
float
>
(
output
->
params
.
zero_point
)
+
offset
*
out_inverse_scale
;
const
float
inverse_num_features
=
1.0
f
/
num_features
;
const
uint8_t
*
const
in_ptr
=
input
->
data
.
uint8
;
uint8_t
*
out_ptr
=
output
->
data
.
uint8
;
for
(
int
i
=
0
;
i
<
time_steps
;
++
i
)
{
int32_t
i32_sum_q
=
0
;
int32_t
i32_sum_qq
=
0
;
const
int32_t
index
=
i
*
num_features
;
for
(
int
j
=
index
;
j
<
index
+
num_features
;
++
j
)
{
const
int32_t
q_i
=
static_cast
<
int32_t
>
(
in_ptr
[
j
]);
// Compute first and second order statistics for qi.
i32_sum_q
+=
q_i
;
i32_sum_qq
+=
q_i
*
q_i
;
}
const
float
second_moment_qq
=
i32_sum_qq
*
inverse_num_features
;
const
float
mean_q
=
i32_sum_q
*
inverse_num_features
;
const
float
var_q
=
second_moment_qq
-
mean_q
*
mean_q
;
const
float
inv_std_q
=
1.0
f
/
sqrt
(
var_q
+
1e-6
);
const
float
dynamic_scale
=
inv_std_q
*
static_scale
;
const
float
dynamic_bias
=
static_bias
-
mean_q
*
dynamic_scale
;
for
(
int
j
=
index
;
j
<
index
+
num_features
;
++
j
)
{
const
int32_t
invalue
=
static_cast
<
int32_t
>
(
in_ptr
[
j
]);
const
float
value
=
invalue
*
dynamic_scale
+
dynamic_bias
;
// Use an offseted cast to perform float round.
const
int32_t
i32value
=
static_cast
<
int32_t
>
(
value
+
((
value
>=
0.0
)
?
0.5
f
:
-
0.5
f
));
// Clamp the result.
out_ptr
[
j
]
=
static_cast
<
uint8_t
>
(
std
::
max
(
std
::
min
(
255
,
i32value
),
0
));
}
}
return
kTfLiteOk
;
}
TfLiteStatus
DefaultLayerNormFloat
(
const
TfLiteTensor
*
input
,
const
float
scale
,
TfLiteStatus
DefaultLayerNormFloat
(
const
TfLiteTensor
*
input
,
const
float
scale
,
const
float
offset
,
TfLiteTensor
*
output
)
{
const
float
offset
,
TfLiteTensor
*
output
)
{
const
int
input_rank
=
input
->
dims
->
size
;
const
int
input_rank
=
input
->
dims
->
size
;
...
@@ -298,7 +394,7 @@ TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) {
...
@@ -298,7 +394,7 @@ TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) {
if
(
num_axis
==
1
&&
(
axis
->
data
.
i32
[
0
]
==
-
1
||
if
(
num_axis
==
1
&&
(
axis
->
data
.
i32
[
0
]
==
-
1
||
axis
->
data
.
i32
[
0
]
==
(
input
->
dims
->
size
-
1
)))
{
axis
->
data
.
i32
[
0
]
==
(
input
->
dims
->
size
-
1
)))
{
if
(
input
->
type
==
kTfLiteUInt8
)
{
if
(
input
->
type
==
kTfLiteUInt8
)
{
return
Default
LayerNorm
(
input
,
scale
,
offset
,
output
);
return
Integer
LayerNorm
(
input
,
scale
,
offset
,
output
);
}
else
if
(
input
->
type
==
kTfLiteFloat32
)
{
}
else
if
(
input
->
type
==
kTfLiteFloat32
)
{
return
DefaultLayerNormFloat
(
input
,
scale
,
offset
,
output
);
return
DefaultLayerNormFloat
(
input
,
scale
,
offset
,
output
);
}
else
{
}
else
{
...
@@ -328,4 +424,4 @@ TfLiteRegistration* Register_LAYER_NORM() {
...
@@ -328,4 +424,4 @@ TfLiteRegistration* Register_LAYER_NORM() {
}
// namespace custom
}
// namespace custom
}
// namespace ops
}
// namespace ops
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
research/seq_flow_lite/tflite_ops/layer_norm.h
View file @
ca552843
...
@@ -17,7 +17,7 @@ limitations under the License.
...
@@ -17,7 +17,7 @@ limitations under the License.
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/kernels/register.h"
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
ops
{
namespace
ops
{
namespace
custom
{
namespace
custom
{
...
@@ -25,6 +25,6 @@ TfLiteRegistration* Register_LAYER_NORM();
...
@@ -25,6 +25,6 @@ TfLiteRegistration* Register_LAYER_NORM();
}
// namespace custom
}
// namespace custom
}
// namespace ops
}
// namespace ops
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
#endif // LEARNING_EXPANDER_POD_DEEP_POD_TFLITE_HANDLERS_LAYER_NORM_H_
#endif // LEARNING_EXPANDER_POD_DEEP_POD_TFLITE_HANDLERS_LAYER_NORM_H_
research/seq_flow_lite/tflite_ops/layer_norm_test.cc
View file @
ca552843
...
@@ -20,40 +20,35 @@ limitations under the License.
...
@@ -20,40 +20,35 @@ limitations under the License.
#include "flatbuffers/flexbuffers.h" // flatbuffer
#include "flatbuffers/flexbuffers.h" // flatbuffer
#include "tensorflow/lite/kernels/test_util.h"
#include "tensorflow/lite/kernels/test_util.h"
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
ops
{
namespace
ops
{
namespace
custom
{
namespace
custom
{
namespace
{
namespace
{
class
LayerNormModel
:
public
SingleOpModel
{
using
::
testing
::
ElementsAreArray
;
using
::
tflite
::
ArrayFloatNear
;
using
::
tflite
::
Dequantize
;
using
::
tflite
::
TensorType_INT32
;
using
::
tflite
::
TensorType_UINT8
;
class
LayerNormModel
:
public
::
tflite
::
SingleOpModel
{
public:
public:
explicit
LayerNormModel
(
const
TensorData
&
input
,
float
output_min
,
explicit
LayerNormModel
(
std
::
initializer_list
<
int
>
input_shape
,
float
input_min
,
float
input_max
,
float
output_min
,
float
output_max
,
float
scale
,
float
offset
,
float
output_max
,
float
scale
,
float
offset
,
std
::
initializer_list
<
int
>
axis_shape
,
std
::
initializer_list
<
int
>
axes
)
std
::
initializer_list
<
int
>
axis
)
:
scale_value_
(
scale
),
offset_value_
(
offset
)
{
:
scale_value_
(
scale
),
offset_value_
(
offset
)
{
input_
=
AddInput
(
input
);
const
int
num_axes
=
axes
.
size
();
input_
=
AddInput
({
TensorType_UINT8
,
input_shape
,
input_min
,
input_max
});
scale_
=
AddInput
(
scale_
=
AddInput
(
{
TensorType_UINT8
,
{
1
},
std
::
min
(
scale
,
0.0
f
),
std
::
max
(
scale
,
0.0
f
)});
{
TensorType_UINT8
,
{
1
},
std
::
min
(
scale
,
0.0
f
),
std
::
max
(
scale
,
0.0
f
)});
offset_
=
AddInput
({
TensorType_UINT8
,
offset_
=
AddInput
({
TensorType_UINT8
,
{
1
},
{
1
},
std
::
min
(
offset
,
0.0
f
),
std
::
min
(
offset
,
0.0
f
),
std
::
max
(
offset
,
0.0
f
)});
std
::
max
(
offset
,
0.0
f
)});
axis_
=
AddConstInput
(
TensorType_INT32
,
ax
i
s
,
axis_shape
);
axis_
=
AddConstInput
(
TensorType_INT32
,
ax
e
s
,
{
num_axes
}
);
output_
=
AddOutput
({
TensorType_UINT8
,
{},
output_min
,
output_max
});
output_
=
AddOutput
({
TensorType_UINT8
,
{},
output_min
,
output_max
});
flexbuffers
::
Builder
fbb
;
SetCustomOp
(
"LayerNorm"
,
{},
Register_LAYER_NORM
);
fbb
.
Map
([
&
]
{
{
size_t
start
=
fbb
.
StartVector
(
"axes"
);
for
(
const
int
&
aval
:
axis
)
{
fbb
.
Int
(
aval
);
}
fbb
.
EndVector
(
start
,
/*typed=*/
true
,
/*fixed=*/
false
);
}
});
fbb
.
Finish
();
SetCustomOp
(
"LayerNorm"
,
fbb
.
GetBuffer
(),
Register_LAYER_NORM
);
BuildInterpreter
({
GetShape
(
input_
)});
BuildInterpreter
({
GetShape
(
input_
)});
}
}
...
@@ -88,8 +83,9 @@ TEST(LayerNormModelTest, RegularInput) {
...
@@ -88,8 +83,9 @@ TEST(LayerNormModelTest, RegularInput) {
const
std
::
vector
<
float
>
expected_output
=
{
0.0
,
-
1.6
,
0.53
,
1.07
,
const
std
::
vector
<
float
>
expected_output
=
{
0.0
,
-
1.6
,
0.53
,
1.07
,
0.0
,
-
1.13
,
1.59
,
-
0.45
};
0.0
,
-
1.13
,
1.59
,
-
0.45
};
LayerNormModel
m
({
TensorType_UINT8
,
{
1
,
2
,
4
},
-
10
,
10
},
-
10
,
10
,
1.0
,
0.0
,
LayerNormModel
m
(
/*input_shape=*/
{
1
,
2
,
4
},
/*input_min=*/
-
10
,
{
1
},
{
2
});
/*input_max=*/
10
,
/*output_min=*/
-
10
,
/*output_max=*/
10
,
/*scale=*/
1.0
,
/*offset=*/
0.0
,
/*axes=*/
{
2
});
m
.
SetInput
(
input
);
m
.
SetInput
(
input
);
m
.
Invoke
();
m
.
Invoke
();
EXPECT_THAT
(
EXPECT_THAT
(
...
@@ -106,8 +102,9 @@ TEST(LayerNormModelTest, NegativeScale) {
...
@@ -106,8 +102,9 @@ TEST(LayerNormModelTest, NegativeScale) {
// Standard deviation values are 3.74, 4.41
// Standard deviation values are 3.74, 4.41
const
std
::
vector
<
float
>
expected_output
=
{
0.0
,
1.6
,
-
0.53
,
-
1.07
,
const
std
::
vector
<
float
>
expected_output
=
{
0.0
,
1.6
,
-
0.53
,
-
1.07
,
0.0
,
1.13
,
-
1.59
,
0.45
};
0.0
,
1.13
,
-
1.59
,
0.45
};
LayerNormModel
m
({
TensorType_UINT8
,
{
1
,
2
,
4
},
-
10
,
10
},
-
10
,
10
,
-
1.0
,
0.0
,
LayerNormModel
m
(
/*input_shape=*/
{
1
,
2
,
4
},
/*input_min=*/
-
10
,
{
1
},
{
2
});
/*input_max=*/
10
,
/*output_min=*/
-
10
,
/*output_max=*/
10
,
/*scale=*/
-
1.0
,
/*offset=*/
0.0
,
/*axes=*/
{
2
});
m
.
SetInput
(
input
);
m
.
SetInput
(
input
);
m
.
Invoke
();
m
.
Invoke
();
EXPECT_THAT
(
EXPECT_THAT
(
...
@@ -124,8 +121,9 @@ TEST(LayerNormModelTest, NegativeOffset) {
...
@@ -124,8 +121,9 @@ TEST(LayerNormModelTest, NegativeOffset) {
// Standard deviation values are 3.74, 4.41
// Standard deviation values are 3.74, 4.41
const
std
::
vector
<
float
>
expected_output
=
{
-
1.0
,
-
2.6
,
-
0.53
,
0.07
,
const
std
::
vector
<
float
>
expected_output
=
{
-
1.0
,
-
2.6
,
-
0.53
,
0.07
,
-
1.0
,
-
2.13
,
0.59
,
-
1.45
};
-
1.0
,
-
2.13
,
0.59
,
-
1.45
};
LayerNormModel
m
({
TensorType_UINT8
,
{
1
,
2
,
4
},
-
10
,
10
},
-
10
,
10
,
1.0
,
-
1.0
,
LayerNormModel
m
(
/*input_shape=*/
{
1
,
2
,
4
},
/*input_min=*/
-
10
,
{
1
},
{
2
});
/*input_max=*/
10
,
/*output_min=*/
-
10
,
/*output_max=*/
10
,
/*scale=*/
1.0
,
/*offset=*/
-
1.0
,
/*axes=*/
{
2
});
m
.
SetInput
(
input
);
m
.
SetInput
(
input
);
m
.
Invoke
();
m
.
Invoke
();
EXPECT_THAT
(
EXPECT_THAT
(
...
@@ -142,8 +140,9 @@ TEST(LayerNormModelTest, NegativeScaleAndOffset) {
...
@@ -142,8 +140,9 @@ TEST(LayerNormModelTest, NegativeScaleAndOffset) {
// Standard deviation values are 3.74, 4.41
// Standard deviation values are 3.74, 4.41
const
std
::
vector
<
float
>
expected_output
=
{
-
1.0
,
0.6
,
-
1.53
,
-
2.07
,
const
std
::
vector
<
float
>
expected_output
=
{
-
1.0
,
0.6
,
-
1.53
,
-
2.07
,
-
1.0
,
0.13
,
-
2.59
,
-
0.55
};
-
1.0
,
0.13
,
-
2.59
,
-
0.55
};
LayerNormModel
m
({
TensorType_UINT8
,
{
1
,
2
,
4
},
-
10
,
10
},
-
10
,
10
,
-
1.0
,
-
1.0
,
LayerNormModel
m
(
/*input_shape=*/
{
1
,
2
,
4
},
/*input_min=*/
-
10
,
{
1
},
{
2
});
/*input_max=*/
10
,
/*output_min=*/
-
10
,
/*output_max=*/
10
,
/*scale=*/
-
1.0
,
/*offset=*/
-
1.0
,
/*axes=*/
{
2
});
m
.
SetInput
(
input
);
m
.
SetInput
(
input
);
m
.
Invoke
();
m
.
Invoke
();
EXPECT_THAT
(
EXPECT_THAT
(
...
@@ -160,8 +159,9 @@ TEST(LayerNormModelTest, MultipleAxis) {
...
@@ -160,8 +159,9 @@ TEST(LayerNormModelTest, MultipleAxis) {
1.12
,
-
2.08
,
0.48
,
-
0.16
,
-
0.95
,
-
1.46
,
-
0.95
,
0.06
,
1.12
,
-
2.08
,
0.48
,
-
0.16
,
-
0.95
,
-
1.46
,
-
0.95
,
0.06
,
-
0.69
,
-
0.23
,
-
1.60
,
-
1.15
,
-
0.80
,
-
0.16
,
0.48
,
1.12
};
-
0.69
,
-
0.23
,
-
1.60
,
-
1.15
,
-
0.80
,
-
0.16
,
0.48
,
1.12
};
LayerNormModel
m
({
TensorType_UINT8
,
{
1
,
2
,
3
,
4
},
-
3
,
3
},
-
3
,
3
,
1.0
,
0.0
,
LayerNormModel
m
(
/*input_shape=*/
{
1
,
2
,
3
,
4
},
/*input_min=*/
-
3
,
{
2
},
{
1
,
3
});
/*input_max=*/
3
,
/*output_min=*/
-
3
,
/*output_max=*/
3
,
/*scale=*/
1.0
,
/*offset=*/
0.0
,
/*axes=*/
{
1
,
3
});
m
.
SetInput
(
input
);
m
.
SetInput
(
input
);
m
.
Invoke
();
m
.
Invoke
();
EXPECT_THAT
(
EXPECT_THAT
(
...
@@ -178,8 +178,9 @@ TEST(LayerNormModelTest, MultipleNegativeAxis) {
...
@@ -178,8 +178,9 @@ TEST(LayerNormModelTest, MultipleNegativeAxis) {
1.12
,
-
2.08
,
0.48
,
-
0.16
,
-
0.95
,
-
1.46
,
-
0.95
,
0.06
,
1.12
,
-
2.08
,
0.48
,
-
0.16
,
-
0.95
,
-
1.46
,
-
0.95
,
0.06
,
-
0.69
,
-
0.23
,
-
1.60
,
-
1.15
,
-
0.80
,
-
0.16
,
0.48
,
1.12
};
-
0.69
,
-
0.23
,
-
1.60
,
-
1.15
,
-
0.80
,
-
0.16
,
0.48
,
1.12
};
LayerNormModel
m
({
TensorType_UINT8
,
{
1
,
2
,
3
,
4
},
-
3
,
3
},
-
3
,
3
,
1.0
,
0.0
,
LayerNormModel
m
(
/*input_shape=*/
{
1
,
2
,
3
,
4
},
/*input_min=*/
-
3
,
{
2
},
{
-
3
,
-
1
});
/*input_max=*/
3
,
/*output_min=*/
-
3
,
/*output_max=*/
3
,
/*scale=*/
1.0
,
/*offset=*/
0.0
,
/*axes=*/
{
-
3
,
-
1
});
m
.
SetInput
(
input
);
m
.
SetInput
(
input
);
m
.
Invoke
();
m
.
Invoke
();
EXPECT_THAT
(
EXPECT_THAT
(
...
@@ -199,8 +200,9 @@ TEST(LayerNormModelTest, MultipleAxisWithLargeDepth) {
...
@@ -199,8 +200,9 @@ TEST(LayerNormModelTest, MultipleAxisWithLargeDepth) {
2.05
,
2.05
,
-
0.67
,
-
0.28
,
1.27
,
1.27
,
-
1.06
,
-
1.06
,
-
0.28
,
2.05
,
2.05
,
-
0.67
,
-
0.28
,
1.27
,
1.27
,
-
1.06
,
-
1.06
,
-
0.28
,
0.
,
-
0.85
,
-
0.42
,
0.
,
0.42
,
-
0.85
,
-
0.42
,
0.
,
0.42
};
0.
,
-
0.85
,
-
0.42
,
0.
,
0.42
,
-
0.85
,
-
0.42
,
0.
,
0.42
};
LayerNormModel
m
({
TensorType_UINT8
,
{
1
,
2
,
2
,
9
},
-
1.0
,
1.0
},
-
3.0
,
3.0
,
1.0
,
LayerNormModel
m
(
/*input_shape=*/
{
1
,
2
,
2
,
9
},
/*input_min=*/
-
1.0
,
0.0
,
{
2
},
{
1
,
3
});
/*input_max=*/
1.0
,
/*output_min=*/
-
3.0
,
/*output_max=*/
3.0
,
/*scale=*/
1.0
,
/*offset=*/
0.0
,
/*axes=*/
{
1
,
3
});
m
.
SetInput
(
input
);
m
.
SetInput
(
input
);
m
.
Invoke
();
m
.
Invoke
();
EXPECT_THAT
(
EXPECT_THAT
(
...
@@ -211,4 +213,4 @@ TEST(LayerNormModelTest, MultipleAxisWithLargeDepth) {
...
@@ -211,4 +213,4 @@ TEST(LayerNormModelTest, MultipleAxisWithLargeDepth) {
}
// namespace
}
// namespace
}
// namespace custom
}
// namespace custom
}
// namespace ops
}
// namespace ops
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
research/seq_flow_lite/tflite_ops/quantization_util.h
View file @
ca552843
...
@@ -20,7 +20,7 @@ limitations under the License.
...
@@ -20,7 +20,7 @@ limitations under the License.
#include "tensorflow/lite/context.h"
#include "tensorflow/lite/context.h"
namespace
tf
lite
{
namespace
seq_flow_
lite
{
// Returns the original (dequantized) value of 8bit value.
// Returns the original (dequantized) value of 8bit value.
inline
float
PodDequantizeValue
(
const
TfLiteTensor
&
tensor
,
uint8_t
value
)
{
inline
float
PodDequantizeValue
(
const
TfLiteTensor
&
tensor
,
uint8_t
value
)
{
...
@@ -48,6 +48,6 @@ inline uint8_t PodQuantize(float value, int32_t zero_point,
...
@@ -48,6 +48,6 @@ inline uint8_t PodQuantize(float value, int32_t zero_point,
return
static_cast
<
uint8_t
>
(
std
::
max
(
std
::
min
(
255
,
integer_value
),
0
));
return
static_cast
<
uint8_t
>
(
std
::
max
(
std
::
min
(
255
,
integer_value
),
0
));
}
}
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
#endif // TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_QUANTIZATION_UTIL_H_
#endif // TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_QUANTIZATION_UTIL_H_
research/seq_flow_lite/tflite_ops/registerer.cc
0 → 100644
View file @
ca552843
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "pybind11/pybind11.h"
#include "pybind11/pytypes.h"
#include "tensorflow/lite/mutable_op_resolver.h"
#include "tflite_ops/expected_value.h" // seq_flow_lite
#include "tflite_ops/layer_norm.h" // seq_flow_lite
#include "tflite_ops/sequence_string_projection.h" // seq_flow_lite
PYBIND11_MODULE
(
registerer
,
m
)
{
m
.
doc
()
=
"Module that provides a registerer from the seq flow lite custom ops"
;
m
.
def
(
"RegisterCustomOps"
,
[](
uintptr_t
ptr
)
{
::
tflite
::
MutableOpResolver
*
resolver
=
reinterpret_cast
<::
tflite
::
MutableOpResolver
*>
(
ptr
);
resolver
->
AddCustom
(
"ExpectedValueOp"
,
::
seq_flow_lite
::
ops
::
custom
::
Register_EXPECTED_VALUE
());
resolver
->
AddCustom
(
"LayerNorm"
,
::
seq_flow_lite
::
ops
::
custom
::
Register_LAYER_NORM
());
resolver
->
AddCustom
(
"SEQUENCE_STRING_PROJECTION"
,
::
seq_flow_lite
::
ops
::
custom
::
Register_SEQUENCE_STRING_PROJECTION
());
resolver
->
AddCustom
(
"SequenceStringProjection"
,
::
seq_flow_lite
::
ops
::
custom
::
Register_SEQUENCE_STRING_PROJECTION
());
resolver
->
AddCustom
(
"SEQUENCE_STRING_PROJECTION_V2"
,
::
seq_flow_lite
::
ops
::
custom
::
Register_SEQUENCE_STRING_PROJECTION
());
resolver
->
AddCustom
(
"SequenceStringProjectionV2"
,
::
seq_flow_lite
::
ops
::
custom
::
Register_SEQUENCE_STRING_PROJECTION_V2
());
},
"Register custom ops used by seq flow lite layers"
);
}
research/seq_flow_lite/tflite_ops/sequence_string_projection.cc
View file @
ca552843
...
@@ -31,7 +31,7 @@ limitations under the License.
...
@@ -31,7 +31,7 @@ limitations under the License.
#include "tf_ops/projection_util.h" // seq_flow_lite
#include "tf_ops/projection_util.h" // seq_flow_lite
#include "tflite_ops/quantization_util.h" // seq_flow_lite
#include "tflite_ops/quantization_util.h" // seq_flow_lite
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
ops
{
namespace
ops
{
namespace
custom
{
namespace
custom
{
...
@@ -163,7 +163,7 @@ class ProjectionParams {
...
@@ -163,7 +163,7 @@ class ProjectionParams {
DocSizeFeature
(
&
doc_size_feature
,
num_tokens
);
DocSizeFeature
(
&
doc_size_feature
,
num_tokens
);
*
data
=
PodQuantize
(
doc_size_feature
,
127.0
f
,
127
);
*
data
=
PodQuantize
(
doc_size_feature
,
127.0
f
,
127
);
}
}
void
Hash
(
const
std
::
string
&
word
,
std
::
vector
<
uint64_t
>
*
hash_codes
)
{
void
Hash
(
const
std
::
string
&
word
,
std
::
vector
<
uint64_t
>
&
hash_codes
)
{
hasher_
->
GetHashCodes
(
word
,
hash_codes
);
hasher_
->
GetHashCodes
(
word
,
hash_codes
);
}
}
// Lower cases the input text and eliminates all unsupported
// Lower cases the input text and eliminates all unsupported
...
@@ -269,6 +269,8 @@ class ProjectionParamsV2 : public ProjectionParams {
...
@@ -269,6 +269,8 @@ class ProjectionParamsV2 : public ProjectionParams {
num_tokens
,
dims
->
data
[
1
]);
num_tokens
,
dims
->
data
[
1
]);
return
kTfLiteError
;
return
kTfLiteError
;
}
}
tokens_
.
clear
();
tokens_
.
reserve
(
num_tokens
);
for
(
int
i
=
0
;
i
<
num_tokens
;
++
i
)
{
for
(
int
i
=
0
;
i
<
num_tokens
;
++
i
)
{
const
tflite
::
StringRef
strref
=
tflite
::
GetString
(
input_t
,
i
);
const
tflite
::
StringRef
strref
=
tflite
::
GetString
(
input_t
,
i
);
tokens_
.
push_back
(
std
::
pair
<
const
char
*
,
size_t
>
(
strref
.
str
,
strref
.
len
));
tokens_
.
push_back
(
std
::
pair
<
const
char
*
,
size_t
>
(
strref
.
str
,
strref
.
len
));
...
@@ -412,7 +414,7 @@ void TypedEval(const T* mapping_table, ProjectionParams* params, T* data) {
...
@@ -412,7 +414,7 @@ void TypedEval(const T* mapping_table, ProjectionParams* params, T* data) {
}
else
{
}
else
{
word
=
kEndToken
;
word
=
kEndToken
;
}
}
params
->
Hash
(
word
,
&
hash_codes
);
params
->
Hash
(
word
,
hash_codes
);
for
(
int
hindex
=
0
,
k
=
0
;
hindex
<
hash_codes
.
size
();
hindex
++
)
{
for
(
int
hindex
=
0
,
k
=
0
;
hindex
<
hash_codes
.
size
();
hindex
++
)
{
auto
hash
=
hash_codes
[
hindex
];
auto
hash
=
hash_codes
[
hindex
];
for
(
int
kmax
=
std
::
min
(
k
+
kIncrement
,
params
->
FeatureSize
());
for
(
int
kmax
=
std
::
min
(
k
+
kIncrement
,
params
->
FeatureSize
());
...
@@ -505,4 +507,4 @@ TfLiteRegistration* Register_SEQUENCE_STRING_PROJECTION_V2() {
...
@@ -505,4 +507,4 @@ TfLiteRegistration* Register_SEQUENCE_STRING_PROJECTION_V2() {
}
// namespace custom
}
// namespace custom
}
// namespace ops
}
// namespace ops
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
research/seq_flow_lite/tflite_ops/sequence_string_projection.h
View file @
ca552843
...
@@ -16,7 +16,7 @@ limitations under the License.
...
@@ -16,7 +16,7 @@ limitations under the License.
#define TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_SEQUENCE_STRING_PROJECTION_H_
#define TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_SEQUENCE_STRING_PROJECTION_H_
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/kernels/register.h"
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
ops
{
namespace
ops
{
namespace
custom
{
namespace
custom
{
...
@@ -29,6 +29,6 @@ extern const char kSequenceStringProjectionV2[];
...
@@ -29,6 +29,6 @@ extern const char kSequenceStringProjectionV2[];
TfLiteRegistration
*
Register_SEQUENCE_STRING_PROJECTION_V2
();
TfLiteRegistration
*
Register_SEQUENCE_STRING_PROJECTION_V2
();
}
// namespace custom
}
// namespace custom
}
// namespace ops
}
// namespace ops
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
#endif // TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_SEQUENCE_STRING_PROJECTION_H_
#endif // TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_SEQUENCE_STRING_PROJECTION_H_
research/seq_flow_lite/tflite_ops/sequence_string_projection_test.cc
View file @
ca552843
...
@@ -25,29 +25,32 @@ limitations under the License.
...
@@ -25,29 +25,32 @@ limitations under the License.
#include "tf_ops/projection_util.h" // seq_flow_lite
#include "tf_ops/projection_util.h" // seq_flow_lite
#include "tflite_ops/tf_tflite_diff_test_util.h" // seq_flow_lite
#include "tflite_ops/tf_tflite_diff_test_util.h" // seq_flow_lite
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
ops
{
namespace
ops
{
namespace
custom
{
namespace
custom
{
namespace
{
namespace
{
using
::
seq_flow_lite
::
testing
::
AttrValue
;
using
::
seq_flow_lite
::
testing
::
FloatTensor
;
using
::
seq_flow_lite
::
testing
::
IntTensor
;
using
::
seq_flow_lite
::
testing
::
OpEquivTestCase
;
using
::
seq_flow_lite
::
testing
::
StringTensor
;
using
::
seq_flow_lite
::
testing
::
TensorflowTfLiteOpTest
;
using
::
testing
::
ElementsAreArray
;
using
::
testing
::
ElementsAreArray
;
using
::
tflite
::
testing
::
AttrValue
;
using
::
tflite
::
TensorType_FLOAT32
;
using
::
tflite
::
testing
::
FloatTensor
;
using
::
tflite
::
TensorType_STRING
;
using
::
tflite
::
testing
::
IntTensor
;
using
::
tflite
::
TensorType_UINT8
;
using
::
tflite
::
testing
::
OpEquivTestCase
;
using
::
tflite
::
testing
::
StringTensor
;
class
SequenceStringProjectionModel
:
public
::
tflite
::
SingleOpModel
{
using
::
tflite
::
testing
::
TensorflowTfLiteOpTest
;
class
SequenceStringProjectionModel
:
public
SingleOpModel
{
public:
public:
explicit
SequenceStringProjectionModel
(
explicit
SequenceStringProjectionModel
(
bool
split_on_space
,
int
max_splits
,
int
word_novelty_bits
,
bool
split_on_space
,
int
max_splits
,
int
word_novelty_bits
,
int
doc_size_levels
,
bool
add_eos_tag
,
TensorType
output_type
,
int
doc_size_levels
,
bool
add_eos_tag
,
::
tflite
::
TensorType
output_type
,
const
std
::
string
&
token_separators
=
""
,
const
std
::
string
&
token_separators
=
""
,
bool
normalize_repetition
=
false
,
float
add_first_cap
=
0.0
,
bool
normalize_repetition
=
false
,
float
add_first_cap
=
0.0
,
float
add_all_caps
=
0.0
,
const
string
&
hashtype
=
kMurmurHash
)
{
float
add_all_caps
=
0.0
,
const
std
::
string
&
hashtype
=
kMurmurHash
)
{
flexbuffers
::
Builder
fbb
;
flexbuffers
::
Builder
fbb
;
fbb
.
Map
([
&
]
{
fbb
.
Map
([
&
]
{
fbb
.
Int
(
"feature_size"
,
4
);
fbb
.
Int
(
"feature_size"
,
4
);
...
@@ -798,11 +801,11 @@ INSTANTIATE_TEST_SUITE_P(
...
@@ -798,11 +801,11 @@ INSTANTIATE_TEST_SUITE_P(
SequenceStringProjectionTests
,
SequenceStringProjectionTest
,
SequenceStringProjectionTests
,
SequenceStringProjectionTest
,
::
testing
::
ValuesIn
(
SequenceStringProjectionTestCases
()));
::
testing
::
ValuesIn
(
SequenceStringProjectionTestCases
()));
class
SequenceStringProjectionV2Model
:
public
SingleOpModel
{
class
SequenceStringProjectionV2Model
:
public
::
tflite
::
SingleOpModel
{
public:
public:
explicit
SequenceStringProjectionV2Model
(
explicit
SequenceStringProjectionV2Model
(
std
::
vector
<
std
::
vector
<
int
>>
input_shapes
,
std
::
vector
<
std
::
vector
<
int
>>
input_shapes
,
const
string
&
hashtype
=
kMurmurHash
)
{
const
std
::
string
&
hashtype
=
kMurmurHash
)
{
flexbuffers
::
Builder
fbb
;
flexbuffers
::
Builder
fbb
;
fbb
.
Map
([
&
]
{
fbb
.
Map
([
&
]
{
fbb
.
Int
(
"feature_size"
,
4
);
fbb
.
Int
(
"feature_size"
,
4
);
...
@@ -827,6 +830,7 @@ class SequenceStringProjectionV2Model : public SingleOpModel {
...
@@ -827,6 +830,7 @@ class SequenceStringProjectionV2Model : public SingleOpModel {
<<
"Cannot allocate tensors"
;
<<
"Cannot allocate tensors"
;
return
SingleOpModel
::
InvokeUnchecked
();
return
SingleOpModel
::
InvokeUnchecked
();
}
}
std
::
vector
<
int
>
GetOutputShape
()
{
return
GetTensorShape
(
output_
);
}
private:
private:
int
input_
;
int
input_
;
...
@@ -884,6 +888,15 @@ TEST(SequenceStringProjectionV2Test, RegularInputUint8) {
...
@@ -884,6 +888,15 @@ TEST(SequenceStringProjectionV2Test, RegularInputUint8) {
m
.
Invoke
({
"hello"
,
"world"
},
kTfLiteOk
);
m
.
Invoke
({
"hello"
,
"world"
},
kTfLiteOk
);
}
}
TEST
(
SequenceStringProjectionV2Test
,
NumberProjectionsForMultipleInputs
)
{
SequenceStringProjectionV2Model
m
({{
1
,
2
}});
std
::
vector
<
std
::
string
>
input
=
{
"hello"
,
"world"
};
m
.
Invoke
(
input
,
kTfLiteOk
);
EXPECT_EQ
(
m
.
GetOutputShape
()[
1
],
input
.
size
());
m
.
Invoke
(
input
,
kTfLiteOk
);
EXPECT_EQ
(
m
.
GetOutputShape
()[
1
],
input
.
size
());
}
class
SequenceStringProjectionV2Test
:
public
TensorflowTfLiteOpTest
{
class
SequenceStringProjectionV2Test
:
public
TensorflowTfLiteOpTest
{
std
::
function
<
TfLiteRegistration
*
()
>
TfLiteOpRegistration
()
override
{
std
::
function
<
TfLiteRegistration
*
()
>
TfLiteOpRegistration
()
override
{
return
ops
::
custom
::
Register_SEQUENCE_STRING_PROJECTION_V2
;
return
ops
::
custom
::
Register_SEQUENCE_STRING_PROJECTION_V2
;
...
@@ -986,7 +999,7 @@ INSTANTIATE_TEST_SUITE_P(
...
@@ -986,7 +999,7 @@ INSTANTIATE_TEST_SUITE_P(
}
// namespace
}
// namespace
}
// namespace custom
}
// namespace custom
}
// namespace ops
}
// namespace ops
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
// On Linux, add: absl::SetFlag(&FLAGS_logtostderr, true);
// On Linux, add: absl::SetFlag(&FLAGS_logtostderr, true);
...
...
research/seq_flow_lite/tflite_ops/tf_tflite_diff_test_util.cc
View file @
ca552843
...
@@ -19,11 +19,16 @@ limitations under the License.
...
@@ -19,11 +19,16 @@ limitations under the License.
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/lib/core/status_test_util.h"
#include "tensorflow/core/lib/core/status_test_util.h"
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
testing
{
namespace
testing
{
using
::
tensorflow
::
TensorProto
;
using
::
tensorflow
::
TensorProto
;
using
::
testing
::
FloatNear
;
using
::
testing
::
FloatNear
;
using
::
tflite
::
TensorType_STRING
;
using
::
tflite
::
TensorType_UINT8
;
using
::
tflite
::
TensorType_INT32
;
using
::
tflite
::
TensorType_BOOL
;
using
::
tflite
::
TensorType_FLOAT32
;
::
tflite
::
TensorType
TfTypeToTfLiteType
(
::
tensorflow
::
DataType
dtype
)
{
::
tflite
::
TensorType
TfTypeToTfLiteType
(
::
tensorflow
::
DataType
dtype
)
{
switch
(
dtype
)
{
switch
(
dtype
)
{
...
@@ -324,7 +329,7 @@ void TensorflowTfLiteOpTest::CompareOpOutput() {
...
@@ -324,7 +329,7 @@ void TensorflowTfLiteOpTest::CompareOpOutput() {
const
auto
&
quantization_params
=
const
auto
&
quantization_params
=
GetParam
().
output_tensors
[
i
].
quantization_params
;
GetParam
().
output_tensors
[
i
].
quantization_params
;
if
(
quantization_params
.
scale
!=
0.0
)
{
if
(
quantization_params
.
scale
!=
0.0
)
{
auto
tflite_output_values
=
Dequantize
(
auto
tflite_output_values
=
tflite
::
Dequantize
(
tflite_op_
.
ExtractVector
<
uint8_t
>
(
tflite_outputs_
[
i
]),
tflite_op_
.
ExtractVector
<
uint8_t
>
(
tflite_outputs_
[
i
]),
quantization_params
.
scale
,
quantization_params
.
zero_point
);
quantization_params
.
scale
,
quantization_params
.
zero_point
);
for
(
int
i
=
0
;
i
<
tf_output_values
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
tf_output_values
.
size
();
i
++
)
{
...
...
research/seq_flow_lite/tflite_ops/tf_tflite_diff_test_util.h
View file @
ca552843
...
@@ -25,7 +25,7 @@ limitations under the License.
...
@@ -25,7 +25,7 @@ limitations under the License.
#include "tensorflow/core/kernels/ops_testutil.h"
#include "tensorflow/core/kernels/ops_testutil.h"
#include "tensorflow/lite/kernels/test_util.h"
#include "tensorflow/lite/kernels/test_util.h"
namespace
tf
lite
{
namespace
seq_flow_
lite
{
namespace
testing
{
namespace
testing
{
// Convenience constructors.
// Convenience constructors.
...
@@ -144,6 +144,6 @@ class TensorflowTfLiteOpTest
...
@@ -144,6 +144,6 @@ class TensorflowTfLiteOpTest
};
};
}
// namespace testing
}
// namespace testing
}
// namespace
tf
lite
}
// namespace
seq_flow_
lite
#endif // TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_TF_TFLITE_DIFF_TEST_UTIL_H_
#endif // TENSORFLOW_MODELS_SEQUENCE_PROJECTION_TFLITE_OPS_TF_TFLITE_DIFF_TEST_UTIL_H_
research/seq_flow_lite/trainer_v2.py
0 → 100644
View file @
ca552843
# Copyright 2021 The TensorFlow Authors All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
# Lint as: python3
"""Binary to train PRADO model with TF 2.0."""
import
importlib
import
json
from
absl
import
app
from
absl
import
flags
from
absl
import
logging
import
tensorflow
as
tf
import
input_fn_reader
# import root module
FLAGS
=
flags
.
FLAGS
flags
.
DEFINE_string
(
"config_path"
,
None
,
"Path to a RunnerConfig."
)
flags
.
DEFINE_enum
(
"runner_mode"
,
"train"
,
[
"train"
,
"train_and_eval"
,
"eval"
],
"Runner mode."
)
flags
.
DEFINE_string
(
"master"
,
None
,
"TensorFlow master URL."
)
flags
.
DEFINE_string
(
"output_dir"
,
"/tmp/testV2"
,
"The output directory where the model checkpoints will be written."
)
flags
.
DEFINE_bool
(
"use_tpu"
,
False
,
"Whether to use TPU or GPU/CPU."
)
flags
.
DEFINE_integer
(
"num_tpu_cores"
,
8
,
"Only used if `use_tpu` is True. Total number of TPU cores to use."
)
def
load_runner_config
():
with
tf
.
io
.
gfile
.
GFile
(
FLAGS
.
config_path
,
"r"
)
as
f
:
return
json
.
loads
(
f
.
read
())
def
compute_loss
(
logits
,
labels
,
model_config
,
mode
):
"""Creates a sequence labeling model."""
if
mode
!=
tf
.
estimator
.
ModeKeys
.
PREDICT
:
if
not
model_config
[
"multilabel"
]:
loss
=
tf
.
nn
.
sparse_softmax_cross_entropy_with_logits
(
labels
=
labels
,
logits
=
logits
)
else
:
loss
=
tf
.
nn
.
sigmoid_cross_entropy_with_logits
(
labels
=
labels
,
logits
=
logits
)
loss
=
tf
.
reduce_mean
(
loss
)
else
:
loss
=
None
return
loss
def
model_fn_builder
(
runner_config
,
mode
):
"""Returns `model_fn` closure for TPUEstimator."""
rel_module_path
=
""
# empty base dir
model
=
importlib
.
import_module
(
rel_module_path
+
runner_config
[
"name"
])
model_config
=
runner_config
[
"model_config"
]
return
model
.
Encoder
(
model_config
,
mode
)
def
main
(
_
):
runner_config
=
load_runner_config
()
if
FLAGS
.
output_dir
:
tf
.
io
.
gfile
.
makedirs
(
FLAGS
.
output_dir
)
train_model
=
model_fn_builder
(
runner_config
,
tf
.
estimator
.
ModeKeys
.
TRAIN
)
optimizer
=
tf
.
keras
.
optimizers
.
Adam
()
train_input_fn
=
input_fn_reader
.
create_input_fn
(
runner_config
=
runner_config
,
mode
=
tf
.
estimator
.
ModeKeys
.
TRAIN
,
drop_remainder
=
True
)
params
=
{
"batch_size"
:
runner_config
[
"batch_size"
]}
train_ds
=
train_input_fn
(
params
)
train_loss
=
tf
.
keras
.
metrics
.
Mean
(
name
=
"train_loss"
)
@
tf
.
function
def
train_step
(
features
):
with
tf
.
GradientTape
()
as
tape
:
logits
=
train_model
(
features
[
"projection"
],
features
[
"seq_length"
])
loss
=
compute_loss
(
logits
,
features
[
"label"
],
runner_config
[
"model_config"
],
tf
.
estimator
.
ModeKeys
.
TRAIN
)
gradients
=
tape
.
gradient
(
loss
,
train_model
.
trainable_variables
)
optimizer
.
apply_gradients
(
zip
(
gradients
,
train_model
.
trainable_variables
))
train_loss
(
loss
)
for
epoch
in
range
(
1
):
train_loss
.
reset_states
()
for
features
in
train_ds
:
train_step
(
features
)
step
=
optimizer
.
iterations
.
numpy
()
if
step
%
100
==
0
:
logging
.
info
(
"Running step %s in epoch %s"
,
step
,
epoch
)
logging
.
info
(
"Training loss: %s, epoch: %s, step: %s"
,
round
(
train_loss
.
result
().
numpy
(),
4
),
epoch
,
step
)
if
__name__
==
"__main__"
:
app
.
run
(
main
)
Prev
1
…
10
11
12
13
14
15
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment