使用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)高 高出来的就是差值
熵公式
e
n
t
r
o
p
y
=
−
∑
i
=
0
N
p
i
∗
l
o
g
2
p
i
entropy=-\sum_{i=0}^{N}pi*log_2{pi}
entropy=−i=0∑Npi∗log2pi
交叉熵 pi代表真实分布y qi代表算法预测分布y_
c
r
o
s
s
_
e
n
t
r
o
p
y
=
−
∑
i
=
0
N
p
i
∗
l
o
g
2
q
i
cross\_entropy=-\sum_{i=0}^{N}pi*log_2{qi}
cross_entropy=−i=0∑Npi∗log2qi
c
o
r
s
s
_
e
n
t
r
o
p
y
=
∑
i
=
0
N
p
i
∗
l
o
g
2
1
q
i
corss\_entropy=\sum_{i=0}^Npi*log_2{\frac{1}{qi}}
corss_entropy=i=0∑Npi∗log2qi1
因此,交叉熵越低,这个策略就越好,最低的交叉熵也就是使用了真实分布所计算出来的信息熵,因为此时 ,交叉熵 = 信息熵。
这也是为什么在机器学习中的分类算法中,我们总是最小化交叉熵,因为交叉熵越低,就证明由算法所产生的策略最接近最优策略,
也间接证明我们算法所算出的非真实分布越接近真实分布。
#损失函数 越小越好
#平均交叉熵--->可以比较大小的数
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