【磐創AI導讀】:本系列文章介紹了與tensorflow的相關知識,包括其介紹、安裝及使用等。本篇文章將接著上篇文章繼續介紹它的安裝及部分使用。查看上篇:文末福利|一文上手TensorFlow2.0(一)。想要獲取更多的機器學習、深度學習資源,歡迎大家點擊上方藍字關注我們的公眾號:磐創AI。
Tensorflow2.0 的安裝(CPU和GPU)「tf.keras」API2. TensorFlow2.0安裝Tensorflow兼容性最好的是Unix內核的系統,如Linux,MacOS等。另外TensorFlow的GPU版本僅支持Linux環境,不支持Windows和Mac環境,因此本節的安裝部分僅針對Linux系統環境。我們會統一使用Anaconda,在Mac和Windows下安裝的過程也較為簡單,讀者可以自行參考其官方文檔。Anaconda官網有各個平臺詳細的安裝使用教程:https://docs.anaconda.com/anaconda/install/。
我們打算使用python3.6,因此我們下載Anaconda5.2.0版本,該版本對應的python版本是3.6.5,為了下載的更快一點,我們從清華大學的鏡像站下載:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/?C=N&O=D,下載「Anaconda3-5.2.0-Linux-x86_64.sh」文件。 1. 執行「bashAnaconda3-5.2.0-Linux-x86_64.sh」,提示需要閱讀licenses,按下回車繼續,如圖1所示。
2. 出現提示是否接受licenses,輸入「yes」回車。提示Anaconda將要安裝的位置,回車確認。
4.提示是否安裝「VSCode」,輸入「no」回車。安裝完成。
如圖5所示,安裝好後我們鍵入「python3」,此時運行的還是系統自帶的python版本,我們執行「source ~/.bashrc」讓配置生效,此時在執行「python3」,運行的就是Anaconda。
接下來我們在Anaconda中創建一個虛擬Python環境,終端中執行如下命令:
接著出現提示是否繼續,輸入「y」回車,稍等片刻一個Python3.6的虛擬環境就創建好了。此時系統中有多個版本的Python,為了方便使用,我們配置一下環境變量,為每個版本的Python設置一個別名。另外為了後面方便使用「pip」來管理虛擬環境的包,我們為虛擬環境的「pip」命令也創建一個別名。
編輯「~/.bashrc」文件,在文件末尾增加如下內容:
alias python="/usr/bin/python2"
alias python3="/usr/bin/python3"
alias apython="/home/lqhou/anaconda3/envs/apython/bin/python3"
alias apip="/home/lqhou/anaconda3/envs/apython/bin/pip"
注意Anaconda的路徑要根據實際情況來填寫,「/home/lqhou/anaconda3」為作者系統上Anaconda的安裝路徑。配置完成後鍵入「source ~/.bashrc」讓配置生效,之後我們分別執行「python」、「python3」和「apython」命令,如圖6所示:
這裡python和python3命名指向的都是系統自帶的python版本,apython命令指向的是我們剛剛創建的python虛擬環境。這裡需要注意,當我們要使用「pip」命令為我們創建的python虛擬環境安裝包時,需要使用這裡我們配置的「apip」命令,直接使用pip或pip3命令,會把包安裝到系統自帶的python環境中。GPU版的TensorFlow包含了CPU版本,如果讀者手上有GPU資源的話,可以直接參考後文會提到的安裝GPU版的TensorFlow。我們可以直接使用「pip installtensorflow==2.0.0-alpha0」命令來進行安裝。由於作者使用的pip源還沒有加入「TensorFlow2.0.0-alpha0」版本,所以這裡我們直接到「PyPi」網站下載TensorFlow2.0 Alpha版的安裝包。進入網址:https://pypi.org/project/tensorflow/2.0.0a0/#files,部分安裝包如圖7所示:
圖7 TensorFlow2.0 Alpha版安裝包列表
這裡我們需要根據實際的Python版本和作業系統環境來下載相應的安裝包,這裡作者的python版本是python3.6.8,作業系統是64位的Ubuntu16.04。因此作者下載的是「tensorflow-2.0.0a0-cp36-cp36m-manylinux1_x86_64.whl」。
apip install tensorflow-2.0.0a0-cp36-cp36m-manylinux1_x86_64.whl
安裝完成後,我們進入python的交互式解釋器環境驗證安裝是否成功,如圖8所示:
圖8 測試TensorFlow2.0 Alpha是否安裝成功
JupyterNotebook是一個開源的Web應用程式,常被用於交互式的開發和展示一些數據科學項目(例如數據清洗和轉換、數據可視化以及機器學習等等)。在本章中為了方便大家學習,我們會使用Jupyter NoteBook作為我們的編程環境(讀者也可以使用Google的Colab:https://colab.research.google.com),後面章節的項目和代碼,讀者可以任意選擇自己喜歡的編程工具。在我們安裝好Anaconda後,Anaconda集成了Jupyter NoteBook,因此我們可以直接使用,如圖9所示。
我們直接點擊Jupyter下方的「運行」即可啟動Jupyter(也可以在終端中輸入「jupyter-notebook」來啟動),啟動之後會自動打開一個WEB頁面,如圖10所示。這裡列出了默認路徑下的所有目錄和文件,我們可以打開自己存放代碼的目錄。
圖10 Jupyter Notebook啟動之後打開的WEB界面如圖11所示,點擊頁面右上角的「new」菜單,再點擊「python[conda env:apython3]」菜單之後就會創建一個新的後綴名為「ipynb」的notebook文件。讀者的「new」菜單中可能只有一個「Python」kernel,而沒有另外兩個Anaconda的python環境的kenel。這裡讀者可以在命令行下執行命令「source activate apython3」進入我們之前創建的「apython3」虛擬環境,然後再執行命令「jupyter-notebook」命令啟動Jupyter,這時我們在「new」菜單下就可以看到我們需要使用的kernel了。
新創建的notebook文件會自動的在新的標籤頁打開,如圖12所示,新創建的是一個空的notebook文件。
如圖13所示,我們在notebook的單元格內輸入代碼,點擊「Run」之後會在單元格的下方顯示代碼運行的結果。
3 TensorFlow2.0使用3.1 「tf.data」API除了GPU和TPU等硬體加速設備以外,一個高效的數據輸入管道也可以很大程度的提升模型性能,減少模型訓練所需要的時間。數據輸入管道本質是一個ELT(Extract、Transform和Load)過程:
Extract:從硬碟中讀取數據(可以是本地的也可以是雲端的)。
Transform:數據的預處理(例如數據清洗、格式轉換等)。
Load:將處理好的數據加載到計算設備(例如CPU、GPU以及TPU等)。
數據輸入管道一般使用CPU來執行ELT過程,GPU等其他硬體加速設備則負責模型的訓練,ELT過程和模型的訓練並行執行,從而提高模型訓練的效率。另外ELT過程的各個步驟也都可以進行相應的優化,例如並行的讀取數據以及並行的處理數據等。在TensorFlow中我們可以使用「tf.data」API來構建這樣的數據輸入管道。我們首先下載接下來的實驗中需要用的圖像數據集(數據集的下載地址為「https://storage.googleapis.com/download.tensorflow.org/example_images/」,由於該地址需要翻牆後才能訪問,本書作者已經將下載好的數據集上傳到百度雲網盤,下載地址為「https://pan.baidu.com/s/16fvNOBvKyGVa8yCB5mDUOQ」。)該數據集是一個花朵圖片的數據集,將下載下來的數據解壓後如圖2-15所示,除了一個License文件以外主要是五個分別存放著對應類別花朵圖片的文件夾。其中「daisy(雛菊)」文件夾中有633張圖片,「dandelion(蒲公英)」文件夾中有898張圖片,「roses(玫瑰)」文件夾中有641張圖片,「sunflowers(向日葵)」文件夾中有699張圖片,「tulips(鬱金香)」文件夾中有799張圖片。
接下來我們開始實現代碼,首先我們導入需要使用的包:
import tensorflow as tf
import pathlib
pathlib提供了一組用於處理文件系統路徑的類。導入需要的包後,可以先檢查一下TensorFlow的版本:
data_root = pathlib.Path.cwd()
all_image_paths = list(data_root.glob('*/*/*'))
print(type(all_image_paths[0]))
all_image_paths = [str(path) for path in all_image_paths]
print(all_image_paths[0])
print(data_root)
接下來我們需要統計圖片的類別,並給每一個類別分配一個類標:
label_names = sorted(item.name for item in data_root.glob('*/*/') if item.is_dir())
label_to_index = dict((name, index) for index, name in enumerate(label_names))
all_image_labels = [label_to_index[pathlib.Path(path).parent.name]
print(label_to_index)
print("First 10 labels indices: ", all_image_labels[:2])
print("First 10 labels indices: ", all_image_paths[:2])
輸出結果如圖16所示,daisy(雛菊)、dandelion(蒲公英)、roses(玫瑰)、sunflowers(向日葵)、tulips(鬱金香)的類標分別為0、1、2、3、4、5。
處理完類標之後,我們接下來需要對圖片本身做一些處理,這裡我們定義一個函數用來加載和預處理圖片數據:
def load_and_preprocess_image(path):
image = tf.io.read_file(path)
image = tf.image.decode_jpeg(image, channels=3)
image = tf.image.resize(image, [192, 192])
image /= 255.0
return image
完成對類標和圖像數據的預處理之後,我們使用「tf.data.Dataset」來構建和管理數據集:
# 構建圖片路徑的「dataset」
path_ds = tf.data.Dataset.from_tensor_slices(all_image_paths)
# 使用AUTOTUNE自動調節管道參數
AUTOTUNE = tf.data.experimental.AUTOTUNE
# 構建圖片數據的「dataset」
image_ds = path_ds.map(load_and_preprocess_image,
num_parallel_calls=AUTOTUNE)
# 構建類標數據的「dataset」
label_ds = tf.data.Dataset.from_tensor_slices(tf.cast(all_image_labels, tf.int64))
# 將圖片和類標壓縮為(圖片,類標)對
image_label_ds = tf.data.Dataset.zip((image_ds, label_ds))
print(image_ds)
print(label_ds)
print(image_label_ds)
在代碼中,我們使用了「from_tensor_slices」方法使用張量的切片元素構建「dataset」,「tf.data.Dataset」類還提供了「from_tensor」直接使用單個張量來構建「dataset」,以及可以使用生成器生成的元素來構建「dataset」的「from_generator」方法。我們使用了「tf.data.Dataset」的「map」方法,該方法允許我們自己定義一個函數,將原數據集中的元素依次經過該函數處理,並將處理後的數據作為新的數據集,處理前和處理後的數據順序不變。例如這裡我們自己定義了一個「load_and_preprocess_image」函數,將「path_ds」中的圖片路徑轉換成了經過預處理的圖像數據,並保存在了「image_ds」中。最後我們使用「tf.data.Dataset」的「zip」方法將圖片數據和類標數據壓縮成「(圖片,類標)」對,其結構如圖17所示。我們可視化一下數據集中的部分數據:
import matplotlib.pyplot as plt
plt.figure(figsize=(8,8))
for n,image_label in enumerate(image_label_ds.take(4)):
plt.subplot(2,2,n+1)
plt.imshow(image_label[0])
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.xlabel(image_label[1])
接下來我們用創建的dataset訓練一個分類模型,這個例子的目的是讓讀者了解如何使用我們創建的dataset,為了簡單,我們直接使用「tf.keras.applications」包中訓練好的模型,並將其遷移到我們的花朵分類任務上來。這裡我們使用「MobileNetV2」模型。
mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_192_no_top.h5」
mobile_net = tf.keras.applications.MobileNetV2(input_shape=(192, 192, 3),
include_top=False)
mobile_net.trainable = False
當我們執行代碼後,訓練好的「MobileNetV2」模型會被下載到本地,該模型是在ImageNet數據集上訓練的。因為我們是想把該訓練好的模型遷移到我們的花朵分類問題中來,所以代碼我們設置該模型的參數不可訓練和更新。接下來我們打亂一下數據集,以及定義好訓練過程中每個「batch」的大小。
image_count = len(all_image_paths)
ds = image_label_ds.shuffle(buffer_size=image_count)
ds = ds.repeat()
BATCH_SIZE = 32
ds = ds.batch(BATCH_SIZE)
ds = ds.prefetch(buffer_size=AUTOTUNE)
在代碼中,我們使用「tf.data.Dataset」類的「shuffle」方法將數據集進行打亂。代碼使用「repeat」方法讓數據集可以重複獲取,通常情況下如果我們一個「epoch」只對完整的數據集訓練一遍的話,可以不需要設置「repeat」。「repeat」方法可以設置參數,例如「ds.repeat(2)」是讓數據集可以重複獲取兩遍,即一個訓練回合(epoch)中我們可以使用兩遍數據集,不加參數的話,則默認可以無限次重複獲取數據集。
代碼裡我們設置了訓練過程中一個「batch」的大小。我們使用「tf.data.Dataset.prefetch」方法讓ELT過程的 「數據準備(EL)」和「數據消耗(T)」過程並行。由於「MobileNetV2」模型接收的輸入數據是歸一化後範圍在[-1,1]之間的數據,我們在第31行代碼中對數據進行了一次歸一化處理後,其範圍在[0,1]之間,因此我們需要將我們的數據映射到[-1,1]之間。
def change_range(image,label):
return 2*image-1, label
keras_ds = ds.map(change_range)
接下來我們定義模型,由於預訓練好的「MobileNetV2」返回的數據維度為「(32,6,6,1280)」,其中32是一個「batch」的大小,「6,6」代表輸出的特徵圖的大小為「6X6」,1280代表該層使用了1280個卷積核。為了適應我們的分類任務,我們需要在「MobileNetV2」返回數據的基礎上再增加兩層網絡層。
model = tf.keras.Sequential([
mobile_net,
tf.keras.layers.GlobalAveragePooling2D(),
tf.keras.layers.Dense(len(label_names))])
全局平均池化(GAP,Global Average Pooling)將每一個特徵圖求平均,將該平均值作為該特徵圖池化後的結果,因此經過該操作後數據的維度變為了(32,1280)。由於我們的花朵分類任務是一個5分類的任務,因此我們再使用一個全連接(Dense),將維度變為(32,5)。
接著我們編譯一下模型,同時指定使用的優化器和損失函數:
model.compile(optimizer=tf.keras.optimizers.Adam(),
loss='sparse_categorical_crossentropy',
metrics=["accuracy"])
model.summary()
「model.summary()」可以輸出模型各層的參數概況,如圖19所示:
model.fit(ds, epochs=1, steps_per_epoch=10)
這裡參數「epochs」指定需要訓練的回合數,「steps_per_epoch」代表每個回合要取多少個「batch」數據,通常「steps_per_epoch」的大小等於我們數據集的大小除以「batch」的大小後上取整。關於模型的訓練部分,我們在後面中會詳細介紹。在本節中我們簡單了解了「tf.data」API的使用,在後面章節的項目實戰部分我們還會用到該API來構建數據輸入管道,包括圖像以及文本數據。
為了鼓勵大家踴躍在文章
留言區分享自己的看法,磐創AI推出了「留言送書」活動~在本文文末
留言即可參與活動,留言內容可以為你學習的故事、對本公眾號的看法或建議,亦或是對人工智慧的看法等。歡迎大家在日常推文中留言,以後將不定期推出「留言送書」活動。這次磐小仙精心挑選了本《TensorFlow與卷積神經網絡》送給大家。書籍詳細介紹可以點擊文末
閱讀原文查看。
書籍簡介:本書從TensorFlow基礎講起,逐步深入TensorFlow進階實戰,最後配合項目實戰案例,重點介紹了實用TensorFlow庫訓練卷積神經網絡模型並將模型移植到伺服器端、Android端和iOS端的知識。讀者不但可以系統地學習TensorFlow庫的使用,還能加深對深度卷積神經網絡的理解。本書分為4篇,共13章,涵蓋的主要內容有人工智慧發展歷程,TensorFlow基礎入門,高維Tensor對象的工具函數,前饋網絡,常見網絡,TensorFlow數據存取,TensorFlow數據預處理,TensorFlow模型訓練,TensorBoard可視化工具,中文手寫字識別,移植模型到TensorFlow Serving端,移植TensorFlow模型到Android端,移植TensorFlow模型到iOS端。
恭喜上期留言讀者yy,獲贈書籍一本。請 yy 同學聯繫小編:cellerai
/ 今日留言主題 /
點擊下方
| 閱讀原文 | 了解更多