TensorFlow实现卷积层和池化层

这里我们将介绍如何实现常见的卷积层和池化层

这里我们以二维数据为例进行介绍

第1步:引入相应的库并创建计算图会话

import tensorflow as tf
import numpy as np

#创建计算图会话
sess = tf.Session()

第2步:创建数据并初始化占位符,这里输入数据shape = [10,10]

#准备数据
data_size = [10,10]
data_2d = np.random.normal(size=data_size)

#占位符
x_input_2d =  tf.placeholder(tf.float32,shape=data_size)

第3步:声明卷积层函数,这里采用TensorFlow内建函数tf.nn.conv2d(),由于该函数需要输入4维数据(批量大小,宽度,高度,颜色通道),因此首先需要对输入数据进行扩维。tf.expand.dims函数为扩维函数,其作用是在给定位置增加一维。例如输入数据shape = [10,10],则tf.expand_dims(input_2d,0)的shape为[1,10,10]。

其次配置相应的滤波器,步长stride以及padding

滤波器选用外部输入滤波器参数myfilter,步长为两个方向为2,padding为VALID。

最后采用tf.squeeze函数将卷积后的数据shape转换为2维数据

#声明卷积层
#由于conv2d()函数为4维数据设计,包括[batch_size,width,height,channels],所以需要4维数据
def conv_layer_2d(input_2d , myfilter):
    #将数据转化为4维
    input_3d  = tf.expand_dims(input_2d,0) #shape = [1,10,10]
    input_4d = tf.expand_dims(input_3d,3) #shape = [1,10,10,1]

    #卷积操作
    #这里设置两个方向上的补偿,padding选择no padding,myfileter采用2*2,因此10*10 ==>5*5
    conv_out = tf.nn.conv2d(input=input_4d,filter=myfilter,strides=[1,2,2,1],padding='VALID')

    #维度还原
    conv_out_2d = tf.squeeze(conv_out) #shape = [5,5]
    return  conv_out_2d

这里定义滤波器大小为2X2,经过上述创建的卷积层后,输出数据shape为[5,5]

myfilter = tf.Variable(tf.random_normal(shape=[2,2,1,1]))
my_convolution_output = conv_layer_2d(x_input_2d,myfilter)

第4步:声明激励函数,激励函数是针对逐个元素的,创建激励函数并初始化后将上述卷积层后得到的数据通过激励函数。

#激励函数
#这里选择ReLu作为激活函数
def activation(input_2d):
    return tf.nn.relu(input_2d)
my_activation_output = activation(my_convolution_output)

第5步:池化层

输入为经激活函数后的数据,shape=[5,5]

池化层仍采用TensorFlow内建函数,其处理方式与卷积层类似,仍然先扩维,然后通过池化函数tf.nn.max_pool,最后降维得到输出数据,这里池化层步长为1,宽和高为2X2,shape变为[4,4]

def max_pool(input_2d,width,height):
    #先将数据扩展为4维
    input_3d  = tf.expand_dims(input_2d,0) #shape = [1,5,5]
    input_4d = tf.expand_dims(input_3d,3) #shape = [1,5,5,1]

    #池化操作
    pool_output = tf.nn.max_pool(input_4d,ksize=[1,height,width,1],strides=[1,1,1,1],padding='VALID')

    #降维
    pool_output_2d = tf.squeeze(pool_output)#shape = [4,4]

    return pool_output_2d

my_maxpool_output = max_pool(my_activation_output,width=2,height=2)

第6步:全连接层

输入为经池化层后的数据,shape = [4,4]以及需要连接的神经元个数num_outputs = 5

这里为保证所有数据均能够与神经元相连接,首先将数据转化为一维向量,并计算y=wx+b中w和b的shape

输入数据的shape变为[16],我们通过tf.shape得到该shape,然后通过tf.stack将输入shape与神经元个数连接得到shape为[[16],[5]],最后通过tf.squeeze得到w的shape为[16,5],b的shape为5

最后由于y=wx+b为矩阵运算,需要将数据扩维至2维数据,经计算后再通过降维还原回一维数据,这里输出为5个神经元的值

#全连接层

def fully_connected(input_layer,num_outputs):
    #首先将数据转化为一维向量,以实现每项连接到每个输出
    flat_input = tf.reshape(input_layer,[-1])

    #创建w和b
    #确定w和b的shape
    #tf.shape得到数据的大小例如4*4的数据变为向量,则shape=16,
    #tf.stack为矩阵拼接,设num_outputs = 5,则其结果为[[16],[5]]
    #tf.squeeze降维,使其结果为[16,5]满足shape输入格式要求
    weight_shape = tf.squeeze(tf.stack([tf.shape(flat_input),[num_outputs]]))

    weight = tf.random_normal(shape=weight_shape,stddev=0.1)
    bias = tf.random_normal(shape=[num_outputs])

    #将数据转化为2维以完成矩阵乘法
    input_2d = tf.expand_dims(flat_input,0)

    #进行计算y=wx+b
    fully_output = tf.add(tf.matmul(input_2d,weight),bias)

    #降维
    fully_output_result = tf.squeeze(fully_output)

    return fully_output_result

my_full_output = fully_connected(my_maxpool_output,num_outputs=5)

第7步:初始化变量并写入计算图中,然后打印出来

#初始化变量
init = tf.initialize_all_variables()
sess.run(init)

feed_dict = {x_input_2d:data_2d}
#打印各层

#卷积层
print('Input = [10 10] array')

print('Convolution [2,2],stride size = [2,2], results in the [5,5] array:')

print(sess.run(my_convolution_output,feed_dict=feed_dict))

#激活函数输出
print('Input = the above [5,5] array ')
print('ReLU element wise returns the [5,5] array ')
print(sess.run(my_activation_output,feed_dict=feed_dict))

#池化层输出
print('Input = the above [5,5] array ')
print('Maxpool,stride size = [1,1], results in the [4,4] array ')
print(sess.run(my_maxpool_output,feed_dict=feed_dict))

#全连接层输出

print('Input = the above [4,4] array ')
print('Fully connected layer on all four rows with five outputs:')
print(sess.run(my_full_output,feed_dict=feed_dict))

下面是打印结果:

Input = [10 10] array
Convolution [2,2],stride size = [2,2], results in the [5,5] array:
[[ 1.32886136 -1.47333026 -1.44128537 -0.95050871 -1.80972886]
 [-2.82501674 -0.35346282 -0.06931959  1.9739815  -0.84173405]
 [ 0.5519557  -1.66942024  0.56509626 -2.68546128  0.71953934]
 [-3.13675737 -1.81401241  1.47897935 -0.1665355   0.05618015]
 [ 2.81271505 -4.40996552 -1.39324057  1.17697966 -2.26855183]]
Input = the above [5,5] array 
ReLU element wise returns the [5,5] array 
[[ 1.32886136  0.          0.          0.          0.        ]
 [ 0.          0.          0.          1.9739815   0.        ]
 [ 0.5519557   0.          0.56509626  0.          0.71953934]
 [ 0.          0.          1.47897935  0.          0.05618015]
 [ 2.81271505  0.          0.          1.17697966  0.        ]]
Input = the above [5,5] array 
Maxpool,stride size = [1,1], results in the [4,4] array 
[[ 1.32886136  0.          1.9739815   1.9739815 ]
 [ 0.5519557   0.56509626  1.9739815   1.9739815 ]
 [ 0.5519557   1.47897935  1.47897935  0.71953934]
 [ 2.81271505  1.47897935  1.47897935  1.17697966]]
Input = the above [4,4] array 
Fully connected layer on all four rows with five outputs:
[-1.14044487  0.18718313  2.26356006 -0.60274446  0.6560365 ]













你可能感兴趣的:(机器学习,Tensorflow,TensorFlow,卷积层,池化层)