逻辑回归区别于线性回归,因为线性回归是预测一个连续的变量,例如函数拟合,而逻辑回归的最终目的是分类,例如对手写字体进行分类。进行编程的时候,它们之间最大的区别在于损失函数的设置。
#2021.10.14 HIT ATCI LZH
#TensorFlow逻辑回归处理MNIST数据集
import tensorflow as tf
import matplotlib.pyplot as plt, matplotlib.image as mping
from tensorflow.examples.tutorials import mnist
from tensorflow.examples.tutorials.mnist import input_data
from tensorflow.python import summary
from tensorflow.python.framework.ops import name_scope
from tensorflow.python.ops.gen_array_ops import one_hot
from tensorflow.python.ops.gen_logging_ops import merge_summary
from tensorflow.python.ops.gen_nn_ops import max_pool
from tensorflow.python.training import optimizer
from tensorflow.python.training.input import batch
max_epochs = 100
batch_size = 100
#导入数据集
mnist = input_data.read_data_sets('MNIST_data/', one_hot = True) #如果当前文件夹下没有 MNIST_data,会首先创建该文件夹,然后下载mnist数据集,有的话直接打开
#在 TensorFlow 图中为训练数据集的输入 x 和标签 y 创建占位符,创建占位符的时候需要指明数据类型和shape
X = tf.placeholder(tf.float32,shape = [None, 784], name='X') #None表示行数待定,依照feed时的大小而定
Y = tf.placeholder(tf.float32, shape = [None, 10], name='Y')
#创建Tensorflow的权重和偏置且初始值设为0
W = tf.Variable(tf.zeros([784, 10]), name = 'w')
b = tf.Variable(tf.zeros([10]), name = 'b')
#创建逻辑回归模型
y_hat = tf.nn.softmax(tf.matmul(X, W) + b)
#定义交叉熵(cross-entropy)和损失(loss)函数,并添加 name scope 和 summary 以实现更好的可视化。使用 scalar summary 来获得随时间变化的损失函数。scalar summary 在 Events 选项卡下可见
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=y_hat))
#采用 TensorFlow GradientDescentOptimizer,学习率为 0.01。为了更好地可视化,定义一个 name_scope:
optimizer = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
#为变量初始化:
init_op = tf.global_variables_initializer()
#现在,定义会话并将所有的summary存储在定义的文件夹中
epoch_loss = [] #存储每次epoch的loss
with tf.Session() as sess:
sess.run(init_op) #初始化所有变量
#开始训练
for epoch in range(max_epochs):#max_epochs指最大次数
loss_avg = 0 #平均误差
num_of_batch = int(mnist.train.num_examples / batch_size)
for i in range(num_of_batch):
batch_xs, batch_ys = mnist.train.next_batch(100) #得到下一批数据
_,l = sess.run([optimizer, loss],feed_dict = {X: batch_xs, Y: batch_ys}) #run the optimizer
loss_avg += l
loss_avg = loss_avg/num_of_batch
epoch_loss.append(loss_avg)
print('Epoch {0} : Loss {1}'.format(epoch, loss_avg))
print('Done!')
#计算模型对测试集的准确率
correct_prediction = tf.equal(tf.argmax(y_hat, 1), tf.argmax(Y, 1))#tf.equal返回Bool型变量
acc = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print("Accuracy: %",100*acc.eval({X: mnist.test.images, Y: mnist.test.labels}))#tf.cast用于转换数据类型
#绘制损失函数曲线
plt.figure(1)
plt.title('loss')
plt.plot(epoch_loss)
plt.show()
epoch是指所有的训练样本进入模型进行训练一次,而batchsize是指进行一次参数的学习所导进去的样本,一定程度而言,batchsize越大,一次读入内存的数据量变越大,因此对内存的利用率便越大。