天天看點

Mnist資料集單隐層BP神經網絡參數調優

本次對mnist資料集采用單隐層的BP神經網絡,在對參數初始化,激活函數,學習率,正則系數選擇,隐層神經元數量選擇,随機采樣樣本數量進行調優後,模型在測試集上的正确率可以達到98%。

1、 參數初始化方式

首先調優w和b的初始化,對比了0矩陣指派tf.zero,均值和方差為0的正太分布指派tf.random_normal,發現随機指派可以收斂速度更快更好,故而選擇了随機指派。

2、 激活函數

在選擇0.3作為學習率時,sigmoid最慢,50k時僅0.97,到200k步時準确率才達到0.9722;而relu較快但正确率在50k時時0.978左右,selu在50k就可以達到0.9804

三種常用激活函數的特點

使用不同模型在minist測試集上,學習率取0.3時,正确率随步數變化
步數(k步) sigmoid relu selu
5 0.9426 0.9491 0.954
10 0.9641 0.9687 0.9715
15 0.9668 0.9796 0.9748
20 0.9618 0.9827 0.971
25 0.9647 0.9833 0.977
30 0.9657 0.9834 0.979
40 0.9689 0.984 0.9814
50 0.969 0.9827 0.9814
60 0.9701 0.9827 0.981
80 0.9703 0.9827 0.9813
100 0.9705 0.9828 0.981
200 0.9722 0.984 0.9804

本次對三種不同的模型,其中relu的性能最好0.984,selu其次,sigmoid最差也最慢,而本文選擇暫選擇了selu作為進一步的資料探索。

3、 學習率

3.1采用固定學習率

首先對比了0.1、0.2、0.25、0.3、0.35、0.4、0.45、0.5、0.7、0.9在計算收斂,此處計算50k步,結果顯示learn_rate=0.3-0.4時效果不錯。

Mnist資料集單隐層BP神經網絡參數調優

3.2采用可衰減學習率

Mnist資料集單隐層BP神經網絡參數調優

考察了學習率衰減的效果,對比了學習率在不同衰減速率下的效果,結果顯示當學習率取0.4時,模型的收斂速度與準确率較好,其在200k步左右可以達到最高進度。故而選擇帶衰減率的學習率,使得學習率在20k步時前保持0.4,随後開始衰減。

4、 正則參數

通過對比不同正則參數對訓練集和測試集上準确率造成的影響,後發現需要将模型訓練收斂後才能判斷參數是否适合,本次調優訓練5k步,進行觀測。

判斷的标準時,正則對應訓練集的正确率需要達到100%,在此間選擇測試集上正确率最高的,本次調優選擇的正則參數是0.0004.

5、 隐層神經元數量

曆遍100~2000區域,訓練100k步後,選擇了神經元數量=1200

6、 對min_batch進行調優

在曆遍100~1000的區域,訓練100k步後選擇了神經元數量=550

defTrain(batch_size=550,n1=1000,learn_rate_0=0.4,learn_rate_reduce=0.00001,regular_rate=0.0004,steps=10000,plot=False):

#此為第一層資料輸入層

   w1=tf.Variable(tf.random_normal([784,n1]))

   b1=tf.Variable(tf.random_normal([n1]))

   logits_1=tf.matmul(x,w1)+b1

   keep_prob = tf.placeholder(tf.float32)

   logits_1_drop = tf.nn.dropout(logits_1, keep_prob)

   h1=tf.nn.selu(logits_1)   

#單層神經網絡,相當于一個資料784維,其分10個神經元輸出故而每個神經元的權重w都有784個

   w2 = tf.Variable(tf.random_normal([n1,10]))

   b2 = tf.Variable(tf.random_normal([10]))

    y= tf.matmul(h1, w2) + b2

    #Define loss and optimizer

#定義我們的ground truth 占位符   

   y_ = tf.placeholder(tf.float32, [None, 10])

#使用正則函數   

#   L2_loss=regular_rate*(tf.nn.l2_loss(w1)+tf.nn.l2_loss(b1)+tf.nn.l2_loss(w2)+tf.nn.l2_loss(b2))

   tv = tf.trainable_variables()

   regularization_cost = regular_rate* tf.reduce_sum([ tf.nn.l2_loss(v) forv in tv ])

#接下來我們計算交叉熵,注意這裡不要使用注釋中的手動計算方式,而是使用系統函數。

#另一個注意點就是,softmax_cross_entropy_with_logits的logits參數是**未經激活的wx+b**

#此處定義損失函數

   cross_entropy =tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y)+regularization_cost)

   learn_rate=learn_rate_0*math.exp(-1*learn_rate_reduce*1)

#生成一個訓練step

   train_step =tf.train.GradientDescentOptimizer(learn_rate).minimize(cross_entropy)

   sess = tf.Session()

   init_op = tf.global_variables_initializer()

    sess.run(init_op)

#在這裡我們仍然調用系統提供的讀取資料,為我們取得一個batch。

#然後我們運作3k個step(5 epochs),對權重進行優化。   

   acc_dict_train={}

   acc_dict={}   #用于存儲一次運作中acc vs step

   for step in range(steps):

    #生成可衰減的學習率

       learn_rate=learn_rate_0*math.exp(-1*learn_rate_reduce*step)  

       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.5})

       if step%500==0:

           correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

           accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

#擷取測試集上的accuracy  

           acc=sess.run(accuracy, feed_dict={x: mnist.test.images,

                                             y_: mnist.test.labels,keep_prob:1})

           acc_dict[step]=acc

#擷取訓練集上的accuracy           

           acc_train=sess.run(accuracy, feed_dict={x: mnist.train.images,

                                             y_:mnist.train.labels,keep_prob:1})

           acc_dict_train[step]=acc_train

           if plot==True:

               print(step,round(step/steps*100,1),'%',acc,learn_rate)

#将accuracy随step變化繪制出來

   if plot==True:

       plt.figure(figsize=(8,4))

       plt.plot(acc_dict.keys(),acc_dict.values())

       plt.plot(acc_dict_train.keys(),acc_dict_train.values())

       plt.xlabel('step')

       plt.ylabel('accuracy')

       plt.show()

       best_value=max(acc_dict.values())

       best_key=list(acc_dict.keys())[list(acc_dict.values()).index(best_value)]

       print('Test_best_accuracy',best_key,best_value)

       best_value_train=max(acc_dict_train.values())

       best_key_train=list(acc_dict_train.keys())[list(acc_dict_train.values()).index(best_value_train)]

       print('Train_best_accuracy',best_value_train,best_key_train)

         # Test trained model

   correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

   accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

   acc=sess.run(accuracy, feed_dict={x: mnist.test.images,

                                      y_:mnist.test.labels,keep_prob:1})

   return(acc,acc_train)

繼續閱讀