1. 程式人生 > >01-基於TensorFlow的自定資料的三分類案例

01-基於TensorFlow的自定資料的三分類案例

一、前言:
由於筆者前段時間學習TensorFlow一直以看書為重心,並沒有很好的把學習到的知識轉變為具體的應用中來,並且前一段時間,為了準備期末考試,很多內容都沒有得到很好的記憶,為了貫穿相關知識,所以本系列博文將以實際案例為導向,結合自身所學知識和具體的應用來熟悉TensorFlow的執行機理和函式原理。本篇為第一篇,主要應用點是由機器學習拓展到深度學習中比較重要的一環,即從機器學習中的Logistic分類器拓展到深度學習softmax分類器,也就是把二分類任務拓展到多分類任務的實踐。其中還穿插介紹TensorFlow的相關基礎知識點。希望在接下來的實踐中能最大限度的把自身所學和實踐結合起來,給自己一個滿意的答卷。
另外,筆者處於焦灼的學習階段,有什麼問題請指正。

二、任務目標
使用softmat分類器進行三分類的任務,具體實現內容如下:
1. 產生自變數x,其有三個特徵值,一個因變數y,y的取值有1,2,3,並轉化為One-Hot編碼
2. 給定任意一函式 y=θ0+θ1*X1+θ2*X2+θ3*X3,這裡使用函式(f(X1,X2,X3)=3+7X1-4X2-X3 )作為判別標準,當f(X1,X2,X3)<0的時候,y的值取1,當0<=f(X1,X2,X3)<=5的時候,y的值取2,當f(X1,X2,X3)>5的時候,y的值取3.
3. 指定不同的裝置執行不同的節點
4. 模型的儲存和載入,以致於能在程式中斷之後可以通過過載來從儲存的節點進行下一次的訓練
5. tensorboard視覺化介面的啟用來梳理網路的構成

三、任務主要內容
1. 模擬資料構成

#設定產生500條樣本
n=500
#設定x為資料輸入,其形狀為500×3 的array
x_data=np.random.uniform(low=-5,high=5,size=(n,3))
#計算公式化的資料y輸出
y_data=np.dot(x_data,np.array([[7],[-4],[-1]]))

#y_data[y_data>=0 and y_data<=5]=1
y_data[y_data>5]=2
y_data[y_data<0]=0
y_data[y_data%1!=0]=1
#這裡將y_data的array資料修改為one-hot編碼,編碼後通過toarray的方法返回一個one-hot型別的陣列
y_data=OneHotEncoder(sparse=True).fit_transform(y_data).toarray()

.
2. 模型構建過程

#x,y定義為佔位符,作為模型的輸入介面
#根據所構建的資料集來定義佔位符的shape為(None,3)
x=tf.placeholder(tf.float32,[None,3],'x_ph')
y=tf.placeholder(tf.float32,[None,3],'y_ph')

#權重和偏執項的節點構建
w=tf.Variable(tf.ones([3,3]),dtype=tf.float32,name='w')
b=tf.Variable(tf.ones([3]),dtype=tf.float32,name='b')

.
3. 使用tf.nn.softmax 得到一個3分類的概率值

probability=tf.nn.softmax(tf.matmul(x,w)+b)

.
4. 計算損失函式並設定最小化損失函式的方式

#構建交叉熵損失函式
loss=tf.reduce_mean(-tf.reduce_sum(y*tf.log(probability),axis=1))
#loss=tf.nn.softmax_cross_entropy_with_logits(labels=y_hat,logits=y_pre,name='loss')

#設定學習率
learn_rate=0.01

#使用一般梯度下降方法的優化器
optimizer=tf.train.GradientDescentOptimizer(learning_rate=learn_rate)
train=optimizer.minimize(loss,name='train')

.
5. 計算準確率

#tf.argmax(probability,axis=1)  按行取概率最大的數的列索引資訊
#tf.argmax(y_data,axis=1)        實際按行取最大的數的列索引資訊
#tf.equal 用於判斷左右兩邊的列索引資訊是否相同,相同則分類正確
equal=tf.equal(tf.argmax(probability,axis=1),tf.argmax(y,axis=1))
#取均值計算正確率
correct=tf.reduce_mean(tf.cast(equal,tf.float32))

.
6. 建立Session()前的準備

#建立初始化變數init
init=tf.global_variables_initializer()

#建立easy_print方法
def easy_print(p_epoch,p_train_epochs,p_loss,p_accuracy):
    print("迭代次數:{}/{}, 損失值:{},訓練集上的準確率:{}".format(p_epoch,p_train_epochs,p_loss,p_accuracy))

#定義總迭代次數
training_epochs=5000
#定義小批量梯度下降的值為10,即使用10條資料迭代一次權重項和偏置引數
batch_size=int(n/10)

.
7. 建立Session()會話,訓練模型

with tf.Session(config=tf.ConfigProto(log_device_placement=True,allow_soft_placement=True)) as sess:
    #變數初始化
    sess.run(init)
    print(sess.run(loss,feed_dict={x:x_data[1:10],y:y_data[1:10]}))
    #迭代訓練
    for epoch in range(training_epochs):
        #打亂資料集的順序,返回資料集的索引資訊
        #使得每次迭代使用的資料不一致,提高資料的複用
        p_loss=0
        p_correct=0
        index=np.random.permutation(n)
        for i in range(batch_size):
            #獲取訓練集索引資訊
            train_index=index[i*10:(i+1)*10]
            #feed傳入引數,並進行模型訓練
            sess.run(train,feed_dict={x:x_data[train_index],y:y_data[train_index]})
            #獲取損失值,這裡計算的是每一個epoch下的batch_size次迭代的平均損失值
            p_loss+=sess.run(loss,feed_dict={x:x_data[train_index],y:y_data[train_index]})/batch_size
            #計算模型的正確率
            p_correct+=sess.run(correct,feed_dict={x:x_data[train_index],y:y_data[train_index]})/batch_size
            easy_print(epoch,training_epochs,p_loss,p_correct)
    result=sess.run([w,b])
    print("最終模型引數為:w={},\nb={}".format(result[0],result[1]))
print("模型訓練完成")

這裡寫圖片描述

四、補充內容
1. 模型的儲存和過載(這裡需要在相應位置新增)

#定義模型的儲存物件
saver=tf.train.Saver()
#=================================
if training_epochs%100==0:
    saver.save(sess,'softmax-model/model.ckpt')
#=================================
#重新建立一個Session()用於測試過載
with tf.Session() as sess:
    saver.restore(sess,'softmax-model/model.ckpt')
    print(sess.run([w,b]))

.
2. tensorboard視覺化(同樣在對應位置新增程式碼段)

#記錄資訊
tf.summary.scalar('w',w)
tf.summary.scalar('x_ph',x)
tf.summary.scalar('y_ph',y)
tf.summary.scalar('b',b)
#==========================================
#merge all summary
merged_summary=tf.summary.merge_all()
#輸出檔案,並建立writer物件
writer=tf.summary.FileWriter('./w_summary',sess.graph)
#===========================================

然後改目錄會自動建立一個名為w_summary的目錄
目錄下面有events.out.tfevents.1531106711.dream-T7610的檔案
然後在終端啟用tensorboard

tensorboard --logdir=w_summary

然後在瀏覽器中輸入localhost:6006
會顯示如下頁面
tensorboard顯示
.
3. 指定CPU或者GPU執行

#指定節點執行在裝置上
with tf.device('/cpu:0'):
    #這裡定義節點資訊
    '''
        ......
    '''

這裡具體的內容就不貼上去了,在以後的編寫過程中會有更加詳細的資訊。
這裡的程式碼其實並不是特別精簡與完善,因為很多庫的使用不是特別的熟練,還需要多加練習。如果有更加好的意見和建議希望拿出來一起學習與分享。

tips:這裡做的三分類實際上是做的線性分類任務,精確度相對沒有特別高,如果需要高的精確度的分類資訊,讀者可以嘗試增加隱層的層數,另外選擇合適的啟用函式以提供非線性的因素等內容。