8 卷积神经网络——解决参数太多问题

8-1 卷积函数使用
手动生成一个55的矩阵来模拟图片,定义一个22的卷积核,来测试tf.nn.conv2d函数里的不同参数,验证其输出结果。

程序:

import tensorflow as tf

#1 定义输入变量
# [batch, in_height, in_width, in_channels] [训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数]  
input = tf.Variable(tf.constant(1.0, shape=[1, 5, 5, 1]))#定义一个5*5大小1个通道的矩阵
input2 = tf.Variable(tf.constant(1.0, shape=[1, 5, 5, 2]))
input3 = tf.Variable(tf.constant(1.0, shape=[1, 4, 4, 1]))

#2 定义卷积核变量
# [filter_height, filter_width, in_channels, out_channels] [卷积核的高度,卷积核的宽度,图像通道数,卷积核个数]   
filter1 = tf.Variable(tf.constant([-1.0, 0, 0, -1], shape=[2, 2, 1, 1]))
filter2 = tf.Variable(tf.constant([-1.0, 0, 0, -1, -1.0, 0, 0, -1], shape=[2, 2, 1, 2]))#卷积核为2*2矩阵,1ch输入,2ch输出
filter3 = tf.Variable(tf.constant([-1.0, 0, 0, -1, -1.0, 0, 0, -1, -1.0, 0, 0, -1], shape=[2, 2, 1, 3]))
filter4 = tf.Variable(tf.constant([-1.0, 0, 0, -1,
                                   -1.0, 0, 0, -1,
                                   -1.0, 0, 0, -1,
                                   -1.0, 0, 0, -1], shape=[2, 2, 2, 2]))
filter5 = tf.Variable(tf.constant([-1.0, 0, 0, -1, -1.0, 0, 0, -1], shape=[2, 2, 2, 1]))

#3 定义卷积操作
# padding的值为‘VALID’,表示边缘不填充, 当其为‘SAME’时,表示填充到卷积核可以到达图像边缘
op1 = tf.nn.conv2d(input, filter1, strides=[1, 2, 2, 1], padding='SAME')  # 1个通道输入,生成1个feature ma
op2 = tf.nn.conv2d(input, filter2, strides=[1, 2, 2, 1], padding='SAME')  # 1个通道输入,生成2个feature map
op3 = tf.nn.conv2d(input, filter3, strides=[1, 2, 2, 1], padding='SAME')  # 1个通道输入,生成3个feature map

op4 = tf.nn.conv2d(input2, filter4, strides=[1, 2, 2, 1], padding='SAME')  # 2个通道输入,生成2个feature
op5 = tf.nn.conv2d(input2, filter5, strides=[1, 2, 2, 1], padding='SAME')  # 2个通道输入,生成一个feature map

vop1 = tf.nn.conv2d(input, filter1, strides=[1, 2, 2, 1], padding='VALID')  # 5*5 对于pading不同而不同
op6 = tf.nn.conv2d(input3, filter1, strides=[1, 2, 2, 1], padding='SAME')
vop6 = tf.nn.conv2d(input3, filter1, strides=[1, 2, 2, 1], padding='VALID')  # 4*4与pading无关

#4 运行卷积操作
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)

    print("op1:\n", sess.run([op1, filter1]))  # 1-1  后面补0
    print("------------------")

    print("op2:\n", sess.run([op2, filter2]))  # 1-2多卷积核 按列取
    print("op3:\n", sess.run([op3, filter3]))  # 1-3
    print("------------------")

    print("op4:\n", sess.run([op4, filter4]))  # 2-2    通道叠加
    print("op5:\n", sess.run([op5, filter5]))  # 2-1
    print("------------------")

    print("op1:\n", sess.run([op1, filter1]))  # 1-1
    print("vop1:\n", sess.run([vop1, filter1]))
    print("op6:\n", sess.run([op6, filter1]))
    print("vop6:\n", sess.run([vop6, filter1]))

结果:

op1:
 [array([[[[-2.],
         [-2.],
         [-1.]],

        [[-2.],
         [-2.],
         [-1.]],

        [[-1.],
         [-1.],
         [-1.]]]], dtype=float32), array([[[[-1.]],

        [[ 0.]]],


       [[[ 0.]],

        [[-1.]]]], dtype=float32)]
------------------
op2:
 [array([[[[-2., -2.],
         [-2., -2.],
         [-2.,  0.]],

        [[-2., -2.],
         [-2., -2.],
         [-2.,  0.]],

        [[-1., -1.],
         [-1., -1.],
         [-1.,  0.]]]], dtype=float32), array([[[[-1.,  0.]],

        [[ 0., -1.]]],


       [[[-1.,  0.]],

        [[ 0., -1.]]]], dtype=float32)]
op3:
 [array([[[[-2., -2., -2.],
         [-2., -2., -2.],
         [-1., -1., -1.]],

        [[-2., -2., -2.],
         [-2., -2., -2.],
         [-1., -1., -1.]],

        [[-2., -1.,  0.],
         [-2., -1.,  0.],
         [-1.,  0.,  0.]]]], dtype=float32), array([[[[-1.,  0.,  0.]],

        [[-1., -1.,  0.]]],


       [[[ 0., -1., -1.]],

        [[ 0.,  0., -1.]]]], dtype=float32)]
------------------
op4:
 [array([[[[-4., -4.],
         [-4., -4.],
         [-2., -2.]],

        [[-4., -4.],
         [-4., -4.],
         [-2., -2.]],

        [[-2., -2.],
         [-2., -2.],
         [-1., -1.]]]], dtype=float32), array([[[[-1.,  0.],
         [ 0., -1.]],

        [[-1.,  0.],
         [ 0., -1.]]],


       [[[-1.,  0.],
         [ 0., -1.]],

        [[-1.,  0.],
         [ 0., -1.]]]], dtype=float32)]
op5:
 [array([[[[-4.],
         [-4.],
         [-2.]],

        [[-4.],
         [-4.],
         [-2.]],

        [[-2.],
         [-2.],
         [-1.]]]], dtype=float32), array([[[[-1.],
         [ 0.]],

        [[ 0.],
         [-1.]]],


       [[[-1.],
         [ 0.]],

        [[ 0.],
         [-1.]]]], dtype=float32)]
------------------
op1:
 [array([[[[-2.],
         [-2.],
         [-1.]],

        [[-2.],
         [-2.],
         [-1.]],

        [[-1.],
         [-1.],
         [-1.]]]], dtype=float32), array([[[[-1.]],

        [[ 0.]]],


       [[[ 0.]],

        [[-1.]]]], dtype=float32)]
vop1:
 [array([[[[-2.],
         [-2.]],

        [[-2.],
         [-2.]]]], dtype=float32), array([[[[-1.]],

        [[ 0.]]],


       [[[ 0.]],

        [[-1.]]]], dtype=float32)]
op6:
 [array([[[[-2.],
         [-2.]],

        [[-2.],
         [-2.]]]], dtype=float32), array([[[[-1.]],

        [[ 0.]]],


       [[[ 0.]],

        [[-1.]]]], dtype=float32)]
vop6:
 [array([[[[-2.],
         [-2.]],

        [[-2.],
         [-2.]]]], dtype=float32), array([[[[-1.]],

        [[ 0.]]],


       [[[ 0.]],

        [[-1.]]]], dtype=float32)]

8-2 sobel

通过卷积操作实现sobel算子,讲彩色图片生成带有边缘化信息的图片

程序:

import matplotlib.pyplot as plt  # plt 用于显示图片
import matplotlib.image as mpimg  # mpimg 用于读取图片
import numpy as np
import tensorflow as tf

#1 载入图片并显示
myimg = mpimg.imread('img.jpg')  # 读取和代码处于同一目录下的图片
plt.imshow(myimg)  # 显示图片
plt.axis('off')  # 不显示坐标轴
plt.show()
print(myimg.shape)
print('-----------------------------------------------------------')

#2 定义占位符、卷积核、卷积op
full = np.reshape(myimg, [1, 3264, 2448, 3])
inputfull = tf.Variable(tf.constant(1.0, shape=[1, 3264, 2448, 3]))

filter = tf.Variable(tf.constant([[-1.0, -1.0, -1.0], [0, 0, 0], [1.0, 1.0, 1.0],
                                  [-2.0, -2.0, -2.0], [0, 0, 0], [2.0, 2.0, 2.0],
                                  [-1.0, -1.0, -1.0], [0, 0, 0], [1.0, 1.0, 1.0]], shape=[3, 3, 3, 1]))

op = tf.nn.conv2d(inputfull, filter, strides=[1, 1, 1, 1], padding='SAME')  # 3个通道输入,生成1个feature ma
o = tf.cast(((op - tf.reduce_min(op)) / (tf.reduce_max(op) - tf.reduce_min(op))) * 255, tf.uint8)
print('-----------------------------------------------------------')

#3 运行卷积操作并显示
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    t, f = sess.run([o, filter], feed_dict={inputfull: full})
    # print(f)
    t = np.reshape(t, [3264, 2448])

    plt.imshow(t, cmap='Greys_r')  # 显示图片
    plt.axis('off')  # 不显示坐标轴
    plt.show()

结果:
8 卷积神经网络——解决参数太多问题_第1张图片
8 卷积神经网络——解决参数太多问题_第2张图片

(3264, 2448, 3)
-----------------------------------------------------------


-----------------------------------------------------------


Process finished with exit code 0

8-3 池化函数使用

定义1个输入变量来模拟输入图片,4*4大小的2通道矩阵,并将其赋予指定的值。2个通道分别为4个0到4个3组成的矩阵,4个4到4个7组成的矩阵。

程序:

import tensorflow as tf

#1 定义输入变量
img = tf.constant([
    [[0.0, 4.0], [0.0, 4.0], [0.0, 4.0], [0.0, 4.0]],
    [[1.0, 5.0], [1.0, 5.0], [1.0, 5.0], [1.0, 5.0]],
    [[2.0, 6.0], [2.0, 6.0], [2.0, 6.0], [2.0, 6.0]],
    [[3.0, 7.0], [3.0, 7.0], [3.0, 7.0], [3.0, 7.0]]
])

img = tf.reshape(img, [1, 4, 4, 2])

#2 定义池化操作
pooling = tf.nn.max_pool(img, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
pooling1 = tf.nn.max_pool(img, [1, 2, 2, 1], [1, 1, 1, 1], padding='VALID')
pooling2 = tf.nn.avg_pool(img, [1, 4, 4, 1], [1, 1, 1, 1], padding='SAME')
pooling3 = tf.nn.avg_pool(img, [1, 4, 4, 1], [1, 4, 4, 1], padding='SAME')
nt_hpool2_flat = tf.reshape(tf.transpose(img), [-1, 16])
pooling4 = tf.reduce_mean(nt_hpool2_flat, 1)  # 1对行求均值(1表示轴是列)   0 对列求均值

#3 运行池化操作
with tf.Session() as sess:
    print("image:")
    image = sess.run(img)
    print(image)
    result = sess.run(pooling)
    print("reslut:\n", result)
    result = sess.run(pooling1)
    print("reslut1:\n", result)
    result = sess.run(pooling2)
    print("reslut2:\n", result)
    result = sess.run(pooling3)
    print("reslut3:\n", result)
    flat, result = sess.run([nt_hpool2_flat, pooling4])
    print("reslut4:\n", result)
    print("flat:\n", flat)

结果:

image:
[[[[0. 4.]
   [0. 4.]
   [0. 4.]
   [0. 4.]]

  [[1. 5.]
   [1. 5.]
   [1. 5.]
   [1. 5.]]

  [[2. 6.]
   [2. 6.]
   [2. 6.]
   [2. 6.]]

  [[3. 7.]
   [3. 7.]
   [3. 7.]
   [3. 7.]]]]
reslut:
 [[[[1. 5.]
   [1. 5.]]

  [[3. 7.]
   [3. 7.]]]]
reslut1:
 [[[[1. 5.]
   [1. 5.]
   [1. 5.]]

  [[2. 6.]
   [2. 6.]
   [2. 6.]]

  [[3. 7.]
   [3. 7.]
   [3. 7.]]]]
reslut2:
 [[[[1.  5. ]
   [1.  5. ]
   [1.  5. ]
   [1.  5. ]]

  [[1.5 5.5]
   [1.5 5.5]
   [1.5 5.5]
   [1.5 5.5]]

  [[2.  6. ]
   [2.  6. ]
   [2.  6. ]
   [2.  6. ]]

  [[2.5 6.5]
   [2.5 6.5]
   [2.5 6.5]
   [2.5 6.5]]]]
reslut3:
 [[[[1.5 5.5]]]]
reslut4:
 [1.5 5.5]
flat:
 [[0. 1. 2. 3. 0. 1. 2. 3. 0. 1. 2. 3. 0. 1. 2. 3.]
 [4. 5. 6. 7. 4. 5. 6. 7. 4. 5. 6. 7. 4. 5. 6. 7.]]

你可能感兴趣的:(原理与进阶实战)