我正在基于这个例子构建一个适合我自己数据的CNN。
基本上,我的数据有3640个特征;我有一个卷积层后面跟着一个池化层,池化层每隔一个特征进行池化,所以我最终得到的维度是(?, 1, 1819, 1),因为卷积层后的3638个特征除以2等于1819。
当我尝试在池化后重塑我的数据以使其符合[n_samples, n_features]的形式时
print("pool_shape", pool_shape) #pool (?, 1, 1819, 10) print("y_shape", y_shape) #y (?,) pool.set_shape([pool_shape[0], pool_shape[2]*pool_shape[3]]) y.set_shape([y_shape[0], 1])
我得到了一个错误:
ValueError: Shapes (?, 1, 1819, 10) and (?, 18190) are not compatible
我的代码如下:
N_FEATURES = 140*26N_FILTERS = 1WINDOW_SIZE = 3def my_conv_model(x, y): x = tf.cast(x, tf.float32) y = tf.cast(y, tf.float32) print("x ", x.get_shape()) print("y ", y.get_shape()) # 形成一个形状为 batch_size x 1 x N_FEATURES x 1 的4D张量 x = tf.reshape(x, [-1, 1, N_FEATURES, 1]) # 这将给你一个1 x WINDOW_SIZE的滑动窗口卷积。 features = tf.contrib.layers.convolution2d(inputs=x, num_outputs=N_FILTERS, kernel_size=[1, WINDOW_SIZE], padding='VALID') print("features ", features.get_shape()) #features (?, 1, 3638, 10) # 在卷积+Relu的输出上进行最大池化。 pool = tf.nn.max_pool(features, ksize=[1, 1, 2, 1], strides=[1, 1, 2, 1], padding='SAME') pool_shape = pool.get_shape() y_shape = y.get_shape() print("pool_shape", pool_shape) #pool (?, 1, 1819, 10) print("y_shape", y_shape) #y (?,)### 这里出现错误 ### pool.set_shape([pool_shape[0], pool_shape[2]*pool_shape[3]]) y.set_shape([y_shape[0], 1]) pool_shape = pool.get_shape() y_shape = y.get_shape() print("pool_shape", pool_shape) #pool (?, 1, 1819, 10) print("y_shape", y_shape) #y (?,) prediction, loss = learn.models.logistic_regression(pool, y) return prediction, loss
如何重塑数据以获得其有意义的表示,并稍后将其传递给逻辑回归层?
回答:
这看起来像是对Tensor.set_shape()
方法和tf.reshape()
操作符的混淆。在这种情况下,你应该使用tf.reshape()
,因为你正在更改pool
和y
张量的形状:
-
tf.reshape(tensor, shape)
操作符接受任何形状的tensor
,并返回一个具有给定shape
的张量,只要它们具有相同数量的元素。应该使用此操作符来更改输入张量的形状。 -
tensor.set_shape(shape)
方法接受一个可能具有部分已知或未知形状的tensor
,并向TensorFlow断言它实际上具有给定的shape
。此方法应该用于提供关于特定张量形状的更多信息。例如,当你使用具有数据依赖输出形状的操作符的输出时(例如
tf.image.decode_jpeg()
),可以使用此方法,并断言它具有静态形状(例如,基于你对数据集中图像大小的了解)。
在你的程序中,你应该用如下内容替换对set_shape()
的调用:
pool_shape = tf.shape(pool)pool = tf.reshape(pool, [pool_shape[0], pool_shape[2] * pool_shape[3]])y_shape = tf.shape(y)y = tf.reshape(y, [y_shape[0], 1])# 或者,更直接地:y = tf.expand_dims(y, 1)