使用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)高 高出來的就是差值
熵公式
交叉熵 pi代表真實分佈y qi代表算法預測分佈y_
因此,交叉熵越低,這個策略就越好,最低的交叉熵也就是使用了真實分佈所計算出來的信息熵,因爲此時 ,交叉熵 = 信息熵。
這也是爲什麼在機器學習中的分類算法中,我們總是最小化交叉熵,因爲交叉熵越低,就證明由算法所產生的策略最接近最優策略,
也間接證明我們算法所算出的非真實分佈越接近真實分佈。
#損失函數 越小越好
#平均交叉熵--->可以比較大小的數
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