Skip to content

Commit f41449e

Browse files
authored
cherry-pick #22418 (#22642)
test=release/1.7, test=develop
1 parent 1cb19bf commit f41449e

File tree

2 files changed

+53
-25
lines changed

2 files changed

+53
-25
lines changed

python/paddle/fluid/dygraph/layers.py

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,11 @@ def parameters(self, include_sublayers=True):
150150
Returns:
151151
list of :ref:`api_guide_Variable_en` : a list of Parameters.
152152
"""
153-
ret = [p for p in self._parameters.values()]
154-
parameters_set = set(ret)
155-
if include_sublayers:
156-
for l in self._sub_layers.values():
157-
for p in l.parameters(include_sublayers):
158-
if p in parameters_set:
159-
continue
160-
parameters_set.add(p)
161-
ret.append(p)
153+
ret = [
154+
param
155+
for _, param in self.named_parameters(
156+
include_sublayers=include_sublayers)
157+
]
162158
return ret
163159

164160
def sublayers(self, include_sublayers=True):
@@ -170,11 +166,11 @@ def sublayers(self, include_sublayers=True):
170166
Returns:
171167
list of Layer : a list of sub layers.
172168
"""
173-
ret = [l for l in self._sub_layers.values()]
174-
if include_sublayers:
175-
for l in self._sub_layers.values():
176-
for sub_l in l.sublayers(include_sublayers):
177-
ret.append(sub_l)
169+
ret = [
170+
layer
171+
for _, layer in self.named_sublayers(
172+
include_sublayers=include_sublayers)
173+
]
178174
return ret
179175

180176
def named_parameters(self, prefix='', include_sublayers=True):
@@ -349,7 +345,12 @@ def add_parameter(self, name, parameter):
349345
Returns:
350346
Parameter: the parameter passed in.
351347
"""
352-
assert isinstance(parameter, framework.Parameter)
348+
if parameter is None:
349+
self._parameters[name] = None
350+
elif not isinstance(parameter, framework.Parameter):
351+
raise TypeError(
352+
"parameter assignment requires Parameter or None, but got '{}'"
353+
.format(type(parameter).__name__))
353354

354355
if len(self._loaddict_holder) > 0:
355356
assert parameter.name in self._loaddict_holder, "Parameter not found, Can't not find [ {} ] in stat_dict".format(
@@ -376,8 +377,8 @@ def _remove_if_exist(*dicts):
376377

377378
if isinstance(getattr(type(self), name, None), property):
378379
object.__setattr__(self, name, value)
380+
params = self.__dict__.get('_parameters', None)
379381
if isinstance(value, framework.Parameter):
380-
params = self.__dict__.get('_parameters', None)
381382
if params is None:
382383
raise ValueError(
383384
"super(YourLayer, self).__init__() should be called first")
@@ -389,16 +390,30 @@ def _remove_if_exist(*dicts):
389390

390391
_remove_if_exist(self.__dict__, self._sub_layers)
391392
params[name] = value
392-
elif isinstance(value, core.Layer):
393-
layers = self.__dict__.get('_sub_layers', None)
394-
if layers is None:
395-
raise ValueError(
396-
"super(YourLayer, self).__init__() should be called first")
397-
398-
_remove_if_exist(self.__dict__, self._parameters)
399-
layers[name] = value
393+
elif params is not None and name in params:
394+
if value is not None:
395+
raise TypeError(
396+
"assignment to parameter '{}' should be of type Parameter or None, but got '{}'"
397+
.format(name, type(value).__name__))
398+
params[name] = None
400399
else:
401-
object.__setattr__(self, name, value)
400+
layers = self.__dict__.get('_sub_layers', None)
401+
if isinstance(value, core.Layer):
402+
if layers is None:
403+
raise ValueError(
404+
"super(YourLayer, self).__init__() should be called first"
405+
)
406+
407+
_remove_if_exist(self.__dict__, self._parameters)
408+
layers[name] = value
409+
elif layers is not None and name in layers:
410+
if value is not None:
411+
raise TypeError(
412+
"assignment to sublayer '{}' should be of type Layer or None, but got '{}'"
413+
.format(name, type(value).__name__))
414+
layers[name] = None
415+
else:
416+
object.__setattr__(self, name, value)
402417

403418
def __delattr__(self, name):
404419
if name in self._parameters:

python/paddle/fluid/tests/unittests/test_imperative_basic.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,19 @@ def test_layer_attrs(self):
497497
self.assertTrue(hasattr(layer, "test_attr"))
498498
self.assertEqual(layer.test_attr, 1)
499499

500+
my_layer = MyLayer()
501+
my_layer.w1 = my_layer.create_parameter([3, 3])
502+
my_layer.add_parameter('w2', None)
503+
self.assertEqual(len(my_layer.parameters()), 1)
504+
self.assertRaises(TypeError, my_layer.__setattr__, 'w1', 'str')
505+
my_layer.w1 = None
506+
self.assertEqual(len(my_layer.parameters()), 0)
507+
my_layer.l1 = fluid.dygraph.Linear(3, 3)
508+
self.assertEqual(len(my_layer.sublayers()), 1)
509+
self.assertRaises(TypeError, my_layer.__setattr__, 'l1', 'str')
510+
my_layer.l1 = None
511+
self.assertEqual(len(my_layer.sublayers()), 0)
512+
500513

501514
if __name__ == '__main__':
502515
unittest.main()

0 commit comments

Comments
 (0)