Tensorflow 2.8.0 - 自定义层不适用于 tf.map_fn(tf.range,...)
Tensorflow 2.8.0 - Custom layer doesn't work out with tf.map_fn(tf.range,...)
亲爱的 Whosebug 社区,
我目前正在尝试创建一个自定义层,该层将整数输入的每个值转换为长度为“omega”的向量。目前,我将 tensorflow 函数 tf.map_fn 与函数 tf.range 结合起来,创建一个参差不齐的张量,然后用零填充该张量。
自定义图层定义如下:
class ReshapeLayer(Layer):
def __init__(self, omega):
super(ReshapeLayer, self).__init__()
# length of outputvector
self.omega = omega
def call(self, inputs, training=False):
inputs = tf.cast(inputs, 'int32') #list of positive integer values
print(inputs.shape) #(None, 1)
output = tf.map_fn(tf.range, inputs, fn_output_signature=tf.RaggedTensorSpec(shape=[None])) #ERROR MESSAGE
output = output.to_tensor(0,shape=[None,1,self.omega])
return output
我得到的错误信息如下:
ValueError: Exception encountered when calling layer "reshape_layer" (type ReshapeLayer).
in user code:
File "C:\Users\User\AppData\Local\Temp\ipykernel_1390449166236.py", line 13, in call *
output = tf.map_fn(tf.range, inputs, fn_output_signature=tf.RaggedTensorSpec(shape=[None])) #ERROR MESSAGE
ValueError: Shape must be rank 0 but is rank 1
for 'limit' for '{{node reshape_layer/map/while/range}} = Range[Tidx=DT_INT32](reshape_layer/map/while/range/start, reshape_layer/map/while/TensorArrayV2Read/TensorListGetItem, reshape_layer/map/while/range/delta)' with input shapes: [], [1], [].
Call arguments received:
• inputs=tf.Tensor(shape=(None, 1), dtype=float32)
• training=False
我试过的是:
-) 我尝试更改输入 -> 输入 [:,1],但这只会将错误消息更改为
ValueError: Exception encountered when calling layer "reshape_layer_3" (type ReshapeLayer).
in user code:
File "C:\Users\User\AppData\Local\Temp\ipykernel_1390417026906.py", line 13, in call *
output = tf.map_fn(tf.range, inputs[:,1], fn_output_signature=tf.RaggedTensorSpec(shape=[None])) #ERROR MESSAGE
ValueError: slice index 1 of dimension 1 out of bounds. for '{{node reshape_layer_3/strided_slice}} = StridedSlice[Index=DT_INT32, T=DT_INT32, begin_mask=1, ellipsis_mask=0, end_mask=1, new_axis_mask=0, shrink_axis_mask=2](reshape_layer_3/Cast, reshape_layer_3/strided_slice/stack, reshape_layer_3/strided_slice/stack_1, reshape_layer_3/strided_slice/stack_2)' with input shapes: [?,1], [2], [2], [2] and with computed input tensors: input[1] = <0 1>, input[2] = <0 2>, input[3] = <1 1>.
Call arguments received:
• inputs=tf.Tensor(shape=(None, 1), dtype=float32)
• training=False
示例:
输入的形式应为 (shape=[None,1]):
示例:
omega = 10
input:
x = [[5],[2],[3],[6]]
output:
y = [[0,1,2,3,4,0,0,0,0,0],
[0,1,0,0,0,0,0,0,0,0],
[0,1,2,0,0,0,0,0,0,0],
[0,1,2,3,4,5,0,0,0,0]]
有人知道这个问题的解决方案吗?
尝试使用 tf.while_loop
和 tf.tensor_scatter_nd_update
:
import tensorflow as tf
class ReshapeLayer(tf.keras.layers.Layer):
def __init__(self, omega):
super(ReshapeLayer, self).__init__()
# length of outputvector
self.omega = omega
def call(self, inputs, training=False):
def body(i, x, zeros):
r = tf.range(x[i][0], dtype=tf.int32)
repeats = tf.repeat([i], tf.shape(r)[0])
zeros = tf.tensor_scatter_nd_update(zeros, tf.stack([repeats, r], axis=1), r)
return tf.add(i, 1), x, zeros
zeros = tf.zeros((tf.shape(inputs)[0], self.omega), dtype=tf.int32)
i = tf.constant(0)
condition = lambda i, inputs, zeros: tf.less(i, tf.shape(inputs)[0])
_, _, output = tf.while_loop(condition, body, loop_vars=[i, inputs, zeros])
return output
omega = 10
x = tf.constant([[5],[2],[3],[6]])
inputs = tf.keras.layers.Input((1,))
reshape_layer = ReshapeLayer(omega=omega)
outputs = reshape_layer(inputs)
model = tf.keras.Model(inputs, outputs)
print(model(x))
tf.Tensor(
[[0 1 2 3 4 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]
[0 1 2 0 0 0 0 0 0 0]
[0 1 2 3 4 5 0 0 0 0]], shape=(4, 10), dtype=int32)
亲爱的 Whosebug 社区,
我目前正在尝试创建一个自定义层,该层将整数输入的每个值转换为长度为“omega”的向量。目前,我将 tensorflow 函数 tf.map_fn 与函数 tf.range 结合起来,创建一个参差不齐的张量,然后用零填充该张量。
自定义图层定义如下:
class ReshapeLayer(Layer):
def __init__(self, omega):
super(ReshapeLayer, self).__init__()
# length of outputvector
self.omega = omega
def call(self, inputs, training=False):
inputs = tf.cast(inputs, 'int32') #list of positive integer values
print(inputs.shape) #(None, 1)
output = tf.map_fn(tf.range, inputs, fn_output_signature=tf.RaggedTensorSpec(shape=[None])) #ERROR MESSAGE
output = output.to_tensor(0,shape=[None,1,self.omega])
return output
我得到的错误信息如下:
ValueError: Exception encountered when calling layer "reshape_layer" (type ReshapeLayer).
in user code:
File "C:\Users\User\AppData\Local\Temp\ipykernel_1390449166236.py", line 13, in call *
output = tf.map_fn(tf.range, inputs, fn_output_signature=tf.RaggedTensorSpec(shape=[None])) #ERROR MESSAGE
ValueError: Shape must be rank 0 but is rank 1
for 'limit' for '{{node reshape_layer/map/while/range}} = Range[Tidx=DT_INT32](reshape_layer/map/while/range/start, reshape_layer/map/while/TensorArrayV2Read/TensorListGetItem, reshape_layer/map/while/range/delta)' with input shapes: [], [1], [].
Call arguments received:
• inputs=tf.Tensor(shape=(None, 1), dtype=float32)
• training=False
我试过的是:
-) 我尝试更改输入 -> 输入 [:,1],但这只会将错误消息更改为
ValueError: Exception encountered when calling layer "reshape_layer_3" (type ReshapeLayer).
in user code:
File "C:\Users\User\AppData\Local\Temp\ipykernel_1390417026906.py", line 13, in call *
output = tf.map_fn(tf.range, inputs[:,1], fn_output_signature=tf.RaggedTensorSpec(shape=[None])) #ERROR MESSAGE
ValueError: slice index 1 of dimension 1 out of bounds. for '{{node reshape_layer_3/strided_slice}} = StridedSlice[Index=DT_INT32, T=DT_INT32, begin_mask=1, ellipsis_mask=0, end_mask=1, new_axis_mask=0, shrink_axis_mask=2](reshape_layer_3/Cast, reshape_layer_3/strided_slice/stack, reshape_layer_3/strided_slice/stack_1, reshape_layer_3/strided_slice/stack_2)' with input shapes: [?,1], [2], [2], [2] and with computed input tensors: input[1] = <0 1>, input[2] = <0 2>, input[3] = <1 1>.
Call arguments received:
• inputs=tf.Tensor(shape=(None, 1), dtype=float32)
• training=False
示例:
输入的形式应为 (shape=[None,1]): 示例:
omega = 10
input:
x = [[5],[2],[3],[6]]
output:
y = [[0,1,2,3,4,0,0,0,0,0],
[0,1,0,0,0,0,0,0,0,0],
[0,1,2,0,0,0,0,0,0,0],
[0,1,2,3,4,5,0,0,0,0]]
有人知道这个问题的解决方案吗?
尝试使用 tf.while_loop
和 tf.tensor_scatter_nd_update
:
import tensorflow as tf
class ReshapeLayer(tf.keras.layers.Layer):
def __init__(self, omega):
super(ReshapeLayer, self).__init__()
# length of outputvector
self.omega = omega
def call(self, inputs, training=False):
def body(i, x, zeros):
r = tf.range(x[i][0], dtype=tf.int32)
repeats = tf.repeat([i], tf.shape(r)[0])
zeros = tf.tensor_scatter_nd_update(zeros, tf.stack([repeats, r], axis=1), r)
return tf.add(i, 1), x, zeros
zeros = tf.zeros((tf.shape(inputs)[0], self.omega), dtype=tf.int32)
i = tf.constant(0)
condition = lambda i, inputs, zeros: tf.less(i, tf.shape(inputs)[0])
_, _, output = tf.while_loop(condition, body, loop_vars=[i, inputs, zeros])
return output
omega = 10
x = tf.constant([[5],[2],[3],[6]])
inputs = tf.keras.layers.Input((1,))
reshape_layer = ReshapeLayer(omega=omega)
outputs = reshape_layer(inputs)
model = tf.keras.Model(inputs, outputs)
print(model(x))
tf.Tensor(
[[0 1 2 3 4 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]
[0 1 2 0 0 0 0 0 0 0]
[0 1 2 3 4 5 0 0 0 0]], shape=(4, 10), dtype=int32)