Tensorflow中級教程——用於Mnist的CNN

教程來自人工智能社區

主要包括10節內容,實現簡單卷積神經網絡對MNIST數據集進行分類:conv2d + activation + pool + fc

#第1節:簡單卷積神經網絡的計算圖設計(上)
#第2節:簡單卷積神經網絡的計算圖設計(下)
#調用寫好的函數構造計算圖,並把計算圖寫入事件文件,在TensorBoard裏面查看
#寫好的函數:WeightsVariable、BiasesVariable、Conv2d、Activation、Pool2d、FullyConnected
#第3節:簡單卷積神經網絡的訓練和評估會話
#加入了csv文件收集訓練過程的數據
#通用的評估函數,用來評估模型在給定的數據集上的損失和準確率,爲了防止內存爆炸,將數據集切片
#第4節:卷積濾波器核的數量與網絡性能之間的關係
#研究卷積層中的卷積核個數K與在訓練集和驗證集上損失曲線、正確率曲線的關係
#在excise3_1_2的基礎上添加了一個變量conv1_kernels_num(卷積核個數K)
具體分析結果:點擊打開鏈接

#第5節:用Excel繪製網絡性能曲線
#輸出結果保存在logs/excise313/evaluate_results.csv,將文件另存爲.xlsx的Excel表格形式,繪製曲線

#第6節:改變網絡激活函數觀察網絡性能的變化
##非線性激活層with tf.name_scope('Activate')
##全連接層activate(wx+b)的封裝 def FullyConnected(x, W, b, activate=tf.nn.relu, act_name='relu')
#不同的激活函數適用於這兩處,詳見點擊打開鏈接
#保持卷積層(全連接層)的激活函數不變,不斷改變全連接層(卷積層)的激活函數,觀察網絡性能的變化
#3.7 學習率與權重初始化對網絡性能的影響分析
#學習率越大麴線抖動越大,網絡越不穩定,受初始條件的影響大
#學習率對網絡的訓練過程有着至關重要的影響:
#1.學習率比較小時,網絡的損失曲線下降的比較慢,但是損失曲線的形態在不同的隨機起始狀態下比較一致,波紋比較小
#2.學習率比較大時,網絡的損失曲線下降的比較快,但是損失曲線的形態在不同的隨機起始狀態下差別比較大,波紋比較大
#所以,學習率的設置應該遵循“穩中求進”的基本原則
#池化層變化對網絡性能的影響分析(最大池化與平均池化),小網絡中並沒有多少影響
#權重初始化對網絡性能的影響分析,默認情況下取stddev=0.1,不能取特別小的值
詳情見點擊打開鏈接

#3.8 使用10種不同的優化器訓練模型,觀察性能曲線
# 定義優化訓練層(train layer)(studyai.com)
with tf.name_scope('Train'):
    learning_rate = tf.placeholder(tf.float32)
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
    global_step = tf.Variable(0,name='global_step', trainable=False, dtype=tf.int64)
    #optimizer = tf.train.AdagradDAOptimizer(learning_rate=learning_rate, global_step=global_step)
    #optimizer = tf.train.AdadeltaOptimizer(learning_rate=learning_rate)
    #optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate)
    #optimizer = tf.train.ProximalGradientDescentOptimizer(learning_rate=learning_rate)
    #optimizer = tf.train.ProximalAdagradOptimizer(learning_rate=learning_rate)
    #RMSPropOptimizer這個優化器比較好,對學習率不太敏感,都能收斂
    #optimizer = tf.train.RMSPropOptimizer(learning_rate=learning_rate)
    #GradientDescentOptimizer這是最早的優化器,對學習率比較敏感
    #optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
    #optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate, momentum=0.9)
    #optimizer = tf.train.FtrlOptimizer(learning_rate=learning_rate)
    trainer = optimizer.minimize(cross_entropy_loss,global_step=global_step)

#3.9 增加一個非線性全連接層並觀察過擬合現象
#增加非線性全連接層with tf.name_scope('FC_ReLU')
#不斷全連接層的神經元個數,觀察其對網絡過擬合的影響

        # 第一個全連接層(fully connected layer)
        with tf.name_scope('FC_ReLU'):
            fcl_units_num = 100
            weights = WeightsVariable(shape=[12 * 12 * conv1_kernels_num, fcl_units_num], name_str='weights')
            biases = BiasesVariable(shape=[fcl_units_num], name_str='biases')
            fc_out = FullyConnected(features, weights, biases,
                                            activate=tf.nn.relu, act_name='relu')
        # 第二個全連接層(fully connected layer)
        with tf.name_scope('FC_Linear'):
            weights = WeightsVariable(shape=[fcl_units_num, n_classes], name_str='weights')
            biases = BiasesVariable(shape=[n_classes], name_str='biases')
            Ypred_logits = FullyConnected(fc_out, weights, biases,
                                          activate=tf.identity, act_name='identity')



#3.10 爲非線性全連接層添加正則化損失
#爲了防止過擬合,增加正則化技術
#方法一:爲非線性全連接層的權重輸出添加dropout正則化,即在FC_ReLU層後添加dropout層
#隨機失活的神經元比例keep_prob,取值0-1,不能取0
#值越大,保留的越多,隨機失活(使其輸出爲0)的神經元越少,即丟棄的越少,正則化強度越弱
設置超參數:keep_prob_init = 0.5
        #dropout層,正則化技術
        with tf.name_scope('Dropout'):
            keep_prob = tf.placeholder(tf.float32)
            fc_dropout = tf.nn.dropout(fcl_out, keep_prob)
                # 運行優化器訓練節點 (backprop)
                sess.run(trainer, feed_dict={X_origin: batch_x,
                                             Y_true: batch_y,
                                             learning_rate: learning_rate_init,
                                             keep_prob: keep_prob_init})

#方法二:爲非線性全連接層的權重添加L2正則化
# 即在FC_ReLU層中添加權重的L2損失,並將其與交叉熵損失相加得到總體損失
#正則化強度係數wd,取值0-1
#值越大,正則化強度越強,取0.1,0.01,0.001,0.0001
#保存l2loss的輸出結果
        # 第一個全連接層(fully connected layer)
        with tf.name_scope('FC_ReLU'):
            fcl_units_num = 100
            weights = WeightsVariable(shape=[12 * 12 * conv1_kernels_num, fcl_units_num], name_str='weights')
            biases = BiasesVariable(shape=[fcl_units_num], name_str='biases')
            fc_out = FullyConnected(features, weights, biases,
                                            activate=tf.nn.relu, act_name='relu')
            #爲非線性全連接層添加L2正則化損失
            with tf.name_scope('L2_Loss'):
                weights_loss = tf.nn.l2_loss(weights)
    # 定義損失層(loss layer)
    with tf.name_scope('Loss'):
        wd = 0.00001
        with tf.name_scope('XEntroyLoss'):
            cross_entropy_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
                labels=Y_true, logits=Ypred_logits))
        with tf.name_scope('TotalLoss'):
            weights_loss = wd * weights_loss
            #總體的損失 = 經驗損失 + 正則化損失
            total_loss = cross_entropy_loss + weights_loss
                    # 計算當前模型的正則化損失,用以保存到.csv文件
                    l2loss = sess.run(weights_loss)

                    # 將評估結果保存到文件
                    results_list.append([training_step, train_loss, validation_loss,l2loss,
                                         training_step, train_acc, validation_acc])


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章