天天看點

4.防止過拟合,使用dropout, 并增加隐藏層

過拟合的了解:線性問題中的過拟合,分類問題的中過拟合

防止過拟合: 1.增加資料集,2.正則化方法 3.Dropout

正則化:就是在代價函數後增加正則項

4.防止過拟合,使用dropout, 并增加隐藏層

Dropout:神經元的随機失活

tensorflow中屏蔽輸出的log資訊方法
TF_CPP_MIN_LOG_LEVEL 取值 0 : 0也是預設值,輸出所有資訊
TF_CPP_MIN_LOG_LEVEL 取值 1 : 屏蔽通知資訊
TF_CPP_MIN_LOG_LEVEL 取值 2 : 屏蔽通知資訊和警告資訊
TF_CPP_MIN_LOG_LEVEL 取值 3 : 屏蔽通知資訊、警告資訊和報錯資訊

import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '0'
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1'
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
           
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
batch_size = 100 
n_batch = mnist.train.num_examples // batch_size

x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10]) 
keep_prob = tf.placeholder(tf.float32)  #設定dropout

#我們一般不初始化為0,一般是以下的初始化,效果會好一點 ====== 并增加新的隐藏層
W1 = tf.Variable(tf.truncated_normal([784,2000],stddev=0.1)) #截斷的正太分布
b1 = tf.Variable(tf.zeros([2000])+0.1) #b是等于w的列
L1 = tf.nn.tanh(tf.matmul(x,W1)+b1)
L1_drop = tf.nn.dropout(L1, keep_prob) #用tenserflow封裝好的函數,keep_prob=1表示100%的工作, 在工作的時候通過placeholder傳入
#輸出2000個神經元
W2 = tf.Variable(tf.truncated_normal([2000,2000],stddev=0.1)) #截斷的正太分布
b2 = tf.Variable(tf.zeros([2000])+0.1)
L2 = tf.nn.tanh(tf.matmul(L1_drop,W2)+b2)
L2_drop = tf.nn.dropout(L2, keep_prob)
#輸出1000個神經元
W3 = tf.Variable(tf.truncated_normal([2000,1000],stddev=0.1)) #截斷的正太分布
b3 = tf.Variable(tf.zeros([1000])+0.1)
L3 = tf.nn.tanh(tf.matmul(L2_drop,W3)+b3)
L3_drop = tf.nn.dropout(L3, keep_prob)

#輸出10個神經元
W4 = tf.Variable(tf.truncated_normal([1000,10],stddev=0.1)) #截斷的正太分布
b4 = tf.Variable(tf.zeros([10])+0.1)
#softmax将輸出轉化為機率值
prediction = tf.nn.softmax(tf.matmul(L3_drop, W4) + b4)

#二次代價函數
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y, logits=prediction)) #logits預測值
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)

corrent_prediction =tf.equal(tf.argmax(y,1), tf.argmax(prediction, 1))
accuracy = tf.reduce_mean(tf.cast(corrent_prediction, tf.float32))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(31):
        for batch in range(n_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train_step, feed_dict={x:batch_xs, y:batch_ys, keep_prob:0.7}) #keep_porb=1.0表示所有神經元都是工作的
            
        test_acc = sess.run(accuracy, feed_dict={x:mnist.test.images, y:mnist.test.labels, keep_prob:1.0})
        train_acc = sess.run(accuracy, feed_dict={x:mnist.train.images, y:mnist.train.labels, keep_prob:1.0})
        #一般都是用測試的資料來測試訓練的資料,這裡又用訓練是資料來進行測試,看看是否出現過拟合的現狀
        print('iter'+ str(epoch)+ ',Testing Accuracy' + str(test_acc),',Training Accuracy'+ str(train_acc))
           

總結: 使用dropout,會使收斂速度變慢。

使用dropout主要是防止過拟合的情況。用複雜的網絡來訓練比非常小的訓練集或模型,才能看到dropout的重要性

繼續閱讀