通过Dropout防止过拟合,增加模型的准确率(04-2)
减小过拟合的几种方法:
我们建一个三层的网络,并给他加上droppout 测试一下训练20次的准确率
1 # -*- coding: UTF-8 -*- 2 3 4 import tensorflow as tf 5 from tensorflow.examples.tutorials.mnist import input_data 6 7 #载入数据集 8 mnist=input_data.read_data_sets("MNIST_data", one_hot=True) 9 #每个批次的大小 10 batch_size=100 11 #计算一共有多少个批次 12 n_batch=mnist.train.num_examples 13 14 #定义两个placeholder 15 x=tf.placeholder(tf.float32,[None,784]) 16 y=tf.placeholder(tf.float32,[None,10]) 17 keep_prob=tf.placeholder(tf.float32) 18 19 #创建一个简单的神经网络(初始化)设置隐藏层 20 W1=tf.Variable(tf.truncated_normal([784,200],stddev=0.1))#这里我们使用了一个截断的正态分布初始化W1,效果比W=tf.Variable(tf.zeros([784,10]))初始化效果好 21 b1=tf.Variable(tf.zeros([200])+0.1) 22 L1=tf.nn.tanh(tf.matmul(x,W1)+b1)#定义L1的输出(L1为当前层神经元的输出) 23 L1_drop=tf.nn.dropout(L1,keep_prob)#keep_prob:设置有百分之多少个神经元是工作的 24 25 W2=tf.Variable(tf.truncated_normal([200,100],stddev=0.1))#这里我们使用了一个截断的正态分布初始化W2,标准差为0.1 26 b2=tf.Variable(tf.zeros([100])+0.1) 27 L2=tf.nn.tanh(tf.matmul(L1_drop,W2)+b2) 28 L2_drop=tf.nn.dropout(L2,keep_prob) 29 30 31 #设置输出层神经网络 32 W3=tf.Variable(tf.truncated_normal([100,10],stddev=0.1)) 33 b3=tf.Variable(tf.zeros([10])+0.1) 34 prediction=tf.nn.softmax(tf.matmul(L2_drop,W3)+b3) 35 36 37 38 #二次代价函数 39 #loss=tf.reduce_mean(tf.square(y-prediction)) 40 #使用交叉熵代价函数 41 loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction)) 42 43 #使用梯度下降法 44 train_step=tf.train.GradientDescentOptimizer(0.2).minimize(loss) 45 46 #初始化变量 47 init=tf.global_variables_initializer() 48 49 #结果存放在一个布尔型列表中 50 correct_prediction=tf.equal(tf.argmax(y,1), tf.argmax(prediction,1)) 51 52 #求准确率 53 accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) 54 55 with tf.Session() as sess: 56 sess.run(init) 57 for epoch in range(20): 58 for batch in range(n_batch): 59 batch_xs,batch_ys=mnist.train.next_batch(batch_size) 60 sess.run(train_step,feed_dict={x:batch_xs, y:batch_ys, keep_prob:1.0})#keep_prob:1.0}所有的神经元都有用到,相当于dropout没有用 61 62 test_acc=sess.run(accuracy,feed_dict={x:mnist.test.images, y:mnist.test.labels,keep_prob:1.0}) 63 train_acc=sess.run(accuracy,feed_dict={x:mnist.train.images, y:mnist.train.labels,keep_prob:1.0}) 64 print("Iter"+str(epoch)+",Testing Accuracy "+str(test_acc)+",Training Accuracy "+str(train_a
没有使用Dropout的运行结果
迭代到11次时几乎收敛了。但是测试值和训练值相差将近2%,训练集测试准确率很高,但是测试集准确率与训练集有很大的偏差,这就是过拟合现象
如果把上述代码的60,62,63行的keep_prob:1.0改为keep_prob:0.7即
sess.run(train_step,feed_dict={x:batch_xs, y:batch_ys, keep_prob:0.7})
test_acc=sess.run(accuracy,feed_dict={x:mnist.test.images, y:mnist.test.labels,keep_prob:0.7}) train_acc=sess.run(accuracy,feed_dict={x:mnist.train.images, y:mnist.train.labels,keep_prob:0.7})
keep_prob:0.7表示神经元只用到了70%还有30%没有用到。再运行一下代码会得到如下结果
训练集与测试集的偏差很小,可以说没有过拟合或者过拟合程度很小