CNN卷积神经网络

Posted by DuHuazhen on March 3, 2017
对卷积神经网络的理解

https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650728746&idx=1&sn=61e9cb824501ec7c505eb464e8317915&scene=0#wechat_redirect
https://en.wikipedia.org/wiki/Convolutional_neural_network https://blog.csdn.net/zouxy09/article/details/8781543 http://deeplearning.net/tutorial/lenet.html

改变某个同学人生的网站(cnn):http://scs.ryerson.ca/~aharley/vis/conv/,这是一个卷积神经网络的一个可视化的3D演示。
基于TensorFlow的神经网络演示:https://playground.tensorflow.org/#activation=tanh&batchSize=10&dataset=circle&regDataset=reg-plane&learningRate=0.03&regularizationRate=0&noise=35&networkShape=4,2,2&seed=0.89675&showTestData=false&discretize=false&percTrainData=50&x=true&y=true&xTimesY=true&xSquared=true&ySquared=true&cosX=false&sinX=true&cosY=false&sinY=true&collectStats=false&problem=classification&initZero=false&hideText=false
github地址:https://github.com/tensorflow/playground

使用TensorFlow创建CNN(MNIST)

#coding=utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

def compute_accuracy(v_xs,v_ys):
    global prediction
    y_pre=sess.run(prediction,feed_dict={xs:v_xs,keep_prob:1}) #这里的keep_prob是保留概率,即我们要保留的RELU的结果所占比例
    correct_prediction=tf.equal(tf.argmax(y_pre,1),tf.argmax(v_ys,1))
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
    result=sess.run(accuracy,feed_dict={xs:v_xs,ys:v_ys,keep_prob:1})
    return result

def weight_variable(shape):
    inital=tf.truncated_normal(shape,stddev=0.1)     #stddev爲標準差
    return tf.Variable(inital)

def bias_variable(shape):
    inital=tf.constant(0.1,shape=shape)
    return tf.Variable(inital)

def conv2d(x,W):    #x爲像素值,W爲權值
    #strides[1,x_movement,y_movement,1]
    #must have strides[0]=strides[3]=1
    #padding=????
    return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')#

def max_pool_2x2(x):
    # strides[1,x_movement,y_movement,1]
    return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')#ksize二三维为池化窗口

#define placeholder for inputs to network
xs=tf.placeholder(tf.float32,[None,784])/255
ys=tf.placeholder(tf.float32,[None,10])
keep_prob=tf.placeholder(tf.float32)
x_image=tf.reshape(xs, [-1,28,28,1]) #-1为这个维度不确定,变成一个4维的矩阵,最后为最里面的维数
#print x_image.shape                 #最后这个1理解为输入的channel,因为为黑白色所以为1

##conv1 layer##
W_conv1=weight_variable([5,5,1,32]) #patch 5x5,in size 1 是image的厚度,outsize 32 是提取的特征的维数
b_conv1=bias_variable([32])
h_conv1=tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)# output size 28x28x32 因为padding='SAME'
h_pool1=max_pool_2x2(h_conv1)      #output size 14x14x32

##conv2 layer##
W_conv2=weight_variable([5,5,32,64]) #patch 5x5,in size 32 是conv1的厚度,outsize 64 是提取的特征的维数
b_conv2=bias_variable([64])
h_conv2=tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)# output size 14x14x64 因为padding='SAME'
h_pool2=max_pool_2x2(h_conv2)      #output size 7x7x64

##func1 layer##
W_fc1=weight_variable([7*7*64,1024])
b_fc1=bias_variable([1024])
#[n_samples,7,7,64]->>[n_samples,7*7*64]
h_pool2_flat=tf.reshape(h_pool2,[-1,7*7*64])
h_fc1=tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1)
h_fc1_drop=tf.nn.dropout(h_fc1,keep_prob)  #防止过拟合

##func2 layer##
W_fc2=weight_variable([1024,10])
b_fc2=bias_variable([10])
#prediction=tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)
prediction=tf.matmul(h_fc1_drop,W_fc2)+b_fc2
#h_fc1_drop=tf.nn.dropout(h_fc1,keep_prob)  #防止过拟合

#the errro between prediction and real data

#cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1]))
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=ys, logits=prediction))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
sess=tf.Session()
sess.run(tf.global_variables_initializer())

for i in range(1000):
    batch_xs,batch_ys=mnist.train.next_batch(100)
    sess.run(train_step,feed_dict={xs:batch_xs,ys:batch_ys,keep_prob:0.5})
    if i%50 ==0:
        accuracy = 0
        for j in range(10):
            test_batch = mnist.test.next_batch(1000)
            acc_forone=compute_accuracy(test_batch[0], test_batch[1])
            accuracy=acc_forone+accuracy  
        #print在python2和python3下的格式不太一样
        print("测试结果:batch:%d,准确率:%f" %(i,accuracy/10))

结果如下

测试结果:batch:0,准确率:0.071800
测试结果:batch:50,准确率:0.767800
测试结果:batch:100,准确率:0.879200
测试结果:batch:150,准确率:0.902800
测试结果:batch:200,准确率:0.918200
测试结果:batch:250,准确率:0.933100
测试结果:batch:300,准确率:0.939100
测试结果:batch:350,准确率:0.944900
测试结果:batch:400,准确率:0.951700
测试结果:batch:450,准确率:0.953500
测试结果:batch:500,准确率:0.957200
测试结果:batch:550,准确率:0.959700
测试结果:batch:600,准确率:0.961400
测试结果:batch:650,准确率:0.963100
测试结果:batch:700,准确率:0.963400
测试结果:batch:750,准确率:0.966100
测试结果:batch:800,准确率:0.966300
测试结果:batch:850,准确率:0.967700
测试结果:batch:900,准确率:0.968500
测试结果:batch:950,准确率:0.969800

import tensorflow as tf
import numpy as np
 
# 下载mnist数据集
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('/tmp/', one_hot=True)
 
 
n_output_layer = 10
 
# 定义待训练的神经网络
def convolutional_neural_network(data):
	weights = {'w_conv1':tf.Variable(tf.random_normal([5,5,1,32])),
              'w_conv2':tf.Variable(tf.random_normal([5,5,32,64])),
              'w_fc':tf.Variable(tf.random_normal([7*7*64,1024])),
              'out':tf.Variable(tf.random_normal([1024,n_output_layer]))}
 
	biases = {'b_conv1':tf.Variable(tf.random_normal([32])),
              'b_conv2':tf.Variable(tf.random_normal([64])),
              'b_fc':tf.Variable(tf.random_normal([1024])),
              'out':tf.Variable(tf.random_normal([n_output_layer]))}
 
	data = tf.reshape(data, [-1,28,28,1])
 
	conv1 = tf.nn.relu(tf.add(tf.nn.conv2d(data, weights['w_conv1'], strides=[1,1,1,1], padding='SAME'), biases['b_conv1']))
	conv1 = tf.nn.max_pool(conv1, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
 
	conv2 = tf.nn.relu(tf.add(tf.nn.conv2d(conv1, weights['w_conv2'], strides=[1,1,1,1], padding='SAME'), biases['b_conv2']))
	conv2 = tf.nn.max_pool(conv2, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
 
	fc = tf.reshape(conv2, [-1,7*7*64])
	fc = tf.nn.relu(tf.add(tf.matmul(fc, weights['w_fc']), biases['b_fc']))
 
	# dropout剔除一些"神经元"
	#fc = tf.nn.dropout(fc, 0.8)
 
	output = tf.add(tf.matmul(fc, weights['out']), biases['out'])
	return output
 
 
# 每次使用100条数据进行训练
batch_size = 100
 
X = tf.placeholder('float', [None, 28*28]) 
Y = tf.placeholder('float')
# 使用数据训练神经网络
def train_neural_network(X, Y):
	predict = convolutional_neural_network(X)
	cost_func = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(predict, Y))
	optimizer = tf.train.AdamOptimizer().minimize(cost_func)  # learning rate 默认 0.001 
 
	epochs = 1
	with tf.Session() as session:
		session.run(tf.initialize_all_variables())
		epoch_loss = 0
		for epoch in range(epochs):
			for i in range( int(mnist.train.num_examples/batch_size) ):
				x, y = mnist.train.next_batch(batch_size)
				_, c = session.run([optimizer, cost_func], feed_dict={X:x,Y:y})
				epoch_loss += c
			print(epoch, ' : ', epoch_loss)
 
		correct = tf.equal(tf.argmax(predict,1), tf.argmax(Y,1))
		accuracy = tf.reduce_mean(tf.cast(correct,'float'))
		print('准确率: ', accuracy.eval({X:mnist.test.images, Y:mnist.test.labels}))
 
train_neural_network(X,Y)

会出现terminate called after throwing an instance of ‘std::bad_alloc’ what(): std::bad_alloc Process finished with exit code 134 (interrupted by signal 6: SIGABRT)这个错误,这是因为一次测试10000幅mnist图像会导致电脑内存不足甚至死机,对此我们可以减少测试的数据集。所以推荐第一种实现cnn的方法,减少了测试的数据集。