tensorflow-Mnist多分类模型

    之前我们介绍过逻辑回归的二分类问题,但是在我们实际应用中往往都是多分类问题,这里我们以Mnist数据集为例来分析多分类问题,首先Mnist输入为图片,是高维度数据,不同于我们之前的一行或者一列,这里我们先从简单的开始,将28x28矩阵,转化为1x784的矩阵,这样我们的输入数据就和前面的一样,既然要对数据进行处理,那我们先分析一下我们要解析的数据是什么样的。


以下为二进制文件信息,前面4个32 bit integer表示文件信息,后面即使图片的二进制形式

magic number 用来标记文件或者协议的格式

number of images 图片数量

number of rows

number of columns    图片大小


下面是读取图片的过程

#--coding:UTF-8 --
import numpy as np
import struct
import matplotlib.pyplot as plt

#读取二进制数据
filename = './MNIST_data/t10k-images-idx3-ubyte'
binfile = open(filename , 'rb')  # python3 'r'  but python2 'rd'
buf = binfile.read()

#index为读取的索引
#读取文件标志、图片数量和大小
index = 0
magic, numImages, numRows, numColumns = struct.unpack_from('>IIII' , buf , index)
index += struct.calcsize('>IIII')

#读取一张图片即784Byte
im = struct.unpack_from('>784B' , buf , index)
index += struct.calcsize('>784B')
#将读取数据转化为矩阵并改成图片格式
im = np.array(im)
im = im.reshape(28,28)
#显示第一张图片
fig = plt.figure()
plotwindow = fig.add_subplot(111)
plt.imshow(im , cmap = 'gray')
plt.show()


以上是mnist数据集的了解过程,下面是我写的解析函数:


#--coding:UTF-8--
#mnist_read.py
import numpy as np
import struct

#对MNIST数据集进行解析,解析为对应矩阵形式,可以根据自己处理需求进行修改
def read_images(filename):
	binfile=open(filename,'rb')
	buf=binfile.read()
	index=0
	magic, numImages, numRows, numColumns = struct.unpack_from('>IIII' , buf , index)
	index += struct.calcsize('>IIII')
	image=[]
	for i in range(numImages):
		im=struct.unpack_from('>784B',buf,index)
		im=list(im)
		image.append(im)
		index+=struct.calcsize('>784B')
	return np.array(image)
#a=read_images('./data/MNIST_data/train-images-idx3-ubyte')
#print a
#将标签表示为10列矩阵
def read_labels(filename):
	binfile=open(filename,'rb')
	buf=binfile.read()
	index=0
	magic,numItems=struct.unpack_from('>II',buf,index)
	index+=struct.calcsize('>II')
	label=[]
	for i in range(numItems):
		l=struct.unpack_from('>1B',buf,index)
		m=[0,0,0,0,0,0,0,0,0,0]
		m[l[0]]=1
		label.append(m)
		index+=1
	return np.array(label)
#b=read_labels('./data/MNIST_data/t10k-labels-idx1-ubyte')
#print b.astype(np.float32)

得到数据即可通过前面的知识进行简单的模型构建,首先是一层神经网络:

#--coding:UTF-8--
import tensorflow as tf
import numpy as np
import mnist_read

#通过自己写的解析函数将数据解析出来,并进行简单的预处理
train_images=mnist_read.read_images('./data/MNIST_data/train-images-idx3-ubyte').astype(np.float32)/255
train_labels=mnist_read.read_labels('./data/MNIST_data/train-labels-idx1-ubyte').astype(np.float32)
test_images=mnist_read.read_images('./data/MNIST_data/t10k-images-idx3-ubyte').astype(np.float32)/255
test_labels=mnist_read.read_labels('./data/MNIST_data/t10k-labels-idx1-ubyte').astype(np.float32)


x=tf.placeholder(tf.float32,shape=[None,784])
y=tf.placeholder(tf.float32,shape=[None,10])

W=tf.Variable(tf.zeros([784,10]))
b=tf.Variable(tf.zeros([10]))

y_=tf.matmul(x,W)+b
#使用欧氏距离表示损失函数
loss=tf.reduce_mean(tf.square(y-y_))

optimizer=tf.train.GradientDescentOptimizer(0.01)
train=optimizer.minimize(loss)

sess=tf.Session()
init=tf.global_variables_initializer()
sess.run(init)
#最大值索引号比较是否相同
correct_prediction=tf.equal(tf.argmax(y_,1),tf.argmax(y,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,'float'))

for i in range(1000):
	sess.run(train,feed_dict={x:train_images,y:train_labels})
	print sess.run(accuracy,feed_dict={x:test_images,y:test_labels})

最后以0.01的学习率训练1000步得到在测试集上正确率为83.91%

通过softmax处理,并使用cross_entropy损失函数,以0.5学习率训练1000步正确率可以达到90.11%

在softmax基础上使用BatchGradientDescent正确率可以达到91.17%


一些小小总结:

二分类问题,可以用sigmiod函数将输出映射到(0,1)
对于多分类问题,可以用softmax将输出表示成(0,1)间的概率值
对于这种概率问题,一般使用交叉熵作为损失函数,即sum{-y_true*log(y_model)}
一般回归问题用mean squared error    分类问题用cross entropy

loss使用cross entropy解释

引用通俗说法即是:熵是什么?设p是一个分布,-plnp表示该种概率分布的熵,而-lnp表示编码长度。所以熵就是最小的平均编码长度。交叉熵,就是用几种分布p去近似未知的分布p,那么如何评价你选的分布q的好坏呢?就是你选定的q去编码分布q,然后得到的编码长度最小就表明你选择的分布q是最好的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值