Skip to main content
 首页 » 编程设计

python之CNN 架构与 TensorFlow

2024年08月15日28duanxz

我正在实现本文 https://cs.nyu.edu/~fergus/papers/zeilerECCV2014.pdf 中的架构使用 tensorflow 。

我已将我的输入格式化为 224, 224, 3 并具有以下 TensorFlow 层。我遇到的问题是 conv1 的输出大小不是本文所述的 110 x 110 x 96,而是 109 x 109 x 96。我该如何解决这个问题?

我遵循了第 8 页论文中指定的超参数。我唯一的想法是填充可能不正确(因为 TensorFlow 为您设置了它)。

我的代码如下:

# Input Layer 
# Reshape X to 4-D tensor: [batch_size, width, height, channels] 
input_layer = tf.reshape(features["x"], [-1, IMG_SIZE, IMG_SIZE, 3]) 
 
print(input_layer.get_shape(), '224, 224, 3') 
# Convolutional Layer #1 
# Input Tensor Shape: [batch_size, 224, 224, 3] 
conv1 = tf.layers.conv2d( 
    inputs=input_layer, 
    filters=96, 
    kernel_size=[7, 7], 
    strides=2, 
    padding="valid",  # padding = 1 
    activation=tf.nn.relu) 
print(conv1.get_shape(), '110, 110, 96') 
 
# Max Pooling Layer 
# Input Tensor Shape: [batch_size, 110, 110, 96] 
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[3, 3], strides=2) 
 
# Contrast Normalisation 
# Input Tensor Shape: [batch_size, 55, 55, 96] 
contrast_norm1 = tf.nn.local_response_normalization( 
    pool1, 
    depth_radius=5, 
    bias=1, 
    alpha=0.0001, 
    beta=0.75) 
print(contrast_norm1.get_shape(), '55, 55, 96') 
 
# The rest of the CNN... 

输出:括号内 - 实际尺寸,外部 - 所需/纸张尺寸

(?, 224, 224, 3) 224, 224, 3  # Input 
(?, 109, 109, 96) 110, 110, 96  # Following conv1 
(?, 54, 54, 96) 55, 55, 96  # Following contrast_norm1 

请您参考如下方法:

带valid padding的卷积运算的输出高宽维度可以计算为:

output_size = (input_size - kernel_size) // stride + 1 

在你的例子中,第一层的输出:

output_size = (224 - 7) // 2 + 1 = 217 // 2 + 1 = 109 

使第一层的输出等于 110 的一种方法是将内核大小设置为 6x6。另一种方法是使用 tf.pad 添加大小为 1 的填充。 :

# suppose this is a batch of 10 images of size 4x4x3 
data = np.ones((10, 4, 4, 3), dtype=np.float32) 
 
paddings = [[0, 0], # no values are added along batch dim 
            [1, 0], # add one value before the content of height dim 
            [1, 0], # add one value before the content of width dim 
            [0, 0]] # no values are added along channel dim 
 
padded_data = tf.pad(tensor=data, 
                     paddings=paddings, 
                     mode='CONSTANT', 
                     constant_values=0) 
 
sess = tf. InteractiveSession() 
output = sess.run(padded_data) 
print(output.shape) 
# >>> (10, 5, 5, 3) 
 
# print content of first channel of first image 
print(output[0,:,:,0]) 
# >>> [[0. 0. 0. 0. 0.] 
#      [0. 1. 1. 1. 1.] 
#      [0. 1. 1. 1. 1.] 
#      [0. 1. 1. 1. 1.] 
#      [0. 1. 1. 1. 1.]] 

在上面的示例中,沿高度和宽度尺寸添加了大小为 1 的零填充。填充的形状应为 [number_of_dimensions, 2],例如对于输入矩阵的每个维度,您指定要在张量内容前后添加多少个值。

如果将此填充应用到输入数据,它将产生形状为 batch x 225 x 225 x 3 的张量,因此卷积层的输出高度和宽度将为 110x110。