TensorFlow-邏輯斯蒂迴歸-Python

使用Python jupyter notebook

導包

import warnings
warnings.filterwarnings('ignore')
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data #tutorial說明書

mnist 美國一個研究機構的縮寫
研究機器學習 需要素材
最開始的時候 使用的就是手寫數字
TensorFlow 裏面有很多案例使用的就是這個樣本集
55000張訓練數據
10000張測試數據

加載數據目標值 類別

mnist=input_data.read_data_sets('./')
mnist
#裏面有validation 驗證數據
#有的分的細 將數據分成三份
mnist.validation.images.shape
#(5000, 784)
mnist.train.images.shape #28*28=724
(55000, 784)
mnist.train.labels[:50]
#array([7, 3, 4, 6, 1, 8, 1, 0, 9, 8, 0, 3, 1, 2, 7, 0, 2, 9, 6, 0, 1, 6,7, 1, 9, 7, 6, 5, 5, 8, 8, 3, 4, 4, 8, 7, 3, 6, 4, 6, 6, 3, 8, 8,9, 9, 4, 4, 0, 7], dtype=uint8)
mnist.test.images.shape
#(10000, 784)

加載數據 目標值變成概率形式 one-hot

mnist=input_data.read_data_sets('./',one_hot=True)
mnist
mnist.train.images.shape
#(55000, 784)
mnist.train.labels[:10]
#屬於7的概率是1  屬於3的概率是1 對應上面的[7, 3, 4, 6, 1, ...]
#array([[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
#       [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
#       [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],..

構建方程

X=tf.placeholder(dtype=tf.float64,shape=(None,784),name='data')
y=tf.placeholder(dtype=tf.float64,shape=(None,10),name='target')
W=tf.Variable(initial_value=tf.zeros(shape=(784,10),dtype=tf.float64)) #因爲y是one-hot 10個值
b=tf.Variable(initial_value=tf.zeros(shape=(10),dtype=tf.float64)) #10個方程 
y_pred=tf.matmul(X,W)+b
y_pred
#<tf.Tensor 'add:0' shape=(?, 10) dtype=float64> ?代表之後添加值後會自動變

構建損失函數

#y和y_pred對比
#y表示是概率[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.]
#y_pred,矩陣運算求解的目標值
#要將y_pred轉化成概率 softmax
y_=tf.nn.softmax(y_pred)
y_
#此時y和y_表示概率
#y和y_越接近 說明預測函數月準確
#<tf.Tensor 'Softmax:0' shape=(?, 10) dtype=float64>
此時不是迴歸問題 不能用最小二乘法 此時屬於分類問題 可以使用交叉熵 表示損失函數 熵:表示的系統混亂程度 交叉熵 是 y和y_ 相乘 計算出的混亂程度比較高 比 熵(pi*pi也就是y*y)高 高出來的就是差值

熵公式
entropy=i=0Npilog2pientropy=-\sum_{i=0}^{N}pi*log_2{pi}
交叉熵 pi代表真實分佈y qi代表算法預測分佈y_
cross_entropy=i=0Npilog2qicross\_entropy=-\sum_{i=0}^{N}pi*log_2{qi}
corss_entropy=i=0Npilog21qicorss\_entropy=\sum_{i=0}^Npi*log_2{\frac{1}{qi}}
因此,交叉熵越低,這個策略就越好,最低的交叉熵也就是使用了真實分佈所計算出來的信息熵,因爲此時 ,交叉熵 = 信息熵。
這也是爲什麼在機器學習中的分類算法中,我們總是最小化交叉熵,因爲交叉熵越低,就證明由算法所產生的策略最接近最優策略,
也間接證明我們算法所算出的非真實分佈越接近真實分佈。

#損失函數 越小越好
#平均交叉熵--->可以比較大小的數
loss=tf.reduce_mean(tf.reduce_sum(tf.multiply(y,tf.log(1/y_)),axis=-1))

最優化

opt = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

訓練

我們一共有55000個數據,將它分爲100份,每次去550個進行操作mnist.train.next_batch()下一批的意思

epoches = 100 #訓練次數
# 保存
saver = tf.train.Saver()

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())    
    for i in range(epoches):
        c = 0 #損失值
        for j in range(100):
            X_train,y_train = mnist.train.next_batch(550)
            opt_,cost = sess.run([opt,loss],feed_dict = {X:X_train,y:y_train})
            c += cost/100
#         計算準確率
        X_test,y_test = mnist.test.next_batch(2000)      
        y_predict = sess.run(y_,feed_dict={X:X_test})        
        y_test = np.argmax(y_test,axis = -1)
        y_predict = np.argmax(y_predict,axis = 1)        
        accuracy = (y_test == y_predict).mean()
        print('執行次數:%d。損失函數是:%0.4f。準確率是:%0.4f'%(i+1,c,accuracy))      
        if accuracy > 0.91:
            saver.save(sess,'./model/estimator',global_step=i)
            print('---------------------------模型保存成功----------------------------')

保存了模型,在上一次訓練的基礎上繼續進行學習

with tf.Session() as sess:
    #還原到sess會話中
    saver.restore(sess,'./model/estimator-99') #restore 還原 不需要變量初始化了
    for i in range(100,200):
        c=0
        for j in range(100):
            X_train,y_train=mnist.train.next_batch(550)
            opt_,cost=sess.run([opt,loss],feed_dict={X:X_train,y:y_train})
            c+=cost/100
        #計算準確率
        X_test,y_test=mnist.test.next_batch(2000)
        y_predict=sess.run(y_,feed_dict={X:X_test})
        y_test=np.argmax(y_test,axis=-1)   
        y_predict=np.argmax(y_predict,axis=1)
        accuracy=(y_test==y_predict).mean()
        print('執行次數:%d。損失函數是:%0.4f。準確率是:%0.4f'%(i+1,c,accuracy))
        if accuracy>0.92:
            saver.save(sess,'./model/estimator',global_step=i)
            print('---------------------模型保存成功-----------------------')        
with tf.Session() as sess:
#     還原到sess會話中
    saver.restore(sess,'./model/estimator-199')  
    for i in range(200,300):
        c = 0
        for j in range(100):
            X_train,y_train = mnist.train.next_batch(550)
            opt_,cost = sess.run([opt,loss],feed_dict = {X:X_train,y:y_train})
            c += cost/100        
#         計算準確率
#        整體數據劃分成兩份:train,test
#        validation驗證,測試一樣,劃分細緻分成三份:train,validation,test
        X_test,y_test = mnist.validation.next_batch(2000)    
        y_predict = sess.run(y_,feed_dict={X:X_test})        
        y_test = np.argmax(y_test,axis = -1)
        y_predict = np.argmax(y_predict,axis = 1)        
        accuracy = (y_test == y_predict).mean()
        print('執行次數:%d。損失函數是:%0.4f。準確率是:%0.4f'%(i+1,c,accuracy))        
        if accuracy > 0.92:
            saver.save(sess,'./model/estimator',global_step=i)
            print('---------------------------模型保存成功----------------------------')

總結:一般分類數據都用one-hot表示,它可以表示概率,分類問題一般都用概率表示。
交叉熵 可以參考 https://www.zhihu.com/question/41252833

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