卷积核的优化1:
多通道卷积:提升捕捉特征的能力。
我们利用不同大小的卷积核对图片提取不同感受野的特征,然后将这些卷积后的结果进行拼接。
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
x_input=tf.placeholder(dtype=tf.float32,shape=[None,784])
y_input=tf.placeholder(dtype=tf.float32,shape=[None,10])
x_image=tf.reshape(x_input,[-1,28,28,1]) #变成一张28*28像素的图片
#下面分别用1x1,3x3,5x5,7x7的卷积核提取不同的特征,然后将这些卷积后的结果进行拼接
#############################################################
conv1_1x1=tf.Variable(tf.truncated_normal([1,1,1,32],mean=0,stddev=0.1))
convb1_1x1=tf.Variable(tf.zeros([32])+0.1)
conv1_3x3=tf.Variable(tf.truncated_normal([3,3,1,32],mean=0,stddev=0.1))
convb1_3x3=tf.Variable(tf.zeros([32])+0.1)
conv1_5x5=tf.Variable(tf.truncated_normal([5,5,1,32],mean=0,stddev=0.1))
convb1_5x5=tf.Variable(tf.zeros([32])+0.1)
conv1_7x7=tf.Variable(tf.truncated_normal([7,7,1,32],mean=0,stddev=0.1))
convb1_7x7=tf.Variable(tf.zeros([32])+0.1)
convlayer1_1x1=tf.nn.relu(tf.add(tf.nn.conv2d(x_image,conv1_1x1,padding="SAME"),convb1_1x1)) #定义32个1x1的卷积核
convlayer1_3x3=tf.nn.relu(tf.add(tf.nn.conv2d(x_image,conv1_3x3,padding="SAME"),convb1_3x3)) #定义32个3x3的卷积核
convlayer1_5x5=tf.nn.relu(tf.add(tf.nn.conv2d(x_image,conv1_5x5,padding="SAME"),convb1_5x5))
convlayer1_7x7=tf.nn.relu(tf.add(tf.nn.conv2d(x_image,conv1_7x7,padding="SAME"),convb1_7x7))
convlayer1=tf.concat([convlayer1_1x1,convlayer1_3x3,convlayer1_5x5,convlayer1_7x7],3)
################################################################
#print(convlayer1)
poollayer1=tf.nn.max_pool(convlayer1,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")
#print(poollayer1)
conv2_3x3=tf.Variable(tf.truncated_normal([3,3,128,16],mean=0,stddev=0.1)) #输入通道变为32*4=128张图片了
convbias2=tf.Variable(tf.zeros([16])+0.1)
convlayer2=tf.nn.relu(tf.add(tf.nn.conv2d(poollayer1,conv2_3x3,padding="SAME"),convbias2))
poollayer2=tf.nn.max_pool(convlayer2,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")
# # print(poollayer2) #查看平铺后会有7*7*16的输入单元
x_nn=tf.reshape(poollayer2,[-1,7*7*16]) #将图片形式的数据平铺用户全连接层分类
w1=tf.Variable(tf.truncated_normal([7*7*16,10],mean=0,stddev=0.1))
b1=tf.Variable(tf.zeros([10])+0.1)
layer1=tf.add(tf.matmul(x_nn,w1),b1)
logit=layer1
loss=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_input,logits=logit))
train_step=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
precise=tf.reduce_mean(tf.cast(tf.equal(tf.argmax(logit,1),tf.argmax(y_input,1)),dtype=tf.float32))
mnist=input_data.read_data_sets("MNIST_data",one_hot=True)
batch_size=1000
n_batch_size=mnist.train.num_examples//batch_size #训练完整一次数据集需要的次数
with tf.Session() as sess:
init=tf.global_variables_initializer()
sess.run(init)
for i in range(10): #训练整个数据集的次数
for j in range(n_batch_size):
x_train_input,y_train_input=mnist.train.next_batch(batch_size)
x_test_input,y_test_input=mnist.test.next_batch(batch_size)
sess.run(train_step,feed_dict={x_input:x_train_input,y_input:y_train_input})
precise_test=sess.run(precise,{x_input:x_train_input,y_input:y_train_input})
print(precise_test) #打印准确率
卷积核的优化2:
拆分卷积核:在不改变效果的前提下减少计算。比如将5x5的卷积核用5x1和1x5的卷积核进行两次卷积计算。
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
x_input=tf.placeholder(dtype=tf.float32,shape=[None,784])
y_input=tf.placeholder(dtype=tf.float32,shape=[None,10])
x_image=tf.reshape(x_input,[-1,28,28,1]) #变成一张28*28像素的一个通道的图片
conv1=tf.Variable(tf.truncated_normal([3,3,1,32],mean=0,stddev=0.1)) #定义卷积核
convb1=tf.Variable(tf.zeros([32])+0.1) #定义偏执
convlayer1=tf.nn.relu(tf.add(tf.nn.conv2d(x_image,conv1,padding="SAME"),convb1)) #卷积
poollayer1=tf.nn.max_pool(convlayer1,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME") #池化
#下面将3x3的卷积核拆分为3x1和1x3的两个卷积核,在不降低效果的前提下通过进行两次卷积来减少运算次数
###########################################
conv2_3x1=tf.Variable(tf.truncated_normal([3,1,32,32],mean=0,stddev=0.1)) #输入通道变为32*4=128张图片了
convbias2_3x1=tf.Variable(tf.zeros([32])+0.1)
convlayer2_3x1=tf.nn.relu(tf.add(tf.nn.conv2d(poollayer1,conv2_3x1,padding="SAME"),convbias2_3x1))
conv2_1x3=tf.Variable(tf.truncated_normal([1,3,32,32],mean=0,stddev=0.1))
convbias2_1x3=tf.Variable(tf.zeros([32])+0.1)
convlayer2=tf.nn.relu(tf.add(tf.nn.conv2d(convlayer2_3x1,conv2_1x3,padding="SAME"),convbias2_1x3))
###########################################
poollayer2=tf.nn.max_pool(convlayer2,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")
#print(poollayer2) #得到平铺后的个数shape=(?, 7, 7, 32)
x_nn=tf.reshape(poollayer2,[-1,7*7*32]) #转化为可用于全连接神经网络的输入
w1=tf.Variable(tf.truncated_normal([7*7*32,10],mean=0,stddev=0.1))
b1=tf.Variable(tf.zeros([10])+0.1)
layer1=tf.add(tf.matmul(x_nn,w1),b1)
logit=layer1
loss=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_input,logits=logit))
train_step=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
precise=tf.reduce_mean(tf.cast(tf.equal(tf.argmax(logit,1),tf.argmax(y_input,1)),dtype=tf.float32))
mnist=input_data.read_data_sets("MNIST_data",one_hot=True)
batch_size=1000
n_batch_size=mnist.train.num_examples//batch_size
with tf.Session() as sess:
init=tf.global_variables_initializer()
sess.run(init)
for i in range(10):
for j in range(n_batch_size):
x_train_input,y_train_input=mnist.train.next_batch(batch_size)
sess.run(train_step,feed_dict={x_input:x_train_input,y_input:y_train_input})
precise_test=sess.run(precise,{x_input:x_train_input,y_input:y_train_input})
loss_p=sess.run(loss,{x_input:x_train_input,y_input:y_train_input})
print(precise_test)
print(loss_p)