分享

tensorflow卷积神经网络CNN实现图片分类【卷积过程完全理解】

regan 发表于 2018-4-12 09:38:54 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 0 58527
本帖最后由 regan 于 2018-4-12 09:44 编辑

1.下载数据
wget http://tensorflow-1253902462.cosgz.myqcloud.com/mnist_cnn/t10k-images-idx3-ubyte.gz

wget http://tensorflow-1253902462.cosgz.myqcloud.com/mnist_cnn/t10k-labels-idx1-ubyte.gz

wget http://tensorflow-1253902462.cosgz.myqcloud.com/mnist_cnn/train-images-idx3-ubyte.gz

wget http://tensorflow-1253902462.cosgz.myqcloud.com/mnist_cnn/train-labels-idx1-ubyte.gz
1.gif
2.引入必要的库
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data

3.定义输入数据并预处理数据,得到训练图片和标签,及测试图片及标签
mnist = input_data.read_data_sets('./',one_hot=True)
trX , trY,teX,teY = mnist.train.images,mnist.train.labels,mnist.test.images,mnist.test.labels
2.png
上面图像的矩阵表现形式,现在需要把这个矩阵变换成(-1,28,28,1)的形状,-1表示不考虑图片的数量,28*28分别表示图片的长度和宽度,1表示颜色通道数量,黑白图片的颜色通道为1,RGB为3.
trX = trX.reshape(-1,28,28,1)
teX = teX.reshape(-1,28,28,1)

4.定义placeholder变量
X = tf.placeholder(tf.float32,[None,28,28,1])
Y = tf.placeholder(tf.float32,[None,10])

5.定义网络结构与初始化网络权重
三个卷积层,3个池化层,1个全连接层,1个输出层。定义一个初始化权重的函数
def init_weights(shape):
return tf.Variable(tf.random_normal(shape,stddev=0.01))
接下来初始化权重,定义卷积核大小为3*3【一般卷积和和最后的输出维度之间的关系为:(int_weight+2*padding-core_weight)/stride步长+1】
对于tensorflow由于padding有两种选择,所以有如下的算法:
3.png
卷积核的stride定义为【1,1,1,1】,池化的stride定义为[1,2,2,1]
下面定义卷积核,大小为3*3,输入维度为1对应输入时的厚度因为是单颜色通道,所以是1,输出维度为32表示有32个patch,卷积之后就是32个厚度的了。w4中的128*4*4是什么意思呢?由上面的公式,第一次卷积之后的matrix大小为【28 / 1】接着是池化【28 / 2 = 14】;第二次卷积matrix大小为【14/1=14】接着池化【14/2=7】,接着第三次卷积matrix大小为【 7 /1 = 7】接着池化【7/2 = 4】。一共128个patch且每个patch大小为4*4。
4.png
w = init_weights([3,3,1,32])
w2 = init_weights([3,3,32,64])
w3 = init_weights([3,3,64,128])
w4 = init_weights([128*4*4,625])
w_o = init_weights([625,10])

6.接下来定义模型函数
def model(X,w,w2,w3,w4,w_o,p_keep_conv,p_keep_hidden):
l1a = tf.nn.relu(tf.nn.conv2d(X,w,strides=[1,1,1,1],padding='SAME'))
l1p = tf.nn.max_pool(l1a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l1 = tf.nn.dropout(l1p,p_keep_conv)

l2a = tf.nn.relu(tf.nn.conv2d(l1,w2,strides=[1,1,1,1],padding='SAME'))
l2p = tf.nn.max_pool(l2a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l2 = tf.nn.dropout(l2p,p_keep_conv)

l3a = tf.nn.relu(tf.nn.conv2d(l2,w3,strides=[1,1,1,1],padding='SAME'))
l3p = tf.nn.max_pool(l3a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l3 = tf.reshape(l3p,[-1,w4.get_shape().as_list()[0]])
l3 = tf.nn.dropout(l3,p_keep_conv)

l4 = tf.nn.relu(tf.matmul(l3,w4))
l4 = tf.nn.dropout(l4,p_keep_hidden)

out = tf.matmul(l4,w_o)
return out

7.定义占位符
p_keep_conv = tf.placeholder('float')
p_keep_hidden = tf.placeholder('float')
out = model(X,w,w2,w3,w4,w_o,p_keep_conv,p_keep_hidden)

8.定义损失值和优化器。采用softmax_cross_entropy_with_logits来比较预测值和真实值之间的差异,这些差异最后做均值处理。优化器采用RMSProp算法实现的RMSPropOptimizer,制定学习率为0.001,学习率的衰减值为0.9,并使损失沿着最小的方向迭代。

cost =  tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out,labels=Y))
train_op = tf.train.RMSPropOptimizer(0.001,0.9).minimize(cost)
predict_op = tf.argmax(out,1)

8.训练和评估模型
定义批次大小为128
batch_size = 128

在session中启动图
with tf.Session() as sess:
tf.global_variables_initializer().run()
for i in range(500):
train_batch = zip(range(0,len(trX),batch_size),range(batch_size,len(trX)+1,batch_size))
for start,end in train_batch:
sess.run(train_op,feed_dict={X:trX[start:end],Y:trY[start:end],p_keep_conv:0.8,p_keep_hidden:0.5})
test = np.arange(len(trX))
np.random.shuffle(test)
test_indices = test[0:batch_size]
print(i,np.mean(np.argmax(teY[test_indices],axis=1)==sess.run(predict_op,feed_dict={X:teX[test_indices],p_keep_conv:1.0,p_keep_hidden:1.0})))

运行结果如下:
5.png
可以看到卷积神经网络预测的准确率确实挺高的。
完整代码如下:
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('./',one_hot=True)
#print(dir(mnist))
trX , trY,teX,teY = mnist.train.images,mnist.train.labels,mnist.test.images,mnist.test.labels

trX = trX.reshape(-1,28,28,1)
teX = teX.reshape(-1,28,28,1)

X = tf.placeholder(tf.float32,[None,28,28,1])
Y = tf.placeholder(tf.float32,[None,10])

def init_weights(shape):
        return tf.Variable(tf.random_normal(shape,stddev=0.01))

w = init_weights([3,3,1,32])
w2 = init_weights([3,3,32,64])
w3 = init_weights([3,3,64,128])
w4 = init_weights([128*4*4,625])
w_o = init_weights([625,10])

def model(X,w,w2,w3,w4,w_o,p_keep_conv,p_keep_hidden):
        l1a = tf.nn.relu(tf.nn.conv2d(X,w,strides=[1,1,1,1],padding='SAME'))
        l1p = tf.nn.max_pool(l1a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
        l1 = tf.nn.dropout(l1p,p_keep_conv)

        l2a = tf.nn.relu(tf.nn.conv2d(l1,w2,strides=[1,1,1,1],padding='SAME'))
        l2p = tf.nn.max_pool(l2a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
        l2 = tf.nn.dropout(l2p,p_keep_conv)

        l3a = tf.nn.relu(tf.nn.conv2d(l2,w3,strides=[1,1,1,1],padding='SAME'))
        l3p = tf.nn.max_pool(l3a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
        l3 = tf.reshape(l3p,[-1,w4.get_shape().as_list()[0]])
        l3 = tf.nn.dropout(l3,p_keep_conv)

        l4 = tf.nn.relu(tf.matmul(l3,w4))
        l4 = tf.nn.dropout(l4,p_keep_hidden)

        out = tf.matmul(l4,w_o)
        return out


p_keep_conv = tf.placeholder('float')
p_keep_hidden = tf.placeholder('float')
out = model(X,w,w2,w3,w4,w_o,p_keep_conv,p_keep_hidden)


cost =  tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out,labels=Y))
train_op = tf.train.RMSPropOptimizer(0.001,0.9).minimize(cost)
predict_op = tf.argmax(out,1)

batch_size = 128

with tf.Session() as sess:
        tf.global_variables_initializer().run()
        for i in range(100):
                train_batch = zip(range(0,len(trX),batch_size),range(batch_size,len(trX)+1,batch_size))
                for start,end in train_batch:
                        sess.run(train_op,feed_dict={X:trX[start:end],Y:trY[start:end],p_keep_conv:0.8,p_keep_hidden:0.5})
                test = np.arange(len(teX))
                np.random.shuffle(test)
                test_indices = test[0:batch_size]
                print(i,np.mean(np.argmax(teY[test_indices],axis=1)==sess.run(predict_op,feed_dict={X:teX[test_indices],p_keep_conv:1.0,p_keep_hidden:1.0})))

6.png
现在的准确率就很高了,能达到99.x%.


没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条