28
28
import copy
29
29
30
30
__all__ = ["full_matrix_projection" , "AggregateLevel" , "ExpandLevel" ,
31
- "identity_projection" , "dotmul_projection" ,
31
+ "identity_projection" , "dotmul_projection" , "dotmul_operator" ,
32
32
"table_projection" , "mixed_layer" , "data_layer" ,
33
33
"embedding_layer" , "fc_layer" , "grumemory" ,
34
34
"pooling_layer" , "lstmemory" , "last_seq" , "first_seq" ,
@@ -389,7 +389,7 @@ def identity_projection(input, offset=None):
389
389
@wrap_param_attr_default ()
390
390
def dotmul_projection (input , param_attr = None , scale = 1 ):
391
391
"""
392
- 1. DotMulProjection if input is a layer.
392
+ DotMulProjection with a layer as input .
393
393
It performs element-wise multiplication with weight.
394
394
395
395
.. math::
@@ -403,48 +403,45 @@ def dotmul_projection(input, param_attr=None, scale=1):
403
403
404
404
proj = dotmul_projection(input=layer)
405
405
406
- 2. DotMulOperator if input is a list or tuple.
407
- It takes two inputs, performs element-wise multiplication:
408
-
409
- .. math::
410
- out.row[i] += scale * (in1.row[i] .* in2.row[i])
411
-
412
- where :math:`.*` means element-wise multiplication, and
413
- scale is a config scalar, its default value is one.
414
-
415
- The example usage is:
416
-
417
- .. code-block:: python
418
-
419
- op = dotmul_projection(input=[layer1, layer2],
420
- scale=2.0)
421
-
422
406
:param input: Input layer.
423
- :type input: LayerOutput|list|tuple
407
+ :type input: LayerOutput
424
408
:param param_attr: Parameter config, None if use default.
425
409
:type param_attr: ParameterAttribute
426
410
:param scale: config scalar, default value is one.
427
411
:type scale: float
428
- :return: A DotMulProjection or DotMulOperator Object.
429
- :rtype: DotMulProjection or DotMulOperator
412
+ :return: A DotMulProjection Object.
413
+ :rtype: DotMulProjection
430
414
"""
431
- if isinstance (input , LayerOutput ):
432
- proj = DotMulProjection (input_layer_name = input .name ,
415
+ proj = DotMulProjection (input_layer_name = input .name ,
433
416
size = input .size ,
434
417
** param_attr .attr )
435
- proj .origin = input
436
- proj .origin .projection = "dot_mul"
437
- return proj
438
- else :
439
- assert isinstance (input , list ) or isinstance (input , tuple )
440
- assert len (input ) == 2
441
- assert param_attr is None
442
- op = DotMulOperator (input_layer_name = [x .name for x in input ],
443
- scale = scale )
444
- op .origin = input
445
- op .origin .operator = "dot_mul"
446
- return op
418
+ proj .origin = input
419
+ return proj
447
420
421
+ def dotmul_operator (x , y , scale = 1 ):
422
+ """
423
+ DotMulOperator takes two inputs and performs element-wise multiplication:
424
+ .. math::
425
+ out.row[i] += scale * (in1.row[i] .* in2.row[i])
426
+ where :math:`.*` means element-wise multiplication, and
427
+ scale is a config scalar, its default value is one.
428
+ The example usage is:
429
+ .. code-block:: python
430
+ op = dotmul_operator(x, y,
431
+ scale=1)
432
+ :param input: Input layer
433
+ :type input: LayerOutput
434
+ :param scale: config scalar, default value is one.
435
+ :type scale: float
436
+ :return: A DotMulOperator Object.
437
+ :rtype: DotMulOperator
438
+ """
439
+ assert isinstance (x , LayerOutput )
440
+ assert isinstance (y , LayerOutput )
441
+ op = DotMulOperator (input_layer_names = [x .name , y .name ],
442
+ scale = scale )
443
+ op .origin = [x , y ]
444
+ return op
448
445
449
446
@wrap_bias_attr_default (['padding_attr' ])
450
447
def context_projection (input , context_len , context_start = None ,
@@ -539,7 +536,10 @@ def __add__(self, other):
539
536
if not self .finalized :
540
537
assert isinstance (other , Projection ) or isinstance (other , Operator )
541
538
self .inputs .append (other )
542
- self .parents .append (other .origin )
539
+ if isinstance (other , Projection ):
540
+ self .parents .append (other .origin )
541
+ else :
542
+ self .parents .extend (other .origin )
543
543
return self
544
544
else :
545
545
raise MixedLayerType .AddToSealedMixedLayerException ()
@@ -565,7 +565,7 @@ def __exit__(self, *args, **kwargs):
565
565
@wrap_act_default (act = LinearActivation ())
566
566
@wrap_bias_attr_default (has_bias = False )
567
567
@layer_support (ERROR_CLIPPING , DROPOUT )
568
- def mixed_layer (size , input = None , name = None , act = None , bias_attr = False ,
568
+ def mixed_layer (size = 0 , input = None , name = None , act = None , bias_attr = False ,
569
569
layer_attr = None ):
570
570
"""
571
571
Mixed Layer. A mixed layer will add all inputs together, then activate.
0 commit comments