@@ -54,16 +54,16 @@ def __init__(self):
54
54
def save_for_backward (self , * tensors ):
55
55
"""
56
56
Saves given tensors that backward need. Use ``saved_tensor`` in the `backward` to get the saved tensors.
57
-
57
+
58
58
.. note::
59
- This API should be called at most once, and only inside `forward`.
59
+ This API should be called at most once, and only inside `forward`.
60
60
61
61
Args:
62
62
tensors(list of Tensors): Tensors to be stored.
63
63
64
64
Returns:
65
65
None
66
-
66
+
67
67
Examples:
68
68
.. code-block:: python
69
69
@@ -94,7 +94,7 @@ def saved_tensor(self):
94
94
Get the tensors stored by ``save_for_backward``.
95
95
96
96
Returns:
97
- list of Tensors or None: If context contains tensors stored by `save_for_backward`,
97
+ list of Tensors or None: If context contains tensors stored by `save_for_backward`,
98
98
then return these tensors, otherwise return None.
99
99
100
100
Examples:
@@ -124,17 +124,14 @@ def backward(ctx, dy):
124
124
125
125
126
126
def with_mateclass (meta , * bases ):
127
-
128
127
class impl (meta ):
129
-
130
128
def __new__ (cls , name , temp_bases , attrs ):
131
129
return meta (name , bases , attrs )
132
130
133
131
return type .__new__ (impl , "impl" , (), {})
134
132
135
133
136
134
class CPyLayer (object ):
137
-
138
135
@classmethod
139
136
@dygraph_only
140
137
def apply (cls , * args , ** kwargs ):
@@ -147,7 +144,7 @@ def apply(cls, *args, **kwargs):
147
144
148
145
Returns:
149
146
tensors or other types : output of PyLayer.
150
-
147
+
151
148
Examples:
152
149
.. code-block:: python
153
150
@@ -182,12 +179,14 @@ def backward(ctx, dy):
182
179
183
180
184
181
class PyLayerBackward (LegacyPyLayerContext ):
185
-
186
182
def backward (self , * args , ** kwargs ):
187
183
with paddle .fluid .dygraph .guard ():
188
184
with paddle .fluid .dygraph .no_grad ():
189
- if self ._amp_state and 'enable' in self ._amp_state and self ._amp_state [
190
- 'enable' ]:
185
+ if (
186
+ self ._amp_state
187
+ and 'enable' in self ._amp_state
188
+ and self ._amp_state ['enable' ]
189
+ ):
191
190
with auto_cast (** args [0 ]._amp_state ):
192
191
return self ._forward_cls .backward (* args , ** kwargs )
193
192
else :
@@ -197,10 +196,10 @@ def backward(self, *args, **kwargs):
197
196
198
197
199
198
class LayerMeta (type ):
200
-
201
199
def __init__ (cls , name , bases , attrs ):
202
- cls ._backward_function = type (name + '_backward' , (PyLayerBackward , ),
203
- {"_forward_cls" : cls })
200
+ cls ._backward_function = type (
201
+ name + '_backward' , (PyLayerBackward ,), {"_forward_cls" : cls }
202
+ )
204
203
205
204
return super (LayerMeta , cls ).__init__ (name , bases , attrs )
206
205
@@ -210,15 +209,15 @@ class LegacyPyLayer(with_mateclass(LayerMeta, CPyLayer)):
210
209
Build a custom `Layer` by creating subclasses. Subclasses need to follow the following rules:
211
210
1. Subclasses contain `forward` and `backward` function. Both forward and backward are @staticmethod.
212
211
Their first argument should be a context and `None` can not be included in the returned result.
213
- 2. Input of backward contains a context as the first argument, and the rest arguments are the
214
- gradient of forward's output tensors. so the number of backward's input tensors equal to
215
- the number of forward output tensors. If you need the forward's inputs or outputs in `backward`,
212
+ 2. Input of backward contains a context as the first argument, and the rest arguments are the
213
+ gradient of forward's output tensors. so the number of backward's input tensors equal to
214
+ the number of forward output tensors. If you need the forward's inputs or outputs in `backward`,
216
215
you can use `save_for_backward` to store the required tensors, and then use them in the backward.
217
216
3. Output of backward function can only be `Tensor` or tuple/list of `Tensor`.
218
- Output tensors of backward are the gradient of forward's input tensors,
217
+ Output tensors of backward are the gradient of forward's input tensors,
219
218
so the number of backward's output tensors equal to the number of forward input tensors.
220
219
After building the custom Layer, run it through the `apply` method.
221
-
220
+
222
221
223
222
Examples:
224
223
.. code-block:: python
@@ -259,8 +258,8 @@ def backward(ctx, dy):
259
258
@staticmethod
260
259
def forward (ctx , * args , ** kwargs ):
261
260
"""
262
- It is to be overloaded by subclasses. It must accept a object of `PyLayerContext` as
263
- the first argument, followed by any number of arguments (tensors or other types).
261
+ It is to be overloaded by subclasses. It must accept a object of `PyLayerContext` as
262
+ the first argument, followed by any number of arguments (tensors or other types).
264
263
`None` can not be included in the returned result.
265
264
266
265
Args:
@@ -269,7 +268,7 @@ def forward(ctx, *args, **kwargs):
269
268
270
269
Returns:
271
270
tensors or other types : output of PyLayer.
272
-
271
+
273
272
Examples:
274
273
.. code-block:: python
275
274
@@ -292,14 +291,15 @@ def backward(ctx, dy):
292
291
return grad
293
292
"""
294
293
raise NotImplementedError (
295
- "You must implement the forward function for PyLayer." )
294
+ "You must implement the forward function for PyLayer."
295
+ )
296
296
297
297
@staticmethod
298
298
def backward (ctx , * args , ** kwargs ):
299
299
"""
300
- This is a function to calculate the gradient. It is to be overloaded by subclasses.
301
- It must accept a object of `PyLayerContext` as the first argument, and the rest
302
- arguments are the gradient of forward's output tensors. Output tensors of backward
300
+ This is a function to calculate the gradient. It is to be overloaded by subclasses.
301
+ It must accept a object of `PyLayerContext` as the first argument, and the rest
302
+ arguments are the gradient of forward's output tensors. Output tensors of backward
303
303
are the gradient of forward's input tensors.
304
304
305
305
Args:
@@ -308,7 +308,7 @@ def backward(ctx, *args, **kwargs):
308
308
309
309
Returns:
310
310
Tensor or list of Tensors: The gradient of forward's input tensor(s).
311
-
311
+
312
312
Examples:
313
313
.. code-block:: python
314
314
@@ -332,24 +332,24 @@ def backward(ctx, dy):
332
332
"""
333
333
334
334
raise NotImplementedError (
335
- "You must implement the backward function for PyLayer." )
335
+ "You must implement the backward function for PyLayer."
336
+ )
336
337
337
338
338
339
class EagerPyLayerContext (object ):
339
-
340
340
def save_for_backward (self , * tensors ):
341
341
"""
342
342
Saves given tensors that backward need. Use ``saved_tensor`` in the `backward` to get the saved tensors.
343
-
343
+
344
344
.. note::
345
- This API should be called at most once, and only inside `forward`.
345
+ This API should be called at most once, and only inside `forward`.
346
346
347
347
Args:
348
348
tensors(list of Tensors): Tensors to be stored.
349
349
350
350
Returns:
351
351
None
352
-
352
+
353
353
Examples:
354
354
.. code-block:: python
355
355
@@ -380,7 +380,7 @@ def saved_tensor(self):
380
380
Get the tensors stored by ``save_for_backward``.
381
381
382
382
Returns:
383
- list of Tensors or None: If context contains tensors stored by `save_for_backward`,
383
+ list of Tensors or None: If context contains tensors stored by `save_for_backward`,
384
384
then return these tensors, otherwise return None.
385
385
386
386
Examples:
@@ -410,11 +410,11 @@ def backward(ctx, dy):
410
410
def mark_not_inplace (self , * args ):
411
411
"""
412
412
Marks inputs as not inplace.
413
- This should be called at most once, only from inside the `forward` method,
413
+ This should be called at most once, only from inside the `forward` method,
414
414
and all arguments should be Tensor inputs.
415
415
416
- If the Tensor returned by `forward` method is the same as the Tensor input of forward,
417
- and this Tensor is marked as not_inplace, then Paddle will help the user create a new Tensor as output.
416
+ If the Tensor returned by `forward` method is the same as the Tensor input of forward,
417
+ and this Tensor is marked as not_inplace, then Paddle will help the user create a new Tensor as output.
418
418
Thereby preventing the auto grad information of the input Tensor from being overwritten.
419
419
420
420
Examples:
@@ -427,7 +427,7 @@ class Exp(paddle.autograd.PyLayer):
427
427
def forward(ctx, x):
428
428
ctx.mark_not_inplace(x)
429
429
return x
430
-
430
+
431
431
@staticmethod
432
432
def backward(ctx, grad_output):
433
433
out = grad_output.exp()
@@ -438,7 +438,7 @@ def backward(ctx, grad_output):
438
438
attn_layers = []
439
439
for idx in range(0, 2):
440
440
attn_layers.append(Exp())
441
-
441
+
442
442
for step in range(0, 2):
443
443
a = x
444
444
for j in range(0,2):
@@ -450,7 +450,7 @@ def backward(ctx, grad_output):
450
450
def mark_non_differentiable (self , * args ):
451
451
"""
452
452
Marks outputs as non-differentiable.
453
- This should be called at most once, only from inside the `forward` method,
453
+ This should be called at most once, only from inside the `forward` method,
454
454
and all arguments should be tensor outputs.
455
455
456
456
This will mark outputs as not requiring gradients, increasing the
@@ -542,30 +542,27 @@ def backward(ctx, grad, grad2):
542
542
543
543
544
544
class EagerPyLayerBackward (core .eager .PyLayer , EagerPyLayerContext ):
545
-
546
545
def backward (self , * args ):
547
546
return self ._forward_cls .backward (self , * args )
548
547
549
548
550
549
class EagerPyLayerMeta (type ):
551
-
552
550
def __init__ (cls , name , bases , attrs ):
553
- cls ._backward_function = type (name + '_backward' ,
554
- (EagerPyLayerBackward , ),
555
- { "_forward_cls" : cls } )
551
+ cls ._backward_function = type (
552
+ name + '_backward' , (EagerPyLayerBackward ,), { "_forward_cls" : cls }
553
+ )
556
554
557
555
return super (EagerPyLayerMeta , cls ).__init__ (name , bases , attrs )
558
556
559
557
560
558
class EagerPyLayer (
561
- with_mateclass (EagerPyLayerMeta , core .eager .PyLayer ,
562
- EagerPyLayerContext )):
563
-
559
+ with_mateclass (EagerPyLayerMeta , core .eager .PyLayer , EagerPyLayerContext )
560
+ ):
564
561
@staticmethod
565
562
def forward (ctx , * args , ** kwargs ):
566
563
"""
567
- It is to be overloaded by subclasses. It must accept a object of `PyLayerContext` as
568
- the first argument, followed by any number of arguments (tensors or other types).
564
+ It is to be overloaded by subclasses. It must accept a object of `PyLayerContext` as
565
+ the first argument, followed by any number of arguments (tensors or other types).
569
566
`None` can not be included in the returned result.
570
567
571
568
Args:
@@ -574,7 +571,7 @@ def forward(ctx, *args, **kwargs):
574
571
575
572
Returns:
576
573
tensors or other types : output of PyLayer.
577
-
574
+
578
575
Examples:
579
576
.. code-block:: python
580
577
@@ -597,14 +594,15 @@ def backward(ctx, dy):
597
594
return grad
598
595
"""
599
596
raise NotImplementedError (
600
- "You must implement the forward function for PyLayer." )
597
+ "You must implement the forward function for PyLayer."
598
+ )
601
599
602
600
@staticmethod
603
601
def backward (ctx , * args ):
604
602
"""
605
- This is a function to calculate the gradient. It is to be overloaded by subclasses.
606
- It must accept a object of `PyLayerContext` as the first argument, and the rest
607
- arguments are the gradient of forward's output tensors. Output tensors of backward
603
+ This is a function to calculate the gradient. It is to be overloaded by subclasses.
604
+ It must accept a object of `PyLayerContext` as the first argument, and the rest
605
+ arguments are the gradient of forward's output tensors. Output tensors of backward
608
606
are the gradient of forward's input tensors.
609
607
610
608
Args:
@@ -613,7 +611,7 @@ def backward(ctx, *args):
613
611
614
612
Returns:
615
613
Tensor or list of Tensors: The gradient of forward's input tensor(s).
616
-
614
+
617
615
Examples:
618
616
.. code-block:: python
619
617
@@ -637,11 +635,11 @@ def backward(ctx, dy):
637
635
"""
638
636
639
637
raise NotImplementedError (
640
- "You must implement the backward function for PyLayer." )
638
+ "You must implement the backward function for PyLayer."
639
+ )
641
640
642
641
643
642
def once_differentiable (backward ):
644
-
645
643
def wrapper (ctx , * args ):
646
644
with paddle .fluid .dygraph .no_grad ():
647
645
outputs = backward (ctx , * args )
0 commit comments