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
f5fc733a
Commit
f5fc733a
authored
Feb 03, 2022
by
Byzantine
Browse files
Removing research/community models
parent
09bc9f54
Changes
326
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
0 additions
and
2159 deletions
+0
-2159
research/compression/entropy_coder/core/code_loader.py
research/compression/entropy_coder/core/code_loader.py
+0
-73
research/compression/entropy_coder/core/config_helper.py
research/compression/entropy_coder/core/config_helper.py
+0
-52
research/compression/entropy_coder/core/entropy_coder_single.py
...ch/compression/entropy_coder/core/entropy_coder_single.py
+0
-116
research/compression/entropy_coder/core/entropy_coder_train.py
...rch/compression/entropy_coder/core/entropy_coder_train.py
+0
-184
research/compression/entropy_coder/dataset/gen_synthetic_dataset.py
...ompression/entropy_coder/dataset/gen_synthetic_dataset.py
+0
-89
research/compression/entropy_coder/dataset/gen_synthetic_single.py
...compression/entropy_coder/dataset/gen_synthetic_single.py
+0
-72
research/compression/entropy_coder/dataset/synthetic_model.py
...arch/compression/entropy_coder/dataset/synthetic_model.py
+0
-75
research/compression/entropy_coder/lib/__init__.py
research/compression/entropy_coder/lib/__init__.py
+0
-0
research/compression/entropy_coder/lib/block_base.py
research/compression/entropy_coder/lib/block_base.py
+0
-258
research/compression/entropy_coder/lib/block_util.py
research/compression/entropy_coder/lib/block_util.py
+0
-101
research/compression/entropy_coder/lib/blocks.py
research/compression/entropy_coder/lib/blocks.py
+0
-24
research/compression/entropy_coder/lib/blocks_binarizer.py
research/compression/entropy_coder/lib/blocks_binarizer.py
+0
-35
research/compression/entropy_coder/lib/blocks_entropy_coding.py
...ch/compression/entropy_coder/lib/blocks_entropy_coding.py
+0
-49
research/compression/entropy_coder/lib/blocks_entropy_coding_test.py
...mpression/entropy_coder/lib/blocks_entropy_coding_test.py
+0
-56
research/compression/entropy_coder/lib/blocks_lstm.py
research/compression/entropy_coder/lib/blocks_lstm.py
+0
-263
research/compression/entropy_coder/lib/blocks_lstm_test.py
research/compression/entropy_coder/lib/blocks_lstm_test.py
+0
-113
research/compression/entropy_coder/lib/blocks_masked_conv2d.py
...rch/compression/entropy_coder/lib/blocks_masked_conv2d.py
+0
-226
research/compression/entropy_coder/lib/blocks_masked_conv2d_lstm.py
...ompression/entropy_coder/lib/blocks_masked_conv2d_lstm.py
+0
-79
research/compression/entropy_coder/lib/blocks_masked_conv2d_test.py
...ompression/entropy_coder/lib/blocks_masked_conv2d_test.py
+0
-207
research/compression/entropy_coder/lib/blocks_operator.py
research/compression/entropy_coder/lib/blocks_operator.py
+0
-87
No files found.
Too many changes to show.
To preserve performance only
326 of 326+
files are displayed.
Plain diff
Email patch
research/compression/entropy_coder/core/code_loader.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Load binary codes stored as tf.Example in a TFRecord table."""
import
tensorflow
as
tf
def
ReadFirstCode
(
dataset
):
"""Read the first example from a binary code RecordIO table."""
for
record
in
tf
.
python_io
.
tf_record_iterator
(
dataset
):
tf_example
=
tf
.
train
.
Example
()
tf_example
.
ParseFromString
(
record
)
break
return
tf_example
def
LoadBinaryCode
(
input_config
,
batch_size
):
"""Load a batch of binary codes from a tf.Example dataset.
Args:
input_config: An InputConfig proto containing the input configuration.
batch_size: Output batch size of examples.
Returns:
A batched tensor of binary codes.
"""
data
=
input_config
.
data
# TODO: Possibly use multiple files (instead of just one).
file_list
=
[
data
]
filename_queue
=
tf
.
train
.
string_input_producer
(
file_list
,
capacity
=
4
)
reader
=
tf
.
TFRecordReader
()
_
,
values
=
reader
.
read
(
filename_queue
)
serialized_example
=
tf
.
reshape
(
values
,
shape
=
[
1
])
serialized_features
=
{
'code_shape'
:
tf
.
FixedLenFeature
([
3
],
dtype
=
tf
.
int64
),
'code'
:
tf
.
VarLenFeature
(
tf
.
float32
),
}
example
=
tf
.
parse_example
(
serialized_example
,
serialized_features
)
# 3D shape: height x width x binary_code_depth
z
=
example
[
'code_shape'
]
code_shape
=
tf
.
reshape
(
tf
.
cast
(
z
,
tf
.
int32
),
[
3
])
# Un-flatten the binary codes.
code
=
tf
.
reshape
(
tf
.
sparse_tensor_to_dense
(
example
[
'code'
]),
code_shape
)
queue_size
=
10
queue
=
tf
.
PaddingFIFOQueue
(
queue_size
+
3
*
batch_size
,
dtypes
=
[
code
.
dtype
],
shapes
=
[[
None
,
None
,
None
]])
enqueue_op
=
queue
.
enqueue
([
code
])
dequeue_code
=
queue
.
dequeue_many
(
batch_size
)
queue_runner
=
tf
.
train
.
queue_runner
.
QueueRunner
(
queue
,
[
enqueue_op
])
tf
.
add_to_collection
(
tf
.
GraphKeys
.
QUEUE_RUNNERS
,
queue_runner
)
return
dequeue_code
research/compression/entropy_coder/core/config_helper.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Helper functions used in both train and inference."""
import
json
import
os.path
import
tensorflow
as
tf
def
GetConfigString
(
config_file
):
config_string
=
''
if
config_file
is
not
None
:
config_string
=
open
(
config_file
).
read
()
return
config_string
class
InputConfig
(
object
):
def
__init__
(
self
,
config_string
):
config
=
json
.
loads
(
config_string
)
self
.
data
=
config
[
"data"
]
self
.
unique_code_size
=
config
[
"unique_code_size"
]
class
TrainConfig
(
object
):
def
__init__
(
self
,
config_string
):
config
=
json
.
loads
(
config_string
)
self
.
batch_size
=
config
[
"batch_size"
]
self
.
learning_rate
=
config
[
"learning_rate"
]
self
.
decay_rate
=
config
[
"decay_rate"
]
self
.
samples_per_decay
=
config
[
"samples_per_decay"
]
def
SaveConfig
(
directory
,
filename
,
config_string
):
path
=
os
.
path
.
join
(
directory
,
filename
)
with
tf
.
gfile
.
Open
(
path
,
mode
=
'w'
)
as
f
:
f
.
write
(
config_string
)
research/compression/entropy_coder/core/entropy_coder_single.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Compute the additional compression ratio after entropy coding."""
import
io
import
os
import
numpy
as
np
import
tensorflow
as
tf
import
config_helper
# pylint: disable=unused-import
from
entropy_coder.all_models
import
all_models
# pylint: enable=unused-import
from
entropy_coder.model
import
model_factory
# Checkpoint used to restore the model parameters.
tf
.
app
.
flags
.
DEFINE_string
(
'checkpoint'
,
None
,
"""Model checkpoint."""
)
# Model selection and configuration.
tf
.
app
.
flags
.
DEFINE_string
(
'model'
,
None
,
"""Underlying encoder model."""
)
tf
.
app
.
flags
.
DEFINE_string
(
'model_config'
,
None
,
"""Model config protobuf given as text file."""
)
# File holding the binary codes.
tf
.
flags
.
DEFINE_string
(
'input_codes'
,
None
,
'Location of binary code file.'
)
FLAGS
=
tf
.
flags
.
FLAGS
def
main
(
_
):
if
(
FLAGS
.
input_codes
is
None
or
FLAGS
.
model
is
None
):
print
(
'
\n
Usage: python entropy_coder_single.py --model=progressive '
'--model_config=model_config.json'
'--iteration=15
\n\n
'
)
return
#if FLAGS.iteration < -1 or FLAGS.iteration > 15:
# print ('\n--iteration must be between 0 and 15 inclusive, or -1 to infer '
# 'from file.\n')
# return
#iteration = FLAGS.iteration
if
not
tf
.
gfile
.
Exists
(
FLAGS
.
input_codes
):
print
(
'
\n
Input codes not found.
\n
'
)
return
with
tf
.
gfile
.
FastGFile
(
FLAGS
.
input_codes
,
'rb'
)
as
code_file
:
contents
=
code_file
.
read
()
loaded_codes
=
np
.
load
(
io
.
BytesIO
(
contents
))
assert
[
'codes'
,
'shape'
]
not
in
loaded_codes
.
files
loaded_shape
=
loaded_codes
[
'shape'
]
loaded_array
=
loaded_codes
[
'codes'
]
# Unpack and recover code shapes.
unpacked_codes
=
np
.
reshape
(
np
.
unpackbits
(
loaded_array
)
[:
np
.
prod
(
loaded_shape
)],
loaded_shape
)
numpy_int_codes
=
unpacked_codes
.
transpose
([
1
,
2
,
3
,
0
,
4
])
numpy_int_codes
=
numpy_int_codes
.
reshape
([
numpy_int_codes
.
shape
[
0
],
numpy_int_codes
.
shape
[
1
],
numpy_int_codes
.
shape
[
2
],
-
1
])
numpy_codes
=
numpy_int_codes
.
astype
(
np
.
float32
)
*
2.0
-
1.0
with
tf
.
Graph
().
as_default
()
as
graph
:
# TF tensor to hold the binary codes to losslessly compress.
batch_size
=
1
codes
=
tf
.
placeholder
(
tf
.
float32
,
shape
=
numpy_codes
.
shape
)
# Create the entropy coder model.
global_step
=
None
optimizer
=
None
model
=
model_factory
.
GetModelRegistry
().
CreateModel
(
FLAGS
.
model
)
model_config_string
=
config_helper
.
GetConfigString
(
FLAGS
.
model_config
)
model
.
Initialize
(
global_step
,
optimizer
,
model_config_string
)
model
.
BuildGraph
(
codes
)
saver
=
tf
.
train
.
Saver
(
sharded
=
True
,
keep_checkpoint_every_n_hours
=
12.0
)
with
tf
.
Session
(
graph
=
graph
)
as
sess
:
# Initialize local variables.
sess
.
run
(
tf
.
local_variables_initializer
())
# Restore model variables.
saver
.
restore
(
sess
,
FLAGS
.
checkpoint
)
tf_tensors
=
{
'code_length'
:
model
.
average_code_length
}
feed_dict
=
{
codes
:
numpy_codes
}
np_tensors
=
sess
.
run
(
tf_tensors
,
feed_dict
=
feed_dict
)
print
(
'Additional compression ratio: {}'
.
format
(
np_tensors
[
'code_length'
]))
if
__name__
==
'__main__'
:
tf
.
app
.
run
()
research/compression/entropy_coder/core/entropy_coder_train.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Train an entropy coder model."""
import
time
import
tensorflow
as
tf
import
code_loader
import
config_helper
# pylint: disable=unused-import
from
entropy_coder.all_models
import
all_models
# pylint: enable=unused-import
from
entropy_coder.model
import
model_factory
FLAGS
=
tf
.
app
.
flags
.
FLAGS
# Hardware resources configuration.
tf
.
app
.
flags
.
DEFINE_string
(
'master'
,
''
,
"""Name of the TensorFlow master to use."""
)
tf
.
app
.
flags
.
DEFINE_string
(
'train_dir'
,
None
,
"""Directory where to write event logs."""
)
tf
.
app
.
flags
.
DEFINE_integer
(
'task'
,
None
,
"""Task id of the replica running the training."""
)
tf
.
app
.
flags
.
DEFINE_integer
(
'ps_tasks'
,
0
,
"""Number of tasks in the ps job.
If 0 no ps job is used."""
)
# Model selection and configuration.
tf
.
app
.
flags
.
DEFINE_string
(
'model'
,
None
,
"""Underlying encoder model."""
)
tf
.
app
.
flags
.
DEFINE_string
(
'model_config'
,
None
,
"""Model config protobuf given as text file."""
)
# Training data and parameters configuration.
tf
.
app
.
flags
.
DEFINE_string
(
'input_config'
,
None
,
"""Path to the training input config file."""
)
tf
.
app
.
flags
.
DEFINE_string
(
'train_config'
,
None
,
"""Path to the training experiment config file."""
)
def
train
():
if
FLAGS
.
train_dir
is
None
:
raise
ValueError
(
'Parameter train_dir must be provided'
)
if
FLAGS
.
task
is
None
:
raise
ValueError
(
'Parameter task must be provided'
)
if
FLAGS
.
model
is
None
:
raise
ValueError
(
'Parameter model must be provided'
)
input_config_string
=
config_helper
.
GetConfigString
(
FLAGS
.
input_config
)
input_config
=
config_helper
.
InputConfig
(
input_config_string
)
# Training parameters.
train_config_string
=
config_helper
.
GetConfigString
(
FLAGS
.
train_config
)
train_config
=
config_helper
.
TrainConfig
(
train_config_string
)
batch_size
=
train_config
.
batch_size
initial_learning_rate
=
train_config
.
learning_rate
decay_rate
=
train_config
.
decay_rate
samples_per_decay
=
train_config
.
samples_per_decay
# Parameters for learning-rate decay.
# The formula is decay_rate ** floor(steps / decay_steps).
decay_steps
=
samples_per_decay
/
batch_size
decay_steps
=
max
(
decay_steps
,
1
)
first_code
=
code_loader
.
ReadFirstCode
(
input_config
.
data
)
first_code_height
=
(
first_code
.
features
.
feature
[
'code_shape'
].
int64_list
.
value
[
0
])
first_code_width
=
(
first_code
.
features
.
feature
[
'code_shape'
].
int64_list
.
value
[
1
])
max_bit_depth
=
(
first_code
.
features
.
feature
[
'code_shape'
].
int64_list
.
value
[
2
])
print
(
'Maximum code depth: {}'
.
format
(
max_bit_depth
))
with
tf
.
Graph
().
as_default
():
ps_ops
=
[
"Variable"
,
"VariableV2"
,
"AutoReloadVariable"
,
"VarHandleOp"
]
with
tf
.
device
(
tf
.
train
.
replica_device_setter
(
FLAGS
.
ps_tasks
,
ps_ops
=
ps_ops
)):
codes
=
code_loader
.
LoadBinaryCode
(
input_config
=
input_config
,
batch_size
=
batch_size
)
if
input_config
.
unique_code_size
:
print
(
'Input code size: {} x {}'
.
format
(
first_code_height
,
first_code_width
))
codes
.
set_shape
(
[
batch_size
,
first_code_height
,
first_code_width
,
max_bit_depth
])
else
:
codes
.
set_shape
([
batch_size
,
None
,
None
,
max_bit_depth
])
codes_effective_shape
=
tf
.
shape
(
codes
)
global_step
=
tf
.
contrib
.
framework
.
create_global_step
()
# Apply learning-rate decay.
learning_rate
=
tf
.
train
.
exponential_decay
(
learning_rate
=
initial_learning_rate
,
global_step
=
global_step
,
decay_steps
=
decay_steps
,
decay_rate
=
decay_rate
,
staircase
=
True
)
tf
.
summary
.
scalar
(
'Learning Rate'
,
learning_rate
)
optimizer
=
tf
.
train
.
AdamOptimizer
(
learning_rate
=
learning_rate
,
epsilon
=
1.0
)
# Create the entropy coder model.
model
=
model_factory
.
GetModelRegistry
().
CreateModel
(
FLAGS
.
model
)
model_config_string
=
config_helper
.
GetConfigString
(
FLAGS
.
model_config
)
model
.
Initialize
(
global_step
,
optimizer
,
model_config_string
)
model
.
BuildGraph
(
codes
)
summary_op
=
tf
.
summary
.
merge_all
()
# Verify that the model can actually be trained.
if
model
.
train_op
is
None
:
raise
ValueError
(
'Input model {} is not trainable'
.
format
(
FLAGS
.
model
))
# We disable the summary thread run by Supervisor class by passing
# summary_op=None. We still pass save_summaries_secs because it is used by
# the global step counter thread.
is_chief
=
(
FLAGS
.
task
==
0
)
sv
=
tf
.
train
.
Supervisor
(
logdir
=
FLAGS
.
train_dir
,
is_chief
=
is_chief
,
global_step
=
global_step
,
# saver=model.saver,
summary_op
=
None
,
save_summaries_secs
=
120
,
save_model_secs
=
600
,
recovery_wait_secs
=
30
)
sess
=
sv
.
PrepareSession
(
FLAGS
.
master
)
sv
.
StartQueueRunners
(
sess
)
step
=
sess
.
run
(
global_step
)
print
(
'Trainer initial step: {}.'
.
format
(
step
))
# Once everything has been setup properly, save the configs.
if
is_chief
:
config_helper
.
SaveConfig
(
FLAGS
.
train_dir
,
'input_config.json'
,
input_config_string
)
config_helper
.
SaveConfig
(
FLAGS
.
train_dir
,
'model_config.json'
,
model_config_string
)
config_helper
.
SaveConfig
(
FLAGS
.
train_dir
,
'train_config.json'
,
train_config_string
)
# Train the model.
next_summary_time
=
time
.
time
()
while
not
sv
.
ShouldStop
():
feed_dict
=
None
# Once in a while, update the summaries on the chief worker.
if
is_chief
and
next_summary_time
<
time
.
time
():
summary_str
=
sess
.
run
(
summary_op
,
feed_dict
=
feed_dict
)
sv
.
SummaryComputed
(
sess
,
summary_str
)
next_summary_time
=
time
.
time
()
+
sv
.
save_summaries_secs
else
:
tf_tensors
=
{
'train'
:
model
.
train_op
,
'code_length'
:
model
.
average_code_length
}
np_tensors
=
sess
.
run
(
tf_tensors
,
feed_dict
=
feed_dict
)
print
(
np_tensors
[
'code_length'
])
sv
.
Stop
()
def
main
(
argv
=
None
):
# pylint: disable=unused-argument
train
()
if
__name__
==
'__main__'
:
tf
.
app
.
run
()
research/compression/entropy_coder/dataset/gen_synthetic_dataset.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Generate a synthetic dataset."""
import
os
import
numpy
as
np
from
six.moves
import
xrange
import
tensorflow
as
tf
import
synthetic_model
FLAGS
=
tf
.
app
.
flags
.
FLAGS
tf
.
app
.
flags
.
DEFINE_string
(
'dataset_dir'
,
None
,
"""Directory where to write the dataset and the configs."""
)
tf
.
app
.
flags
.
DEFINE_integer
(
'count'
,
1000
,
"""Number of samples to generate."""
)
def
int64_feature
(
values
):
"""Returns a TF-Feature of int64s.
Args:
values: A scalar or list of values.
Returns:
A TF-Feature.
"""
if
not
isinstance
(
values
,
(
tuple
,
list
)):
values
=
[
values
]
return
tf
.
train
.
Feature
(
int64_list
=
tf
.
train
.
Int64List
(
value
=
values
))
def
float_feature
(
values
):
"""Returns a TF-Feature of floats.
Args:
values: A scalar of list of values.
Returns:
A TF-Feature.
"""
if
not
isinstance
(
values
,
(
tuple
,
list
)):
values
=
[
values
]
return
tf
.
train
.
Feature
(
float_list
=
tf
.
train
.
FloatList
(
value
=
values
))
def
AddToTFRecord
(
code
,
tfrecord_writer
):
example
=
tf
.
train
.
Example
(
features
=
tf
.
train
.
Features
(
feature
=
{
'code_shape'
:
int64_feature
(
code
.
shape
),
'code'
:
float_feature
(
code
.
flatten
().
tolist
()),
}))
tfrecord_writer
.
write
(
example
.
SerializeToString
())
def
GenerateDataset
(
filename
,
count
,
code_shape
):
with
tf
.
python_io
.
TFRecordWriter
(
filename
)
as
tfrecord_writer
:
for
_
in
xrange
(
count
):
code
=
synthetic_model
.
GenerateSingleCode
(
code_shape
)
# Convert {0,1} codes to {-1,+1} codes.
code
=
2.0
*
code
-
1.0
AddToTFRecord
(
code
,
tfrecord_writer
)
def
main
(
argv
=
None
):
# pylint: disable=unused-argument
GenerateDataset
(
os
.
path
.
join
(
FLAGS
.
dataset_dir
+
'/synthetic_dataset'
),
FLAGS
.
count
,
[
35
,
48
,
8
])
if
__name__
==
'__main__'
:
tf
.
app
.
run
()
research/compression/entropy_coder/dataset/gen_synthetic_single.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2016 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.
# ==============================================================================
"""Generate a single synthetic sample."""
import
io
import
os
import
numpy
as
np
import
tensorflow
as
tf
import
synthetic_model
FLAGS
=
tf
.
app
.
flags
.
FLAGS
tf
.
app
.
flags
.
DEFINE_string
(
'sample_filename'
,
None
,
"""Output file to store the generated binary code."""
)
def
GenerateSample
(
filename
,
code_shape
,
layer_depth
):
# {0, +1} binary codes.
# No conversion since the output file is expected to store
# codes using {0, +1} codes (and not {-1, +1}).
code
=
synthetic_model
.
GenerateSingleCode
(
code_shape
)
code
=
np
.
round
(
code
)
# Reformat the code so as to be compatible with what is generated
# by the image encoder.
# The image encoder generates a tensor of size:
# iteration_count x batch_size x height x width x iteration_depth.
# Here: batch_size = 1
if
code_shape
[
-
1
]
%
layer_depth
!=
0
:
raise
ValueError
(
'Number of layers is not an integer'
)
height
=
code_shape
[
0
]
width
=
code_shape
[
1
]
code
=
code
.
reshape
([
1
,
height
,
width
,
-
1
,
layer_depth
])
code
=
np
.
transpose
(
code
,
[
3
,
0
,
1
,
2
,
4
])
int_codes
=
code
.
astype
(
np
.
int8
)
exported_codes
=
np
.
packbits
(
int_codes
.
reshape
(
-
1
))
output
=
io
.
BytesIO
()
np
.
savez_compressed
(
output
,
shape
=
int_codes
.
shape
,
codes
=
exported_codes
)
with
tf
.
gfile
.
FastGFile
(
filename
,
'wb'
)
as
code_file
:
code_file
.
write
(
output
.
getvalue
())
def
main
(
argv
=
None
):
# pylint: disable=unused-argument
# Note: the height and the width is different from the training dataset.
# The main purpose is to show that the entropy coder model is fully
# convolutional and can be used on any image size.
layer_depth
=
2
GenerateSample
(
FLAGS
.
sample_filename
,
[
31
,
36
,
8
],
layer_depth
)
if
__name__
==
'__main__'
:
tf
.
app
.
run
()
research/compression/entropy_coder/dataset/synthetic_model.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2016 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.
# ==============================================================================
"""Binary code sample generator."""
import
numpy
as
np
from
six.moves
import
xrange
_CRC_LINE
=
[
[
0
,
1
,
0
],
[
1
,
1
,
0
],
[
1
,
0
,
0
]
]
_CRC_DEPTH
=
[
1
,
1
,
0
,
1
]
def
ComputeLineCrc
(
code
,
width
,
y
,
x
,
d
):
crc
=
0
for
dy
in
xrange
(
len
(
_CRC_LINE
)):
i
=
y
-
1
-
dy
if
i
<
0
:
continue
for
dx
in
xrange
(
len
(
_CRC_LINE
[
dy
])):
j
=
x
-
2
+
dx
if
j
<
0
or
j
>=
width
:
continue
crc
+=
1
if
(
code
[
i
,
j
,
d
]
!=
_CRC_LINE
[
dy
][
dx
])
else
0
return
crc
def
ComputeDepthCrc
(
code
,
y
,
x
,
d
):
crc
=
0
for
delta
in
xrange
(
len
(
_CRC_DEPTH
)):
k
=
d
-
1
-
delta
if
k
<
0
:
continue
crc
+=
1
if
(
code
[
y
,
x
,
k
]
!=
_CRC_DEPTH
[
delta
])
else
0
return
crc
def
GenerateSingleCode
(
code_shape
):
code
=
np
.
zeros
(
code_shape
,
dtype
=
np
.
int
)
keep_value_proba
=
0.8
height
=
code_shape
[
0
]
width
=
code_shape
[
1
]
depth
=
code_shape
[
2
]
for
d
in
xrange
(
depth
):
for
y
in
xrange
(
height
):
for
x
in
xrange
(
width
):
v1
=
ComputeLineCrc
(
code
,
width
,
y
,
x
,
d
)
v2
=
ComputeDepthCrc
(
code
,
y
,
x
,
d
)
v
=
1
if
(
v1
+
v2
>=
6
)
else
0
if
np
.
random
.
rand
()
<
keep_value_proba
:
code
[
y
,
x
,
d
]
=
v
else
:
code
[
y
,
x
,
d
]
=
1
-
v
return
code
research/compression/entropy_coder/lib/__init__.py
deleted
100644 → 0
View file @
09bc9f54
research/compression/entropy_coder/lib/block_base.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Base class for Tensorflow building blocks."""
import
collections
import
contextlib
import
itertools
import
tensorflow
as
tf
_block_stacks
=
collections
.
defaultdict
(
lambda
:
[])
class
BlockBase
(
object
):
"""Base class for transform wrappers of Tensorflow.
To implement a Tensorflow transform block, inherit this class.
1. To create a variable, use NewVar() method. Do not overload this method!
For example, use as follows.
a_variable = self.NewVar(initial_value)
2. All Tensorflow-related code must be done inside 'with self._BlockScope().'
Otherwise, name scoping and block hierarchy will not work. An exception
is _Apply() method, which is already called inside the context manager
by __call__() method.
3. Override and implement _Apply() method. This method is called by
__call__() method.
The users would use blocks like the following.
nn1 = NN(128, bias=Bias(0), act=tf.nn.relu)
y = nn1(x)
Some things to consider.
- Use lazy-initialization if possible. That is, initialize at first Apply()
rather than at __init__().
Note: if needed, the variables can be created on a specific parameter
server by creating blocks in a scope like:
with g.device(device):
linear = Linear(...)
"""
def
__init__
(
self
,
name
):
self
.
_variables
=
[]
self
.
_subblocks
=
[]
self
.
_called
=
False
# Intentionally distinguishing empty string and None.
# If name is an empty string, then do not use name scope.
self
.
name
=
name
if
name
is
not
None
else
self
.
__class__
.
__name__
self
.
_graph
=
tf
.
get_default_graph
()
if
self
.
name
:
# Capture the scope string at the init time.
with
self
.
_graph
.
name_scope
(
self
.
name
)
as
scope
:
self
.
_scope_str
=
scope
else
:
self
.
_scope_str
=
''
# Maintain hierarchy structure of blocks.
self
.
_stack
=
_block_stacks
[
self
.
_graph
]
if
self
.
__class__
is
BlockBase
:
# This code is only executed to create the root, which starts in the
# initialized state.
assert
not
self
.
_stack
self
.
_parent
=
None
self
.
_called
=
True
# The root is initialized.
return
# Create a fake root if a root is not already present.
if
not
self
.
_stack
:
self
.
_stack
.
append
(
BlockBase
(
'NoOpRoot'
))
self
.
_parent
=
self
.
_stack
[
-
1
]
self
.
_parent
.
_subblocks
.
append
(
self
)
# pylint: disable=protected-access
def
__repr__
(
self
):
return
'"{}" ({})'
.
format
(
self
.
_scope_str
,
self
.
__class__
.
__name__
)
@
contextlib
.
contextmanager
def
_OptionalNameScope
(
self
,
scope_str
):
if
scope_str
:
with
self
.
_graph
.
name_scope
(
scope_str
):
yield
else
:
yield
@
contextlib
.
contextmanager
def
_BlockScope
(
self
):
"""Context manager that handles graph, namescope, and nested blocks."""
self
.
_stack
.
append
(
self
)
try
:
with
self
.
_graph
.
as_default
():
with
self
.
_OptionalNameScope
(
self
.
_scope_str
):
yield
self
finally
:
# Pop from the stack no matter exception is raised or not.
# The following line is executed when leaving 'with self._BlockScope()'
self
.
_stack
.
pop
()
def
__call__
(
self
,
*
args
,
**
kwargs
):
assert
self
.
_stack
is
_block_stacks
[
self
.
_graph
]
with
self
.
_BlockScope
():
ret
=
self
.
_Apply
(
*
args
,
**
kwargs
)
self
.
_called
=
True
return
ret
def
_Apply
(
self
,
*
args
,
**
kwargs
):
"""Implementation of __call__()."""
raise
NotImplementedError
()
# Redirect all variable creation to this single function, so that we can
# switch to better variable creation scheme.
def
NewVar
(
self
,
value
,
**
kwargs
):
"""Creates a new variable.
This function creates a variable, then returns a local copy created by
Identity operation. To get the Variable class object, use LookupRef()
method.
Note that each time Variable class object is used as an input to an
operation, Tensorflow will create a new Send/Recv pair. This hurts
performance.
If not for assign operations, use the local copy returned by this method.
Args:
value: Initialization value of the variable. The shape and the data type
of the variable is determined by this initial value.
**kwargs: Extra named arguments passed to Variable.__init__().
Returns:
A local copy of the new variable.
"""
v
=
tf
.
Variable
(
value
,
**
kwargs
)
self
.
_variables
.
append
(
v
)
return
v
@
property
def
initialized
(
self
):
"""Returns bool if the block is initialized.
By default, BlockBase assumes that a block is initialized when __call__()
is executed for the first time. If this is an incorrect assumption for some
subclasses, override this property in those subclasses.
Returns:
True if initialized, False otherwise.
"""
return
self
.
_called
def
AssertInitialized
(
self
):
"""Asserts initialized property."""
if
not
self
.
initialized
:
raise
RuntimeError
(
'{} has not been initialized.'
.
format
(
self
))
def
VariableList
(
self
):
"""Returns the list of all tensorflow variables used inside this block."""
variables
=
list
(
itertools
.
chain
(
itertools
.
chain
.
from_iterable
(
t
.
VariableList
()
for
t
in
self
.
_subblocks
),
self
.
_VariableList
()))
return
variables
def
_VariableList
(
self
):
"""Returns the list of all tensorflow variables owned by this block."""
self
.
AssertInitialized
()
return
self
.
_variables
def
CreateWeightLoss
(
self
):
"""Returns L2 loss list of (almost) all variables used inside this block.
When this method needs to be overridden, there are two choices.
1. Override CreateWeightLoss() to change the weight loss of all variables
that belong to this block, both directly and indirectly.
2. Override _CreateWeightLoss() to change the weight loss of all
variables that directly belong to this block but not to the sub-blocks.
Returns:
A Tensor object or None.
"""
losses
=
list
(
itertools
.
chain
(
itertools
.
chain
.
from_iterable
(
t
.
CreateWeightLoss
()
for
t
in
self
.
_subblocks
),
self
.
_CreateWeightLoss
()))
return
losses
def
_CreateWeightLoss
(
self
):
"""Returns weight loss list of variables that belong to this block."""
self
.
AssertInitialized
()
with
self
.
_BlockScope
():
return
[
tf
.
nn
.
l2_loss
(
v
)
for
v
in
self
.
_variables
]
def
CreateUpdateOps
(
self
):
"""Creates update operations for this block and its sub-blocks."""
ops
=
list
(
itertools
.
chain
(
itertools
.
chain
.
from_iterable
(
t
.
CreateUpdateOps
()
for
t
in
self
.
_subblocks
),
self
.
_CreateUpdateOps
()))
return
ops
def
_CreateUpdateOps
(
self
):
"""Creates update operations for this block."""
self
.
AssertInitialized
()
return
[]
def
MarkAsNonTrainable
(
self
):
"""Mark all the variables of this block as non-trainable.
All the variables owned directly or indirectly (through subblocks) are
marked as non trainable.
This function along with CheckpointInitOp can be used to load a pretrained
model that consists in only one part of the whole graph.
"""
assert
self
.
_called
all_variables
=
self
.
VariableList
()
collection
=
tf
.
get_collection_ref
(
tf
.
GraphKeys
.
TRAINABLE_VARIABLES
)
for
v
in
all_variables
:
if
v
in
collection
:
collection
.
remove
(
v
)
def
CreateWeightLoss
():
"""Returns all weight losses from the blocks in the graph."""
stack
=
_block_stacks
[
tf
.
get_default_graph
()]
if
not
stack
:
return
[]
return
stack
[
0
].
CreateWeightLoss
()
def
CreateBlockUpdates
():
"""Combines all updates from the blocks in the graph."""
stack
=
_block_stacks
[
tf
.
get_default_graph
()]
if
not
stack
:
return
[]
return
stack
[
0
].
CreateUpdateOps
()
research/compression/entropy_coder/lib/block_util.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Utility functions for blocks."""
from
__future__
import
division
from
__future__
import
unicode_literals
import
math
import
numpy
as
np
import
six
import
tensorflow
as
tf
class
RsqrtInitializer
(
object
):
"""Gaussian initializer with standard deviation 1/sqrt(n).
Note that tf.truncated_normal is used internally. Therefore any random sample
outside two-sigma will be discarded and re-sampled.
"""
def
__init__
(
self
,
dims
=
(
0
,),
**
kwargs
):
"""Creates an initializer.
Args:
dims: Dimension(s) index to compute standard deviation:
1.0 / sqrt(product(shape[dims]))
**kwargs: Extra keyword arguments to pass to tf.truncated_normal.
"""
if
isinstance
(
dims
,
six
.
integer_types
):
self
.
_dims
=
[
dims
]
else
:
self
.
_dims
=
dims
self
.
_kwargs
=
kwargs
def
__call__
(
self
,
shape
,
dtype
):
stddev
=
1.0
/
np
.
sqrt
(
np
.
prod
([
shape
[
x
]
for
x
in
self
.
_dims
]))
return
tf
.
truncated_normal
(
shape
=
shape
,
dtype
=
dtype
,
stddev
=
stddev
,
**
self
.
_kwargs
)
class
RectifierInitializer
(
object
):
"""Gaussian initializer with standard deviation sqrt(2/fan_in).
Note that tf.random_normal is used internally to ensure the expected weight
distribution. This is intended to be used with ReLU activations, specially
in ResNets.
For details please refer to:
Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet
Classification
"""
def
__init__
(
self
,
dims
=
(
0
,),
scale
=
2.0
,
**
kwargs
):
"""Creates an initializer.
Args:
dims: Dimension(s) index to compute standard deviation:
sqrt(scale / product(shape[dims]))
scale: A constant scaling for the initialization used as
sqrt(scale / product(shape[dims])).
**kwargs: Extra keyword arguments to pass to tf.truncated_normal.
"""
if
isinstance
(
dims
,
six
.
integer_types
):
self
.
_dims
=
[
dims
]
else
:
self
.
_dims
=
dims
self
.
_kwargs
=
kwargs
self
.
_scale
=
scale
def
__call__
(
self
,
shape
,
dtype
):
stddev
=
np
.
sqrt
(
self
.
_scale
/
np
.
prod
([
shape
[
x
]
for
x
in
self
.
_dims
]))
return
tf
.
random_normal
(
shape
=
shape
,
dtype
=
dtype
,
stddev
=
stddev
,
**
self
.
_kwargs
)
class
GaussianInitializer
(
object
):
"""Gaussian initializer with a given standard deviation.
Note that tf.truncated_normal is used internally. Therefore any random sample
outside two-sigma will be discarded and re-sampled.
"""
def
__init__
(
self
,
stddev
=
1.0
):
self
.
_stddev
=
stddev
def
__call__
(
self
,
shape
,
dtype
):
return
tf
.
truncated_normal
(
shape
=
shape
,
dtype
=
dtype
,
stddev
=
self
.
_stddev
)
research/compression/entropy_coder/lib/blocks.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
from
block_base
import
*
from
block_util
import
*
from
blocks_binarizer
import
*
from
blocks_entropy_coding
import
*
from
blocks_lstm
import
*
from
blocks_masked_conv2d
import
*
from
blocks_masked_conv2d_lstm
import
*
from
blocks_operator
import
*
from
blocks_std
import
*
research/compression/entropy_coder/lib/blocks_binarizer.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Activation and weight binarizer implementations."""
import
math
import
numpy
as
np
import
tensorflow
as
tf
def
ConvertSignCodeToZeroOneCode
(
x
):
"""Conversion from codes {-1, +1} to codes {0, 1}."""
return
0.5
*
(
x
+
1.0
)
def
ConvertZeroOneCodeToSignCode
(
x
):
"""Convert from codes {0, 1} to codes {-1, +1}."""
return
2.0
*
x
-
1.0
def
CheckZeroOneCode
(
x
):
return
tf
.
reduce_all
(
tf
.
equal
(
x
*
(
x
-
1.0
),
0
))
research/compression/entropy_coder/lib/blocks_entropy_coding.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Set of blocks related to entropy coding."""
import
math
import
tensorflow
as
tf
import
block_base
# pylint does not recognize block_base.BlockBase.__call__().
# pylint: disable=not-callable
class
CodeLength
(
block_base
.
BlockBase
):
"""Theoretical bound for a code length given a probability distribution.
"""
def
__init__
(
self
,
name
=
None
):
super
(
CodeLength
,
self
).
__init__
(
name
)
def
_Apply
(
self
,
c
,
p
):
"""Theoretical bound of the coded length given a probability distribution.
Args:
c: The binary codes. Belong to {0, 1}.
p: The probability of: P(code==+1)
Returns:
The average code length.
Note: the average code length can be greater than 1 bit (e.g. when
encoding the least likely symbol).
"""
entropy
=
((
1.0
-
c
)
*
tf
.
log
(
1.0
-
p
)
+
c
*
tf
.
log
(
p
))
/
(
-
math
.
log
(
2
))
entropy
=
tf
.
reduce_mean
(
entropy
)
return
entropy
research/compression/entropy_coder/lib/blocks_entropy_coding_test.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Tests for basic tensorflow blocks_entropy_coding."""
from
__future__
import
division
from
__future__
import
unicode_literals
import
math
import
numpy
as
np
import
tensorflow
as
tf
import
blocks_entropy_coding
class
BlocksEntropyCodingTest
(
tf
.
test
.
TestCase
):
def
testCodeLength
(
self
):
shape
=
[
2
,
4
]
proba_feed
=
[[
0.65
,
0.25
,
0.70
,
0.10
],
[
0.28
,
0.20
,
0.44
,
0.54
]]
symbol_feed
=
[[
1.0
,
0.0
,
1.0
,
0.0
],
[
0.0
,
0.0
,
0.0
,
1.0
]]
mean_code_length
=
-
(
(
math
.
log
(
0.65
)
+
math
.
log
(
0.75
)
+
math
.
log
(
0.70
)
+
math
.
log
(
0.90
)
+
math
.
log
(
0.72
)
+
math
.
log
(
0.80
)
+
math
.
log
(
0.56
)
+
math
.
log
(
0.54
))
/
math
.
log
(
2.0
))
/
(
shape
[
0
]
*
shape
[
1
])
symbol
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
shape
)
proba
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
shape
)
code_length_calculator
=
blocks_entropy_coding
.
CodeLength
()
code_length
=
code_length_calculator
(
symbol
,
proba
)
with
self
.
test_session
():
tf
.
global_variables_initializer
().
run
()
code_length_eval
=
code_length
.
eval
(
feed_dict
=
{
symbol
:
symbol_feed
,
proba
:
proba_feed
})
self
.
assertAllClose
(
mean_code_length
,
code_length_eval
)
if
__name__
==
'__main__'
:
tf
.
test
.
main
()
research/compression/entropy_coder/lib/blocks_lstm.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Blocks of LSTM and its variants."""
import
numpy
as
np
import
tensorflow
as
tf
import
block_base
import
block_util
import
blocks_std
# pylint does not recognize block_base.BlockBase.__call__().
# pylint: disable=not-callable
def
LSTMBiasInit
(
shape
,
dtype
):
"""Returns ones for forget-gate, and zeros for the others."""
shape
=
np
.
array
(
shape
)
# Check internal consistencies.
assert
shape
.
shape
==
(
1
,),
shape
assert
shape
[
0
]
%
4
==
0
,
shape
n
=
shape
[
0
]
//
4
ones
=
tf
.
fill
([
n
],
tf
.
constant
(
1
,
dtype
=
dtype
))
zeros
=
tf
.
fill
([
3
*
n
],
tf
.
constant
(
0
,
dtype
=
dtype
))
return
tf
.
concat
([
ones
,
zeros
],
0
)
class
LSTMBase
(
block_base
.
BlockBase
):
"""Base class for LSTM implementations.
These LSTM implementations use the pattern found in [1]. No peephole
connection, i.e., cell content is not used in recurrence computation.
Hidden units are also output units.
[1] Zaremba, Sutskever, Vinyals. Recurrent Neural Network Regularization,
2015. arxiv:1409.2329.
"""
def
__init__
(
self
,
output_shape
,
name
):
"""Initializes LSTMBase class object.
Args:
output_shape: List representing the LSTM output shape. This argument
does not include batch dimension. For example, if the LSTM output has
shape [batch, depth], then pass [depth].
name: Name of this block.
"""
super
(
LSTMBase
,
self
).
__init__
(
name
)
with
self
.
_BlockScope
():
self
.
_output_shape
=
[
None
]
+
list
(
output_shape
)
self
.
_hidden
=
None
self
.
_cell
=
None
@
property
def
hidden
(
self
):
"""Returns the hidden units of this LSTM."""
return
self
.
_hidden
@
hidden
.
setter
def
hidden
(
self
,
value
):
"""Assigns to the hidden units of this LSTM.
Args:
value: The new value for the hidden units. If None, the hidden units are
considered to be filled with zeros.
"""
if
value
is
not
None
:
value
.
get_shape
().
assert_is_compatible_with
(
self
.
_output_shape
)
self
.
_hidden
=
value
@
property
def
cell
(
self
):
"""Returns the cell units of this LSTM."""
return
self
.
_cell
@
cell
.
setter
def
cell
(
self
,
value
):
"""Assigns to the cell units of this LSTM.
Args:
value: The new value for the cell units. If None, the cell units are
considered to be filled with zeros.
"""
if
value
is
not
None
:
value
.
get_shape
().
assert_is_compatible_with
(
self
.
_output_shape
)
self
.
_cell
=
value
# Consider moving bias terms to the base, and require this method to be
# linear.
def
_TransformInputs
(
self
,
_
):
"""Transforms the input units to (4 * depth) units.
The forget-gate, input-gate, output-gate, and cell update is computed as
f, i, j, o = T(h) + R(x)
where h is hidden units, x is input units, and T, R are transforms of
h, x, respectively.
This method implements R. Note that T is strictly linear, so if LSTM is
going to use bias, this method must include the bias to the transformation.
Subclasses must implement this method. See _Apply() for more details.
"""
raise
NotImplementedError
()
def
_TransformHidden
(
self
,
_
):
"""Transforms the hidden units to (4 * depth) units.
The forget-gate, input-gate, output-gate, and cell update is computed as
f, i, j, o = T(h) + R(x)
where h is hidden units, x is input units, and T, R are transforms of
h, x, respectively.
This method implements T in the equation. The method must implement a
strictly linear transformation. For example, it may use MatMul or Conv2D,
but must not add bias. This is because when hidden units are zeros, then
the LSTM implementation will skip calling this method, instead of passing
zeros to this function.
Subclasses must implement this method. See _Apply() for more details.
"""
raise
NotImplementedError
()
def
_Apply
(
self
,
*
args
):
xtransform
=
self
.
_TransformInputs
(
*
args
)
depth_axis
=
len
(
self
.
_output_shape
)
-
1
if
self
.
hidden
is
not
None
:
htransform
=
self
.
_TransformHidden
(
self
.
hidden
)
f
,
i
,
j
,
o
=
tf
.
split
(
value
=
htransform
+
xtransform
,
num_or_size_splits
=
4
,
axis
=
depth_axis
)
else
:
f
,
i
,
j
,
o
=
tf
.
split
(
value
=
xtransform
,
num_or_size_splits
=
4
,
axis
=
depth_axis
)
if
self
.
cell
is
not
None
:
self
.
cell
=
tf
.
sigmoid
(
f
)
*
self
.
cell
+
tf
.
sigmoid
(
i
)
*
tf
.
tanh
(
j
)
else
:
self
.
cell
=
tf
.
sigmoid
(
i
)
*
tf
.
tanh
(
j
)
self
.
hidden
=
tf
.
sigmoid
(
o
)
*
tf
.
tanh
(
self
.
cell
)
return
self
.
hidden
class
LSTM
(
LSTMBase
):
"""Efficient LSTM implementation used in [1].
[1] Zaremba, Sutskever, Vinyals. Recurrent Neural Network Regularization,
2015. arxiv:1409.2329.
"""
def
__init__
(
self
,
depth
,
bias
=
LSTMBiasInit
,
initializer
=
block_util
.
RsqrtInitializer
(),
name
=
None
):
super
(
LSTM
,
self
).
__init__
([
depth
],
name
)
with
self
.
_BlockScope
():
self
.
_depth
=
depth
self
.
_nn
=
blocks_std
.
NN
(
4
*
depth
,
bias
=
bias
,
act
=
None
,
initializer
=
initializer
)
self
.
_hidden_linear
=
blocks_std
.
Linear
(
4
*
depth
,
initializer
=
initializer
)
def
_TransformInputs
(
self
,
*
args
):
return
self
.
_nn
(
*
args
)
def
_TransformHidden
(
self
,
h
):
return
self
.
_hidden_linear
(
h
)
class
Conv2DLSTM
(
LSTMBase
):
"""Convolutional LSTM implementation with optimizations inspired by [1].
Note that when using the batch normalization feature, the bias initializer
will not be used, since BN effectively cancels its effect out.
[1] Zaremba, Sutskever, Vinyals. Recurrent Neural Network Regularization,
2015. arxiv:1409.2329.
"""
def
__init__
(
self
,
depth
,
filter_size
,
hidden_filter_size
,
strides
,
padding
,
bias
=
LSTMBiasInit
,
initializer
=
block_util
.
RsqrtInitializer
(
dims
=
(
0
,
1
,
2
)),
use_moving_average
=
False
,
name
=
None
):
super
(
Conv2DLSTM
,
self
).
__init__
([
None
,
None
,
depth
],
name
)
self
.
_iter
=
0
with
self
.
_BlockScope
():
self
.
_input_conv
=
blocks_std
.
Conv2D
(
4
*
depth
,
filter_size
,
strides
,
padding
,
bias
=
None
,
act
=
None
,
initializer
=
initializer
,
name
=
'input_conv2d'
)
self
.
_hidden_conv
=
blocks_std
.
Conv2D
(
4
*
depth
,
hidden_filter_size
,
[
1
,
1
],
'SAME'
,
bias
=
None
,
act
=
None
,
initializer
=
initializer
,
name
=
'hidden_conv2d'
)
if
bias
is
not
None
:
self
.
_bias
=
blocks_std
.
BiasAdd
(
bias
,
name
=
'biases'
)
else
:
self
.
_bias
=
blocks_std
.
PassThrough
()
def
_TransformInputs
(
self
,
x
):
return
self
.
_bias
(
self
.
_input_conv
(
x
))
def
_TransformHidden
(
self
,
h
):
return
self
.
_hidden_conv
(
h
)
def
_Apply
(
self
,
*
args
):
xtransform
=
self
.
_TransformInputs
(
*
args
)
depth_axis
=
len
(
self
.
_output_shape
)
-
1
if
self
.
hidden
is
not
None
:
htransform
=
self
.
_TransformHidden
(
self
.
hidden
)
f
,
i
,
j
,
o
=
tf
.
split
(
value
=
htransform
+
xtransform
,
num_or_size_splits
=
4
,
axis
=
depth_axis
)
else
:
f
,
i
,
j
,
o
=
tf
.
split
(
value
=
xtransform
,
num_or_size_splits
=
4
,
axis
=
depth_axis
)
if
self
.
cell
is
not
None
:
self
.
cell
=
tf
.
sigmoid
(
f
)
*
self
.
cell
+
tf
.
sigmoid
(
i
)
*
tf
.
tanh
(
j
)
else
:
self
.
cell
=
tf
.
sigmoid
(
i
)
*
tf
.
tanh
(
j
)
self
.
hidden
=
tf
.
sigmoid
(
o
)
*
tf
.
tanh
(
self
.
cell
)
self
.
_iter
+=
1
return
self
.
hidden
research/compression/entropy_coder/lib/blocks_lstm_test.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Tests for LSTM tensorflow blocks."""
from
__future__
import
division
import
numpy
as
np
import
tensorflow
as
tf
import
block_base
import
blocks_std
import
blocks_lstm
class
BlocksLSTMTest
(
tf
.
test
.
TestCase
):
def
CheckUnary
(
self
,
y
,
op_type
):
self
.
assertEqual
(
op_type
,
y
.
op
.
type
)
self
.
assertEqual
(
1
,
len
(
y
.
op
.
inputs
))
return
y
.
op
.
inputs
[
0
]
def
CheckBinary
(
self
,
y
,
op_type
):
self
.
assertEqual
(
op_type
,
y
.
op
.
type
)
self
.
assertEqual
(
2
,
len
(
y
.
op
.
inputs
))
return
y
.
op
.
inputs
def
testLSTM
(
self
):
lstm
=
blocks_lstm
.
LSTM
(
10
)
lstm
.
hidden
=
tf
.
zeros
(
shape
=
[
10
,
10
],
dtype
=
tf
.
float32
)
lstm
.
cell
=
tf
.
zeros
(
shape
=
[
10
,
10
],
dtype
=
tf
.
float32
)
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
[
10
,
11
])
y
=
lstm
(
x
)
o
,
tanhc
=
self
.
CheckBinary
(
y
,
'Mul'
)
self
.
assertEqual
(
self
.
CheckUnary
(
o
,
'Sigmoid'
).
name
,
'LSTM/split:3'
)
self
.
assertIs
(
lstm
.
cell
,
self
.
CheckUnary
(
tanhc
,
'Tanh'
))
fc
,
ij
=
self
.
CheckBinary
(
lstm
.
cell
,
'Add'
)
f
,
_
=
self
.
CheckBinary
(
fc
,
'Mul'
)
self
.
assertEqual
(
self
.
CheckUnary
(
f
,
'Sigmoid'
).
name
,
'LSTM/split:0'
)
i
,
j
=
self
.
CheckBinary
(
ij
,
'Mul'
)
self
.
assertEqual
(
self
.
CheckUnary
(
i
,
'Sigmoid'
).
name
,
'LSTM/split:1'
)
j
=
self
.
CheckUnary
(
j
,
'Tanh'
)
self
.
assertEqual
(
j
.
name
,
'LSTM/split:2'
)
def
testLSTMBiasInit
(
self
):
lstm
=
blocks_lstm
.
LSTM
(
9
)
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
[
15
,
7
])
lstm
(
x
)
b
=
lstm
.
_nn
.
_bias
with
self
.
test_session
():
tf
.
global_variables_initializer
().
run
()
bias_var
=
b
.
_bias
.
eval
()
comp
=
([
1.0
]
*
9
)
+
([
0.0
]
*
27
)
self
.
assertAllEqual
(
bias_var
,
comp
)
def
testConv2DLSTM
(
self
):
lstm
=
blocks_lstm
.
Conv2DLSTM
(
depth
=
10
,
filter_size
=
[
1
,
1
],
hidden_filter_size
=
[
1
,
1
],
strides
=
[
1
,
1
],
padding
=
'SAME'
)
lstm
.
hidden
=
tf
.
zeros
(
shape
=
[
10
,
11
,
11
,
10
],
dtype
=
tf
.
float32
)
lstm
.
cell
=
tf
.
zeros
(
shape
=
[
10
,
11
,
11
,
10
],
dtype
=
tf
.
float32
)
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
[
10
,
11
,
11
,
1
])
y
=
lstm
(
x
)
o
,
tanhc
=
self
.
CheckBinary
(
y
,
'Mul'
)
self
.
assertEqual
(
self
.
CheckUnary
(
o
,
'Sigmoid'
).
name
,
'Conv2DLSTM/split:3'
)
self
.
assertIs
(
lstm
.
cell
,
self
.
CheckUnary
(
tanhc
,
'Tanh'
))
fc
,
ij
=
self
.
CheckBinary
(
lstm
.
cell
,
'Add'
)
f
,
_
=
self
.
CheckBinary
(
fc
,
'Mul'
)
self
.
assertEqual
(
self
.
CheckUnary
(
f
,
'Sigmoid'
).
name
,
'Conv2DLSTM/split:0'
)
i
,
j
=
self
.
CheckBinary
(
ij
,
'Mul'
)
self
.
assertEqual
(
self
.
CheckUnary
(
i
,
'Sigmoid'
).
name
,
'Conv2DLSTM/split:1'
)
j
=
self
.
CheckUnary
(
j
,
'Tanh'
)
self
.
assertEqual
(
j
.
name
,
'Conv2DLSTM/split:2'
)
def
testConv2DLSTMBiasInit
(
self
):
lstm
=
blocks_lstm
.
Conv2DLSTM
(
9
,
1
,
1
,
[
1
,
1
],
'SAME'
)
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
[
1
,
7
,
7
,
7
])
lstm
(
x
)
b
=
lstm
.
_bias
with
self
.
test_session
():
tf
.
global_variables_initializer
().
run
()
bias_var
=
b
.
_bias
.
eval
()
comp
=
([
1.0
]
*
9
)
+
([
0.0
]
*
27
)
self
.
assertAllEqual
(
bias_var
,
comp
)
if
__name__
==
'__main__'
:
tf
.
test
.
main
()
research/compression/entropy_coder/lib/blocks_masked_conv2d.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Define some typical masked 2D convolutions."""
import
numpy
as
np
from
six.moves
import
xrange
import
tensorflow
as
tf
import
block_util
import
blocks_std
# pylint does not recognize block_base.BlockBase.__call__().
# pylint: disable=not-callable
class
RasterScanConv2D
(
blocks_std
.
Conv2DBase
):
"""Conv2D with no dependency on future pixels (in raster scan order).
For example, assuming a 5 x 5 kernel, the kernel is applied a spatial mask:
T T T T T
T T T T T
T T x F F
F F F F F
F F F F F
where 'T' are pixels which are available when computing the convolution
for pixel 'x'. All the pixels marked with 'F' are not available.
'x' itself is not available if strict_order is True, otherwise, it is
available.
"""
def
__init__
(
self
,
depth
,
filter_size
,
strides
,
padding
,
strict_order
=
True
,
bias
=
None
,
act
=
None
,
initializer
=
None
,
name
=
None
):
super
(
RasterScanConv2D
,
self
).
__init__
(
depth
,
filter_size
,
strides
,
padding
,
bias
,
act
,
name
=
name
)
if
(
filter_size
[
0
]
%
2
)
!=
1
or
(
filter_size
[
1
]
%
2
)
!=
1
:
raise
ValueError
(
'Kernel size should be odd.'
)
with
self
.
_BlockScope
():
if
initializer
is
None
:
initializer
=
block_util
.
RsqrtInitializer
(
dims
=
(
0
,
1
,
2
))
self
.
_initializer
=
initializer
self
.
_strict_order
=
strict_order
def
_CreateKernel
(
self
,
shape
,
dtype
):
init
=
self
.
_initializer
(
shape
,
dtype
)
kernel
=
self
.
NewVar
(
init
)
mask
=
np
.
ones
(
shape
[:
2
],
dtype
=
dtype
.
as_numpy_dtype
)
center
=
shape
[:
2
]
//
2
mask
[
center
[
0
]
+
1
:,
:]
=
0
if
not
self
.
_strict_order
:
mask
[
center
[
0
],
center
[
1
]
+
1
:]
=
0
else
:
mask
[
center
[
0
],
center
[
1
]:]
=
0
mask
=
mask
.
reshape
(
mask
.
shape
+
(
1
,
1
))
return
tf
.
convert_to_tensor
(
mask
,
dtype
)
*
kernel
class
DepthOrderConv2D
(
blocks_std
.
Conv2DBase
):
"""Conv2D with no dependency on higher depth dimensions.
More precisely, the output depth #n has only dependencies on input depths #k
for k < n (if strict_order is True) or for k <= n (if strict_order is False).
"""
def
__init__
(
self
,
depth
,
filter_size
,
strides
,
padding
,
strict_order
=
True
,
bias
=
None
,
act
=
None
,
initializer
=
None
,
name
=
None
):
super
(
DepthOrderConv2D
,
self
).
__init__
(
depth
,
filter_size
,
strides
,
padding
,
bias
,
act
,
name
=
name
)
with
self
.
_BlockScope
():
if
initializer
is
None
:
initializer
=
block_util
.
RsqrtInitializer
(
dims
=
(
0
,
1
,
2
))
self
.
_initializer
=
initializer
self
.
_strict_order
=
strict_order
def
_CreateKernel
(
self
,
shape
,
dtype
):
init
=
self
.
_initializer
(
shape
,
dtype
)
kernel
=
self
.
NewVar
(
init
)
mask
=
np
.
ones
(
shape
[
2
:],
dtype
=
dtype
.
as_numpy_dtype
)
depth_output
=
shape
[
3
]
for
d
in
xrange
(
depth_output
):
if
self
.
_strict_order
:
mask
[
d
:,
d
]
=
0
else
:
mask
[
d
+
1
:,
d
]
=
0
mask
=
mask
.
reshape
((
1
,
1
)
+
mask
.
shape
)
return
tf
.
convert_to_tensor
(
mask
,
dtype
)
*
kernel
class
GroupRasterScanConv2D
(
blocks_std
.
Conv2DBase
):
"""Conv2D with no dependency on future pixels (in raster scan order).
This version only introduces dependencies on previous pixels in raster scan
order. It can also introduce some dependencies on previous depth positions
of the current pixel (current pixel = center pixel of the kernel) in the
following way:
the depth dimension of the input is split into Ki groups of size
|input_group_size|, the output dimension is split into Ko groups of size
|output_group_size| (usually Ki == Ko). Each output group ko of the current
pixel position can only depend on previous input groups ki
(i.e. ki < ko if strict_order is True or ki <= ko if strict_order is False).
Notes:
- Block RasterScanConv2D is a special case of GroupRasterScanConv2D
where Ki == Ko == 1 (i.e. input_group_size == input_depth and
output_group_size == output_depth).
- For 1x1 convolution, block DepthOrderConv2D is a special case of
GroupRasterScanConv2D where input_group_size == 1 and
output_group_size == 1.
"""
def
__init__
(
self
,
depth
,
filter_size
,
strides
,
padding
,
strict_order
=
True
,
input_group_size
=
1
,
output_group_size
=
1
,
bias
=
None
,
act
=
None
,
initializer
=
None
,
name
=
None
):
super
(
GroupRasterScanConv2D
,
self
).
__init__
(
depth
,
filter_size
,
strides
,
padding
,
bias
,
act
,
name
=
name
)
if
(
filter_size
[
0
]
%
2
)
!=
1
or
(
filter_size
[
1
]
%
2
)
!=
1
:
raise
ValueError
(
'Kernel size should be odd.'
)
with
self
.
_BlockScope
():
if
initializer
is
None
:
initializer
=
block_util
.
RsqrtInitializer
(
dims
=
(
0
,
1
,
2
))
self
.
_initializer
=
initializer
self
.
_input_group_size
=
input_group_size
self
.
_output_group_size
=
output_group_size
self
.
_strict_order
=
strict_order
if
depth
%
self
.
_output_group_size
!=
0
:
raise
ValueError
(
'Invalid depth group size: {} for depth {}'
.
format
(
self
.
_output_group_size
,
depth
))
self
.
_output_group_count
=
depth
//
self
.
_output_group_size
def
_CreateKernel
(
self
,
shape
,
dtype
):
init
=
self
.
_initializer
(
shape
,
dtype
)
kernel
=
self
.
NewVar
(
init
)
depth_input
=
shape
[
2
]
if
depth_input
%
self
.
_input_group_size
!=
0
:
raise
ValueError
(
'Invalid depth group size: {} for depth {}'
.
format
(
self
.
_input_group_size
,
depth_input
))
input_group_count
=
depth_input
//
self
.
_input_group_size
output_group_count
=
self
.
_output_group_count
# Set the mask to 0 for future pixels in raster scan order.
center
=
shape
[:
2
]
//
2
mask
=
np
.
ones
([
shape
[
0
],
shape
[
1
],
input_group_count
,
self
.
_input_group_size
,
output_group_count
,
self
.
_output_group_size
],
dtype
=
dtype
.
as_numpy_dtype
)
mask
[
center
[
0
]
+
1
:,
:,
:,
:,
:,
:]
=
0
mask
[
center
[
0
],
center
[
1
]
+
1
:,
:,
:,
:,
:]
=
0
# Adjust the mask for the current position (the center position).
depth_output
=
shape
[
3
]
for
d
in
xrange
(
output_group_count
):
mask
[
center
[
0
],
center
[
1
],
d
+
1
:,
:,
d
:
d
+
1
,
:]
=
0
if
self
.
_strict_order
:
mask
[
center
[
0
],
center
[
1
],
d
,
:,
d
:
d
+
1
,
:]
=
0
mask
=
mask
.
reshape
([
shape
[
0
],
shape
[
1
],
depth_input
,
depth_output
])
return
tf
.
convert_to_tensor
(
mask
,
dtype
)
*
kernel
class
InFillingConv2D
(
blocks_std
.
Conv2DBase
):
"""Conv2D with kernel having no dependency on the current pixel.
For example, assuming a 5 x 5 kernel, the kernel is applied a spatial mask:
T T T T T
T T T T T
T T x T T
T T T T T
T T T T T
where 'T' marks a pixel which is available when computing the convolution
for pixel 'x'. 'x' itself is not available.
"""
def
__init__
(
self
,
depth
,
filter_size
,
strides
,
padding
,
bias
=
None
,
act
=
None
,
initializer
=
None
,
name
=
None
):
super
(
InFillingConv2D
,
self
).
__init__
(
depth
,
filter_size
,
strides
,
padding
,
bias
,
act
,
name
=
name
)
if
(
filter_size
[
0
]
%
2
)
!=
1
or
(
filter_size
[
1
]
%
2
)
!=
1
:
raise
ValueError
(
'Kernel size should be odd.'
)
if
filter_size
[
0
]
==
1
and
filter_size
[
1
]
==
1
:
raise
ValueError
(
'Kernel size should be larger than 1x1.'
)
with
self
.
_BlockScope
():
if
initializer
is
None
:
initializer
=
block_util
.
RsqrtInitializer
(
dims
=
(
0
,
1
,
2
))
self
.
_initializer
=
initializer
def
_CreateKernel
(
self
,
shape
,
dtype
):
init
=
self
.
_initializer
(
shape
,
dtype
)
kernel
=
self
.
NewVar
(
init
)
mask
=
np
.
ones
(
shape
[:
2
],
dtype
=
dtype
.
as_numpy_dtype
)
center
=
shape
[:
2
]
//
2
mask
[
center
[
0
],
center
[
1
]]
=
0
mask
=
mask
.
reshape
(
mask
.
shape
+
(
1
,
1
))
return
tf
.
convert_to_tensor
(
mask
,
dtype
)
*
kernel
research/compression/entropy_coder/lib/blocks_masked_conv2d_lstm.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Masked conv2d LSTM."""
import
block_base
import
block_util
import
blocks_masked_conv2d
import
blocks_lstm
import
blocks_std
# pylint: disable=not-callable
class
RasterScanConv2DLSTM
(
blocks_lstm
.
LSTMBase
):
"""Convolutional LSTM implementation with optimizations inspired by [1].
Note that when using the batch normalization feature, the bias initializer
will not be used, since BN effectively cancels its effect out.
[1] Zaremba, Sutskever, Vinyals. Recurrent Neural Network Regularization,
2015. arxiv:1409.2329.
"""
def
__init__
(
self
,
depth
,
filter_size
,
hidden_filter_size
,
strides
,
padding
,
bias
=
blocks_lstm
.
LSTMBiasInit
,
initializer
=
block_util
.
RsqrtInitializer
(
dims
=
(
0
,
1
,
2
)),
name
=
None
):
super
(
RasterScanConv2DLSTM
,
self
).
__init__
([
None
,
None
,
depth
],
name
)
with
self
.
_BlockScope
():
self
.
_input_conv
=
blocks_masked_conv2d
.
RasterScanConv2D
(
4
*
depth
,
filter_size
,
strides
,
padding
,
strict_order
=
False
,
bias
=
None
,
act
=
None
,
initializer
=
initializer
,
name
=
'input_conv2d'
)
self
.
_hidden_conv
=
blocks_std
.
Conv2D
(
4
*
depth
,
hidden_filter_size
,
[
1
,
1
],
'SAME'
,
bias
=
None
,
act
=
None
,
initializer
=
initializer
,
name
=
'hidden_conv2d'
)
if
bias
is
not
None
:
self
.
_bias
=
blocks_std
.
BiasAdd
(
bias
,
name
=
'biases'
)
else
:
self
.
_bias
=
blocks_std
.
PassThrough
()
def
_TransformInputs
(
self
,
x
):
return
self
.
_bias
(
self
.
_input_conv
(
x
))
def
_TransformHidden
(
self
,
h
):
return
self
.
_hidden_conv
(
h
)
research/compression/entropy_coder/lib/blocks_masked_conv2d_test.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Tests of the 2D masked convolution blocks."""
from
__future__
import
division
from
__future__
import
unicode_literals
import
numpy
as
np
from
six.moves
import
xrange
import
tensorflow
as
tf
import
blocks_masked_conv2d
class
MaskedConv2DTest
(
tf
.
test
.
TestCase
):
def
testRasterScanKernel
(
self
):
kernel_size
=
5
input_depth
=
1
output_depth
=
1
kernel_shape
=
[
kernel_size
,
kernel_size
,
input_depth
,
output_depth
]
# pylint: disable=bad-whitespace
kernel_feed
=
[[
1.0
,
2.0
,
3.0
,
4.0
,
5.0
],
[
6.0
,
7.0
,
8.0
,
9.0
,
10.0
],
[
11.0
,
12.0
,
13.0
,
14.0
,
15.0
],
[
16.0
,
17.0
,
18.0
,
19.0
,
20.0
],
[
21.0
,
22.0
,
23.0
,
24.0
,
25.0
]]
kernel_feed
=
np
.
reshape
(
kernel_feed
,
kernel_shape
)
kernel_expected
=
[[
1.0
,
2.0
,
3.0
,
4.0
,
5.0
],
[
6.0
,
7.0
,
8.0
,
9.0
,
10.0
],
[
11.0
,
12.0
,
0.0
,
0.0
,
0.0
],
[
0.0
,
0.0
,
0.0
,
0.0
,
0.0
],
[
0.0
,
0.0
,
0.0
,
0.0
,
0.0
]]
kernel_expected
=
np
.
reshape
(
kernel_expected
,
kernel_shape
)
# pylint: enable=bad-whitespace
init_kernel
=
lambda
s
,
t
:
tf
.
constant
(
kernel_feed
,
dtype
=
t
,
shape
=
s
)
masked_conv2d
=
blocks_masked_conv2d
.
RasterScanConv2D
(
output_depth
,
[
kernel_size
]
*
2
,
[
1
]
*
2
,
'SAME'
,
initializer
=
init_kernel
)
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
[
10
]
*
3
+
[
input_depth
])
_
=
masked_conv2d
(
x
)
with
self
.
test_session
():
tf
.
global_variables_initializer
().
run
()
kernel_value
=
masked_conv2d
.
_kernel
.
eval
()
self
.
assertAllEqual
(
kernel_expected
,
kernel_value
)
def
testDepthOrderKernel
(
self
):
kernel_size
=
1
input_depth
=
7
output_depth
=
input_depth
kernel_shape
=
[
kernel_size
,
kernel_size
,
input_depth
,
output_depth
]
kernel_feed
=
np
.
ones
(
kernel_shape
)
x_shape
=
[
5
]
*
3
+
[
input_depth
]
x_feed
=
np
.
ones
(
x_shape
)
y_expected
=
np
.
zeros
(
x_shape
[
0
:
3
]
+
[
output_depth
])
y_expected
[:,
:,
:]
=
np
.
arange
(
output_depth
)
init_kernel
=
lambda
s
,
t
:
tf
.
constant
(
kernel_feed
,
dtype
=
t
,
shape
=
s
)
masked_conv2d
=
blocks_masked_conv2d
.
DepthOrderConv2D
(
output_depth
,
[
kernel_size
]
*
2
,
[
1
]
*
2
,
'SAME'
,
strict_order
=
True
,
initializer
=
init_kernel
)
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
x_shape
)
y
=
masked_conv2d
(
x
)
with
self
.
test_session
():
tf
.
global_variables_initializer
().
run
()
y_value
=
y
.
eval
(
feed_dict
=
{
x
:
x_feed
})
self
.
assertAllEqual
(
y_expected
,
y_value
)
def
testGroupRasterScanKernel
(
self
):
kernel_size
=
3
input_depth
=
4
input_group_size
=
2
output_depth
=
2
output_group_size
=
1
kernel_shape
=
[
kernel_size
,
kernel_size
,
input_depth
,
output_depth
]
kernel_feed
=
np
.
ones
(
shape
=
kernel_shape
)
height
=
5
width
=
5
x_shape
=
[
1
,
height
,
width
,
input_depth
]
x_feed
=
np
.
ones
(
shape
=
x_shape
)
# pylint: disable=bad-whitespace
y_expected
=
[
[[
0
,
2
],
[
4
,
6
],
[
4
,
6
],
[
4
,
6
],
[
4
,
6
]],
[[
8
,
10
],
[
16
,
18
],
[
16
,
18
],
[
16
,
18
],
[
12
,
14
]],
[[
8
,
10
],
[
16
,
18
],
[
16
,
18
],
[
16
,
18
],
[
12
,
14
]],
[[
8
,
10
],
[
16
,
18
],
[
16
,
18
],
[
16
,
18
],
[
12
,
14
]],
[[
8
,
10
],
[
16
,
18
],
[
16
,
18
],
[
16
,
18
],
[
12
,
14
]],
]
y_expected
=
np
.
reshape
(
y_expected
,
[
1
,
height
,
width
,
output_depth
])
# pylint: enable=bad-whitespace
init_kernel
=
lambda
s
,
t
:
tf
.
constant
(
kernel_feed
,
dtype
=
t
,
shape
=
s
)
masked_conv2d
=
blocks_masked_conv2d
.
GroupRasterScanConv2D
(
output_depth
,
[
kernel_size
]
*
2
,
[
1
]
*
2
,
'SAME'
,
strict_order
=
True
,
input_group_size
=
input_group_size
,
output_group_size
=
output_group_size
,
initializer
=
init_kernel
)
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
x_shape
)
y
=
masked_conv2d
(
x
)
with
self
.
test_session
():
tf
.
global_variables_initializer
().
run
()
y_value
=
y
.
eval
(
feed_dict
=
{
x
:
x_feed
})
self
.
assertAllEqual
(
y_expected
,
y_value
)
def
testInFillingKernel
(
self
):
kernel_size
=
5
input_depth
=
1
output_depth
=
1
kernel_shape
=
[
kernel_size
,
kernel_size
,
input_depth
,
output_depth
]
# pylint: disable=bad-whitespace
kernel_feed
=
[[
1.0
,
2.0
,
3.0
,
4.0
,
5.0
],
[
6.0
,
7.0
,
8.0
,
9.0
,
10.0
],
[
11.0
,
12.0
,
13.0
,
14.0
,
15.0
],
[
16.0
,
17.0
,
18.0
,
19.0
,
20.0
],
[
21.0
,
22.0
,
23.0
,
24.0
,
25.0
]]
kernel_feed
=
np
.
reshape
(
kernel_feed
,
kernel_shape
)
kernel_expected
=
[[
1.0
,
2.0
,
3.0
,
4.0
,
5.0
],
[
6.0
,
7.0
,
8.0
,
9.0
,
10.0
],
[
11.0
,
12.0
,
0.0
,
14.0
,
15.0
],
[
16.0
,
17.0
,
18.0
,
19.0
,
20.0
],
[
21.0
,
22.0
,
23.0
,
24.0
,
25.0
]]
kernel_expected
=
np
.
reshape
(
kernel_expected
,
kernel_shape
)
# pylint: enable=bad-whitespace
init_kernel
=
lambda
s
,
t
:
tf
.
constant
(
kernel_feed
,
dtype
=
t
,
shape
=
s
)
masked_conv2d
=
blocks_masked_conv2d
.
InFillingConv2D
(
output_depth
,
[
kernel_size
]
*
2
,
[
1
]
*
2
,
'SAME'
,
initializer
=
init_kernel
)
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
[
10
]
*
3
+
[
input_depth
])
_
=
masked_conv2d
(
x
)
with
self
.
test_session
():
tf
.
global_variables_initializer
().
run
()
kernel_value
=
masked_conv2d
.
_kernel
.
eval
()
self
.
assertAllEqual
(
kernel_expected
,
kernel_value
)
def
testConv2DMaskedNumerics
(
self
):
kernel_size
=
5
input_shape
=
[
1
,
10
,
10
,
1
]
filter_shape
=
[
kernel_size
,
kernel_size
,
1
,
1
]
strides
=
[
1
,
1
,
1
,
1
]
output_shape
=
[
1
,
10
,
10
,
1
]
conv
=
blocks_masked_conv2d
.
RasterScanConv2D
(
depth
=
filter_shape
[
-
1
],
filter_size
=
filter_shape
[
0
:
2
],
strides
=
strides
[
1
:
3
],
padding
=
'SAME'
,
initializer
=
tf
.
constant_initializer
(
value
=
1.0
))
x
=
tf
.
placeholder
(
dtype
=
tf
.
float32
,
shape
=
input_shape
)
y
=
conv
(
x
)
x_feed
=
-
np
.
ones
(
input_shape
,
dtype
=
float
)
y_expected
=
np
.
ones
(
output_shape
,
dtype
=
float
)
for
i
in
xrange
(
input_shape
[
1
]):
for
j
in
xrange
(
input_shape
[
2
]):
x_feed
[
0
,
i
,
j
,
0
]
=
10
*
(
j
+
1
)
+
i
v
=
0
ki_start
=
max
(
i
-
kernel_size
//
2
,
0
)
kj_start
=
max
(
j
-
kernel_size
//
2
,
0
)
kj_end
=
min
(
j
+
kernel_size
//
2
,
input_shape
[
2
]
-
1
)
for
ki
in
range
(
ki_start
,
i
+
1
):
for
kj
in
range
(
kj_start
,
kj_end
+
1
):
if
ki
>
i
:
continue
if
ki
==
i
and
kj
>=
j
:
continue
v
+=
10
*
(
kj
+
1
)
+
ki
y_expected
[
0
,
i
,
j
,
0
]
=
v
with
self
.
test_session
():
tf
.
global_variables_initializer
().
run
()
y_value
=
y
.
eval
(
feed_dict
=
{
x
:
x_feed
})
self
.
assertAllEqual
(
y_expected
,
y_value
)
if
__name__
==
'__main__'
:
tf
.
test
.
main
()
research/compression/entropy_coder/lib/blocks_operator.py
deleted
100644 → 0
View file @
09bc9f54
# Copyright 2017 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.
# ==============================================================================
"""Common blocks which work as operators on other blocks."""
import
tensorflow
as
tf
import
block_base
# pylint: disable=not-callable
class
CompositionOperator
(
block_base
.
BlockBase
):
"""Composition of several blocks."""
def
__init__
(
self
,
block_list
,
name
=
None
):
"""Initialization of the composition operator.
Args:
block_list: List of blocks.BlockBase that are chained to create
a new blocks.BlockBase.
name: Name of this block.
"""
super
(
CompositionOperator
,
self
).
__init__
(
name
)
self
.
_blocks
=
block_list
def
_Apply
(
self
,
x
):
"""Apply successively all the blocks on the given input tensor."""
h
=
x
for
layer
in
self
.
_blocks
:
h
=
layer
(
h
)
return
h
class
LineOperator
(
block_base
.
BlockBase
):
"""Repeat the same block over all the lines of an input tensor."""
def
__init__
(
self
,
block
,
name
=
None
):
super
(
LineOperator
,
self
).
__init__
(
name
)
self
.
_block
=
block
def
_Apply
(
self
,
x
):
height
=
x
.
get_shape
()[
1
].
value
if
height
is
None
:
raise
ValueError
(
'Unknown tensor height'
)
all_line_x
=
tf
.
split
(
value
=
x
,
num_or_size_splits
=
height
,
axis
=
1
)
y
=
[]
for
line_x
in
all_line_x
:
y
.
append
(
self
.
_block
(
line_x
))
y
=
tf
.
concat
(
values
=
y
,
axis
=
1
)
return
y
class
TowerOperator
(
block_base
.
BlockBase
):
"""Parallel execution with concatenation of several blocks."""
def
__init__
(
self
,
block_list
,
dim
=
3
,
name
=
None
):
"""Initialization of the parallel exec + concat (Tower).
Args:
block_list: List of blocks.BlockBase that are chained to create
a new blocks.BlockBase.
dim: the dimension on which to concat.
name: Name of this block.
"""
super
(
TowerOperator
,
self
).
__init__
(
name
)
self
.
_blocks
=
block_list
self
.
_concat_dim
=
dim
def
_Apply
(
self
,
x
):
"""Apply successively all the blocks on the given input tensor."""
outputs
=
[
layer
(
x
)
for
layer
in
self
.
_blocks
]
return
tf
.
concat
(
outputs
,
self
.
_concat_dim
)
Prev
1
…
10
11
12
13
14
15
16
17
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