我正在尝试实现一个自定义的dropout层。在这个dropout层中,我希望生成一个随机数来开启或关闭输出。这个想法很简单,我以为实现起来也会很容易。
我尝试使用常规的Python ‘random’函数,但这只是不断生成相同的输出。我也尝试使用tf.random.uniform(),但这在尝试索引numpy数组时会导致错误。
NotImplementedError: 无法将符号tf.Tensor (add:0)转换为numpy数组。此错误可能表明您正试图将Tensor传递给不支持的NumPy调用。
我尝试从张量中提取值,以便我可以索引数组,但转换为int没有任何效果,它的类型仍然是张量。但是,当我在Jupyter Notebook中运行代码而不是在实际层中时,它可以正常工作,并且符合我的预期。
def call(self, inputs, *args, **kwargs): if isinstance(self.level_size, numbers.Real) and self.level_size == 0: return tf.identity(inputs) return tf.math.multiply(tf.identity(inputs), self.create_mask(inputs[0]))@tf.function #<== 我不知道这是做什么用的。我尝试过添加和删除它def create_mask(self, input_tensor): self.seed += 1 self.rand.seed(self.seed) #<== 常规的Python随机数 arr = np.full(input_tensor.get_shape().as_list()[0], 0, dtype='float32') for i in range(0, len(arr), self.level_size): temp = self.rand.randint(0, self.level_size - 1) # temp = tf.random.uniform(shape=(), minval=0, maxval=self.level_size, dtype='int32') arr[i + temp] = self.scalar if not self.use_all_nodes else 1 # arr[i + int(temp)] = self.scalar if not self.use_all_nodes else 1 tf.print(arr) arr = arr[None, :] return tf.convert_to_tensor(arr)
回答:
这是我的解决方案。这只是一个选项。TensorFlow中没有专门的函数来创建随机整数,所以我使用了tf.random.categorical
。我没有测试速度,只是想找到一个解决方案。
注意:我的输入张量是二维的,形状为(num_samples, num_features)
。在您的应用中,您可能需要一个形状为(batch_size, num_samples, num_features)
的张量,但您应该能够相应地更改代码。
这是我的代码:
class SliceMasker: def __init__(self, num_samples, num_features, step_size): self.pseudo_logits = tf.ones(shape=(1, step_size)) self.num_masked = num_samples//step_size self.offsets = tf.expand_dims( tf.range(self.num_masked) * step_size, axis=0) self.mask = tf.zeros((self.num_masked, num_features)) def mask_slices(self, tensor): slice_ids = tf.random.categorical( self.pseudo_logits, 4, dtype=tf.int32) slice_ids = tf.reshape(slice_ids + self.offsets, (self.num_masked, 1)) return tf.tensor_scatter_nd_update(tensor, slice_ids, self.mask)num_samples = 20num_features = 3step_size = 5sm = SliceMasker(num_samples, num_features, step_size)example = tf.random.normal(shape=(num_samples, num_features))print("遮蔽前:")print(example.numpy())masked = sm.mask_slices(example)print("遮蔽后:")print(masked.numpy())
输出:
遮蔽前:[[ 0.2977529 -1.0069662 0.18448827] [ 1.4570498 0.416826 -1.9352742 ] [ 0.1615839 -0.0706018 0.79011333] [ 0.1402558 -1.285141 -0.2618603 ] [ 2.360426 -0.5306141 0.02061797] [ 0.6496891 0.02275689 -0.10618226] [ 0.5680644 -0.5271083 1.4394306 ] [-0.62021923 -0.49577036 -0.9902582 ] [-0.47593793 1.0605363 -0.13049011] [ 1.4284478 0.43213463 -0.55216306] [ 0.32337463 1.4737866 0.21306337] [-1.3215414 0.47005925 -0.7038767 ] [-1.2404966 1.548273 -0.77220184] [-1.0531787 0.17857324 -0.28259423] [ 0.30251816 0.2874606 0.31080458] [-0.4658653 -0.4285968 1.1454991 ] [-0.87822616 -1.8857303 -0.3963113 ] [ 0.2780536 -0.6733958 0.11874776] [-3.01591 -0.7286207 -1.9439988 ] [-0.01809683 -0.38306755 -1.4614321 ]]遮蔽后:[[ 0.2977529 -1.0069662 0.18448827] [ 0. 0. 0. ] [ 0.1615839 -0.0706018 0.79011333] [ 0.1402558 -1.285141 -0.2618603 ] [ 2.360426 -0.5306141 0.02061797] [ 0.6496891 0.02275689 -0.10618226] [ 0. 0. 0. ] [-0.62021923 -0.49577036 -0.9902582 ] [-0.47593793 1.0605363 -0.13049011] [ 1.4284478 0.43213463 -0.55216306] [ 0. 0. 0. ] [-1.3215414 0.47005925 -0.7038767 ] [-1.2404966 1.548273 -0.77220184] [-1.0531787 0.17857324 -0.28259423] [ 0.30251816 0.2874606 0.31080458] [-0.4658653 -0.4285968 1.1454991 ] [-0.87822616 -1.8857303 -0.3963113 ] [ 0.2780536 -0.6733958 0.11874776] [-3.01591 -0.7286207 -1.9439988 ] [ 0. 0. 0. ]]
我希望这是您想要的功能。请告诉我是否合适。如果不合适,我会尝试修改它。