TensorFlow實現卷積神經網路(進階)_神經網路

來源:互聯網
上載者:User

此模型中如果使用100k個batch,並結合學習速率的decay(即每隔一段時間將學習速率下降一個比率),正確率可以高達86%。模型中需要訓練的參數約為100萬個,而預測時需要進行的四則運算總量在2000萬次左右。所以這個卷積神經網路模型中,使用一些技巧。
(1)對weight進行L2的正則化。
(2)對圖片進行翻轉,隨機剪下等資料增強,製造更多樣本。
(3)在每個卷積-最大池化層後面使用LRN層,增強模型的泛化能力。

卷積加池化的組合目前已經是做Image Recognition的一個標準組件了。卷積層主要做特徵提取,全串連層開始多特徵進行組合匹配,並進行分類。卷積層的訓練相對於全串連層更複雜,訓練全串連層基本是進行一些矩陣的乘法運算。

下載TensorFow Model,在構建模型時會用到讀取CTFAR-10資料的類(cifar10.py和cifar10_input.py)(CTFAR-10一個經典的資料集)

git clone git@github.com:tensorflow/models.gitcd models/tutorials/image/cifar10 

卷積神經網路結構:
conv1 卷積層和啟用函數
pool1 最大池化
norm1 LRN
conv2 卷積層和啟用函數
norm2 LRN
pool2 最大池化層
local3 全串連層和啟用函數
local4 全串連層和啟用函數
logits 模型Inference的輸出結果

# coding:UTF-8# 載入常用庫,NumPy的time,並載入TlensorFow Models中的自動下載、讀取CIFAR-10資料的類。import cifar10,cifar10_inputimport tensorflow as tfimport numpy as npimport time########輸入資料######### 訓練論數、batch大小(3000個batch,每個batch包含128個樣本)。max_steps = 3000batch_size = 128# 下載CIFAR-10資料的預設路徑data_dir = '/tmp/cifar10_data/cifar-10-batches-bin'########初始化權重######### 定義初始化weight的函數,依然使用tf.truncated_normal截斷的常態分佈來初始化權重。# 這裡給weight加一個L2的loss,相當於做了一個L2的正則化處理。這個collection名為“losses”,會在後面計算總體loss時被用上def variable_with_weight_loss(shape, stddev, wl):    var = tf.Variable(tf.truncated_normal(shape, stddev = stddev))    if wl is not None:        weight_loss = tf.multiply(tf.nn.l2_loss(var), wl, name = 'weight_loss')        tf.add_to_collection('losses', weight_loss)    return var########資料處理######### 把cifar10的資料解壓到data_dir中,然後將下一行代碼注釋掉,取消運行# (用到cifar-10.py)使用CIFAR-10下載資料集,並解壓展開到其預設位置cifar10.maybe_download_and_extract()# 使用cifar10_input類中的distorted_input函數產生訓練需要使用的資料,返回的是已經封裝好的tensor,每次執行都會產生一個batch_size的數量的樣本。images_train, labels_train = cifar10_input.distorted_inputs(data_dir = data_dir, batch_size = batch_size)# 使用cifar10_input.inputs函數產生測試資料。需要裁剪圖片正中間的24*24的區塊,並進行資料標準化操作。images_test, labels_test = cifar10_input.inputs(eval_data = True, data_dir = data_dir, batch_size = batch_size)# 建立輸入資料的placeholder。batche_size在之後定義網路結構時被用到了,所以資料尺寸的第一個值樣本條數需要提前設定。image_holder = tf.placeholder(tf.float32, [batch_size, 24, 24, 3])label_holder = tf.placeholder(tf.int32, [batch_size])########設計網路結構######### 第一個卷積層# 建立卷積核並進行初始化,不對第一個卷積層的weight進行L2正則weight1 = variable_with_weight_loss(shape = [5,5,3,64], stddev = 5e-2, wl = 0.0)# 對輸入資料進行卷積操作kernel1 = tf.nn.conv2d(image_holder, weight1, [1,1,1,1], padding = 'SAME')# 這層的bias全部初始化為0,再將卷積的結果加上biasbias1 = tf.Variable(tf.constant(0.0, shape = [64]))# 使用啟用函數進行非線性化conv1 = tf.nn.relu(tf.nn.bias_add(kernel1, bias1))# 使用尺寸為3*3且步長為2*2的最大池化層處理資料,最大池化層的尺寸和步長不一致,增加資料的豐富性pool1 = tf.nn.max_pool(conv1, ksize = [1,3,3,1], strides = [1,2,2,1], padding = 'SAME')# 使用LRN對結果進行處理,對局部神經元的活動建立競爭環境,增強模型的泛化能力norm1 = tf.nn.lrn(pool1, 4, bias = 1.0, alpha = 0.001/9.0, beta = 0.75)# 第二個卷積層(與上一層相似)# 上一層的卷積核心數量為64(即輸出64個通道)。本層卷積核的第三維度輸入通道數為64。weight2 = variable_with_weight_loss(shape = [5,5,64,64], stddev = 5e-2, wl = 0.0)kernel2 = tf.nn.conv2d(norm1, weight2, [1,1,1,1], padding = 'SAME')# bias值全部初始化為0.1。bias2 = tf.Variable(tf.constant(0.1, shape = [64]))conv2 = tf.nn.relu(tf.nn.bias_add(kernel2, bias2))# 與上一層不同,先進行LRN處理,在進行最大池化層。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')# 全串連層# 將上一層的輸出結果進行flatten。tf.reshape函數將每個樣本都變成一維向量。reshape = tf.reshape(pool2, [batch_size, -1])# 擷取資料扁平化之後的長度。dim = reshape.get_shape()[1].value# 對全串連層的weight進行初始化,隱含節點數為384,正太分布的標準差0.04。設定非零的weight loss,這一程所有參數被L2正則約束。weight3 = variable_with_weight_loss(shape = [dim, 384], stddev = 0.04, wl = 0.004)# bias值初始化為0.1bias3 = tf.Variable(tf.constant(0.1, shape = [384]))# 使用啟用函數進行非線性化local3 = tf.nn.relu(tf.matmul(reshape, weight3) + bias3)# 全串連層(與上一層類似)# 隱含層節點數下降一半隻有192個,其他超參數保持不變weight4 = variable_with_weight_loss(shape = [384,192], stddev = 0.04, wl = 0.004)bias4 = tf.Variable(tf.constant(0.1, shape = [192]))local4 = tf.nn.relu(tf.matmul(local3, weight4) + bias4)# 輸出層(把Softmax的操作放在了loss部分)# 建立weight,其常態分佈標準差為上一層隱含節點的倒數,並且不計入L2的正則。weight5 = variable_with_weight_loss(shape = [192,10], stddev = 1/192.0, wl = 0.0)bias5 = tf.Variable(tf.constant(0.0, shape = [10]))# Softmax放在下面的原因。我們不需要對inference的輸出進行softmax處理就可以獲得最終的分類結果。 # 直接比較inference輸出的各類的數值大小即可。計算softmax主要是為了計算loss。因此softmax操作整合到後面合適。# 模型Inference的輸出結果logits = tf.nn.relu(tf.matmul(local4, weight5) + bias5)########計算CNN的loss######### softmax和cross entropy loss的計算合在一起# 得到最終的loss,其中包括cross entropy loss和後兩個全串連層weight的L2 lossdef loss(logits, labels):    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('losses', cross_entropy_mean)    return tf.add_n(tf.get_collection('losses'), name = 'total_loss')# loss函數中傳入值,獲得最終的lossloss = loss(logits, label_holder)########訓練設定 ######### 選擇最佳化器,學習速率設為1e-3train_op = tf.train.AdamOptimizer(1e-3).minimize(loss)# 輸出結果中top k的準確率,也就是輸出分數最高的那一類的準確率top_k_op = tf.nn.in_top_k(logits, label_holder, 1)# 建立預設的Sessionsess = tf.InteractiveSession()# 初始化全部模型參數tf.global_variables_initializer().run()# 啟動圖片資料增強線程隊列,一共使用16個線程進行加速。不啟動無法開始後面的inferencetf.train.start_queue_runners()########開始訓練######### 記錄每個step花費的時間,每隔10個step計算並展示當前的loss、每秒能訓練的樣本數量,以及在一個batch花費的時間。for step in range(max_steps):    start_time = time.time()    # 在每一個step的訓練過程,先獲得一個batch資料。再將這個batch資料傳入train_op和loss的計算。    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_time    if step %10 ==0:        examples_per_sec = batch_size / duration    sec_per_batch = float(duration)        format_str = ('step %d,loss=%.2f (%.1f example/sec; %.3f sec/batch)')    print(format_str % (step, loss_value, examples_per_sec, sec_per_batch))# 測試集評測準確率# 測試集樣本數num_examples = 10000import math# 計算多少個batch能將全部樣本評測完num_iter = int(math.ceil(num_examples / batch_size))true_count = 0total_sample_count = num_iter * batch_sizestep = 0# 在每一個的step中使用Session的run方法擷取test的batch# 再執行top_k_op計算模型在這個batch的top 1上預測正確的樣本數。# 最後匯總所有預測正確的結果,求得全部測試樣本中預測正確的數量。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)    step += 1# 最後將準確率評測結果計算並列印出來。precision = true_count / total_sample_count# print('precision @ 1 = %.3f' % precision)print (' Num examples: %d  Num correct: %d  Precision @ 1: %0.02f ' % (total_sample_count, true_count, precision))

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.