Tensorflow之逻辑回归(基于MNIST数据集)

一、操作环境

tensorflow 1.13.0(建议使用1.几的版本 2.0很多地方都不兼容)

python 3.7.0(pycharm)

二、数据集的准备

将mnist数据集下载至指定目录位置

例:

 

 无需解压。

Tensorflow导入mnist代码:

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import os
import matplotlib.pyplot as plt
os.environ["CUDA_VISIBLE_DEVICES"]="0"
#导入mnist数据集
MINIST_data=r'D:\mnist' #数据集存放位置
mnist=input_data.read_data_sets(MINIST_data,one_hot=True)
print("类型是 %s"%(type(mnist)))
print (" 训练数据有 %d" % (mnist.train.num_examples))
print (" 测试数据有 %d" % (mnist.test.num_examples))
trainimg   = mnist.train.images
trainlabel = mnist.train.labels
testimg    = mnist.test.images
testlabel  = mnist.test.labels
print (" 数据类型 is %s"    % (type(trainimg)))
print (" 标签类型 %s"  % (type(trainlabel)))
print (" 训练集的shape %s"   % (trainimg.shape,))
print (" 训练集的标签的shape %s" % (trainlabel.shape,))
print (" 测试集的shape' is %s"    % (testimg.shape,))
print (" 测试集的标签的shape %s"  % (testlabel.shape,))

运行结果:

 

数据集解释

Mnist数据集是来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据。

分为训练数据(train)和测试数据(test),训练集和测试集分别对应相应的lable(标签)

训练集的shape为(55000,784),55000是指有55000行图像,784=28*28理解为这些图像的长和宽,每张图由784个像素点组成。训练集的标签的shape是(55000, 10),55000还是指有55000张图像,10是指有10类标签,0到9一共是10个数据。每张图都会对应着这十类标签。

例如:这张图片为显示的数字为2 那么其对应的标签则是[0,0,1,0,0,0,0,0,0,0],同理若对应为8,则[0,0,0,0,0,0,0,0,1,0]

下面让我们来看一下图像具体样子

代码:

nsample=5
#随机挑选5张图
randidx = np.random.randint(trainimg.shape[0], size=nsample)
#遍历
for i in randidx:
    curr_img=np.reshape(trainimg[i,:],(28,28))
    curr_lable=np.argmax(trainlabel[i,:])
    plt.matshow(curr_img,cmap=plt.get_cmap('gray'))
    print(""+str(i)+"th 训练数据"+"标签是"+str(curr_lable))
plt.show()

运行结果:

 

 至此,对于MNIST数据集的理解也应该十分清楚了。

三、利用MNIST进行逻辑回归训练

完整代码如下:

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import os
import matplotlib.pyplot as plt
os.environ["CUDA_VISIBLE_DEVICES"]="0"
#导入mnist数据集
MINIST_data=r'D:\mnist' #数据集存放位置
mnist=input_data.read_data_sets(MINIST_data,one_hot=True)

#设置训练参数
learning_rate=0.01  #学习率
training_epochs=25 #跑完全部样本集的次数
batch_size=100 #定义批量梯度下降次数,每100张图计算一次
display_step=1
#构造计算图,使用占位符placeholder函数构造变量x,y,
x=tf.placeholder(tf.float32,[None,784])
y=tf.placeholder(tf.float32,[None,10])
#使用Variable函数,设置模型的初始权重
W=tf.Variable(tf.zeros([784,10]))
b=tf.Variable(tf.zeros([10]))
#构造逻辑回归模型
#返回一个10维矩阵,[None,784]*[784,10]=[None,10]
pred=tf.nn.softmax(tf.matmul(x,W)+b)
#构造代价函数cost
#-y*tf.log(pred):交叉熵代价函数
#reduce_sum() 求和
#reduce_mean() 求平均值,返回数字
cost=tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1))
#使用梯度下降法求最小值,即最优解
optimizer=tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
#初始化全部变量
init=tf.global_variables_initializer()
#使用tf.Session()创建Session会话对象,会话封装了Tensorflow运行时的状态和控制。
with tf.Session() as sess:
    sess.run(init)
    #跑总样本25次
    for epochs in range(training_epochs):
        avg_cost=0 #记录训练集误差
        total_batch=int(mnist.train.num_examples/batch_size)#一次训练一百,总数除以100
        for i in range(total_batch):
            # 每次训练取100张图片(随机取一个batch_size)
            batch_xs,batch_ys=mnist.train.next_batch(batch_size)
            #返回一个[optimizer,cost]的list
            _,c=sess.run([optimizer,cost],feed_dict={x:batch_xs,y:batch_ys})
            #返回训练100张图产生的训练误差
            avg_cost+=c/total_batch
        #打印每次迭代产生的误差
        if (epochs+1)%display_step==0:
            print("Epoch :", "%04d" % (epochs + 1), "Train_cost", "{:9f}".format(avg_cost))
    print("Optimization finished!")
    #argmax返回数组中最大元素的位置 0代表按列算,1代表按行算
    #tf.equal() 返回布尔值,判断对应元素是否相等,相等返回1,否则返回0
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))

    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print("Accuracy:", accuracy.eval({x: mnist.test.images[:3000], y: mnist.test.labels[:3000]}))

至于其中诸多函数用法,自行百度了解即可。

这里解释一下 我认为必要数据的含义

x(图片特征值):x=tf.placeholder(tf.float32,[None,784]) 此代码将图片表示为若干行,784列的数组。

w(特征值对应的权重):一开始这个值是随即设置,随着我们的不断训练得到最佳的权重

y(正确的结果):此结果来自MNIST标签训练集,此数据用于与我们机器学习预测的结果相比较,看是否预测正确,同时计算准确率

pred:机器学习预测的结果。

training_epochs:指的是遍历全部样本集的次数

batch_size:我们需要分好几次来遍历完全样本集,batch_size指的是每次分步提取出数据集的数量,例如样本集有5000个,batch_size=100时代表每次需分析100张图片,共迭代50次全部完成。

四、进一步分析预测结果

我们可以通过写代码来了解机器学习在哪出现了错误。

以下为代码:

print("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV")
    for i in range(0, len(mnist.test.images)):
        result = sess.run(correct_prediction,feed_dict={x: np.array([mnist.test.images[i]]), y: np.array([mnist.test.labels[i]])})
        if not result:
            print('预测的值是:',
                  sess.run(pred, feed_dict={x: np.array([mnist.test.images[i]]), y: np.array([mnist.test.labels[i]])}))
            print('实际的值是:',
                  sess.run(y, feed_dict={x: np.array([mnist.test.images[i]]), y: np.array([mnist.test.labels[i]])}))
            one_pic_arr = np.reshape(mnist.test.images[i], (28, 28))
            pic_matrix = np.matrix(one_pic_arr, dtype="float")
            plt.imshow(pic_matrix)
            plt.show()
            break

我们来判断图片与测试是否正确,是通过比较pred(预测值)与y(真实数据)中最大数据(即为1)的位置来判断(参考argmax()函数用法),若位置相同,则返回true,位置不同,则返回false。利用这个原理可以写if语句,遇到错误,break循环,并打印出错的图片。

运行截图:

 

 我们可以看到预测值中最大数值位置为6 预测图片数字为6 ,但真实数据为5.

打印图片为:

 

 最后的最后附上全部完整代码:

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import os
import matplotlib.pyplot as plt
os.environ["CUDA_VISIBLE_DEVICES"]="0"
#导入mnist数据集
MINIST_data=r'D:\mnist' #数据集存放位置
mnist=input_data.read_data_sets(MINIST_data,one_hot=True)

#设置训练参数
learning_rate=0.01  #学习率
training_epochs=25 #跑完全部样本集的次数
batch_size=100 #定义批量梯度下降次数,每100张图计算一次
display_step=1
#构造计算图,使用占位符placeholder函数构造变量x,y,
x=tf.placeholder(tf.float32,[None,784])
y=tf.placeholder(tf.float32,[None,10])
#使用Variable函数,设置模型的初始权重
W=tf.Variable(tf.zeros([784,10]))
b=tf.Variable(tf.zeros([10]))
#构造逻辑回归模型
#返回一个10维矩阵,[None,784]*[784,10]=[None,10]
pred=tf.nn.softmax(tf.matmul(x,W)+b)
#构造代价函数cost
#-y*tf.log(pred):交叉熵代价函数
#reduce_sum() 求和
#reduce_mean() 求平均值,返回数字
cost=tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1))
#使用梯度下降法求最小值,即最优解
optimizer=tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
#初始化全部变量
init=tf.global_variables_initializer()
#使用tf.Session()创建Session会话对象,会话封装了Tensorflow运行时的状态和控制。
with tf.Session() as sess:
    sess.run(init)
    #跑总样本25次
    for epochs in range(training_epochs):
        avg_cost=0 #记录训练集误差
        total_batch=int(mnist.train.num_examples/batch_size)#一次训练一百,总数除以100
        for i in range(total_batch):
            # 每次训练取100张图片(随机取一个batch_size)
            batch_xs,batch_ys=mnist.train.next_batch(batch_size)
            #返回一个[optimizer,cost]的list
            _,c=sess.run([optimizer,cost],feed_dict={x:batch_xs,y:batch_ys})
            #返回训练100张图产生的训练误差
            avg_cost+=c/total_batch
        #打印每次迭代产生的误差
        if (epochs+1)%display_step==0:
            print("Epoch :", "%04d" % (epochs + 1), "Train_cost", "{:9f}".format(avg_cost))
    print("Optimization finished!")
    #argmax返回数组中最大元素的位置 0代表按列算,1代表按行算
    #tf.equal() 返回布尔值,判断对应元素是否相等,相等返回1,否则返回0
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))

    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print("Accuracy:", accuracy.eval({x: mnist.test.images[:3000], y: mnist.test.labels[:3000]}))
    print("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV")
    for i in range(0, len(mnist.test.images)):
        result = sess.run(correct_prediction,feed_dict={x: np.array([mnist.test.images[i]]), y: np.array([mnist.test.labels[i]])})
        if not result:
            print('预测的值是:',
                  sess.run(pred, feed_dict={x: np.array([mnist.test.images[i]]), y: np.array([mnist.test.labels[i]])}))
            print('实际的值是:',
                  sess.run(y, feed_dict={x: np.array([mnist.test.images[i]]), y: np.array([mnist.test.labels[i]])}))
            one_pic_arr = np.reshape(mnist.test.images[i], (28, 28))
            pic_matrix = np.matrix(one_pic_arr, dtype="float")
            plt.imshow(pic_matrix)
            plt.show()
            break

 

五、感谢

https://www.cnblogs.com/lizheng114/p/7439556.html

https://www.lizenghai.com/archives/47834.html#121_tensorflow(解释十分全面)

 

posted @ 2020-03-30 12:44  Caper123  阅读(645)  评论(0编辑  收藏  举报