學習筆記TF016:CNN實現、資料集、TFRecord、載入映像、模型、訓練、調試,tf016tfrecord

來源:互聯網
上載者:User

學習筆記TF016:CNN實現、資料集、TFRecord、載入映像、模型、訓練、調試,tf016tfrecord

AlexNet(Alex Krizhevsky,ILSVRC2012冠軍)適合做映像分類。層自左向右、自上向下讀取,關聯層分為一組,高度、寬度減小,深度增加。深度增加減少網路計算量。

訓練模型資料集 Stanford電腦視覺網站Stanford Dogs http://vision.stanford.edu/aditya86/ImageNetDogs/ 。資料下載解壓到模型代碼同一路徑imagenet-dogs目錄下。包含的120種狗映像。80%訓練,20%測試。產品模型需要預留未經處理資料交叉驗證。每幅映像JPEG格式(RGB),尺寸不一。

映像轉TFRecord檔案,有助加速訓練,簡化映像標籤匹配,映像分離利用檢查點檔案對模型進行不間斷測試。轉換映像格式把色彩空間轉灰階,映像修改統一尺寸,標籤除上每幅映像。訓練前只進行一次預先處理,時間較長。

glob.glob 枚舉指定路徑目錄,顯示資料集檔案結構。“*”萬用字元可以實現模糊尋找。檔案名稱中8個數字對應ImageNet類別WordNetID。ImageNet網站可用WordNetID查映像細節: http://www.image-net.org/synset?wnid=n02085620 。

檔案名稱分解為品種和相應的檔案名稱,品種對應檔案夾名稱。依據品種對映像分組。枚舉每個品種映像,20%映像劃入測試集。檢查每個品種測試映像是否至少有全部映像的18%。目錄和映像組織到兩個與每個品種相關的字典,包含各品種所有映像。分類映像組織到字典中,簡化選擇分類映像及歸類過程。

預先處理階段,依次遍曆所有分類映像,開啟列表中檔案。用dataset映像填充TFRecord檔案,把類別包含進去。dataset索引值對應檔案清單標籤。record_location 儲存TFRecord輸出路徑。枚舉dataset,當前索引用於檔案劃分,每隔100m幅映像,訓練樣本資訊寫入新的TFRecord檔案,加快寫操作進程。無法被TensorFlow識別為JPEG映像,用try/catch忽略。轉為灰階圖減少計算量和記憶體佔用。tf.cast把RGB值轉換到[0,1)區間內。標籤按字串儲存較高效,最好轉換為整數索引或獨熱編碼秩1張量。

開啟每幅映像,轉換為灰階圖,調整尺寸,添加到TFRecord檔案。tf.image.resize_images函數把所有映像調整為相同尺寸,不考慮長寬比,有扭曲。裁剪、邊界填充能保持映像長寬比。

按照TFRecord檔案讀取映像,每次載入少量映像及標籤。修改映像形狀有助訓練和輸出可視化。匹配所有在訓練集目錄下TFRecord檔案載入訓練映像。每個TFRecord檔案包含多幅映像。tf.parse_single_example只從檔案提取單個樣本。批運算可同時訓練多幅映像或單幅映像,需要足夠系統記憶體。

映像轉灰階值為[0,1)浮點類型,匹配convolution2d期望輸入。卷積輸出第1維和最後一維不改變,中間兩維發生變化。tf.contrib.layers.convolution2d建立模型第1層。weights_initializer設定正態隨機值,第一組濾波器填充常態分佈隨機數。濾波器設定trainable,資訊輸入網路,權值調整,提高模型準確率。
max_pool把輸出降採樣。ksize、strides ([1,2,2,1]),卷積輸出形狀減半。輸出形狀減小,不改變濾波器數量(輸出通道)或映像批資料尺寸。減少分量,與映像(濾波器)高度、寬度有關。更多輸出通道,濾波器數量增加,2倍於第一層。多個卷積和池化層減少輸入高度、寬度,增加深度。很多架構,卷積層和池化層超過5層。訓練調試時間更長,能匹配更多更複雜模式。
映像每個點與輸出神經元建立全串連。softmax,全串連層需要二階張量。第1維區分映像,第2維輸入張量秩1張量。tf.reshape 指示和使用其餘所有維,-1把最後池化層調整為巨大秩1張量。
池化層展開,網路目前狀態與預測全串連層整合。weights_initializer接收可調用參數,lambda運算式返回截斷常態分佈,指定分布標準差。dropout 削減模型中神經元重要性。tf.contrib.layers.fully_connected 輸出前面所有層與訓練中分類的全串連。每個像素與分類關聯。網路每一步將輸入映像轉化為濾波減小尺寸。濾波器與標籤匹配。減少訓練、測試網路計算量,輸出更具一般性。

訓練資料真實標籤和模型預測結果,輸入到訓練最佳化器(最佳化每層權值)計算模型損失。數次迭代,每次提升模型準確率。大部分分類函數(tf.nn.softmax)要求數實值型別標籤。每個標籤轉換代表包含所有分類清單索引整數。tf.map_fn 匹配每個標籤並返回類別清單索引。map依據目錄列表建立包含分類列表。tf.map_fn 可用指定函數對資料流圖張量映射,產生僅包含每個標籤在所有類標籤清單索引秩1張量。tf.nn.softmax用索引預測。

調試CNN,觀察濾波器(卷積核)每輪迭代變化。設計良好CNN,第一個卷積層工作,輸入權值被隨機初始化。權值通過映像啟用,啟用函數輸出(特徵圖)隨機。特徵圖可視化,輸出外觀與原始圖相似,被施加靜力(static)。靜力由所有權值的隨機激發。經過多輪迭代,權值被調整擬合訓練反饋,濾波器趨於一致。網路收斂,濾波器與映像不同細小模式類似。tf.image_summary得到訓練後的濾波器和特徵圖簡單視圖。資料流圖映像概要輸出(image summary output)從整體瞭解所使用的濾波器和輸入映像特徵圖。TensorDebugger,迭代中以GIF動畫查看濾波器變化。

文本輸入儲存在SparseTensor,大部分分量為0。CNN使用稠密輸入,每個值都重要,輸入大部分分量非0。

 

    import tensorflow as tf    import glob    from itertools import groupby    from collections import defaultdict    sess = tf.InteractiveSession()    image_filenames = glob.glob("./imagenet-dogs/n02*/*.jpg")    image_filenames[0:2]    training_dataset = defaultdict(list)    testing_dataset = defaultdict(list)    image_filename_with_breed = map(lambda filename: (filename.split("/")[2], filename), image_filenames)    for dog_breed, breed_images in groupby(image_filename_with_breed, lambda x: x[0]):        for i, breed_image in enumerate(breed_images):            if i % 5 == 0:                testing_dataset[dog_breed].append(breed_image[1])            else:                training_dataset[dog_breed].append(breed_image[1])        breed_training_count = len(training_dataset[dog_breed])        breed_testing_count = len(testing_dataset[dog_breed])        breed_training_count_float = float(breed_training_count)        breed_testing_count_float = float(breed_testing_count)        assert round(breed_testing_count_float / (breed_training_count_float + breed_testing_count_float), 2) > 0.18, "Not enough testing images."    print "training_dataset testing_dataset END ------------------------------------------------------"    def write_records_file(dataset, record_location):        writer = None        current_index = 0        for breed, images_filenames in dataset.items():            for image_filename in images_filenames:                if current_index % 100 == 0:                    if writer:                        writer.close()                    record_filename = "{record_location}-{current_index}.tfrecords".format(                        record_location=record_location,                        current_index=current_index)                    writer = tf.python_io.TFRecordWriter(record_filename)                    print record_filename + "------------------------------------------------------"                 current_index += 1                image_file = tf.read_file(image_filename)                try:                    image = tf.image.decode_jpeg(image_file)                except:                    print(image_filename)                    continue                grayscale_image = tf.image.rgb_to_grayscale(image)                resized_image = tf.image.resize_images(grayscale_image, [250, 151])                image_bytes = sess.run(tf.cast(resized_image, tf.uint8)).tobytes()                image_label = breed.encode("utf-8")                example = tf.train.Example(features=tf.train.Features(feature={                    'label': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_label])),                    'image': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_bytes]))                }))                writer.write(example.SerializeToString())        writer.close()    write_records_file(testing_dataset, "./output/testing-images/testing-image")    write_records_file(training_dataset, "./output/training-images/training-image")    print "write_records_file testing_dataset training_dataset END------------------------------------------------------"    filename_queue = tf.train.string_input_producer(    tf.train.match_filenames_once("./output/training-images/*.tfrecords"))    reader = tf.TFRecordReader()    _, serialized = reader.read(filename_queue)    features = tf.parse_single_example(    serialized,        features={            'label': tf.FixedLenFeature([], tf.string),            'image': tf.FixedLenFeature([], tf.string),        })    record_image = tf.decode_raw(features['image'], tf.uint8)    image = tf.reshape(record_image, [250, 151, 1])    label = tf.cast(features['label'], tf.string)    min_after_dequeue = 10    batch_size = 3    capacity = min_after_dequeue + 3 * batch_size    image_batch, label_batch = tf.train.shuffle_batch(        [image, label], batch_size=batch_size, capacity=capacity, min_after_dequeue=min_after_dequeue)    print "load image from TFRecord END------------------------------------------------------"    float_image_batch = tf.image.convert_image_dtype(image_batch, tf.float32)    conv2d_layer_one = tf.contrib.layers.convolution2d(        float_image_batch,        num_outputs=32,        kernel_size=(5,5),        activation_fn=tf.nn.relu,        weights_initializer=tf.random_normal,        stride=(2, 2),        trainable=True)    pool_layer_one = tf.nn.max_pool(conv2d_layer_one,        ksize=[1, 2, 2, 1],        strides=[1, 2, 2, 1],        padding='SAME')    conv2d_layer_one.get_shape(), pool_layer_one.get_shape()    print "conv2d_layer_one pool_layer_one END------------------------------------------------------"    conv2d_layer_two = tf.contrib.layers.convolution2d(        pool_layer_one,        num_outputs=64,        kernel_size=(5,5),        activation_fn=tf.nn.relu,        weights_initializer=tf.random_normal,        stride=(1, 1),        trainable=True)    pool_layer_two = tf.nn.max_pool(conv2d_layer_two,        ksize=[1, 2, 2, 1],        strides=[1, 2, 2, 1],        padding='SAME')    conv2d_layer_two.get_shape(), pool_layer_two.get_shape()    print "conv2d_layer_two pool_layer_two END------------------------------------------------------"    flattened_layer_two = tf.reshape(        pool_layer_two,        [            batch_size,            -1        ])    flattened_layer_two.get_shape()    print "flattened_layer_two END------------------------------------------------------"    hidden_layer_three = tf.contrib.layers.fully_connected(        flattened_layer_two,        512,        weights_initializer=lambda i, dtype: tf.truncated_normal([38912, 512], stddev=0.1),        activation_fn=tf.nn.relu    )    hidden_layer_three = tf.nn.dropout(hidden_layer_three, 0.1)    final_fully_connected = tf.contrib.layers.fully_connected(        hidden_layer_three,        120,        weights_initializer=lambda i, dtype: tf.truncated_normal([512, 120], stddev=0.1)    )    print "final_fully_connected END------------------------------------------------------"    labels = list(map(lambda c: c.split("/")[-1], glob.glob("./imagenet-dogs/*")))    train_labels = tf.map_fn(lambda l: tf.where(tf.equal(labels, l))[0,0:1][0], label_batch, dtype=tf.int64)    loss = tf.reduce_mean(        tf.nn.sparse_softmax_cross_entropy_with_logits(            final_fully_connected, train_labels))    batch = tf.Variable(0)    learning_rate = tf.train.exponential_decay(        0.01,        batch * 3,        120,        0.95,        staircase=True)    optimizer = tf.train.AdamOptimizer(        learning_rate, 0.9).minimize(        loss, global_step=batch)    train_prediction = tf.nn.softmax(final_fully_connected)    print "train_prediction END------------------------------------------------------"    filename_queue.close(cancel_pending_enqueues=True)    coord.request_stop()    coord.join(threads)    print "END------------------------------------------------------"

 

參考資料:
《面向機器智能的TensorFlow實踐》

歡迎加我交流:qingxingfengzi
我的公眾號:qingxingfengzigz
我老婆張幸清的公眾號:qingqingfeifangz

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.