TensorFlow基于cifar10数据集实现进阶的卷积网络
TensorFlow基于cifar10數(shù)據(jù)集實(shí)現(xiàn)進(jìn)階的卷積網(wǎng)絡(luò)
- 學(xué)習(xí)鏈接
- CIFAR10模型及數(shù)據(jù)集介紹
- 綜述
- CIFAR10數(shù)據(jù)集介紹
- CIFAR10數(shù)據(jù)集可視化
- CIFAR10模型
- CIFAR10代碼
學(xué)習(xí)鏈接
https://github.com/tensorflow/models/tree/master/tutorials/image/cifar10
http://www.cs.toronto.edu/~kriz/cifar.html
http://blog.csdn.net/diligent_321/article/details/53130913
http://blog.csdn.net/diligent_321/article/details/53008840
http://blog.csdn.net/barry_j/article/details/79158017
http://blog.csdn.net/yangdashi888/article/details/77918311
CIFAR10模型及數(shù)據(jù)集介紹
綜述
Cifar-10 是由Hinton 的兩個(gè)大弟子 Alex Krizhevsky、Ilya Sutskever 收集的一個(gè)用于普適物體識(shí)別的數(shù)據(jù)集。Cifar 是加拿大政府牽頭投資的一個(gè)先進(jìn)科學(xué)項(xiàng)目研究所。Hinton、Bengio和他的學(xué)生在2004年拿到了 Cifar 投資的少量資金,建立了神經(jīng)計(jì)算和自適應(yīng)感知項(xiàng)目。這個(gè)項(xiàng)目結(jié)集了不少計(jì)算機(jī)科學(xué)家、生物學(xué)家、電氣工程師、神經(jīng)科學(xué)家、物理學(xué)家、心理學(xué)家,加速推動(dòng)了 Deep Learning 的進(jìn)程。從這個(gè)陣容來(lái)看,DL 已經(jīng)和 ML 系的數(shù)據(jù)挖掘分的很遠(yuǎn)了。Deep Learning 強(qiáng)調(diào)的是自適應(yīng)感知和人工智能,是計(jì)算機(jī)與神經(jīng)科學(xué)交叉;Data Mining 強(qiáng)調(diào)的是高速、大數(shù)據(jù)、統(tǒng)計(jì)數(shù)學(xué)分析,是計(jì)算機(jī)和數(shù)學(xué)的交叉。
CIFAR-10是機(jī)器學(xué)習(xí)分類問(wèn)題中的一個(gè)標(biāo)尺問(wèn)題。目標(biāo)是將RGB 32*32的圖像分成10類:飛機(jī)(airplane),汽車(automobile),鳥(bird),貓(cat),鹿(deer),狗(dog),青蛙(frog),馬(horse),船(ship),卡車(truck)。
可以看到,同已經(jīng)成熟的人臉識(shí)別相比,普適物體識(shí)別挑戰(zhàn)巨大,數(shù)據(jù)中含有大量特征、噪聲,識(shí)別物體比例不一。因而,Cifar-10 相對(duì)于傳統(tǒng)圖像識(shí)別數(shù)據(jù)集,是相當(dāng)有挑戰(zhàn)的。想了解更多信息請(qǐng)參考CIFAR-10 page,以及 Alex Krizhevsky 的技術(shù)報(bào)告。
學(xué)習(xí)CIFAR-10模型的用處
- 強(qiáng)調(diào)了網(wǎng)絡(luò)結(jié)構(gòu)、訓(xùn)練和評(píng)估的規(guī)范組織方式。
- 提供了構(gòu)建更大和更精細(xì)的模型的模板。
選擇CIFAR-10的原因:
- 它足夠復(fù)雜,可以訓(xùn)練TensorFlow的大規(guī)模模型的大部分能力;
- 它足夠小,可以快速訓(xùn)練,這對(duì)于嘗試新想法和實(shí)驗(yàn)新技術(shù)是理想的。
CIFAR-10模型在TensorFlow中設(shè)計(jì)更大和更精細(xì)的模型了展示幾個(gè)重要構(gòu)想:
核心數(shù)學(xué)元素包括:
- 卷積
- 激活函數(shù)ReLu
- 池化max-pooling
- 標(biāo)準(zhǔn)化local response normalization
可視化(visualization)訓(xùn)練過(guò)程中的網(wǎng)絡(luò)激活(network activities),包含圖像輸入,損失函數(shù),激活值和梯度的分布。
計(jì)算學(xué)習(xí)參數(shù)的移動(dòng)平均(moving average),使用移動(dòng)平均法提升預(yù)測(cè)效果。
實(shí)現(xiàn)隨時(shí)間下降的學(xué)習(xí)率(learning rate)。
對(duì)輸入數(shù)據(jù)預(yù)提取隊(duì)列(queues),讓模型從硬盤延遲和圖像預(yù)處理中獨(dú)立出來(lái)。
也提供了多GPU版本,暫時(shí)忽略。
正則化:防止過(guò)擬合,提高泛化能力
在機(jī)器學(xué)習(xí)中,不管是分類還是回歸,都可能因特征過(guò)多而產(chǎn)生過(guò)擬合,一般可以通過(guò)減少特征或者懲罰不重要特征的權(quán)重來(lái)緩解這個(gè)問(wèn)題,通常我們并不知道該懲罰哪些特征的權(quán)重,而正則化就是幫我們懲罰特征權(quán)重的,即特征的權(quán)重也會(huì)成為模型損失函數(shù)的一部分??梢岳斫鉃?#xff0c;為了使用某個(gè)特征,我們需要付出loss的代價(jià)。這樣我們就可以篩選出最有效的特征,減少特征權(quán)重防止過(guò)擬合。這也是奧卡姆剃刀法則,越簡(jiǎn)單的東西越有效。
- L1正則會(huì)制造稀疏的特征,大部分無(wú)用特征的權(quán)重會(huì)被置為0
- L2正則會(huì)讓特征的權(quán)重不過(guò)大,使得特征的權(quán)重比較平均。
https://www.cnblogs.com/jianxinzhou/p/4083921.html
深度學(xué)習(xí)的局部響應(yīng)歸一化LRN
CIFAR10數(shù)據(jù)集介紹
CIFAR-10數(shù)據(jù)集包含60000張32*32的彩色圖像,訓(xùn)練集50000張,測(cè)試集10000張,共標(biāo)注10類,每一類有6000張圖片。在這個(gè)卷積神經(jīng)網(wǎng)絡(luò)模型中,我們使用了一些新的技巧:
CIFAR10模型與tensorflow官方開源的很多圖像分類模型如Mnist等一并放在了GitHub的tensorflow官方地址中。
(1) 下載CIFAR10模型
https://github.com/tensorflow/models/tree/master/tutorials/image/cifar10
文件 說(shuō)明
下載Tensorflow Models庫(kù),以便使用CIFAR-10數(shù)據(jù)的類
根據(jù)上面兩行代碼下載劃線部分的四個(gè)文件,raw-ctrlA-ctrlc-test右鍵new-Python Package-分別命名四個(gè)文件(對(duì)應(yīng)下載的四個(gè)文件命名),執(zhí)行cifar10_train即可。下載的包依舊在c:tmp中
或者按照此方法統(tǒng)一下載
svn下載github單個(gè)目錄文件夾
(2) 下載CIFAR10模型數(shù)據(jù)集
http://www.cs.toronto.edu/~kriz/cifar.html
這里有三個(gè)版本,分別是python版、matlab版和binary版,根據(jù)下載的模型選用 數(shù)據(jù)集版本,這里選用CIFAR-10二進(jìn)制版本(適用于C語(yǔ)言)
(如果這里不下載數(shù)據(jù)集,也可以在運(yùn)行cifar10_train.py程序時(shí)自動(dòng)下載)
(3) CIFAR10數(shù)據(jù)集解析:
CIFAR10/CIFAR100數(shù)據(jù)集介紹
二進(jìn)制版本包含文件data_batch_1.bin,data_batch_2.bin,…,data_batch_5.bin以及test_batch.bin。這些文件中的每一個(gè)格式如下:
<1×標(biāo)簽> <3072×像素>
…
<1×標(biāo)簽> <3072×像素>
換句話說(shuō),第一個(gè)字節(jié)是第一個(gè)圖像的標(biāo)簽,它是0-9范圍內(nèi)的一個(gè)數(shù)字。接下來(lái)的3072字節(jié)是圖像像素的值。前1024個(gè)字節(jié)是紅色通道值,下個(gè)1024個(gè)綠色,最后1024個(gè)藍(lán)色。值以行優(yōu)先順序存儲(chǔ),所以前32個(gè)字節(jié)是圖像第一行的紅色通道值。
每個(gè)文件包含10000個(gè)這樣的3073個(gè)字節(jié)的“行”圖像,雖然沒有任何分隔的行。因此每個(gè)文件應(yīng)該是30730000字節(jié)長(zhǎng)。
還有另一個(gè)文件叫做batches.meta.txt。這是一個(gè)ASCII文件,它將0-9范圍內(nèi)的數(shù)字標(biāo)簽映射到有意義的類名。這只是10個(gè)類名的列表,每行一個(gè)。第i行的類名稱對(duì)應(yīng)于數(shù)字標(biāo)簽i。
這里是像素是0-255之間的整數(shù),占兩個(gè)bytes。
CIFAR10數(shù)據(jù)集可視化
"""作者:Heart Sea功能:實(shí)現(xiàn)cifar10數(shù)據(jù)集的圖片可視化版本:1.0日期:10/12/2019""" import numpy as np import imageio import ospath_train = './訓(xùn)練集圖片' path_test = './測(cè)試集圖片' if not os.path.exists(path_train):os.makedirs(path_train) if not os.path.exists(path_test):os.makedirs(path_test)# 生成訓(xùn)練集5個(gè)batch圖片,訓(xùn)練集5萬(wàn)張32*32*3的圖片,每個(gè)batch1萬(wàn)張 # 生成測(cè)試集1個(gè)batch圖片,測(cè)試集1萬(wàn)張32*32*3的圖片,batch1萬(wàn)張 for j in range(1, 7):if j != 6:filename = 'd:/tmp/cifar10_data/cifar-10-batches-bin/data_batch_'+str(j)+'.bin'else:filename = 'd:/tmp/cifar10_data/cifar-10-batches-bin/test_batch.bin'bytestream = open(filename, "rb") # rb 以二進(jìn)制讀模式打開# 1是占位字節(jié)(存放標(biāo)簽),一行(每個(gè)圖片的記錄長(zhǎng)度)為32*32*3+1(存放像素)# read函數(shù),從文件中讀取的所有字節(jié)數(shù),返回從字符串中讀取的字節(jié)buf = bytestream.read(10000 * (1 + 32 * 32 * 3))bytestream.close()# numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)# buffer 任何暴露緩沖區(qū)借口的對(duì)象# dtype 返回?cái)?shù)組的數(shù)據(jù)類型,默認(rèn)為float# count 需要讀取的數(shù)據(jù)數(shù)量,默認(rèn)為-1,讀取所有數(shù)據(jù)# offset 需要讀取的起始位置,默認(rèn)為0data = np.frombuffer(buf, dtype=np.uint8) # 帶有\(zhòng)n格式的一維數(shù)組data = data.reshape(10000, 1 + 32 * 32 * 3) # 二維數(shù)組labels_images = np.hsplit(data, [1]) # 將data分成兩個(gè)array,一組是data的第一列,另一組是剩下的所有列labels = labels_images[0].reshape(10000) # 第一組為標(biāo)簽images = labels_images[1].reshape(10000, 32, 32, 3) # 第二組為圖像for i in range(0, 5): # 輸出一個(gè)batch的前5個(gè)圖片,可以自行修改img = np.reshape(images[i], (3, 32, 32)) # 導(dǎo)出第一幅圖img = img.transpose(1, 2, 0)if j != 6:picname = 'train'+str(i+(j-1)*10)+'.jpg'imageio.imwrite('訓(xùn)練集圖片/' + picname, img)else:picname = 'test' + str(i + (j - 1) * 10) + '.jpg'imageio.imwrite('測(cè)試集圖片/' + picname, img) print("photo loaded.")CIFAR10模型
CIFAR10代碼
"""作者:Heart Sea功能:基于cifar10數(shù)據(jù)集實(shí)現(xiàn)圖片的分類Model:輸入層, 數(shù)據(jù)增強(qiáng)(翻轉(zhuǎn),剪切24*24,亮度,對(duì)比度),標(biāo)準(zhǔn)化卷積層, 卷積, 激活relu, 最大池化,卷積層, 卷積, 激活relu, LRN, 最大池化全連接, 激活relu,L2正則全連接, 激活relu,L2正則輸出層, (全連接, 不需要l2,直接比較大小)日期:10/12/2019 """ # 圖像分類實(shí)驗(yàn) # 下載Tensorflow Models庫(kù),以便使用CIFAR-10數(shù)據(jù)的類 # git clone https://github.com/tensorflow/models.git # cd models/tutorials/image/cifar10# 載入numpy和time,并載入CIFAR-10數(shù)據(jù)的類 import cifar10, cifar10_input import tensorflow as tf import numpy as np import time import mathmax_steps = 3000 # 訓(xùn)練輪數(shù) batch_size = 128 data_dir = '/tmp/cifar10_data/cifar-10-batches-bin' # 下載CIAR-10的默認(rèn)路徑def variable_with_weight_loss(shape, stddev, w1):"""對(duì)weight施加L2正則化處理,為了防止過(guò)擬合,正則化幫助我們懲罰權(quán)重特征,即特征的權(quán)重也會(huì)成為模型損失函數(shù)的一部分初始化weight函數(shù),但是為了防止因?yàn)樘卣鬟^(guò)多而引起的過(guò)擬合,給每個(gè)weight加一個(gè)L2的lossL1正則會(huì)造成稀疏的特征,大部分無(wú)用特征會(huì)被置為0。L2特征會(huì)讓權(quán)重不過(guò)大,是權(quán)重比較平均.函數(shù)中用w1來(lái)控制L2 loss的大小使用tf.add_to_collection把weight_loss統(tǒng)一存放到一個(gè)collection,名字叫l(wèi)oss"""var = tf.Variable(tf.truncated_normal(shape, stddev=stddev)) # 從截?cái)嗟恼龖B(tài)分布中輸出隨機(jī)值if w1 is not None:weight_loss = tf.multiply(tf.nn.l2_loss(var), w1, name='weight_loss')tf.add_to_collection('losses', weight_loss)return var# 使用CIFAR-10類下載數(shù)據(jù)集,并解壓、展開到默認(rèn)位置 cifar10.maybe_download_and_extract()# 使用CIFAR-10類中的distorted_inputs函數(shù)產(chǎn)生訓(xùn)練使用的數(shù)據(jù),并封裝好作為tensor。 # 同時(shí)還進(jìn)行了數(shù)據(jù)增強(qiáng)包括水平翻轉(zhuǎn)、隨機(jī)剪切、設(shè)置隨機(jī)的亮度和對(duì)比度,以及對(duì)數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化。 # 數(shù)據(jù)增強(qiáng)采用16個(gè)線程進(jìn)行加速,函數(shù)內(nèi)部會(huì)產(chǎn)生線程池,需要使用時(shí)通過(guò)tensorflow queue進(jìn)行調(diào)度 images_train, labels_train = cifar10_input.distorted_inputs(data_dir=data_dir, batch_size=batch_size)# 使用CIFAR-10類中的cifar10_input.inputs函數(shù)生成測(cè)試數(shù)據(jù), # 不需翻轉(zhuǎn)、修改亮度,只需要剪切圖片的中心24*24的大小的區(qū)塊,標(biāo)準(zhǔn)化圖片 images_test, labels_test = cifar10_input.inputs(eval_data=True, data_dir=data_dir, batch_size=batch_size)# 創(chuàng)建輸入數(shù)據(jù)的placeholder,由于batch_size在之后定義網(wǎng)絡(luò)結(jié)構(gòu)會(huì)用到,所以數(shù)據(jù)尺寸中的第一個(gè)值即樣本條數(shù)需要被預(yù)先設(shè)定, # 數(shù)據(jù)尺寸中的圖片尺寸為24*24,是剪切后的大小,通道數(shù)為3,代表圖片是彩色的有RGB三條通道 image_holder = tf.placeholder(tf.float32, [batch_size, 24, 24, 3]) label_holder = tf.placeholder(tf.int32, [batch_size])"""構(gòu)建第一個(gè)卷積層第一層卷積的權(quán)重不進(jìn)行L2正則化,w1控制L2正則權(quán)重,利用tf.nn.conv2d對(duì)image_holder數(shù)據(jù)進(jìn)行訓(xùn)練,然后經(jīng)過(guò)relu非線性激活,之后最大池化,最后加入LRN層增加模型的泛化能力 """ weight1 = variable_with_weight_loss(shape=[5, 5, 3, 64], stddev=5e-2, w1=0.0) kernel1 = tf.nn.conv2d(image_holder, weight1, [1, 1, 1, 1], padding='SAME') bias1 = tf.Variable(tf.constant(0.0, shape=[64])) conv1 = tf.nn.relu(tf.nn.bias_add(kernel1, bias1))# 最大池化的尺寸和步長(zhǎng)不一致,這樣可以增加數(shù)據(jù)的豐富性 pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')# 應(yīng)用局部相應(yīng)歸一化層LRN,使得響應(yīng)較大的值變得相對(duì)更大,并抑制其他反饋較小的神經(jīng)元,增強(qiáng)了模型的泛化能力 # LRN對(duì)ReLU這種沒有上限邊界的激活函數(shù)比較有用,因?yàn)樗鼤?huì)從附近的多個(gè)卷積核的響應(yīng)中挑選比較大的反饋 # 但不適合sigmoid這種有固定邊界并且能抑制過(guò)大值的激活函數(shù) norm1 = tf.nn.lrn(pool1, 4, bias=1.0, alpha=0.001 /9.0, beta=0.75)"""構(gòu)建第二個(gè)卷積層,相比于第一層,調(diào)換了最大池化層與LRN層的順序,bias=0.1,而不是0,上一層的卷積核數(shù)量為64(即輸出64個(gè)通道),所以第三個(gè)維度(輸入的通道數(shù))為64 """ weight2 = variable_with_weight_loss(shape=[5, 5, 64, 64], stddev=5e-2, w1=0.0) kernel2 = tf.nn.conv2d(norm1, weight2, [1, 1, 1, 1], padding='SAME') bias2 = tf.Variable(tf.constant(0.1, shape=[64])) conv2 = tf.nn.relu(tf.nn.bias_add(kernel2, bias2)) norm2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75) pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME')"""第一個(gè)全連接層,先把第二個(gè)卷積層的輸出結(jié)果進(jìn)行扁平化,然后使所有的參數(shù)都被L2正則約束,最后relu激活tf.reshape函數(shù)將每個(gè)樣本都變成一維向量,get_shape函數(shù)獲取數(shù)據(jù)扁平化后的長(zhǎng)度 """ reshape = tf.reshape(pool2, [batch_size, -1]) dim = reshape.get_shape()[1].value weight3 = variable_with_weight_loss(shape=[dim, 384], stddev=0.04, w1=0.004) bias3 = tf.Variable(tf.constant(0.1, shape=[384])) local3 = tf.nn.relu(tf.matmul(reshape, weight3) + bias3)"""第2個(gè)全連接層,隱含節(jié)點(diǎn)下降一半 """ weight4 = variable_with_weight_loss(shape=[384, 192], stddev=0.04, w1=0.004) bias4 = tf.Variable(tf.constant(0.1, shape=[192])) local4 = tf.nn.relu(tf.matmul(local3, weight4) + bias4)"""最后一層,不計(jì)入正則,不需要softmax就可以輸出分類結(jié)果,直接計(jì)算模型inferfence輸出結(jié)果,直接比較數(shù)值大小即可 """ weight5 = variable_with_weight_loss(shape=[192, 10], stddev=1/192.0, w1=0.0) bias5 = tf.Variable(tf.constant(0.0, shape=[10])) logits = tf.add(tf.matmul(local4, weight5), bias5) # 整個(gè)網(wǎng)絡(luò)結(jié)構(gòu)部分已經(jīng)完成def loss(logits, labels):"""logits: 輸出層的結(jié)果labels:實(shí)際結(jié)果計(jì)算CNN的loss,將softmax的計(jì)算和cross entropy loss的計(jì)算整合到一起使用tf.add_to_collection把cross entropy的loss添加到整體losses的collection中,使用tf.add_n將整體lossesDE collection中的全部loss求和,得到最終的loss,包括cross entropy loss,還有后面兩個(gè)全連接層weight的L2 loss"""labels = tf.cast(labels, tf.int64)cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels,name='cross_entropy_per_example')cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')tf.add_to_collection('loss', cross_entropy_mean)return tf.add_n(tf.get_collection('losses'), name='total_loss') # 將logits節(jié)點(diǎn)和label_holder傳入loss函數(shù) loss = loss(logits, label_holder)# 優(yōu)化器選擇Adam train_op = tf.train.AdamOptimizer(1e-3).minimize(loss)# 使用tf.nn.in_top_k函數(shù)求出top1的準(zhǔn)確率,輸出分?jǐn)?shù)最高的那一類的準(zhǔn)確率 # 測(cè)試集用 top_k_op = tf.nn.in_top_k(logits, label_holder, 1)# 創(chuàng)建默認(rèn)的session,接著初始化全部模型參數(shù) sess = tf.InteractiveSession() tf.global_variables_initializer().run()# 啟動(dòng)前面圖片數(shù)據(jù)增強(qiáng)的線程隊(duì)列,共16個(gè)線程進(jìn)行加速 tf.train.start_queue_runners()"""開始正式訓(xùn)練,在每一個(gè)step的訓(xùn)練過(guò)程中,我們先使用session的run方法執(zhí)行images_train、label_train的計(jì)算,獲得一個(gè)batch的訓(xùn)練數(shù)據(jù),再將這個(gè)batch的數(shù)據(jù)傳入到train_op和loss的計(jì)算每隔10個(gè)step會(huì)計(jì)算并展示當(dāng)前的loss,每秒鐘能訓(xùn)練的樣本數(shù)量,以及訓(xùn)練一個(gè)batch數(shù)據(jù)所花費(fèi)的時(shí)間 """ for step in range(max_steps):start_time = time.time()image_batch, label_batch = sess.run([images_train, labels_train])_,loss_value = sess.run([train_op, loss],feed_dict={image_holder: image_batch, label_holder: label_batch})duration = time.time() - start_timeif step % 10 == 0:examples_per_sec = batch_size / durationsec_per_batch = float(duration)format_str=('step %d,loss=%.2f(%.1f examples/sec;%.3f sec/batch)')print(format_str % (step, loss_value, examples_per_sec, sec_per_batch))"""評(píng)測(cè)測(cè)試集的準(zhǔn)確率 """ num_examples = 10000 # 測(cè)試集樣本數(shù)量# 返回多少個(gè)batch num_iter = int(math.ceil(num_examples / batch_size)) # math.ceil函數(shù),返回?cái)?shù)字的上入整數(shù) true_count = 0 total_sample_count = num_iter * batch_size # 總樣本數(shù) step = 0 while step < num_iter:image_batch, label_batch = sess.run([images_test, labels_test])predictions = sess.run([top_k_op],feed_dict={image_holder: image_batch,label_holder: label_batch})true_count += np.sum(predictions) # 匯總所有預(yù)測(cè)正確的結(jié)果step += 1 # 最后將評(píng)測(cè)結(jié)果計(jì)算出來(lái) precision = true_count / total_sample_count print('precision @ 1 = %.3f' % precision)總結(jié)
以上是生活随笔為你收集整理的TensorFlow基于cifar10数据集实现进阶的卷积网络的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: TensorFlow基于minist数据
- 下一篇: nlp-关键词搜索