在tensorflow1.2版本下糾正書上一個函數(shù)的用法

看了幾天的Deep Learnning的書,全是高數(shù)公式,看得一臉懵逼, 所以找了個tensorflow的例子看看這個些矩陣變化的意義。機(jī)器學(xué)習(xí)交流可訪問
http://www.jokls.com

這里是tensorflow 書上的一個列子MNIST,數(shù)據(jù)來源 http://yann.lecun.com/exdb/mnist/
就是一個手寫體阿拉伯?dāng)?shù)字的圖像識別的程序。

訓(xùn)練集有55000張圖片, 檢驗集中有5000張圖片,處理后的每張圖片都是784像素的一維數(shù)組,數(shù)組中的數(shù)字對應(yīng)了 (28*28=784) 像素矩陣中的每一個數(shù)字

我安裝的tensorflow版本是 1.2 whl.
書上的例子在tensorflow1.2上運行不了, 會報錯, 看了tensorflow的這個sparse_softmax_cross_entropy_with_logits函數(shù)的源碼,發(fā)現(xiàn)調(diào)用方式有變化,改成這樣即可:
tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))

程序代碼如下:

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf


INPUT_NODE= 784  #輸入層的節(jié)點數(shù),即為圖片的像素
OUTPUT_NODE = 10 #輸出的節(jié)點數(shù),在MINST中需要區(qū)分的是0-9,所以輸出節(jié)點數(shù)是10

LAYER1_NODE= 500 #隱藏層的節(jié)點數(shù)

BATCH_SIZE= 100 #一個訓(xùn)練batch中的訓(xùn)練數(shù)據(jù)個數(shù), 值越少越接近隨機(jī)梯度,值越大越接近梯度下降

LEARNING_RATE_BASE= 0.8   #基礎(chǔ)學(xué)習(xí)率
LEARNING_RATE_DECAY= 0.99 #學(xué)習(xí)率的衰減率


REGULARIZATION_RATE= 0.0001    #描述模型復(fù)雜度正則化項在損失函數(shù)中的系數(shù)
TRAINING_STEPS= 30000          #訓(xùn)練輪數(shù)
MOVING_AVERAGE_DECAY= 0.99     #滑動平均衰減率

#計算神經(jīng)網(wǎng)絡(luò)的前向傳播結(jié)果
# 在這里定義了一個使用ReLU激活函數(shù)的三層全連接神經(jīng)網(wǎng)絡(luò),通過加入隱藏層實現(xiàn)了多層網(wǎng)絡(luò)結(jié)構(gòu)
#通過ReLu激活函數(shù)實現(xiàn)了去線性化,這個函數(shù)也支持滑動平均計算mean(股票的MACD就是用這個滑動平均算的)
def inference(input_tensor, avg_class, weight1,biases1, weight2, biases2):
    #如果沒有提供滑動平均函數(shù),則直接使用參數(shù)當(dāng)前值
    if avg_class == None:
        #計算隱藏層的前向傳播結(jié)果,這里使用ReLU作為激活函數(shù)
        layer1 = tf.nn.relu(tf.matmul(input_tensor,weight1) + biases1)

        #計算輸出層前向傳播的結(jié)果,因為在計算損失函數(shù)時會一并計算softmax 函數(shù)
        #所以這里不需要加入激活函數(shù),而且不加入softmax函數(shù)也不會影響結(jié)果,因為預(yù)測時使用的是
        #不同類別對應(yīng)節(jié)點輸出值的大小,有沒有softmax層對最后分類結(jié)果的計算沒有影響,于是在計算整個神經(jīng)
        #網(wǎng)絡(luò)的前向傳播時可以不加入最后的softmax層
        return tf.matmul(layer1, weight2) + biases2
    else:
        #先使用avg_class計算變量的滑動平均值,然后再計算神經(jīng)網(wǎng)絡(luò)前向傳播結(jié)果
        layer1 = tf.nn.relu(tf.matmul(input_tensor, avg_class.average(weight1)) + avg_class.average(biases1))

        return tf.matmul(layer1, avg_class.average(weight2)) + avg_class.average(biases2)

#神經(jīng)網(wǎng)絡(luò)訓(xùn)練函數(shù)
def train(minst):
    x = tf.placeholder(tf.float32, [None, INPUT_NODE], name="x_input")
    y_ = tf.placeholder(tf.float32, [None, OUTPUT_NODE], name="y_input")


    #生成隱藏層的參數(shù)
    weight1= tf.Variable(tf.truncated_normal([INPUT_NODE, LAYER1_NODE], stddev= 0.1))
    biases1= tf.Variable(tf.constant(0.1, shape=[LAYER1_NODE]))

    #生成輸出層的參數(shù)
    weight2= tf.Variable(tf.truncated_normal([LAYER1_NODE, OUTPUT_NODE], stddev= 0.1))
    biases2= tf.Variable(tf.constant(0.1, shape=[OUTPUT_NODE]))

    #計算當(dāng)前參數(shù)下神經(jīng)網(wǎng)絡(luò)前向傳播的結(jié)果
    y = inference(x, None, weight1, biases1, weight2, biases2)

    #定義存儲訓(xùn)練輪數(shù)的變量,這個變量不需要計算滑動平均值,所以這里指定這個變量為不可訓(xùn)練的變量(trainable=False)
    #在使用Tensorflow訓(xùn)練神經(jīng)網(wǎng)絡(luò)時,一般將代表訓(xùn)練輪數(shù)的變量指定為不可訓(xùn)練的參數(shù)
    global_step= tf.Variable(0, trainable=False)

    #給定滑動平均衰減率和訓(xùn)練輪數(shù)的變量,初始化滑動平均類
    variable_avg= tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)


    variable_avg_op= variable_avg.apply(tf.trainable_variables())

    avg_y= inference(x, variable_avg, weight1, biases1, weight2, biases2)


    #計算交叉熵作為刻畫預(yù)測值與真實值之間差距的損失函數(shù),這里使用了Tensorflow的sparse_softmax_cross_entropy_with_logits函數(shù)來計算交叉熵
    #當(dāng)分類問題只有一個正確答案是,這個函數(shù)可以加速交叉熵的計算。MNIS

    #cross_entopy= tf.nn.sparse_softmax_cross_entropy_with_logits(y, tf.argmax(y_, 1))
    cross_entopy= tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))



    print("cross_entopy = ",cross_entopy)
    #這里是計算使用reduce_mean求向量的均值,也就是Loss函數(shù)的值,如果要求代價函數(shù)H的值,則需要使用tf.reduce_sum
    cross_entopy_mean= tf.reduce_mean(cross_entopy)

    #計算L2的正則化損失函數(shù)
    regularizer= tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)

    #計算模型的正則化損失,一般只計算神經(jīng)網(wǎng)絡(luò)邊上權(quán)重的正則化損失,而不使用偏置項
    regularization= regularizer(weight1) + regularizer(weight2)

    #總得損失函數(shù)的值等于交叉熵的值和正則化損失之和
    loss= cross_entopy_mean + regularization


    #設(shè)置指數(shù)衰減的學(xué)習(xí)率
    learning_rate= tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, minst.train.num_examples, LEARNING_RATE_DECAY)

    #使用梯度下降優(yōu)化算法來優(yōu)化損失函數(shù), 這里的損失函數(shù)包含了交叉熵和L2正則化損失
    train_step= tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step= global_step)


    #在神經(jīng)網(wǎng)絡(luò)中,每循環(huán)一遍,就需要更新通過反向傳播來更新參數(shù)的值,并且更新參數(shù)的滑動平均值
    #為了一次完成這兩個操作,Tensorflow提供了 control_dependencies 和group兩種機(jī)制,結(jié)果是等價的
    with tf.control_dependencies([train_step,variable_avg_op]):
        train_op= tf.no_op(name='train')

    #檢查使用了滑動平均模型的神經(jīng)網(wǎng)絡(luò)前向傳播結(jié)果是否正確
    #tf.argmax()用來獲取每一個樣例的預(yù)測結(jié)果, argmax 的第二個參數(shù)"1"表示選取最大值得操作僅在第一個維度中進(jìn)行,也就是只在第一行選取最大值得下標(biāo)
    #于是就得到一個長度為batch的一維數(shù)組,這個一維數(shù)組中的值就表示了每一個樣例對應(yīng)數(shù)字的識別結(jié)果, tf.equal用來判斷兩個張量的每一維是否相等
    correct_prediction = tf.equal(tf.argmax(avg_y,1),tf.argmax(y_,1))

    #這里是將一個布爾類型的值轉(zhuǎn)換成實數(shù)類型的值,然后計算平均值,這個平均值就是模型在這一組數(shù)據(jù)上的正確率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

    with tf.Session() as sess:
        tf.global_variables_initializer().run()

        #準(zhǔn)備驗證數(shù)據(jù).一般在神經(jīng)網(wǎng)絡(luò)的訓(xùn)練過程中會通過驗證數(shù)據(jù)來大致判斷停止的條件和評判訓(xùn)練的效果
        validate_feed = {x: minst.validation.images, y_: minst.validation.labels}

        #準(zhǔn)備測試數(shù)據(jù),在真是的應(yīng)用中,這部分?jǐn)?shù)據(jù)在訓(xùn)練時是不可見的,這個數(shù)據(jù)是模型的優(yōu)劣的最后評價標(biāo)準(zhǔn)
        test_feed= {x:minst.test.images, y_:minst.test.labels}

        for i in range(TRAINING_STEPS):
            if i % 1000 == 0:
                #計算滑動平均模型在驗證數(shù)據(jù)上的結(jié)果
                validate_acc = sess.run(accuracy, feed_dict=validate_feed)
                print("After %d traing step(s), validation accuracy use average model is %g" % (i, validate_acc))
            xs, ys = minst.train.next_batch(BATCH_SIZE)

            sess.run(train_op,feed_dict={x:xs, y_:ys})
        #訓(xùn)練結(jié)束后 在測試數(shù)據(jù)上檢測神經(jīng)網(wǎng)絡(luò)模型的最終正確率
        test_acc=sess.run(accuracy,feed_dict=test_feed)
        print("After %d traing step(s), validation accuracy use average model is %g" % (TRAINING_STEPS, test_acc))

def main(argv=None):
    minst = input_data.read_data_sets("/path/to/Minst_Data", one_hot=True)

    print("trainning dataset ", minst.train.num_examples)
    print("trainning data label  ", minst.train.labels[0])
    train(minst)

if __name__ == '__main__':
    tf.app.run()

識別的準(zhǔn)確率能達(dá)到 98.5%

Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容