繁体   English   中英

从 keras 中的扩展张量制作输入特征 map

[英]make input features map from expansion tensor in keras

我在图像分类任务中使用了泰勒展开。 基本上,首先,像素向量是从 RGB 图像生成的,并且来自像素向量的每个像素值将用sin(x)的泰勒级数展开来近似。 在 tensorflow 实现中,我尝试使用 tensorflow 进行编码,当我尝试通过将张量与扩展项叠加来创建特征图时,我仍然遇到一些问题。 谁能提供可能的观点,我怎样才能使我目前的尝试更有效率? 有什么可能的想法吗?

这是sin(x)的泰勒级数的展开项:

sin(x) 的泰勒展开式

这是我目前的尝试:

term = 2
c = tf.constant([1, -1/6])
power = tf.constant([1, 3])

x = tf.keras.Input(shape=(32, 32, 3))
res =[]
for x in range(term):
    expansion = c * tf.math.pow(tf.tile(x[..., None], [1, 1, 1, 1, term]),power)
    m_ij = tf.math.cumsum(expansion, axis=-1)
    res.append(m_i)

但这不太有效,因为我想从每个扩展神经元创建输入特征图, delta_1delta_2需要堆叠,我在上面的尝试中没有正确进行,而且我的代码也没有很好地概括。 如何以正确的实施方式改进上述编码尝试? 任何人都可以给我可能的想法或规范的答案来改进我目前的尝试吗?

如果按照所述进行级数扩展,如果输入具有 C 通道并且扩展具有 T 项,则扩展输入应具有 C*T 通道,否则形状相同。 因此,原始输入和被近似到每个项的 function 应该沿着通道维度连接。 使用转置和重塑比实际连接更容易做到这一点。

以下是在 CIFAR10 上训练的卷积网络的示例代码:

inputs = tf.keras.Input(shape=(32, 32, 3))

x = inputs
n_terms = 2
c = tf.constant([1, -1/6])
p = tf.constant([1, 3], dtype=tf.float32)

terms = []
for i in range(n_terms):
    m = c[i] * tf.math.pow(x, p[i])
    terms.append(m)
expansion = tf.math.cumsum(terms)
expansion_terms_last = tf.transpose(expansion, perm=[1, 2, 3, 4, 0])
x = tf.reshape(expansion_terms_last, tf.constant([-1, 32, 32, 3*n_terms])) 

x = Conv2D(32, (3, 3), input_shape=(32,32,3*n_terms))(x)

这假设原始网络(没有扩展)将具有如下所示的第一层:

x = Conv2D(32, (3, 3), input_shape=(32,32,3))(inputs)

和网络的rest完全一样,没有扩展。

terms包含原始的 c_i * x ^ p_i 列表; expansion包含单个张量(其中 T 是第一个维度)中的项(第一个,然后是第一个和第二个等)的总和 expansion_terms_last将 T 维度移动到最后,并且 reshape 将形状从(..., C, T)更改为(..., C*T)

model.summary()的 output 然后看起来像这样:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_4 (InputLayer)            [(None, 32, 32, 3)]  0                                            
__________________________________________________________________________________________________
tf_op_layer_Pow_6 (TensorFlowOp [(None, 32, 32, 3)]  0           input_4[0][0]                    
__________________________________________________________________________________________________
tf_op_layer_Pow_7 (TensorFlowOp [(None, 32, 32, 3)]  0           input_4[0][0]                    
__________________________________________________________________________________________________
tf_op_layer_Mul_6 (TensorFlowOp [(None, 32, 32, 3)]  0           tf_op_layer_Pow_6[0][0]          
__________________________________________________________________________________________________
tf_op_layer_Mul_7 (TensorFlowOp [(None, 32, 32, 3)]  0           tf_op_layer_Pow_7[0][0]          
__________________________________________________________________________________________________
tf_op_layer_x_3 (TensorFlowOpLa [(2, None, 32, 32, 3 0           tf_op_layer_Mul_6[0][0]          
                                                                 tf_op_layer_Mul_7[0][0]          
__________________________________________________________________________________________________
tf_op_layer_Cumsum_3 (TensorFlo [(2, None, 32, 32, 3 0           tf_op_layer_x_3[0][0]            
__________________________________________________________________________________________________
tf_op_layer_Transpose_3 (Tensor [(None, 32, 32, 3, 2 0           tf_op_layer_Cumsum_3[0][0]       
__________________________________________________________________________________________________
tf_op_layer_Reshape_3 (TensorFl [(None, 32, 32, 6)]  0           tf_op_layer_Transpose_3[0][0]    
__________________________________________________________________________________________________
conv2d_5 (Conv2D)               (None, 30, 30, 32)   1760        tf_op_layer_Reshape_3[0][0]      

在 CIFAR10 上,该网络在扩展时训练得稍微好一些——准确率可能提高 1%(从 71% 到 72%)。

使用示例数据逐步解释代码:

# create a sample input
x = tf.convert_to_tensor([[1,2,3],[4,5,6],[7,8,9]], dtype=tf.float32) # start with H=3, W=3
x = tf.expand_dims(x, axis=0) # add batch dimension N=1
x = tf.expand_dims(x, axis=3) # add channel dimension C=1
# x is now NHWC or (1, 3, 3, 1)

n_terms = 2 # expand to T=2
c = tf.constant([1, -1/6])
p = tf.constant([1, 3], dtype=tf.float32)

terms = []
for i in range(n_terms):
    # this simply calculates m = c_i * x ^ p_i
    m = c[i] * tf.math.pow(x, p[i])
    terms.append(m)
print(terms)
# list of two tensors with shape NHWC or (1, 3, 3, 1)

# calculate each partial sum
expansion = tf.math.cumsum(terms)
print(expansion.shape)
# tensor with shape TNHWC or (2, 1, 3, 3, 1)

# move the T dimension last
expansion_terms_last = tf.transpose(expansion, perm=[1, 2, 3, 4, 0])
print(expansion_terms_last.shape)
# tensor with shape NHWCT or (1, 3, 3, 1, 2)

# stack the last two dimensions together
x = tf.reshape(expansion_terms_last, tf.constant([-1, 3, 3, 1*2])) 
print(x.shape)
# tensor with shape NHW and C*T or (1, 3, 3, 2)
# if the input had 3 channels for example, this would be (1, 3, 3, 6)
# now use this as though it was the input

关键假设(1) c_i 和 p_i 不是学习参数,因此“扩展神经元”实际上不是神经元,它们只是一个乘法和求和节点(尽管神经元听起来更酷:)和 (2) 扩展发生在每个输入通道独立,因此 C 输入通道扩展为 T 项,每个产生 C*T 输入特征,但每个通道的 T 特征完全独立于其他通道计算(如图所示),以及(3)输入包含所有部分和(即 c_1 * x ^ p_1、c_1 * x ^ p_1 + c_2 * x ^ p_2 等等)但不包含项(再次,看起来像在图中)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM