From 84f9b9ef4990d4de0202cf49e17e2a9e7de6c3a4 Mon Sep 17 00:00:00 2001 From: hong <43953930+phlrain@users.noreply.github.com> Date: Mon, 6 Jul 2020 23:36:05 +0800 Subject: [PATCH] Connect stop gradient with trainbale (#25248) * connect stop_gradient with trainable; test=develop * add value error message; test=develop --- python/paddle/fluid/framework.py | 16 ++++++- .../test_imperative_layer_trainable.py | 47 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 python/paddle/fluid/tests/unittests/test_imperative_layer_trainable.py diff --git a/python/paddle/fluid/framework.py b/python/paddle/fluid/framework.py index 7454c70d55b..a8b4e55a1b0 100644 --- a/python/paddle/fluid/framework.py +++ b/python/paddle/fluid/framework.py @@ -5111,7 +5111,8 @@ class ParamBase(core.VarBase): list(shape) if shape else [], name, core.VarDesc.VarType.LOD_TENSOR, True) - self.trainable = kwargs.get('trainable', True) + trainable = kwargs.get('trainable', True) + self.stop_gradient = not trainable self.optimize_attr = kwargs.get('optimize_attr', {'learning_rate': 1.0}) @@ -5126,6 +5127,19 @@ class ParamBase(core.VarBase): def __str__(self): return self.to_string(True) + @property + def trainable(self): + return not self.stop_gradient + + @trainable.setter + def trainable(self, trainable): + if isinstance(trainable, bool): + self.stop_gradient = not trainable + else: + raise ValueError( + "The type of trainable MUST be bool, but the type is ", + type(trainable)) + def to_string(self, throw_on_error, with_details=False): """ To debug string. diff --git a/python/paddle/fluid/tests/unittests/test_imperative_layer_trainable.py b/python/paddle/fluid/tests/unittests/test_imperative_layer_trainable.py new file mode 100644 index 00000000000..909b1be0f7f --- /dev/null +++ b/python/paddle/fluid/tests/unittests/test_imperative_layer_trainable.py @@ -0,0 +1,47 @@ +# Copyright (c) 2020 PaddlePaddle 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. + +import unittest +import paddle.fluid as fluid +import numpy as np + +import paddle.fluid.dygraph as dygraph + + +class TestImperativeLayerTrainable(unittest.TestCase): + def test_set_trainable(self): + with fluid.dygraph.guard(): + label = np.random.uniform(-1, 1, [10, 10]).astype(np.float32) + + label = dygraph.to_variable(label) + + linear = dygraph.Linear(10, 10) + y = linear(label) + self.assertTrue(y.stop_gradient == False) + + linear.weight.trainable = False + linear.bias.trainable = False + + self.assertTrue(linear.weight.trainable == False) + self.assertTrue(linear.weight.stop_gradient == True) + + y = linear(label) + self.assertTrue(y.stop_gradient == True) + + with self.assertRaises(ValueError): + linear.weight.trainable = "1" + + +if __name__ == '__main__': + unittest.main() -- GitLab