官网链接:http://www.cs.toronto.edu/~kriz/cifar.html
CIFAR-10是一个更接近普适物体的彩色图像数据集。CIFAR-10 是由Hinton 的学生Alex Krizhevsky 和Ilya Sutskever 整理的一个用于识别普适物体的小型数据集。白一共包含10 个类别的RGB 彩色图片:飞机( airplane )、汽车( automobile )、鸟类( bird )、猫( cat )、鹿( deer )、狗( dog )、蛙类( frog )、马( horse )、船( ship )和卡车( truck )。图片的尺寸为32 × 32 ,数据集中一共有50000 张训练圄片和10000 张测试图片。
在CIFAR-10 数据集中,文件data_batch_1、data_batch_2 、··data_batch_5 和test_ batch 中各有10000 个样本。一个样本由3072 个字节组成,第一个字节为标签label ,剩下3072 个字节为图像数据。样本和样本之间没高多余的字节分割, 因此这几个文件的大小都是30730000 字节。
通过如下代码可将数值文件转化为图片显示
import pickle
import numpy
import os
CIFAR_DIR = “…/cifar-10-batches-py”
print (os.listdir(CIFAR_DIR))
with open(os.path.join(CIFAR_DIR,“data_batch_1”),“rb”) as f:
data = pickle.load(f, encoding=‘bytes’)
image_arr = data[b’data’][100]
image_arr = image_arr.reshape((3,32,32))
image_arr = image_arr.transpose((1,2,0))
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
%matplotlib inline
imshow(image_arr)
显示结果为:
使用单个神经元对CIFAR-10中的两个分类进行逻辑斯蒂回归,代码如下:
import tensorflow as tf
import os
import pickle
import numpy as np
CIFAR_DIR = “…/cifar-10-batches-py”
print (os.listdir(CIFAR_DIR))
#加载data_batch数据并且返回data(10000,3072)的矩阵数据和labels长度为10000的数组
def load_data(filename) :
“”“read data from data file.”""
with open(filename,‘rb’) as f:
data = pickle.load(f, encoding=‘bytes’)
return data[b’data’],data[b’labels’]
class CifarData:
#初始化数据,filenames为文件名,need_shuffle为是否需要打乱数据集合
def init(self,filenames,need_shuffle):
all_data = []
all_labels = []
for filename in filenames:
#加载数据集返回data数据和labels数据集合
data,labels = load_data(filename)
#每个图片对应每个类即每个图片数据对应item,类别对应label
for item,label in zip(data,labels):
#只提取第0和第1个类别的数据来进行处理
if label in [0,1]:
all_data.append(item)
all_labels.append(label)
#沿着行方向进行叠加,把数据从上往下进行堆叠
self._data = np.vstack(all_data)
#把数据进行二值归一化处理
self._data = self._data / 127.5 - 1
#沿着列方向进行叠加,把数据从左向右排列
self._labels = np.hstack(all_labels)
#_num_examples表示属于类别0和1的图片数据个数
self._num_examples = self._data.shape[0]
self._need_shuffle = need_shuffle
self._indicator = 0
#是否打乱数据
if self._need_shuffle:
self._shuffle_data()
def _shuffle_data(self):
#[0,1,2,3,4,5] -> [5,3,2,4,0,1]
p = np.random.permutation(self._num_examples)
self._data = self._data[p]
self._labels = self._labels[p]
def next_batch(self,batch_size) :
"""return batch_size examples as a batch."""
end_indicator = self._indicator + batch_size
#类别数据超出结尾的情况处理
if end_indicator > self._num_examples :
#打乱顺序的话,无论类别数据是否超出没关系
if self._need_shuffle:
self._shuffle_data()
self._indicator = 0
end_indicator = batch_size
else:
raise Exception("have no more examples")
#类别数据太少,或者在不打乱数据的情况下超出结尾的处理
if end_indicator > self._num_examples:
raise Exception("batch size is ;arger than all examples")
#提取起点为self._indicator的batch_size个数据
batch_data = self._data[self._indicator: end_indicator]
batch_labels = self._labels[self._indicator: end_indicator]
#下一个起点为当前的结束点开始
self._indicator = end_indicator
return batch_data,batch_labels
#一次性加载很多个数据
train_filenames = [os.path.join(CIFAR_DIR,‘data_batch_%d’ % i)for i in range(1,6)]
test_filenames = [os.path.join(CIFAR_DIR,‘test_batch’)]
train_data = CifarData(train_filenames,True)
test_data= CifarData(test_filenames,False)
#构建计算图
tf.reset_default_graph()
y = tf.placeholder(tf.int64,[None])
x = tf.placeholder(tf.float32,[None,3072])
#(3072,1) w为权值,初始时为服从正态分布的随机数
w = tf.get_variable(‘w’,[x.get_shape()[-1],1],initializer=tf.random_normal_initializer(0,1))
#(1,) b为偏移量 初始时为0
b = tf.get_variable(‘b’,[1],initializer=tf.constant_initializer(0.0))
#[None, 3072] * [3072,1] = [None,1],他为xw
y_ = tf.matmul(x,w) + b
#[None,1] 对xw的结果用sigmoid激活函数进行处理
p_y_1 = tf.nn.sigmoid(y_)
#把y行矩阵编程列矩阵存储在y_reshaped
y_reshaped = tf.reshape(y,(-1,1))
#对y_reshaped即y做类型转化为float32类型
y_reshaped_float = tf.cast(y_reshaped, tf.float32)
#把y值和预测的值求方差做平均值
loss = tf.reduce_mean(tf.square(y_reshaped_float - p_y_1))
predict = p_y_1 > 0.5
correct_prediction = tf.equal(tf.cast(predict,tf.int64),y_reshaped)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float64))
with tf.name_scope(‘train_op’):
train_op = tf.train.AdamOptimizer(1e-3).minimize(loss)
init = tf.global_variables_initializer()
batch_size = 20
train_steps = 100000
test_steps = 100
with tf.Session() as sess:
sess.run(init)
for i in range(train_steps):
batch_data,batch_labels = train_data.next_batch(batch_size)
loss_val, acc_val, _ = sess.run(
#返回loss和acc,加上train_op表示对这些数据进行训练,不加代表不训练
[loss, accuracy, train_op],
feed_dict={x: batch_data,y: batch_labels})
if (i+1) % 500 == 0:
print(’[Train] Step: %d ,loss: %4.5f,acc: %4.5f’ % (i + 1, loss_val, acc_val))
if (i + 1) % 5000 == 0:
test_data = CifarData(test_filenames,False)
all_test_acc_val = []
#对前test_steps*batch_size个数据进行测试,并求出其准确率进行显示
for j in range(test_steps) :
test_batch_data,test_batch_labels = test_data.next_batch(batch_size)
test_acc_val = sess.run([accuracy],feed_dict = {x:test_batch_data,y:test_batch_labels})
all_test_acc_val.append(test_acc_val)
test_acc = np.mean(all_test_acc_val)
print(’[Test] Step: %d, acc: %4.5f’ % (i + 1,test_acc))
对这个二分类代码结果进行测试,在train_steps=100000时测试结果的精度达到0.82150。
使用单个神经元对CIFAR-10中的多个分类进行逻辑斯蒂回归,代码如下:
import tensorflow as tf
import os
import pickle
import numpy as np
CIFAR_DIR = “…/cifar-10-batches-py”
print (os.listdir(CIFAR_DIR))
#加载data_batch数据并且返回data(10000,3072)的矩阵数据和labels长度为10000的数组
def load_data(filename) :
“”“read data from data file.”""
with open(filename,‘rb’) as f:
data = pickle.load(f, encoding=‘bytes’)
return data[b’data’],data[b’labels’]
class CifarData:
#初始化数据,filenames为文件名,need_shuffle为是否需要打乱数据集合
def init(self,filenames,need_shuffle):
all_data = []
all_labels = []
for filename in filenames:
#加载数据集返回data数据和labels数据集合
data,labels = load_data(filename)
all_data.append(data)
all_labels.append(labels)
#沿着行方向进行叠加,把数据从上往下进行堆叠
self._data = np.vstack(all_data)
#把数据进行二值归一化处理
self._data = self._data / 127.5 - 1
#沿着列方向进行叠加,把数据从左向右排列
self._labels = np.hstack(all_labels)
print(self._data.shape)
print(self._labels.shape)
#_num_examples表示属于类别0和1的图片数据个数
self._num_examples = self._data.shape[0]
self._need_shuffle = need_shuffle
self._indicator = 0
#是否打乱数据
if self._need_shuffle:
self._shuffle_data()
def _shuffle_data(self):
#[0,1,2,3,4,5] -> [5,3,2,4,0,1]
p = np.random.permutation(self._num_examples)
self._data = self._data[p]
self._labels = self._labels[p]
def next_batch(self,batch_size) :
"""return batch_size examples as a batch."""
end_indicator = self._indicator + batch_size
#类别数据超出结尾的情况处理
if end_indicator > self._num_examples :
#打乱顺序的话,无论类别数据是否超出没关系
if self._need_shuffle:
self._shuffle_data()
self._indicator = 0
end_indicator = batch_size
else:
raise Exception("have no more examples")
#类别数据太少,或者在不打乱数据的情况下超出结尾的处理
if end_indicator > self._num_examples:
raise Exception("batch size is ;arger than all examples")
#提取起点为self._indicator的batch_size个数据
batch_data = self._data[self._indicator: end_indicator]
batch_labels = self._labels[self._indicator: end_indicator]
#下一个起点为当前的结束点开始
self._indicator = end_indicator
return batch_data,batch_labels
#一次性加载很多个数据
train_filenames = [os.path.join(CIFAR_DIR,‘data_batch_%d’ % i)for i in range(1,6)]
test_filenames = [os.path.join(CIFAR_DIR,‘test_batch’)]
train_data = CifarData(train_filenames,True)
test_data= CifarData(test_filenames,False)
#构建计算图
tf.reset_default_graph()
#eg:[0,6,5,3]
y = tf.placeholder(tf.int64,[None])
x = tf.placeholder(tf.float32,[None,3072])
#(3072,10) w为权值,初始时为服从正态分布的随机数
w = tf.get_variable(‘w’,[x.get_shape()[-1],10],initializer=tf.random_normal_initializer(0,1))
#(10,) b为偏移量 初始时为0
b = tf.get_variable(‘b’,[10],initializer=tf.constant_initializer(0.0))
#[None, 3072] * [3072,10] = [None,10],他为xw
y_ = tf.matmul(x,w) + b
“”"
#mean square loss
#course: 1+e^x
#api : ex/sum(ex)
p_y = tf.nn.softmax(y_)
5 ->p[0,0,0,0,0,1,0,0,0,0] 就是y做类型转化
y_one_hot = tf.one_hot(y,10,dtype = tf.float32)
#损失函数把y值和预测的值求方差做平均值
loss = tf.reduce_mean(tf.square(y_one_hot - p_y))
“”"
loss = tf.losses.sparse_softmax_cross_entropy(labels = y,logits = y_)
#y_ -> softmax
#y -> one_hot
#loss = ylogy
#indices
predict = tf.argmax(p_y , 1)
#[1,0,1,1,1,0,0,0]
correct_prediction = tf.equal(predict,y)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float64))
with tf.name_scope(‘train_op’):
train_op = tf.train.AdamOptimizer(1e-3).minimize(loss)
init = tf.global_variables_initializer()
batch_size = 20
train_steps = 100000
test_steps = 100
with tf.Session() as sess:
sess.run(init)
for i in range(train_steps):
batch_data,batch_labels = train_data.next_batch(batch_size)
loss_val, acc_val, _ = sess.run(
#返回loss和acc,加上train_op表示对这些数据进行训练,不加代表不训练
[loss, accuracy, train_op],
feed_dict={x: batch_data,y: batch_labels})
if (i+1) % 500 == 0:
print(’[Train] Step: %d ,loss: %4.5f,acc: %4.5f’ % (i + 1, loss_val, acc_val))
if (i + 1) % 5000 == 0:
test_data = CifarData(test_filenames,False)
all_test_acc_val = []
#对前test_steps*batch_size个数据进行测试,并求出其准确率进行显示
for j in range(test_steps) :
test_batch_data,test_batch_labels = test_data.next_batch(batch_size)
test_acc_val = sess.run([accuracy],feed_dict = {x:test_batch_data,y:test_batch_labels})
all_test_acc_val.append(test_acc_val)
test_acc = np.mean(all_test_acc_val)
print(’[Test] Step: %d, acc: %4.5f’ % (i + 1,test_acc))
对这个多分类代码结果进行测试,在train_steps=100000时测试结果的精度不算很高只有0.38450。