Permalink
Browse files

Add copy and deepcopy functionality for resource_variable_ops.Resourc…

…eVariable.

PiperOrigin-RevId: 209823375
  • Loading branch information...
zafarali authored and tensorflower-gardener committed Aug 22, 2018
1 parent 401cb1a commit 7acfb875a0217777287a299ea8013e16fca59d4e
@@ -18,18 +18,36 @@
from __future__ import division
from __future__ import print_function
import copy
import os
import numpy as np
from tensorflow.python import keras
from tensorflow.python.eager import context
from tensorflow.python.framework import test_util
from tensorflow.python.keras import metrics
from tensorflow.python.keras import models
from tensorflow.python.ops import random_ops
from tensorflow.python.ops import resource_variable_ops
from tensorflow.python.platform import test
from tensorflow.python.training import adam
class TestModel(keras.Model):
"""A model subclass."""
def __init__(self, n_outputs=4, trainable=True):
"""A test class with one dense layer and number of outputs as a variable."""
super(TestModel, self).__init__()
self.layer1 = keras.layers.Dense(n_outputs)
self.n_outputs = resource_variable_ops.ResourceVariable(
n_outputs, trainable=trainable)
def call(self, x):
return self.layer1(x)
class TestModelCloning(test.TestCase):
def test_clone_sequential_model(self):
@@ -187,6 +205,36 @@ def test_model_backend_float64_use_cases(self):
keras.backend.set_floatx(floatx)
class TestModelDeepCopy(test.TestCase):
def test_deep_copy_eager_mode_trainable(self):
with context.eager_mode():
x = random_ops.random_normal((32, 4))
model = TestModel(trainable=True)
model(x) # Initialize Variables.
model_copy = copy.deepcopy(model)
self.assertEqual(len(model_copy.trainable_variables), 3)
model_copy.n_outputs.assign(1200)
self.assertFalse(
np.allclose(model_copy.n_outputs.numpy(),
model.n_outputs.numpy()))
def test_deep_copy_eager_mode_not_trainable(self):
with context.eager_mode():
x = random_ops.random_normal((32, 4))
model = TestModel(trainable=False)
model(x)
model_copy = copy.deepcopy(model)
self.assertEqual(len(model_copy.trainable_variables), 2)
weights = model_copy.get_weights()
weights = [w * 4 for w in weights]
model_copy.set_weights(weights)
self.assertFalse(
np.allclose(model.get_weights()[0],
model_copy.get_weights()[0]))
class TestCloneAndBuildModel(test.TestCase):
def test_clone_and_build_non_compiled_model(self):
@@ -17,6 +17,7 @@
from __future__ import division
from __future__ import print_function
import copy
import gc
import numpy as np
@@ -106,6 +107,27 @@ def testEagerBool(self):
v = resource_variable_ops.ResourceVariable(False, name="bool_test")
self.assertAllEqual(bool(v), False)
def testEagerDeepCopy(self):
with context.eager_mode():
init_value = np.ones((4, 4, 4))
variable = resource_variable_ops.ResourceVariable(init_value,
name="init")
copied_variable = copy.deepcopy(variable)
copied_variable.assign(4 * np.ones((4, 4, 4)))
# Copying the variable should create a new underlying tensor with distinct
# values.
self.assertFalse(np.allclose(variable.numpy(), copied_variable.numpy()))
def testGraphDeepCopy(self):
with self.test_session():
init_value = np.ones((4, 4, 4))
variable = resource_variable_ops.ResourceVariable(init_value,
name="init")
with self.assertRaises(NotImplementedError):
copy.deepcopy(variable)
@test_util.run_in_graph_and_eager_modes
def testStridedSliceAssign(self):
v = resource_variable_ops.ResourceVariable([1.0, 2.0])
@@ -586,6 +586,22 @@ def __nonzero__(self):
def __bool__(self):
return bool(self.read_value())
def __copy__(self):
return self
def __deepcopy__(self, memo):
if not context.executing_eagerly():
raise NotImplementedError(
"__deepcopy__() is only available when eager execution is enabled.")
copied_variable = ResourceVariable(
initial_value=self.read_value(),
trainable=self._trainable,
constraint=self._constraint,
dtype=self._dtype,
name=self._shared_name + "_copy")
memo[self._unique_id] = copied_variable
return copied_variable
@property
def dtype(self):
"""The dtype of this variable."""

0 comments on commit 7acfb87

Please sign in to comment.