@@ -87,6 +87,51 @@ public static Tensor reduced_shape(Tensor input_shape, Tensor axes)
8787 return gen_data_flow_ops . dynamic_stitch ( a1 , a2 ) ;
8888 }
8989
90+ /// <summary>
91+ /// Computes log(sum(exp(elements across dimensions of a tensor))).
92+ /// Reduces `input_tensor` along the dimensions given in `axis`.
93+ /// Unless `keepdims` is true, the rank of the tensor is reduced by 1 for each
94+ /// entry in `axis`. If `keepdims` is true, the reduced dimensions
95+ /// are retained with length 1.
96+
97+ /// If `axis` has no entries, all dimensions are reduced, and a
98+ /// tensor with a single element is returned.
99+
100+ /// This function is more numerically stable than log(sum(exp(input))). It avoids
101+ /// overflows caused by taking the exp of large inputs and underflows caused by
102+ /// taking the log of small inputs.
103+ /// </summary>
104+ /// <param name="input_tensor"> The tensor to reduce. Should have numeric type.</param>
105+ /// <param name="axis"> The dimensions to reduce. If `None` (the default), reduces all
106+ /// dimensions.Must be in the range `[-rank(input_tensor), rank(input_tensor))`.</param>
107+ /// <param name="keepdims"></param>
108+ /// <returns> The reduced tensor.</returns>
109+ public static Tensor reduce_logsumexp ( Tensor input_tensor , int [ ] axis = null , bool keepdims = false , string name = null )
110+ {
111+ with ( ops . name_scope ( name , "ReduceLogSumExp" , new { input_tensor } ) , scope =>
112+ {
113+ var raw_max = reduce_max ( input_tensor , axis , true ) ;
114+ var my_max = array_ops . stop_gradient ( array_ops . where ( gen_math_ops . is_finite ( raw_max ) , raw_max , array_ops . zeros_like ( raw_max ) ) ) ;
115+ var result = gen_math_ops . log (
116+ reduce_sum (
117+ gen_math_ops . exp ( gen_math_ops . sub ( input_tensor , my_max ) ) ,
118+ new Tensor ( axis ) ,
119+ keepdims ) ) ;
120+ if ( ! keepdims )
121+ {
122+ my_max = array_ops . reshape ( my_max , array_ops . shape ( result ) ) ;
123+ }
124+ result = gen_math_ops . add ( result , my_max ) ;
125+ return _may_reduce_to_scalar ( keepdims , axis , result ) ;
126+ } ) ;
127+ return null ;
128+ }
129+
130+ public static Tensor reduce_max ( Tensor input_tensor , int [ ] axis = null , bool keepdims = false , string name = null )
131+ {
132+ return _may_reduce_to_scalar ( keepdims , axis , gen_math_ops . _max ( input_tensor , ( int [ ] ) _ReductionDims ( input_tensor , axis ) , keepdims , name ) ) ;
133+ }
134+
90135 /// <summary>
91136 /// Casts a tensor to type `int32`.
92137 /// </summary>
0 commit comments