我正在努力处理来自带有 tf.boolean_mask 的 Flatten 层的自定义屏蔽输入。你能不能给我一个提示,为什么没有屏蔽产生(无,1024)输出?我将不胜感激任何帮助。
谢谢:)
class InputReduction(keras.layers.Layer):
def __init__(self, mask_idx):
super(InputReduction, self).__init__()
self.mask_idx = mask_idx
def call(self, inputs):
mask = np.array([True for _ in range(inputs.shape[1])])
for idx in self.mask_idx:
mask[idx] = False
print(mask)
inputs = tf.boolean_mask(inputs, mask)
print(inputs.shape)
return inputs
model = keras.models.Sequential([
keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=x_train.shape[1:]),
keras.layers.Conv2D(32, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Dropout(0.25),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Dropout(0.25),
keras.layers.Flatten(),
InputReduction(mask_idx=[1,2,3]),
keras.layers.Dense(512, activation = 'relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(num_classes, activation='softmax')
])
model.summary()
我的输出:
input_reduction_5 (InputRedu (None, 1024) 0
答案 0 :(得分:0)
您可能希望使用 tf.gather
而不是 tf.mask_boolean
。在所有解决方案中,inputs.shape
应为 [Batchsize, Channels]。
tf.mask(..., axis=1)
import tensorflow as tf
print('tf.__version__ =', tf.__version__)
class InputReduction(tf.keras.layers.Layer):
def __init__(self, mask_idx):
super(InputReduction, self).__init__()
self.mask_idx = mask_idx
def call(self, inputs):
batchsize, channels = inputs.shape
mask = tf.constant([True if i in self.mask_idx else False for i in range(channels)], dtype=tf.bool) # [C,]
tf.print('mask =', mask)
return tf.boolean_mask(inputs, mask, axis=1) # mask from axis=1 to ignore batchsize axis
x = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) # (3, 4)
print('x =', x)
y = InputReduction(mask_idx=[0, 2])(x)
print('y =', y)
输出
tf.__version__ = 2.4.1
x = tf.Tensor(
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]], shape=(3, 4), dtype=int32)
mask = [1 0 1 0]
y = tf.Tensor(
[[ 1 3]
[ 5 7]
[ 9 11]], shape=(3, 2), dtype=int32)
tf.reshape
输出import tensorflow as tf
print('tf.__version__ =', tf.__version__)
class InputReduction(tf.keras.layers.Layer):
def __init__(self, mask_idx):
super(InputReduction, self).__init__()
self.mask_idx = mask_idx
def call(self, inputs):
batchsize, channels = inputs.shape
mask = tf.constant([True if i in self.mask_idx else False for i in range(channels)], dtype=tf.bool) # [C,]
mask = tf.stack((mask,) * batchsize, axis=0)
tf.print('mask =', mask)
outputs = tf.boolean_mask(inputs, mask) # [Batchsize * N]
return tf.reshape(outputs, (batchsize, -1)) # [Batchsize, N]
x = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) # (3, 4)
print('x =', x)
y = InputReduction(mask_idx=[0, 2])(x)
print('y =', y)
输出
tf.__version__ = 2.4.1
x = tf.Tensor(
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]], shape=(3, 4), dtype=int32)
mask = [[1 0 1 0]
[1 0 1 0]
[1 0 1 0]]
y = tf.Tensor(
[[ 1 3]
[ 5 7]
[ 9 11]], shape=(3, 2), dtype=int32)
tf.gather
(推荐)不需要口罩。
import tensorflow as tf
print('tf.__version__ =', tf.__version__)
class InputReduction(tf.keras.layers.Layer):
def __init__(self, mask_idx):
super(InputReduction, self).__init__()
self.mask_idx = mask_idx
def call(self, inputs):
return tf.gather(inputs, self.mask_idx, axis=1)
x = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) # (3, 4)
print('x =', x)
y = InputReduction(mask_idx=[0, 2])(x)
print('y =', y)
输出
tf.__version__ = 2.4.1
x = tf.Tensor(
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]], shape=(3, 4), dtype=int32)
y = tf.Tensor(
[[ 1 3]
[ 5 7]
[ 9 11]], shape=(3, 2), dtype=int32)
https://www.tensorflow.org/api_docs/python/tf/boolean_mask
https://www.tensorflow.org/api_docs/python/tf/gather
答案 1 :(得分:-1)
一开始你创建了你定义层的一个实例并传递了一个列表:
keras.layers.Flatten(),
InputReduction(mask_idx=[1,2,3]), # <---
keras.layers.Dense(512, activation = 'relu'),
在构造函数中,列表已保存。
class InputReduction(keras.layers.Layer):
def __init__(self, mask_idx):
super(InputReduction, self).__init__()
self.mask_idx = mask_idx # <---
在调用中,您遍历了这个包含三个数字 [1, 2, 3]
的列表并将值设置为 False
:
def call(self, inputs):
mask = np.array([True for _ in range(inputs.shape[1])])
for idx in self.mask_idx: # <--- `[1, 2, 3]`
mask[idx] = False
结果是……
[True, False, False, False, True, True, True, True, True, True, ...]
最后 tf.boolean_mask
缩小输出:
tensor = [0, 1, 2, 3] # 1-D example
mask = np.array([True, False, True, False])
tf.boolean_mask(tensor, mask)
# <tf.Tensor: shape=(2,), dtype=int32, numpy=array([0, 2], dtype=int32)>
来源:https://www.tensorflow.org/api_docs/python/tf/boolean_mask
从技术上讲,这应该可行,但覆盖输入没有意义。所以我的问题是:你想做什么?这个自定义图层你想要的结果是什么?这是紧跟在 Flatten
层之后的地方吗?