摘要:遷移學習遷移學習就是用別人已經訓練好的模型,如,等,把它當做,幫助我們提取特征??偨Y通過遷移學習我們可以使用較少的數據訓練出來一個相對不錯的模型,簡化了機器學習編程特別是在分布式環境下。代碼實現部分參考,在此表示感謝。
遷移學習
遷移學習就是用別人已經訓練好的模型,如:Inception Model,Resnet Model等,把它當做Pre-trained Model,幫助我們提取特征。常用方法是去除Pre-trained Model的最后一層,按照自己的需求重新更改,然后用訓練集訓練。
因為Pre-trained Model可能已經使用過大量數據集,經過了長時間的訓練,所以我們通過遷移學習可以使用較少的數據集訓練就可以獲得相對不錯的結果。
由于項目中使用到Estimator,所以我們再簡單介紹下Estimator。
TF Estimator這里引用下官網 Estimator的介紹。
您可以在本地主機上或分布式多服務器環境中運行基于 Estimator 的模型,而無需更改模型。此外,您可以在 CPU、GPU 或 TPU 上運行基于 Estimator 的模型,而無需重新編碼模型。
Estimator 簡化了在模型開發者之間共享實現的過程。
您可以使用高級直觀代碼開發先進的模型。簡言之,采用 Estimator 創建模型通常比采用低階 TensorFlow API 更簡單。
Estimator 本身在 tf.layers 之上構建而成,可以簡化自定義過程。
Estimator 會為您構建圖。
Estimator 提供安全的分布式訓練循環,可以控制如何以及何時:構建圖,初始化變量,開始排隊,處理異常,創建檢查點并從故障中恢復,保存TensorBoard的摘要。
使用 Estimator 編寫應用時,您必須將數據輸入管道從模型中分離出來。這種分離簡化了不同數據集的實驗流程。
案例我們可以使用“tf.keras.estimator.model_to_estimator”將keras轉換Estimator。這里使用的數據集是Fashion-MNIST。
Fashion-MNIST數據標簽:
數據導入:
import os import time import tensorflow as tf import numpy as np import tensorflow.contrib as tcon (train_image,train_lables),(test_image,test_labels)=tf.keras.datasets.fashion_mnist.load_data() TRAINING_SIZE=len(train_image) TEST_SIZE=len(test_image) # 將像素值由0-255 轉為0-1 之間 train_image=np.asarray(train_image,dtype=np.float32)/255 # 4維張量[batch_size,height,width,channels] train_image=train_image.reshape(shape=(TRAINING_SIZE,28,28,1)) test_image=np.asarray(test_image,dtype=np.float32)/255 test_image=test_image.reshape(shape=(TEST_SIZE,28,28,1))
使用tf.keras.utils.to_categorical將標簽轉為獨熱編碼表示:
# lables 轉為 one_hot表示 # 類別數量 LABEL_DIMENSIONS=10 train_lables_onehot=tf.keras.utils.to_categorical( y=train_lables,num_classes=LABEL_DIMENSIONS ) test_labels_onehot=tf.keras.utils.to_categorical( y=test_labels,num_classes=LABEL_DIMENSIONS ) train_lables_onehot=train_lables_onehot.astype(np.float32) test_labels_onehot=test_labels_onehot.astype(np.float32)
創建Keras模型:
“”“ 3層卷積層,2層池化層,最后展平添加全連接層使用softmax分類 ”“” inputs=tf.keras.Input(shape=(28,28,1)) conv_1=tf.keras.layers.Conv2D( filters=32, kernel_size=3, # relu激活函數在輸入值為負值時,激活值為0,此時可以使用LeakyReLU activation=tf.nn.relu )(inputs) pool_1=tf.keras.layers.MaxPooling2D( pool_size=2, strides=2 )(conv_1) conv_2=tf.keras.layers.Conv2D( filters=64, kernel_size=3, activation=tf.nn.relu )(pool_1) pool_2=tf.keras.layers.MaxPooling2D( pool_size=2, strides=2 )(conv_2) conv_3=tf.keras.layers.Conv2D( filters=64, kernel_size=3, activation=tf.nn.relu )(pool_2) conv_flat=tf.keras.layers.Flatten()(conv_3) dense_64=tf.keras.layers.Dense( units=64, activation=tf.nn.relu )(conv_flat) predictions=tf.keras.layers.Dense( units=LABEL_DIMENSIONS, activation=tf.nn.softmax )(dense_64)
模型配置:
model=tf.keras.Model( inputs=inputs, outputs=predictions ) model.compile( loss="categorical_crossentropy", optimizer=tf.train.AdamOptimizer(learning_rate=0.001), metrics=["accuracy"] )創建Estimator
指定GPU數量,然后將keras轉為Estimator,代碼如下:
NUM_GPUS=2 strategy=tcon.distribute.MirroredStrategy(num_gpus=NUM_GPUS) config=tf.estimator.RunConfig(train_distribute=strategy) estimator=tf.keras.estimator.model_to_estimator( keras_model=model,config=config )
前面說到過使用 Estimator 編寫應用時,您必須將數據輸入管道從模型中分離出來,所以,我們先創建input function。使用prefetch將data預置緩沖區可以加快數據讀取。因為下面的遷移訓練使用的數據集較大,所以在這里有必要介紹下優化數據輸入管道的相關內容。
優化數據輸入管道TensorFlow數據輸入管道是以下三個過程:
Extract:數據讀取,如本地,服務端
Transform:使用CPU處理數據,如圖片翻轉,裁剪,數據shuffle等
Load:將數據轉給GPU進行計算
數據讀取:
通常,當CPU為計算準備數據時,GPU/TPU處于閑置狀態;當GPU/TPU運行時,CPU處于閑置,顯然設備沒有被合理利用。
tf.data.Dataset.prefetch可以將上述行為并行實現,當GPU/TPU執行第N次訓練,此時讓CPU準備N+1次訓練使兩個操作重疊,從而利用設備空閑時間。
通過使用tf.contrib.data.parallel_interleave可以并行從多個文件讀取數據,并行文件數有cycle_length指定。
數據轉換:
使用tf.data.Dataset.map對數據集中的數據進行處理,由于數據獨立,所以可以并行處理。此函數讀取的文件是含有確定性順序,如果順序對訓練沒有影響,也可以取消確定性順序加快訓練。
def input_fn(images,labels,epochs,batch_size): ds=tf.data.Dataset.from_tensor_slices((images,labels)) # repeat值為None或者-1時將無限制迭代 ds=ds.shuffle(500).repeat(epochs).batch(batch_size).prefetch(batch_size) return ds模型訓練
# 用于計算迭代時間 class TimeHistory(tf.train.SessionRunHook): def begin(self): self.times = [] def before_run(self, run_context): self.iter_time_start = time.time() def after_run(self, run_context, run_values): self.times.append(time.time() - self.iter_time_start) time_hist = TimeHistory() BATCH_SIZE = 512 EPOCHS = 5 # lambda為了填寫參數 estimator.train(lambda:input_fn(train_images, train_labels, epochs=EPOCHS, batch_size=BATCH_SIZE), hooks=[time_hist]) # 訓練時間 total_time = sum(time_hist.times) print(f"total time with {NUM_GPUS} GPU(s): {total_time} seconds") # 訓練數據量 avg_time_per_batch = np.mean(time_hist.times) print(f"{BATCH_SIZE*NUM_GPUS/avg_time_per_batch} images/second with {NUM_GPUS} GPU(s)")
結果如圖:
得益于Estimator數據輸入和模型的分離,評估方法很簡單。
estimator.evaluate(lambda:input_fn(test_images, test_labels, epochs=1, batch_size=BATCH_SIZE))遷移學習訓練新模型
我們使用Retinal OCT images數據集進行遷移訓練,數據標簽為:NORMAL, CNV, DME DRUSEN,包含分辨率為512*296,84495張照片。
數據讀取,設置input_fn:
labels = ["CNV", "DME", "DRUSEN", "NORMAL"] train_folder = os.path.join("OCT2017", "train", "**", "*.jpeg") test_folder = os.path.join("OCT2017", "test", "**", "*.jpeg")
def input_fn(file_pattern, labels, image_size=(224,224), shuffle=False, batch_size=64, num_epochs=None, buffer_size=4096, prefetch_buffer_size=None): # 創建查找表,將string 轉為 int 64ID table = tcon.lookup.index_table_from_tensor(mapping=tf.constant(labels)) num_classes = len(labels) def _map_func(filename): # sep = "/" label = tf.string_split([filename], delimiter=os.sep).values[-2] image = tf.image.decode_jpeg(tf.read_file(filename), channels=3) image = tf.image.convert_image_dtype(image, dtype=tf.float32) image = tf.image.resize_images(image, size=image_size) # tf.one_hot:根據輸入的depth返回one_hot張量 # indices = [0, 1, 2] # depth = 3 # tf.one_hot(indices, depth) return: # [[1., 0., 0.], # [0., 1., 0.], # [0., 0., 1.]] return (image, tf.one_hot(table.lookup(label), num_classes)) dataset = tf.data.Dataset.list_files(file_pattern, shuffle=shuffle) if num_epochs is not None and shuffle: dataset = dataset.apply( tcon.data.shuffle_and_repeat(buffer_size, num_epochs)) elif shuffle: dataset = dataset.shuffle(buffer_size) elif num_epochs is not None: dataset = dataset.repeat(num_epochs) dataset = dataset.apply( tcon.data.map_and_batch(map_func=_map_func, batch_size=batch_size, num_parallel_calls=os.cpu_count())) dataset = dataset.prefetch(buffer_size=prefetch_buffer_size) return dataset使用VGG16網絡
通過keras使用預訓練的VGG16網絡,我們重訓練最后5層:
# include_top:不包含最后3個全連接層 keras_vgg16 = tf.keras.applications.VGG16(input_shape=(224,224,3), include_top=False) output = keras_vgg16.output output = tf.keras.layers.Flatten()(output) prediction = tf.keras.layers.Dense(len(labels), activation=tf.nn.softmax)(output) model = tf.keras.Model(inputs=keras_vgg16.input, outputs=prediction) # 后5層不訓練 for layer in keras_vgg16.layers[:-4]: layer.trainable = False
重新訓練模型:
# 通過遷移學習得到模型 model.compile(loss="categorical_crossentropy", # 使用默認學習率 optimizer=tf.train.AdamOptimizer(), metrics=["accuracy"]) NUM_GPUS = 2 strategy = tf.contrib.distribute.MirroredStrategy(num_gpus=NUM_GPUS) config = tf.estimator.RunConfig(train_distribute=strategy) # 轉至estimator estimator = tf.keras.estimator.model_to_estimator(model, config=config) BATCH_SIZE = 64 EPOCHS = 1 estimator.train(input_fn=lambda:input_fn(train_folder, labels, shuffle=True, batch_size=BATCH_SIZE, buffer_size=2048, num_epochs=EPOCHS, prefetch_buffer_size=4), hooks=[time_hist]) # 模型評估: estimator.evaluate(input_fn=lambda:input_fn(test_folder, labels, shuffle=False, batch_size=BATCH_SIZE, buffer_size=1024, num_epochs=1))VGG16網絡
如圖所示,VGG16有13個卷積層和3個全連接層。VGG16輸入為[224,224,3],卷積核大小為(3,3),池化大小為(2,2)步長為2。各層的詳細參數可以查看VGG ILSVRC 16 layers因為圖片較大,這里只給出部分截圖,詳情請點擊鏈接查看。
VGG16模型結構規整,簡單,通過幾個小卷積核(3,3)卷積層組合比大卷積核如(7,7)更好,因為多個(3,3)卷積比一個大的卷積擁有更多的非線性,更少的參數。此外,驗證了不斷加深的網絡結構可以提升性能(卷積+卷積+卷積+池化,代替卷積+池化,這樣減少W的同時有可以擬合更復雜的數據),不過VGG16參數量很多,占用內存較大。
總結通過遷移學習我們可以使用較少的數據訓練出來一個相對不錯的模型,Estimator簡化了機器學習編程特別是在分布式環境下。對于輸入數據較多的情況我們要從Extract,Transform,Load三方面考慮進行優化處理。當然,除了VGG16我們還有很多選擇,如:Inception Model,Resnet Model。
代碼實現部分參考Kashif Rasul,在此表示感謝。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/42743.html
摘要:論文可遷移性對抗樣本空間摘要對抗樣本是在正常的輸入樣本中故意添加細微的干擾,旨在測試時誤導機器學習模型。這種現象使得研究人員能夠利用對抗樣本攻擊部署的機器學習系統。 現在,卷積神經網絡(CNN)識別圖像的能力已經到了出神入化的地步,你可能知道在 ImageNet 競賽中,神經網絡對圖像識別的準確率已經超過了人。但同時,另一種奇怪的情況也在發生。拿一張計算機已經識別得比較準確的圖像,稍作調整,...
摘要:本文著重以人臉識別為例介紹深度學習技術在其中的應用,以及優圖團隊經過近五年的積累對人臉識別技術乃至整個人工智能領域的一些認識和分享。從年左右,受深度學習在整個機器視覺領域迅猛發展的影響,人臉識別的深時代正式拉開序幕。 騰訊優圖隸屬于騰訊社交網絡事業群(SNG),團隊整體立足于騰訊社交網絡大平臺,專注于圖像處理、模式識別、機器學習、數據挖掘、深度學習、音頻語音分析等領域開展技術研發和業務落地。...
摘要:介紹本次項目使用深度學習自動生成圖像字幕。本次,我們利用遷移學習使用模型實現此功能。使用對損失修正。至于文本預測部分與使用注意力機制實現機器翻譯大體一致。 介紹 showImg(https://segmentfault.com/img/bVbkSso?w=2048&h=1358); 本次項目使用深度學習自動生成圖像字幕。如上圖,模型自動生成The person is riding a ...
閱讀 3427·2021-11-19 09:40
閱讀 1313·2021-10-11 11:07
閱讀 4843·2021-09-22 15:07
閱讀 2889·2021-09-02 15:15
閱讀 1964·2019-08-30 15:55
閱讀 538·2019-08-30 15:43
閱讀 882·2019-08-30 11:13
閱讀 1449·2019-08-29 15:36