python tf学习(三) 手动实现logistic逻辑斯蒂算法手写数字识别
import tensorflow as tf
from tensorflow.examples.tutorials.mnist.input_data import read_data_sets
# 实现机器学习算法的三个步骤
# 1. 找到目标函数 : 逻辑斯蒂函数 1/ (1 + e^-θX)
# 2. 找到损失函数: 交叉熵损失. ∑pk.log(1/qk)
# 3. 找到让损失最小的时候的系数, 梯度下降法
# 找到一个分界线的回归方程,带入逻辑斯蒂函数中,转化为概率,通过概率进行分类.
# 逻辑斯蒂函数只能做2类.
# 使用softmax实现多分类.
# 使用独热编码, 把真实标记变成10个数, 10个数对应10个概率.
# 所谓的独热编码就是, 在标记位上记1, 其他位置上置0.
# digits shape(55000,784)
digits = read_data_sets('./', one_hot=True)
# 定义预测函数
# 定义X原始数据,Y标记结果为占位符
X = tf.placeholder(dtype=tf.float64, shape=(None, 784))
Y = tf.placeholder(dtype=tf.float64, shape=(None, 10))
# 定义W,B为变量
W = tf.Variable(initial_value=tf.random_normal(shape=(784, 10), stddev=0.1, dtype=tf.float64), shape=(784, 10))
B = tf.Variable(initial_value=tf.zeros(shape=10, dtype=tf.float64))
# 线性方程
Y_pred = tf.add(tf.matmul(X, W), B) # X shape (100, 784) . W (784, 10) + B (10) -> (100, 10)
# 概率
Y_proba = tf.nn.softmax(Y_pred) # 变成10个概率了, shape: (None, 10)
# 定义损失函数 (None, 10)
cost = tf.reduce_mean(Y * tf.log(1 / Y_proba)) # Y和Y_proba的shape是一样 的,所以可以直接相乘, 这个时候是对应的元素 相乘
# 定义优化器, AdamOptimizer 是对普通梯度下降法的改进.
optimizer = tf.train.AdamOptimizer(0.01).minimize(cost)
# 初始化
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for i in range(20):
# 一遍所有数据epoch
for j in range(550):
X_train, y_train = digits.train.next_batch(batch_size=100)
sess.run(optimizer, feed_dict={X: X_train, Y: y_train})
X_test, y_test = digits.test.next_batch(5000) # 总共有10000个测试
loss = sess.run(cost, feed_dict={X: X_test, Y: y_test})
prob = sess.run(Y_proba, feed_dict={X: X_test})
# 从10个概率找到最大的概率的下标,axis=1 (5000,10) 和测试的标记比较, tf.cast转化为0和1 计算
acc = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(prob, axis=1), tf.argmax(y_test, axis=1)), dtype=tf.float64))
acc_ = sess.run(acc)
print(f'损失:{loss},准确率:{acc_}')
# 最终的准确率
X_test, y_test = digits.test.next_batch(5000)
prob = sess.run(Y_proba, feed_dict={X: X_test})
acc = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(prob, axis=1), tf.argmax(y_test, axis=1)), dtype=tf.float64))
acc_ = sess.run(acc)
print(f'准确率:{acc_}')
好好学习,天天向上