从keras中的展开张量生成输入特征映射

2024-05-15 02:45:04 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

Taylor expansion of 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需要堆叠,这是我在上面的尝试中没有正确完成的,而且我的代码也没有很好地通用化。如何以正确的实现方式改进上述编码尝试?有谁能给我可能的想法或规范的答案来改进我目前的尝试吗


Tags: 图像编码tftensorflowresmath像素特征
1条回答
网友
1楼 · 发布于 2024-05-15 02:45:04

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

下面是在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)

网络的其余部分与不进行扩展时完全相同

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

model.summary()的输出如下所示:

__________________________________________________________________________________________________
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)每个输入通道的扩展是独立的,因此,扩展为T项的C输入通道每个产生C*T输入特征,但每个通道的T特征完全独立于其他通道计算(如图中所示),并且(3)输入包含所有部分和(即C_1*x^p_1、C_1*x^p_1+C_2*x^p_2等等)但不包含术语(同样,在图表中看起来是这样的)

相关问题 更多 >

    热门问题