如何将Python函数列表应用于Tensor并通过tf.reduce_sum保持形状
Got it, let's break down how to solve this problem step by step. First, there's a critical Python pitfall to watch out for with your lambda list, then we'll handle the TensorFlow part to apply each function and sum the results while keeping the output shape matching X.
Your initial fn_list = [lambda x: x + 2 for x in some_data] has a hidden issue: Python lambdas use late binding for variables in the closure. This means all lambdas in the list will reference the final value of x from the loop, not the value when each lambda was created.
To fix this, explicitly bind the loop variable to each lambda using a default parameter, or use functools.partial for clearer code:
# Option 1: Use default parameters to bind the current value some_data = [2, 3, 4] # Example data fn_list = [lambda x, val=i: x + val for i in some_data] # Option 2: Use functools.partial (more readable for complex functions) from functools import partial def add_val(x, val): return x + val fn_list = [partial(add_val, val=i) for i in some_data]
Both approaches ensure each lambda in fn_list behaves as expected, using the unique value from some_data it was created with.
We need to apply every function in fn_list to each element in the None (batch) dimension of X, sum the results per element, and keep the output shape [None, 1] matching X.
Here's a clean implementation using tf.map_fn to iterate over the batch dimension:
import tensorflow as tf # Assume we've already fixed fn_list as above some_data = [2, 3, 4] fn_list = [lambda x, val=i: x + val for i in some_data] # Define your placeholder X = tf.placeholder(tf.float32, shape=[None, 1]) # Define a helper function to process one element from X def process_single_element(x): # x is a shape [1] tensor; convert to scalar first x_scalar = tf.squeeze(x) # Apply all functions in fn_list to the scalar function_results = [fn(x_scalar) for fn in fn_list] # Stack results into a single tensor and sum them summed_result = tf.reduce_sum(tf.stack(function_results, axis=0)) # Convert back to shape [1] to match input element shape return tf.expand_dims(summed_result, axis=0) # Apply the helper function to every element in X output = tf.map_fn(process_single_element, X)
How it works:
tf.map_fniterates over the first dimension (batch size,None) ofX, passing each shape[1]element toprocess_single_element.- Inside the helper, we convert the input to a scalar for easier function application, stack all function results into a 1D tensor, then sum them.
- We convert the summed scalar back to a shape
[1]tensor, sotf.map_fnreturns an output tensor with the same shape asX:[None, 1].
Let's verify with sample input:
with tf.Session() as sess: test_input = [[1], [5], [10]] result = sess.run(output, feed_dict={X: test_input}) print(result)
Expected output:
[[12.] [24.] [39.]]
Which matches the manual calculation:
- For
1:(1+2)+(1+3)+(1+4) = 3+4+5 = 12 - For
5:(5+2)+(5+3)+(5+4) =7+8+9=24 - For
10:(10+2)+(10+3)+(10+4)=12+13+14=39
内容的提问来源于stack exchange,提问作者Bogdan Buduroiu

