tensorflow实现线性分类之MNIST

本文介绍了MNIST数据集及其结构,并详细讲述了逻辑回归模型,包括模型定义、线性函数和损失函数的设定。接着,通过TensorFlow实现逻辑分类,解释了如何初始化变量和设置权重及偏差,提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、MNIST数据集简介

       MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取, 它包含了四个部分:

     1.Training set images: train-images-idx3-ubyte.gz (9.9 MB, 解压后 47 MB, 包含 60,000 个样本)

     2.Training set labels: train-labels-idx1-ubyte.gz (29 KB, 解压后 60 KB, 包含 60,000 个标签)

    3.Test set images: t10k-images-idx3-ubyte.gz (1.6 MB, 解压后 7.8 MB, 包含 10,000 个样本)

    4.Test set labels: t10k-labels-idx1-ubyte.gz (5KB, 解压后 10 KB, 包含 10,000 个标签)

    MNIST 数据集来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据.在MNIST训练集中,mnist.train.images是一个形状为[60000,784]的张量,第一个维度用来索引图片,第二个维度用来索引图片的像素点。我们使用的标签数据是“one--hot vector",一个one--向量除了某一个位置的数字是1以外其余的数字全为0。所以mnist.train.labels是一个[60000,10]的数字矩阵。

二、逻辑回归

1.模型

逻辑回归是一个概率,线性分类器。它的参数包含一个权值矩阵

W和一个偏置向量b。分类器将输入向量映射到一系列超平面上,每个超平面对应一个类别。输入向量与超平面的距离反映了输入属于对应类别的概率。 
在数学上,一个输入向量x属于类别i(概率变量Y的值)的概率,记为:

P(Y=i|x,W,b)=softmaxi(Wx+b)=eWix+bijeWix+bi
模型的预测值 ypred 为概率最大的类别,定义为
ypred=argmaxiP(Y=i|x,W,b)

2.线性函数

当我们想把输入x转化为标签y的时候,比如,把图像分类成数字,我们会推导出一个函数 y=Wx+b。

x将是我们的像素值列表,y将是对数,对应每一个数字。让我们来看看y = Wx,其中权重W确定x在预测每个y时的影响。

y = Wx允许我们绘出一条直线将数据对应到各自的标签。 然而,这条线必须通过原点,因为当x等于0,y也等于0。

我们希望能够将线从原点移开以适应更复杂的数据。最简单的解决方案是给函数添加一个数字,我们称之为“bias”(偏差)。

我们的新函数变为Wx + b,允许我们对线性可分离数据创建预测.

3.定义损失函数

训练最优化模型参数,涉及到最小化损失函数。在多类别的分类问题中,很自然的想法是使用负对数似然作为损失函数。这等价于在参数为θ的模型下,最大化数据集D的似然。我们从定义似然L和损失始:

L(θ={W,b},D)=i=0|D|log(P(Y=y(i)|x(i),W,b))
(θ={W,b},D)=L(θ={W,b},D)
在最优化理论中,最小化任意非线性函数的最简单方法是梯度下降法(gradient descent)。 
这里使用的是小批量的概率梯度方法(mini-batches Stochastic Gradient Descent, MSGD)。

三、tensorflow实现逻辑分类

训练神经网络的目的是修改权重和偏差以最好地预测标签。 为了使用权重和偏差,你需要一个可以修改的Tensor。也就是说不能使用tf.placeholder()和tf.constant(),因为那些Tensors不能被修改。所以这里应该使用tf.Variable。

tf.Variable()

x = tf.Variable(5)

tf.Variable类创建了一个具有可以修改的初始值的张量,很像一个普通的Python变量。 该张量在会话中存储其状态,因此您必须手动初始化张量的状态。

使用tf.global_variables_initializer()函数初始化所有可变张量的状态。

init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)

使用tf.Variable类允许我们改变权重和偏差,但是需要选择一个初始值。如上所示,使用session(会话)调用tf.global_variables_initializer()操作。tf.global_variables_initializer()会返回一个操作,从计算图中初始化所有TensorFlow变量。

用正态分布的随机数初始化权重是一个好的做法。而使权重随机化则有助于避免模型在每次训练时都卡在相同的位置。

类似地,从正态分布选择权重可以防止任何一个权重压倒其他权重。

TensorFlow提供了一个tf.truncated_normal()函数从正态分布生成随机数。

tf.truncated_normal()

n_features = 120
n_labels = 5
weights = tf.Variable(tf.truncated_normal((n_features, n_labels)))

tf.truncated_normal()函数返回具有来自正态分布的随机值的张量,该正态分布的幅度与平均值相差不超过2个标准偏差。

由于权重已经帮助防止模型卡住,你不需要再随机化偏差。 在这里最简单的解决方案,将偏差设置为0。

tf.zeros()

_labels = 5
bias = tf.Variable(tf.zeros(n_labels))

tf.zeros()函数返回具有全零的张量。

具体代码如下:

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
print(mnist.train.images.shape, mnist.train.labels.shape)
print(mnist.test.images.shape, mnist.test.labels.shape)
print(mnist.validation.images.shape, mnist.validation.labels.shape)
X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])
W1 = tf.Variable(tf.truncated_normal([784, 10], stddev=0.1))
b1 = tf.Variable(tf.zeros([10]))
print(b1.shape)
y_ = tf.nn.softmax(tf.matmul(X, W1) + b1)
loss = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(y_), reduction_indices=[1]))
step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    costs = []
    for i in range(1000):
        batch_x, batch_y = mnist.train.next_batch(100)
        cost, _ = sess.run([loss, step], feed_dict={X: batch_x, Y: batch_y})
        if i % 50 == 0:
            costs.append(cost)
            correct_prediction = tf.equal(tf.argmax(Y, 1), tf.argmax(y_, 1))
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
            print("i=", i,"accuracy:", accuracy.eval({X: mnist.test.images, Y: mnist.test.labels}))
    plt.xlabel("Iteration")
    plt.ylabel("loss")
    plt.title("learning_rate=0.3")
    plt.plot(costs)
    plt.show()


运行结果如下, 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值