走向TensorFlow 2.0(深度學(xué)習(xí)應(yīng)用編程快速入門)_第1頁
走向TensorFlow 2.0(深度學(xué)習(xí)應(yīng)用編程快速入門)_第2頁
走向TensorFlow 2.0(深度學(xué)習(xí)應(yīng)用編程快速入門)_第3頁
走向TensorFlow 2.0(深度學(xué)習(xí)應(yīng)用編程快速入門)_第4頁
走向TensorFlow 2.0(深度學(xué)習(xí)應(yīng)用編程快速入門)_第5頁
已閱讀5頁,還剩148頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

走向TensorFlow2.0深度學(xué)習(xí)應(yīng)用編程快速入門目錄TOC\h\h第1章Python基礎(chǔ)編程入門\h1.1Python的歷史\h1.2Python的基本數(shù)據(jù)類型\h1.3Python數(shù)據(jù)處理工具之Pandas\h1.4Python圖像處理工具之PIL\h第2章TensorFlow2.0快速入門\h2.1TensorFlow2.0簡介\h2.2TensorFlow2.0環(huán)境搭建\h2.3TensorFlow2.0基礎(chǔ)知識\h2.4TensorFlow2.0高階API(tf.keras)\h第3章基于CNN的圖像識別應(yīng)用編程實(shí)踐\h3.1CNN相關(guān)基礎(chǔ)理論\h3.2TensorFlow2.0API詳解\h3.3項(xiàng)目工程結(jié)構(gòu)設(shè)計\h3.4項(xiàng)目實(shí)現(xiàn)代碼詳解\h第4章基于Seq2Seq的中文聊天機(jī)器人編程實(shí)踐\h4.1NLP基礎(chǔ)理論知識\h4.2TensorFlow2.0API詳解\h4.3項(xiàng)目工程結(jié)構(gòu)設(shè)計\h4.4項(xiàng)目實(shí)現(xiàn)代碼詳解\h第5章基于CycleGAN的圖像風(fēng)格遷移應(yīng)用編程實(shí)踐\h5.1GAN基礎(chǔ)理論\h5.2CycleGAN的算法原理\h5.3TensorFlow2.0API詳解\h5.4項(xiàng)目工程結(jié)構(gòu)設(shè)計\h5.5項(xiàng)目實(shí)現(xiàn)代碼詳解\h第6章基于Transformer的文本情感分析編程實(shí)踐\h6.1Transformer相關(guān)理論知識\h6.2TensorFlow2.0API詳解\h6.3項(xiàng)目工程結(jié)構(gòu)設(shè)計\h6.4項(xiàng)目實(shí)現(xiàn)代碼詳解\h第7章基于TensorFlowServing的模型部署實(shí)踐\h7.1TensorFlowServing框架簡介\h7.2TensorFlowServing環(huán)境搭建\h7.3API詳解\h7.4項(xiàng)目工程結(jié)構(gòu)設(shè)計\h7.5項(xiàng)目實(shí)現(xiàn)代碼詳解第1章Python基礎(chǔ)編程入門Python是當(dāng)前人工智能領(lǐng)域的主要編程語言。本書開篇我們先講解Python的基礎(chǔ)編程入門,目的是讓各位讀者能夠?qū)W習(xí)或溫習(xí)Python的基礎(chǔ)用法,以便在閱讀后續(xù)章節(jié)中的代碼時不會感到陌生。本章將介紹Python的歷史、Python的基本數(shù)據(jù)類型、Python的數(shù)據(jù)處理工具Pandas和圖像處理工具PIL。1.1Python的歷史Python是一種計算機(jī)程序設(shè)計語言,從它誕生至今已有將近30年的時間。Python的設(shè)計目的是要創(chuàng)造一種簡單、易用且功能全面的語言。在Python發(fā)展的30年中,前20年一直是小眾語言,近10年隨著人工智能的興起才逐步進(jìn)入全世界程序員的視野。1.1.1Python版本的演進(jìn)Python是由GuidovanRossum(以下稱Guido)在1989年12月底著手開始編寫的一種編程語言。編寫Python語言是想創(chuàng)造一種處于C語言和shell之間的功能全面、易學(xué)、易用且可拓展的“膠水”語言。1991年,Guido編寫的第一個Python編譯器誕生,這也標(biāo)志著Python語言的誕生。在接下來的20年中,Python從1.0版本演進(jìn)到了2.7版本。Python2.7版本是Python2.x系列的終結(jié)版本。2008年P(guān)ython社區(qū)發(fā)布了Python3.0版本,且宣布自2020年之后社區(qū)只對Python3.x版本進(jìn)行支持,Python2.x版本將停止更新和支持。如果你剛剛開始學(xué)習(xí)Python,那么建議選擇Python3.x版本。1.1.2Python的工程應(yīng)用情況近幾年P(guān)ython變得炙手可熱,這得益于其在人工智能和數(shù)據(jù)分析領(lǐng)域的應(yīng)用,但是Python能做的并不僅限于此。Python擁有豐富的函數(shù)庫和框架,這讓它在Web開發(fā)領(lǐng)域也得到了較多的應(yīng)用,比如國外的YouTube、DropBox和Instagram,國內(nèi)的知乎、豆瓣等許多大型互聯(lián)網(wǎng)應(yīng)用的開發(fā)都使用了Python。由此可知,Python已經(jīng)是一種比較完善的工程開發(fā)語言,你可以在掌握它的前提下開發(fā)任意應(yīng)用。本章中,我們將重點(diǎn)學(xué)習(xí)Python在人工智能領(lǐng)域和數(shù)據(jù)處理領(lǐng)域的應(yīng)用。1.2Python的基本數(shù)據(jù)類型Python的基本數(shù)據(jù)類型主要包括變量(Variable)、數(shù)字(Number)、字符串(String)、列表(List)、元組(Tuple)和字典(Dictionary)。其中數(shù)字、字符串、列表、元組和字典是Python中5種標(biāo)準(zhǔn)的數(shù)據(jù)類型,我們必須要掌握它們的含義、操作以及屬性。1.變量在Python中,變量是不需要進(jìn)行類型聲明的,可以直接賦值后使用。我們使用“=”為變量賦值,變量會自動獲取所賦數(shù)值的類型。變量存儲在內(nèi)存中,根據(jù)變量類型的不同解釋器會分配指定的內(nèi)存,并根據(jù)變量的類型來存儲對應(yīng)的數(shù)據(jù)。示例代碼如下:輸出結(jié)果如下:注:print是Python中的保留字,其作用是打印內(nèi)容。“#-*-coding:UTF-8-*-”注明代碼的編碼使用UTF-8,這樣可以避免出現(xiàn)中文字符的編碼錯誤問題。type是Python中的保留字,可以直接返回變量的類型。在Python中變量賦值是極其靈活和方便的,可以使用上面示例代碼中的賦值方式,也可以使用“=”對多個變量賦不同類型的值。示例代碼如下:輸出結(jié)果如下:2.數(shù)字(Number)在Python3.x中數(shù)字類型包括int(整型)、float(浮點(diǎn)型)和complex(復(fù)數(shù))。對數(shù)字類型的變量賦值,示例代碼如下:以上就完成了對數(shù)字類型變量的賦值,不過在日常開發(fā)中這種賦值方式一般用得比較少,更多的是使用參數(shù)傳遞進(jìn)行賦值。3.字符串(String)字符串類型是我們在日常開發(fā)中經(jīng)常用到的一種數(shù)據(jù)類型。在數(shù)據(jù)處理階段,我們需要對字符串類型的數(shù)據(jù)進(jìn)行類型轉(zhuǎn)換、字符串截取等操作。需要注意的是,String屬于Python內(nèi)置序列類型的扁平序列。在扁平序列中存放的是實(shí)際值而不是值的引用。String和Tuple一樣都屬于不可變序列,也就是說,其保存的值是不可被修改的。String可以使用“=”直接進(jìn)行賦值,示例代碼如下:4.列表(List)列表屬于Python的容器序列,能存放不同類型的數(shù)據(jù)。列表是可變序列,我們可以根據(jù)需要對列表內(nèi)的數(shù)據(jù)進(jìn)行修改。列表的創(chuàng)建和賦值示例代碼如下:5.元組(Tuple)元組的屬性和列表十分類似,不同的是元組中的元素是不能修改的。元組用小括號來表示。元組具有以下操作特性。?當(dāng)元組只包含一個值時,需要在這個值后面添加逗號,以消除歧義。例如?元組與字符串類似,下標(biāo)的索引是從0開始的,不能對元組中的元素進(jìn)行刪除操作,但是可以進(jìn)行截取和組合操作。?當(dāng)一個對象沒有指定符號時,如果以逗號隔開,則默認(rèn)為元組。?元組內(nèi)的元素是不能被刪除的,我們可以使用del語句來刪除元組。?元組本身也是一個序列,因此我們可以訪問元組中指定的位置,也可以使用索引來截取元組中的元素。?元組內(nèi)置了一些函數(shù)用于對元組進(jìn)行操作,比如len(tuple),計算元組中元素的個數(shù);max(tuple),返回元組中元素的最大值;min(tuple),返回元組中元素的最小值;tuple(seq),將列表轉(zhuǎn)換為元組。6.字典(Dictionary)字典是一個可變?nèi)萜髂P停梢源娣湃我忸愋偷膶ο?。?shù)據(jù)在字典中是按照key-value存儲的,存儲時key是唯一的且不可變的數(shù)據(jù)類型,value可以重復(fù)。字典類型用“{}”來表示,代碼如下:對字典中數(shù)據(jù)的訪問是通過key來實(shí)現(xiàn)的,不同于列表或者元組通過下標(biāo)的方式來實(shí)現(xiàn)訪問。示例代碼如下:字典中的key不可以改變,但是value是可以改變的。我們可以直接通過重新賦值的方式修改字典里的元素。如果需要刪除字典里的元素,則可以通過key讀取字典中的元素后,用del命令實(shí)現(xiàn)。在Python字典中內(nèi)置了一些方法可以對字典進(jìn)行操作,比如dict.clear(),刪除字典內(nèi)所有的元素;dict.copy(),返回一個字典的淺復(fù)制;dict.fromkeys(seq[,val]),創(chuàng)建一個新字典,以序列seq中的元素做字典的鍵,val為字典中所有鍵對應(yīng)的初始值;dict.get(key,default=None),返回指定鍵的value,如果value不存在,則返回default;dict.has_key(key),判斷字典中是否存在所要查詢的key;dict.items(),以列表形式返回可遍歷的(key,value)元組數(shù)組;dict.keys(),以列表形式返回一個字典中所有的鍵;dict.update(dict1),把字典dict1的鍵值更新到dict中;dict.values(),以列表形式返回字典中所有的值。1.3Python數(shù)據(jù)處理工具之PandasPandas最核心的兩個數(shù)據(jù)結(jié)構(gòu)是一維的Series和二維的DataFrame,Series是帶有標(biāo)簽的同構(gòu)類型數(shù)組,而DataFrame是一個二維的表結(jié)構(gòu)。在同構(gòu)類型的數(shù)據(jù)中,一個DataFrame可以看作是由多個Series組成的。1.3.1數(shù)據(jù)讀取和存儲Pandas是處理結(jié)構(gòu)化數(shù)據(jù)非常重要的一個工具,其功能強(qiáng)大且好用。Pandas可以從CSV、JSON、Text等格式文件中讀取數(shù)據(jù),本節(jié)講解CSV、JSON格式數(shù)據(jù)的讀取和存儲。1.CSV文件的讀取和存儲對CSV文件進(jìn)行操作有兩個接口(API),分別是read_csv和to_csv。(1)API:read_csvread_csv()是用來讀取CSV文件的接口,其具有豐富的參數(shù),可以配置來滿足實(shí)際的數(shù)據(jù)讀取需要。下面介紹一些關(guān)鍵的且常用的參數(shù)。?filepath_or_buffer:配置所需讀取CSV文件的路徑。?sep:配置CSV文件的列分隔符,默認(rèn)是逗號“,”。?delimiter:可選配置,作為sep配置分隔符的別名。?delim_whitespace:配置是否用空格來作為列分隔符。如果設(shè)置為True,那么sep配置參數(shù)就不起作用了。?header:配置用行數(shù)來作為列名,默認(rèn)配置成自動推斷。?names:配置列名,如果所讀取的CSV文件沒有表頭,那么需要配置header=None,否則會將第一行數(shù)據(jù)作為對應(yīng)的列名。?usecols:當(dāng)只需要讀取CSV文件中的部分?jǐn)?shù)據(jù)時,可以使用usecols來指定讀取列名以獲取數(shù)據(jù)。?dtype:配置所讀取數(shù)據(jù)的類型。?encoding:配置文件的編碼方式,一般使用UTF-8或者GBK。(2)API:to_csvto_csv()用于將數(shù)據(jù)保存到CSV文件中。其參數(shù)比較多,如下所示,但只有第一個參數(shù)是必需的。?path_or_buf:配置CSV文件的保存路徑。?sep:配置保存文件的分隔符,默認(rèn)是逗號“,”。?na_rep:配置空值補(bǔ)全的值,默認(rèn)用空格代替。?float_format:配置將浮點(diǎn)數(shù)格式化成字符串類型。?columns:配置需要寫入列的列名,如果不配置,則默認(rèn)從第1列開始寫入。?header:配置是否寫入列名,默認(rèn)是需要寫的。?index:配置是否寫入行名,默認(rèn)是需要寫的。?index_label:配置用來作為列索引的列,默認(rèn)是沒有的。?mode:配置寫入模式,默認(rèn)是W。?encoding:配置編碼格式,該配置只針對Python3以前的版本。?line_terminator:配置每行的結(jié)束符,默認(rèn)使用“\n”。?quotin:配置CSV的引用規(guī)則。?quotechar:配置用來作為引用的字符,默認(rèn)是空格。?chunksize:配置每次寫入的行數(shù)。?tuplesize_cols:配置寫入list的格式,默認(rèn)以元組的方式寫入。?date_format:配置時間數(shù)據(jù)的格式。2.JSON文件的讀取和存儲對JOSN文件進(jìn)行操作有兩個API,分別是read_json和to_json。(1)API:read_json()read_json()是用于讀取JSON文件或者返回JSON數(shù)據(jù)的接口。日常需要用到的配置參數(shù)如下。?filepath_or_buffer:配置有效的JSON字符串、JSON文件的路徑或者數(shù)據(jù)接口。數(shù)據(jù)接口可以是一個URL地址。?type:配置將讀取的數(shù)據(jù)生成Series還是DataFrame,默認(rèn)是DataFrame。(2)API:to_json()to_json()用于將數(shù)據(jù)保存為JSON格式。日常需要用到的配置參數(shù)如下。?path_or_buf:配置JSON數(shù)據(jù)保存的路徑或者寫入的內(nèi)存區(qū)域。?date_format:配置時間數(shù)據(jù)的格式,epoch表示配置成時間戳的格式,iso表示配置成ISO8601的格式。?double_precision:配置小數(shù)點(diǎn)后保留的位數(shù),默認(rèn)是10位。?force_ascii:配置是否強(qiáng)制將String轉(zhuǎn)碼成ASCII,默認(rèn)強(qiáng)制進(jìn)行轉(zhuǎn)碼。?date_unit:配置時間數(shù)據(jù)的格式,可以實(shí)現(xiàn)精確到秒級或毫秒級。1.3.2數(shù)據(jù)查看和選取Pandas的數(shù)據(jù)對象有Series、DataFrame和Panel,常用的數(shù)據(jù)類型是一維的Series和二維的DataFrame。DataFrame擁有非常豐富的API,能夠滿足我們對數(shù)據(jù)選取和處理的需求。1.查看數(shù)據(jù)(1)df.shapedf.shape用于查看數(shù)據(jù)的維度。由于DataFrame是二維的,因此df.shape的返回值包含兩個元素,df.shape[0]返回的是行數(shù),df.shape[1]返回的是列數(shù)。示例代碼如下:(2)df.head()df.head()默認(rèn)返回DataFrame數(shù)據(jù)的前5行,如果需要查看更多的行數(shù),則只要傳參進(jìn)去即可。df.tail()默認(rèn)返回數(shù)據(jù)的后5行,想要查看更多的數(shù)據(jù)同樣可以傳參進(jìn)去。查看數(shù)據(jù)的匯總統(tǒng)計可以使用df.describe(),查看數(shù)據(jù)概況可以使用。示例代碼如下:想要查看列名可以使用df.columns(),查看各列的平均值可以直接用df.mean()。2.選取數(shù)據(jù)在選取數(shù)據(jù)時,既可以使用列名來選取,也可以使用索引來選取。如果要查看某列的數(shù)據(jù),則可以用df[col_name]或者df.col_name,當(dāng)查看多列時可以將多列的列名作為一個數(shù)組傳參進(jìn)去,如df[[col1,col2]]。使用索引來選取數(shù)據(jù),則要用到df.iloc。大家要注意df.loc和df.iloc在使用上是有區(qū)別的,df.loc傳遞的是索引的名稱,df.iloc傳遞的是索引的相對位置,我們常用的是df.iloc。示例代碼如下:1.3.3數(shù)據(jù)處理PandasDataFrame提供了豐富的數(shù)據(jù)處理方法,為我們進(jìn)行必要的數(shù)據(jù)操作和預(yù)處理提供了非常大的幫助。下面我們來看看常用的數(shù)據(jù)處理方法。1.數(shù)據(jù)合并在進(jìn)行數(shù)據(jù)預(yù)處理時,需要進(jìn)行必要的數(shù)據(jù)合并操作,將分散的數(shù)據(jù)或者部分?jǐn)?shù)據(jù)整合到一起進(jìn)行神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練。DataFrame提供了多個數(shù)據(jù)拼接的方法,使用pd.concat()可以直接放到數(shù)組中按行拼接,也可以使用pd.merge()按列拼接,或者使用df.append()增加某列數(shù)據(jù)。示例代碼如下:2.數(shù)據(jù)清理在使用DataFrame進(jìn)行數(shù)據(jù)處理時,如果數(shù)據(jù)質(zhì)量不高,則需要清理一些空值或者進(jìn)行空值補(bǔ)全。我們可以使用df3.isnull()檢查數(shù)據(jù)是否為空值,使用df3.isnull().sum()進(jìn)行空值的統(tǒng)計。如果需要對空值進(jìn)行補(bǔ)全,則可以使用df3.fillna(n),n值就是替換空值的值。如果想要去掉所有帶有空值的數(shù)據(jù),則可以使用df3.dropna()刪除包含空值的行和列,默認(rèn)刪除包含空值的行。df3.dropna(axis=1)會刪除包含空值的列。示例代碼如下:3.數(shù)據(jù)處理在進(jìn)行數(shù)據(jù)處理時,我們還會遇到諸如轉(zhuǎn)換數(shù)據(jù)類型、統(tǒng)計唯一值的個數(shù)以及序列排序等需求。DataFrame也提供了一些對應(yīng)的操作方法供使用,比如,轉(zhuǎn)換數(shù)據(jù)類型可以使用df3.astype(),統(tǒng)計唯一值的個數(shù)可以使用df3.columns.value_counts(),序列排序可以使用df3.sort_values(by=colname,ascending=True)。示例代碼如下:1.4Python圖像處理工具之PIL在Python中進(jìn)行圖像處理有PIL、OpenCV等工具。PIL是Python中常用的圖像處理工具,本書中我們使用PIL進(jìn)行圖像處理。本節(jié)詳細(xì)介紹圖像處理工具PIL。1.4.1PIL簡介PIL是PythonImagingLibrary的簡稱,目前已經(jīng)是Python生態(tài)系統(tǒng)中圖像處理的標(biāo)準(zhǔn)庫。PIL之所以如此受歡迎,是因?yàn)樗墓δ芊浅?qiáng)大且API非常簡單、易用。PIL只支持Python2.x版本,目前支持Python3.x的是社區(qū)在PIL的基礎(chǔ)上Fork的版本,項(xiàng)目叫Pillow。1.4.2PIL接口詳解下面我們會對PIL的常用接口進(jìn)行講解并給出示例代碼。1.圖像讀寫(1)從文件中讀取圖像數(shù)據(jù)Image.open():本API提供了打開圖像文件和讀取圖像數(shù)據(jù)的功能。示例代碼如下:(2)從壓縮文件中讀取圖像數(shù)據(jù)TarIO():本API提供了tar文件的讀取功能,不用解壓縮就可以直接從tar文件中讀取圖像數(shù)據(jù)。示例代碼如下:(3)將圖像數(shù)據(jù)保存為JPEG格式Image.save():本API提供了圖像數(shù)據(jù)的保存功能,可以保存成訓(xùn)練所需要的圖像格式。示例代碼如下:2.圖像編輯圖像編輯包含生成圖像縮略圖、圖像格式查詢和圖像截取幾種操作,尤其是圖像截取操作,是我們在編程中經(jīng)常需要做的。(1)生成圖像縮略圖在編程中我們有時會遇到圖像數(shù)據(jù)過大導(dǎo)致出現(xiàn)內(nèi)存或者顯存溢出的問題。im.thumbnai這個API提供了將圖像制作成縮略圖的功能,在不改變主要圖像特征的情況下對圖像進(jìn)行縮略變換,以減小圖像數(shù)據(jù)。示例代碼如下:(2)圖像格式查詢在進(jìn)行圖像處理時,我們需要查看或者判別圖像的格式,以防止出現(xiàn)因圖像格式不一致引起的錯誤。im.format、im.size和im.mode這些API分別提供了圖像的格式、尺寸、色彩模式(RGB、L)信息的查詢功能。示例代碼如下:(3)圖像截取在實(shí)際業(yè)務(wù)場景中,我們獲得的圖像尺寸可能是不一樣的,而在進(jìn)行訓(xùn)練時需要數(shù)據(jù)維度是固定的。因此,在進(jìn)行訓(xùn)練前需要對數(shù)據(jù)進(jìn)行預(yù)處理,我們使用im.crop對圖像進(jìn)行截取以保持圖像的尺寸統(tǒng)一。示例代碼如下:3.圖像尺寸變換im.resize()提供了圖像尺寸變換功能,可以按照需要變換源圖像的尺寸。im.rotate()提供了圖像旋轉(zhuǎn)功能,可以根據(jù)需要旋轉(zhuǎn)不同的角度。示例代碼如下:4.像素變換(1)像素色彩模式變換在實(shí)際工業(yè)生產(chǎn)中,通常需要對圖像進(jìn)行二值化,可以通過convert()對圖像進(jìn)行二值化處理。這個API提供了將圖像進(jìn)行像素色彩模式轉(zhuǎn)換的功能,可以在支持的像素色彩格式間進(jìn)行轉(zhuǎn)換。在人工智能算法編程中常用的是將RGB模式進(jìn)行二值化操作,示例代碼如下:(2)像素對比度調(diào)節(jié)在進(jìn)行圖像數(shù)據(jù)處理時,為了增加圖像數(shù)據(jù)的特征,可以調(diào)節(jié)像素對比度。im.filter()提供了調(diào)節(jié)像素對比度的功能,通過調(diào)節(jié)訓(xùn)練文件的對比度來降低噪聲也是一種特征處理的手段。示例代碼如下:1.4.3PIL圖像處理實(shí)踐在日常圖像處理編程中,我們經(jīng)常會遇到需要對訓(xùn)練數(shù)據(jù)進(jìn)行文件格式轉(zhuǎn)換的情況,比如從JPG文件轉(zhuǎn)換為CIFAR-10文件,這樣可以提高對訓(xùn)練數(shù)據(jù)的讀取效率,并且為數(shù)據(jù)操作帶來更大的便捷性。下面是將正常JPG文件轉(zhuǎn)換為CIFAR-10文件的示例代碼:第2章TensorFlow2.0快速入門本章中,我們將會介紹TensorFlow相關(guān)知識并帶領(lǐng)大家完成TensorFlow2.0的快速入門。本章分為TensorFlow2.0簡介、TensorFlow2.0環(huán)境搭建、TensorFlow2.0基礎(chǔ)知識、TensorFlow2.0高階API(tf.keras)共4節(jié)。2.1TensorFlow2.0簡介TensorFlow起源于谷歌內(nèi)部的DisBelief平臺,2015年11月9日谷歌依據(jù)Apache2.0協(xié)議將其開源。TensorFlow是一個非常優(yōu)秀的深度神經(jīng)網(wǎng)絡(luò)機(jī)器開源平臺,自發(fā)布以來受到人工智能研究者和工程師的熱烈追捧,在學(xué)術(shù)界和工業(yè)界迅速得到大量應(yīng)用。TensorFlow1.x經(jīng)過三年多的迭代,在2018年的GoogleCloudNext上TensorFlow團(tuán)隊(duì)宣布開啟TensorFlow2.0的迭代,2019年3月TensorFlow團(tuán)隊(duì)發(fā)布了TensorFlow2.0-Alpha版本,同年6月發(fā)布了TensorFlow2.0-Beta版本。TensorFlow2.0在TensorFlow1.x版本上進(jìn)行了大幅度改進(jìn),主要的變化如下:?將Eager模式作為TensorFlow2.0默認(rèn)的運(yùn)行模式。Eager模式是一種命令行交互式的運(yùn)行環(huán)境,不用構(gòu)建Session就可以完成控制流的計算和輸出。?刪除tf.contrib庫,將tf.contrib庫中的高階API和應(yīng)用整合到tf.keras庫下。?合并精簡API,將TensorFlow1.x中大量重復(fù)、重疊的API進(jìn)行合并精簡。?刪除全局變量,在TensorFlow2.0中不再有變量自動追蹤機(jī)制,需要開發(fā)者自己實(shí)現(xiàn)對變量的追蹤。一旦丟失對變量的追蹤,變量就會被垃圾回收機(jī)制回收,不過開發(fā)者可以使用Keras對象來減輕自己的負(fù)擔(dān)。?確立Keras的高階API的唯一地位,在TensorFlow2.0中所有的高階API全部集中到tf.keras庫下。2.2TensorFlow2.0環(huán)境搭建TensorFlow支持CPU和GPU作為計算資源,而且不管使用Windows系統(tǒng)還是Linux系統(tǒng)都可以安裝TensorFlow。如果使用的是Windows系統(tǒng)環(huán)境,為了安裝方便、快捷,可以使用Anaconda作為安裝工具。Anaconda提供了包括Python在內(nèi)的豐富的工具和計算庫。2.2.1CPU環(huán)境搭建在Linux環(huán)境下建議直接使用python3-pip安裝TensorFlow2.0。以Ubuntu16.04為例,安裝代碼如下:在Windows環(huán)境下建議使用Anaconda安裝TensorFlow2.0,以Windows10為例,安裝過程如下:(1)打開Anaconda官網(wǎng)下載適應(yīng)自己系統(tǒng)的安裝版本,如圖2-1所示。圖2-1選擇安裝版本(2)安裝完成后,打開AnacondaPrompt,就可以直接使用pip命令進(jìn)行安裝了。2.2.2基于Docker的GPU環(huán)境搭建TensorFlow官方提供了基于NVIDIAGPU顯卡的Docker鏡像,只需要在操作系統(tǒng)中安裝GPU的顯卡驅(qū)動即可,不需要安裝cuDNN和CUDA就可以直接構(gòu)建起一個TensorFLow-GPU開發(fā)環(huán)境。我們以Ubuntu16.04和NVIDIATeslaP4為例演示整個安裝過程。(1)在NVIDIA官網(wǎng)查看并下載NVIDIATeslaP4顯卡的驅(qū)動程序,下載地址為/Download/index.aspx?lang=cn,如圖2-2所示。圖2-2下載顯卡的驅(qū)動程序(2)按照以下命令行順序完成相關(guān)操作。2.3TensorFlow2.0基礎(chǔ)知識使用TensorFlow2.0編程需要先掌握其基礎(chǔ)知識,包括運(yùn)行模式和基本的語法操作等。2.3.1TensorFlow2.0Eager模式簡介TensorFlow2.0把Enger模式作為默認(rèn)的模式,以此來提高TensorFlow的易用性和交互的友好性。TensorFlow2.0的Eager模式是一種命令式編程環(huán)境,無須構(gòu)建計算圖,所有的操作會立即返回結(jié)果。Eager模式不但使開發(fā)者可以輕松地使用TensorFlow進(jìn)行編程和調(diào)試模型,而且還使編程代碼變得更加簡潔。在TensorFlow官網(wǎng)總結(jié)的Eager模式的優(yōu)勢如下。?直觀的代碼結(jié)構(gòu):使代碼更加符合Python的代碼結(jié)構(gòu),整個代碼邏輯一目了然。?更輕松的調(diào)試功能:直接調(diào)用操作以檢查正在運(yùn)行的模型并測試更改。?自然控制流程:使用Python控制流程而不是圖控制流程,降低了動態(tài)圖模型的規(guī)模。2.3.2TensorFlow2.0AutoGraph簡介AutoGraph是tf.function裝飾器帶來的一個魔法功能,可以將Python控制流轉(zhuǎn)換為計算圖,換句話說,就是我們可以直接使用Python實(shí)現(xiàn)對計算圖進(jìn)行另一種意義的編輯。AutoGraph將控制流轉(zhuǎn)換為計算圖的方式可以帶來更快的模型運(yùn)行效率,以及模型導(dǎo)出上的便利,使用tf.function裝飾器具有如下優(yōu)勢:?雖然一個函數(shù)被tf.function注釋后會被編譯成圖,但是依然可以按照函數(shù)的方式進(jìn)行調(diào)用。?如果在注釋的函數(shù)中有被調(diào)用的函數(shù),那么被調(diào)用的函數(shù)也將以圖的模式運(yùn)行。?tf.function支持Python所有的控制流語句,比如if、for、while等。2.3.3TensorFlow2.0低階API基礎(chǔ)編程在TensorFlow2.0中定義了很多低階API,在日常編程中除需要用到高階API外,也需要用到一些低階API,下面列舉一些常用的重要的低階API。1.tf.constanttf.constant提供了常量的聲明功能,示例代碼如下:2.tf.Variabletf.Variable提供了變量的聲明功能,示例代碼如下:3.tf.reshapetf.reshape提供了多階Tensor的形狀變換功能,示例代碼如下:4.tf.math.reduce_meantf.math.reduce_mean提供了對Tensor求平均值的功能,輸出數(shù)據(jù)類型會根據(jù)輸入數(shù)據(jù)類型來確定。使用該API時可以配置的參數(shù)如下。?input_tensor:配置輸入的Tensor。?axis:配置按行求平均值或按列求平均值,默認(rèn)是全行全列求平均值。?keepdims:配置輸出結(jié)果是否保持二維矩陣特性。?name:配置操作的名稱。示例代碼如下:5.tf.random.normaltf.random.normal可以隨機(jī)生成一個Tensor,其值符合正態(tài)分布。使用該API時有如下參數(shù)需要配置。?shape:配置生成Tensor的維度。?mean:配置正態(tài)分布的中心值。?stddev:配置正態(tài)分布的標(biāo)準(zhǔn)差。?seed:配置正態(tài)分布的隨機(jī)生成粒子。?dtype:配置生成Tensor的數(shù)據(jù)類型。示例代碼如下:6.tf.random.uniformtf.random.uniform可以隨機(jī)生成一個Tensor,其值符合均勻分布。使用該API時有如下參數(shù)需要配置。?shape:配置生成Tensor的維度。?minval:配置隨機(jī)生成數(shù)值的最小值。?maxval:配置隨機(jī)生成數(shù)值的最大值。?seed:配置正態(tài)分布的隨機(jī)生成粒子。?dtype:配置生成Tensor的數(shù)據(jù)類型。示例代碼如下:7.tf.transposetf.transpose提供了矩陣的轉(zhuǎn)置功能。使用該API時配置的參數(shù)如下。?a:輸入需要轉(zhuǎn)置的矩陣。?perm:配置轉(zhuǎn)置后矩陣的形狀。?conjugate:當(dāng)輸入矩陣是復(fù)數(shù)時,需要配置為True。?name:配置本次操作的名稱。示例代碼如下:8.tf.math.argmaxtf.math.argmax提供了返回一個數(shù)組內(nèi)最大值對應(yīng)索引的功能。使用該API時有如下參數(shù)可以配置。?input:配置輸入的數(shù)組。?axis:配置計算的維度。?output_type:配置輸出的格式。?name:配置操作的名稱。示例代碼如下:9.tf.expand_dimstf.expand_dims的作用是在輸入的Tensor中增加一個維度,比如t是一個維度為[2]的Tensor,那么tf.expand_dims(t,0)的維度就會變成[1,2]。使用這個API時需要配置如下參數(shù)。?input:配置輸入的Tensor。?axis:配置需要添加維度的下標(biāo),比如[2,1]需要在2和1之間添加,則配置值為1。?name:配置輸出Tensor的名稱。示例代碼如下:10.tf.concattf.concat的作用是將多個Tensor在同一個維度上進(jìn)行連接,使用該API時需要進(jìn)行如下參數(shù)配置。?values:配置Tensor的列表或者是一個單獨(dú)的Tensor。?axis:配置按行或按列連接,axis=0表示按行連接,axis=1表示按列連接。?name:配置運(yùn)算操作的名稱。示例代碼如下:11.tf.bitcasttf.bitcast提供了數(shù)據(jù)類型轉(zhuǎn)換功能,使用該API時需要進(jìn)行如下參數(shù)配置。?input:配置需要進(jìn)行類型轉(zhuǎn)換的Tensor,Tensor的類型可以為bfloat16,half,float32,float64,int64,int32,uint8,uint16,uint32,uint64,int8,int16,complex64,complex128,qint8,quint8,qint16,quint16,qint32。?type:配置轉(zhuǎn)換后的數(shù)據(jù)類型,可以選擇的類型包括tf.bfloat16,tf.half,tf.float32,tf.float64,64,32,tf.uint8,tf.uint16,tf.uint32,tf.uint64,8,16,plex64,plex128,tf.qint8,tf.quint8,tf.qint16,tf.quint16,tf.qint32。?name:配置運(yùn)算操作的名稱。示例代碼如下:2.4TensorFlow2.0高階API(tf.keras)在TensorFlow2.0中對大量的高階API庫進(jìn)行了刪減與合并,根據(jù)官方的解釋,這一切的變化都是為了使TensorFlow2.0更加易用和簡潔。本節(jié)我們以官方推薦的唯一高階API庫tf.keras為主,概括地介紹TensorFlow2.0的高階API。2.4.1tf.keras高階API概覽在TensorFlow2.0版本中完全移除了tf.contrib這個高階API庫,官方推薦的高階API只有tf.keras。Keras是一個意在降低機(jī)器學(xué)習(xí)編程入門門檻的項(xiàng)目,其在業(yè)界擁有眾多的擁護(hù)者和使用者。經(jīng)過Keras社區(qū)的多年發(fā)展,Keras集成了很多符合工業(yè)和研究需求的高階API,使用這些API只需要幾行代碼就可以構(gòu)建和運(yùn)行一個非常復(fù)雜的神經(jīng)網(wǎng)絡(luò)。TensorFlow官方社區(qū)首次宣布發(fā)布TensorFlow2.0版本計劃時就明確了Keras會深度融合到TensorFlow中,并且作為官方支持的高階API。下面我們看看官方文檔中提到的tf.keras下的接口模塊。?activations:tf.keras.actibations中包含了當(dāng)前主流的激活函數(shù),可以直接通過該API進(jìn)行激活函數(shù)的調(diào)用。?applications:tf.keras.applications中包含的是已經(jīng)進(jìn)行預(yù)訓(xùn)練的神經(jīng)網(wǎng)絡(luò)模型,可以直接進(jìn)行預(yù)測或者遷移學(xué)習(xí)。目前該模塊中包含了主流的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。?backend:tf.keras.backend中包含了Keras后臺的一些基礎(chǔ)API接口,用于實(shí)現(xiàn)高階API或者自己構(gòu)建神經(jīng)網(wǎng)絡(luò)。?datasets:tf.keras.datasets中包含了常用的公開數(shù)據(jù)訓(xùn)練集,可以直接進(jìn)行使用(需要翻墻),數(shù)據(jù)集有CIFAR-100、BostonHousing等。?layers:tf.keras.layers中包含了已經(jīng)定義好的常用的神經(jīng)網(wǎng)絡(luò)層。?losses:tf.keras.losses中包含了常用的損失函數(shù),可以根據(jù)實(shí)際需求直接進(jìn)行調(diào)用。?optimizers:tf.keras.optimizers中包含了主流的優(yōu)化器,可以直接調(diào)用API使用。比如Adm等優(yōu)化器可以直接調(diào)用,然后配置所需要的參數(shù)即可。?preprocessing:tf.keras.preprocessing中包含了數(shù)據(jù)處理的一些方法,分為圖片數(shù)據(jù)處理、語言序列處理、文本數(shù)據(jù)處理等,比如NLP常用的pad_sequences等,在神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練前的數(shù)據(jù)處理上提供了非常強(qiáng)大的功能。?regularizers:tf.keras.regularizers中提供了常用的正則化方法,包括L1、L2等正則化方法。?wrappers:tf.keras.wrappers是一個Keras模型的包裝器,當(dāng)需要進(jìn)行跨框架遷移時,可以使用該API接口提供與其他框架的兼容性。?Sequential類:tf.keras.Sequential可以讓我們將神經(jīng)網(wǎng)絡(luò)層進(jìn)行線性組合形成神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。2.4.2tf.keras高階API編程在后面的章節(jié)中,我們會結(jié)合實(shí)踐案例詳細(xì)講解主要高階API的使用,而本節(jié)將以構(gòu)建一個線性回歸模型為例介紹TensorFlow2.0高階API的使用。1.使用tf.keras高階API構(gòu)建神經(jīng)網(wǎng)絡(luò)模型在TensorFlow2.0中可以使用高階APItf.keras.Sequential進(jìn)行神經(jīng)網(wǎng)絡(luò)模型的構(gòu)建。示例代碼如下:2.使用tf.keras高階API訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型在完成神經(jīng)網(wǎng)絡(luò)模型的構(gòu)建和編譯之后,需要準(zhǔn)備訓(xùn)練數(shù)據(jù),然后對神經(jīng)網(wǎng)絡(luò)模型進(jìn)行訓(xùn)練??梢允褂胻f.keras.Sequential的fit方法進(jìn)行訓(xùn)練,示例代碼如下:3.使用tf.keras高階API保存神經(jīng)網(wǎng)絡(luò)模型在完成神經(jīng)網(wǎng)絡(luò)模型的訓(xùn)練之后,可以使用Sequential的save方法將訓(xùn)練的神經(jīng)網(wǎng)絡(luò)模型保存為H5格式的模型文件。示例代碼如下:4.使用tf.keras高階API加載模型進(jìn)行預(yù)測加載神經(jīng)網(wǎng)絡(luò)模型需要使用tf.keras.models.load_model這個API,在完成模型的加載后可以使用Sequential的predict方法進(jìn)行預(yù)測。示例代碼如下:第3章基于CNN的圖像識別應(yīng)用編程實(shí)踐在本章中我們以CNN為基礎(chǔ)完成一個CIFAR-10圖像識別應(yīng)用,將分為4個部分來講解,分別為:CNN相關(guān)基礎(chǔ)理論、TensorFlow2.0API、項(xiàng)目工程結(jié)構(gòu)設(shè)計和項(xiàng)目實(shí)現(xiàn)代碼。3.1CNN相關(guān)基礎(chǔ)理論在開始編程前先介紹CNN的相關(guān)基礎(chǔ)理論知識,以便更好地理解編程實(shí)踐中的網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計和數(shù)據(jù)處理。3.1.1卷積神經(jīng)網(wǎng)絡(luò)概述CNN(ConvolutionalNeuralNetwork,卷積神經(jīng)網(wǎng)絡(luò))是DNN(深度神經(jīng)網(wǎng)絡(luò))中一個非常重要的并且應(yīng)用廣泛的分支,CNN自從被提出在圖像處理領(lǐng)域得到了大量應(yīng)用。在工業(yè)實(shí)踐中,CNN出現(xiàn)了各種分支和應(yīng)用,從簡單的圖像識別到圖像分割再到圖像生成,一直是業(yè)界研究的熱點(diǎn)。3.1.2卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)卷積神經(jīng)網(wǎng)絡(luò)按照層級可以分為5層:數(shù)據(jù)輸入層、卷積層、激活層、池化層和全連接層。1.數(shù)據(jù)輸入層數(shù)據(jù)輸入層主要是對原始圖像數(shù)據(jù)進(jìn)行預(yù)處理,預(yù)處理方式如下。?去均值:把輸入數(shù)據(jù)各個維度都中心化為0,其目的是把樣本數(shù)據(jù)的中心拉回到坐標(biāo)系原點(diǎn)上。?歸一化:對數(shù)據(jù)進(jìn)行處理后將其限定在一定的范圍內(nèi),這樣可以減少各維度數(shù)據(jù)因取值范圍差異而帶來的干擾。比如有兩個維度的特征數(shù)據(jù)A和B,A的取值范圍是(0,10),而B的取值范圍是(0,10000),我們會發(fā)現(xiàn)在B的面前A的取值變化是可以忽略的,這樣就造成A的特征被噪聲所淹沒。為了防止出現(xiàn)這種情況,就需要對數(shù)據(jù)進(jìn)行歸一化處理,即將A和B的數(shù)據(jù)都限定在(0,1)范圍內(nèi)。?PCA:通過提取主成分的方式避免數(shù)據(jù)特征稀疏化。2.卷積層卷積層通過卷積計算將樣本數(shù)據(jù)進(jìn)行降維采樣,以獲取具有空間關(guān)系特征的數(shù)據(jù)。3.激活層激活層對數(shù)據(jù)進(jìn)行非線性變換處理,目的是對數(shù)據(jù)維度進(jìn)行扭曲來獲得更多連續(xù)的概率密度空間。在CNN中,激活層一般采用的激活函數(shù)是ReLU,它具有收斂快、求梯度簡單等特點(diǎn)。4.池化層池化層夾在連續(xù)的卷積層中間,用于壓縮數(shù)據(jù)的維度以減少過擬合。池化層使得CNN具有局部平移不變性,當(dāng)需要處理那些只關(guān)注某個特征是否出現(xiàn)而不關(guān)注其出現(xiàn)的具體位置的任務(wù)時,局部平移不變性相當(dāng)于為神經(jīng)網(wǎng)絡(luò)模型增加了一個無限強(qiáng)大的先驗(yàn)輸入,這樣可以極大地提高網(wǎng)絡(luò)統(tǒng)計效率。當(dāng)采用最大池化策略時,可以采用最大值來代替一個區(qū)域的像素特征,這樣就相當(dāng)于忽略了這個區(qū)域的其他像素值,大幅度降低了數(shù)據(jù)采樣維度。5.全連接層和常規(guī)的DNN一樣,全連接層在所有的神經(jīng)網(wǎng)絡(luò)層級之間都有權(quán)重連接,最終連接到輸出層。在進(jìn)行模型訓(xùn)練時,神經(jīng)網(wǎng)絡(luò)會自動調(diào)整層級之間的權(quán)重以達(dá)到擬合數(shù)據(jù)的目的。3.1.3卷積神經(jīng)網(wǎng)絡(luò)三大核心概念1.稀疏交互所謂的稀疏交互是指在深度神經(jīng)網(wǎng)絡(luò)中,處于深層次的單元可能與絕大部分輸入是間接交互的。為了幫助理解,我們可以想象一個金字塔模型,塔頂尖的點(diǎn)與塔底層的點(diǎn)就是一個間接交互的關(guān)系。如果特征信息是按照金字塔模型的走向從底層向上逐步傳播的,那么可以發(fā)現(xiàn),對于處在金字塔頂尖的點(diǎn),它的視野可以包含所有底層輸入的信息。因?yàn)镃NN具有稀疏交互性,我們可以通過非常小的卷積核來提取巨大維度圖像數(shù)據(jù)中有意義的特征信息,因此稀疏交互性使CNN中的輸出神經(jīng)元之間的連接數(shù)呈指數(shù)級下降,這樣神經(jīng)網(wǎng)絡(luò)計算的時間復(fù)雜度也會呈指數(shù)級下降,進(jìn)而可以提高神經(jīng)網(wǎng)絡(luò)模型的訓(xùn)練速度。2.參數(shù)共享所謂的參數(shù)共享是指在一個模型的多個函數(shù)中使用相同的參數(shù),在卷積計算中參數(shù)共享可以使神經(jīng)網(wǎng)絡(luò)模型只需要學(xué)習(xí)一個參數(shù)集合,而不需要針對每一個位置學(xué)習(xí)單獨(dú)的參數(shù)集合。參數(shù)共享可以顯著降低我們需要存儲的參數(shù)數(shù)量,進(jìn)而提高神經(jīng)網(wǎng)絡(luò)的統(tǒng)計效率。3.等變表示所謂的等變表示是指當(dāng)一個函數(shù)輸入改變時,如果其輸出也以同樣的方式改變,那么這個函數(shù)就具備等變表示性。這個特性的存在說明卷積函數(shù)具備等變性,經(jīng)過卷積計算之后我們可以等變地獲取數(shù)據(jù)的特征信息。3.2TensorFlow2.0API詳解在基于TensorFlow2.0的編程實(shí)踐中,我們主要通過調(diào)用其API完成編程,本節(jié)將詳細(xì)講解本案例編程中使用到的API。3.2.1tf.keras.SequentialSequential是一個方法類,可以幫助我們輕而易舉地以堆疊神經(jīng)網(wǎng)絡(luò)層的方式集成構(gòu)建一個復(fù)雜的神經(jīng)網(wǎng)絡(luò)模型。Sequential提供了豐富的方法,利用這些方法可以快速地實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)模型的網(wǎng)絡(luò)層級集成、神經(jīng)網(wǎng)絡(luò)模型編譯、神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練和保存,以及神經(jīng)網(wǎng)絡(luò)模型加載和預(yù)測。1.神經(jīng)網(wǎng)絡(luò)模型的網(wǎng)絡(luò)層級集成我們使用Sequential().add()方法來實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)層級的集成,可以根據(jù)實(shí)際需要將tf.keras.layers中的各類神經(jīng)網(wǎng)絡(luò)層級添加進(jìn)去。示例代碼如下:在上面的示例代碼中完成了三個全連接神經(jīng)網(wǎng)絡(luò)層級的集成,構(gòu)建了一個全連接神經(jīng)網(wǎng)絡(luò)模型。2.神經(jīng)網(wǎng)絡(luò)模型編譯在完成神經(jīng)網(wǎng)絡(luò)層級的集成之后需要對神經(jīng)網(wǎng)絡(luò)模型進(jìn)行編譯,只有編譯后才能對神經(jīng)網(wǎng)絡(luò)模型進(jìn)行訓(xùn)練。對神經(jīng)網(wǎng)絡(luò)模型進(jìn)行編譯是將高階API轉(zhuǎn)換成可以直接運(yùn)行的低階API,理解時可以類比高級開發(fā)語言的編譯。Sequential().compile()提供了神經(jīng)網(wǎng)絡(luò)模型的編譯功能,示例代碼如下:在compile方法中需要定義三個參數(shù),分別是loss、optimizer和metrics。loss參數(shù)用來配置模型的損失函數(shù),可以通過名稱調(diào)用tf.lossesAPI中已經(jīng)定義好的loss函數(shù);optimizer參數(shù)用來配置模型的優(yōu)化器,可以調(diào)用tf.keras.optimizersAPI配置模型所需要的優(yōu)化器;metrics參數(shù)用來配置模型評價的方法,如accuracy、mse等。3.神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練和保存在神經(jīng)網(wǎng)絡(luò)模型編譯后,我們可以使用準(zhǔn)備好的訓(xùn)練數(shù)據(jù)對模型進(jìn)行訓(xùn)練,Sequential().fit()方法提供了神經(jīng)網(wǎng)絡(luò)模型的訓(xùn)練功能。Sequential().fit()有很多集成的參數(shù)需要配置,其中主要的配置參數(shù)如下。?x:配置訓(xùn)練的輸入數(shù)據(jù),可以是array或者tensor類型。?y:配置訓(xùn)練的標(biāo)注數(shù)據(jù),可以是array或者tensor類型。?batch_size:配置批大小,默認(rèn)值是32。?epochs:配置訓(xùn)練的epochs的數(shù)量。?verbose:配置訓(xùn)練過程信息輸出的級別,共有三個級別,分別是0、1、2。0代表不輸出任何訓(xùn)練過程信息;1代表以進(jìn)度條的方式輸出訓(xùn)練過程信息;2代表每個epoch輸出一條訓(xùn)練過程信息。?validation_split:配置驗(yàn)證數(shù)據(jù)集占訓(xùn)練數(shù)據(jù)集的比例,取值范圍為0~1。?validation_data:配置驗(yàn)證數(shù)據(jù)集。如果已經(jīng)配置validation_split參數(shù),則可以不配置該參數(shù)。如果同時配置validation_split和validation_data參數(shù),那么validation_split參數(shù)的配置將會失效。?shuffle:配置是否隨機(jī)打亂訓(xùn)練數(shù)據(jù)。當(dāng)配置steps_per_epoch為None時,本參數(shù)的配置失效。?initial_epoch:配置進(jìn)行fine-tune時,新的訓(xùn)練周期是從指定的epoch開始繼續(xù)訓(xùn)練的。?steps_per_epoch:配置每個epoch訓(xùn)練的步數(shù)。我們可以使用save()或者save_weights()方法保存并導(dǎo)出訓(xùn)練得到的模型,在使用這兩個方法時需要分別配置以下參數(shù)。4.神經(jīng)網(wǎng)絡(luò)模型加載和預(yù)測當(dāng)需要使用模型進(jìn)行預(yù)測時,可以使用tf.keras.models中的load_model()方法重新加載已經(jīng)保存的模型文件。在完成模型文件的重新加載之后,可以使用predict()方法對數(shù)據(jù)進(jìn)行預(yù)存輸出。在使用這兩個方法時需要分別進(jìn)行如下參數(shù)配置。3.2.2tf.keras.layers.Conv2D使用Conv2D可以創(chuàng)建一個卷積核來對輸入數(shù)據(jù)進(jìn)行卷積計算,然后輸出結(jié)果,其創(chuàng)建的卷積核可以處理二維數(shù)據(jù)。依此類推,Conv1D可以用于處理一維數(shù)據(jù),Conv3D可以用于處理三維數(shù)據(jù)。在進(jìn)行神經(jīng)網(wǎng)絡(luò)層級集成時,如果使用該層作為第一層級,則需要配置input_shape參數(shù)。在使用Conv2D時,需要配置的主要參數(shù)如下。?filters:配置輸出數(shù)據(jù)的維度,數(shù)值類型是整型。?kernel_size:配置卷積核的大小。這里使用的是二維卷積核,因此需要配置卷積核的長和寬。數(shù)值是包含兩個整型元素值的列表或者元組。?strides:配置卷積核在做卷積計算時移動步幅的大小,分為X、Y兩個方向的步幅。數(shù)值是包含兩個整型元素值的列表或者元組,當(dāng)X、Y兩個方向的步幅大小一樣時,只需要配置一個步幅即可。?padding:配置圖像邊界數(shù)據(jù)處理策略。SAME表示補(bǔ)零,VALID表示不進(jìn)行補(bǔ)零。在進(jìn)行卷積計算或者池化時都會遇到圖像邊界數(shù)據(jù)處理的問題,當(dāng)邊界像素不能正好被卷積或者池化的步幅整除時,只能在邊界外補(bǔ)零湊成一個步幅長度,或者直接舍棄邊界的像素特征。?data_format:配置輸入圖像數(shù)據(jù)的格式,默認(rèn)格式是channels_last,也可以根據(jù)需要設(shè)置成channels_first。圖像數(shù)據(jù)的格式分為channels_last(batch,height,width,channels)和channels_first(batch,channels,height,width)兩種。?dilation_rate:配置使用擴(kuò)張卷積時每次的擴(kuò)張率。?activation:配置激活函數(shù),如果不配置則不會使用任何激活函數(shù)。?use_bias:配置該層的神經(jīng)網(wǎng)絡(luò)是否使用偏置向量。?kernel_initializer:配置卷積核的初始化。?bias_initializer:配置偏置向量的初始化。3.2.3tf.keras.layers.MaxPool2DMaxPool2D的作用是對卷積層輸出的空間數(shù)據(jù)進(jìn)行池化,采用的池化策略是最大值池化。在使用MaxPool2D時需要配置的參數(shù)如下。?pool_size:配置池化窗口的維度,包括長和寬。數(shù)值是包含兩個整型元素值的列表或者元組。?strides:配置卷積核在做池化時移動步幅的大小,分為X、Y兩個方向的步幅。數(shù)值是包含兩個整型元素值的列表或者元組,默認(rèn)與pool_size相同。?padding:配置處理圖像數(shù)據(jù)進(jìn)行池化時在邊界補(bǔ)零的策略。SAME表示補(bǔ)零,VALID表示不進(jìn)行補(bǔ)零。在進(jìn)行卷積計算或者池化時都會遇到圖像邊界數(shù)據(jù)的問題,當(dāng)邊界像素不能正好被卷積或者池化的步幅整除時,就只能在邊界外補(bǔ)零湊成一個步幅長度,或者直接舍棄邊界的像素特征。?data_format:配置輸入圖像數(shù)據(jù)的格式,默認(rèn)格式是channels_last,也可以根據(jù)需要設(shè)置成channels_first。在進(jìn)行圖像數(shù)據(jù)處理時,圖像數(shù)據(jù)的格式分為channels_last(batch,height,width,channels)和channels_first(batch,channels,height,width)兩種。3.2.4tf.keras.layers.Flatten與tf.keras.layer.Dense?Flatten將輸入該層級的數(shù)據(jù)壓平,不管輸入數(shù)據(jù)的維度數(shù)是多少,都會被壓平成一維。這個層級的參數(shù)配置很簡單,只需要配置data_format即可。data_format可被設(shè)置成channels_last或channels_first,默認(rèn)值是channels_last。?Dense提供了全連接的標(biāo)準(zhǔn)神經(jīng)網(wǎng)絡(luò)。3.2.5tf.keras.layers.Dropout對于Dropout在神經(jīng)網(wǎng)絡(luò)模型中具體作用的認(rèn)識,業(yè)界分為兩派,其中一派認(rèn)為Dropout極大簡化了訓(xùn)練時神經(jīng)網(wǎng)絡(luò)的復(fù)雜度,加快了神經(jīng)網(wǎng)絡(luò)的訓(xùn)練速度;另一派認(rèn)為Dropout的主要作用是防止神經(jīng)網(wǎng)絡(luò)的過擬合,提高了神經(jīng)網(wǎng)絡(luò)的泛化性。簡單來說,Dropout的工作機(jī)制就是每步訓(xùn)練時按照一定的概率隨機(jī)使神經(jīng)網(wǎng)絡(luò)的神經(jīng)元失效,這樣可以極大降低連接的復(fù)雜度。同時由于每次訓(xùn)練都是由不同的神經(jīng)元協(xié)同工作的,這樣的機(jī)制也可以很好地避免數(shù)據(jù)帶來的過擬合,提高了神經(jīng)網(wǎng)絡(luò)的泛化性。在使用Dropout時,需要配置的參數(shù)如下。?rate:配置神經(jīng)元失效的概率。?noise_shape:配置Dropout的神經(jīng)元。?seed:生成隨機(jī)數(shù)。3.2.6tf.keras.optimizers.AdamAdam是一種可以替代傳統(tǒng)隨機(jī)梯度下降算法的梯度優(yōu)化算法,它是由OpenAI的DiederikKingma和多倫多大學(xué)的JimmyBa在2015年發(fā)表的ICLR論文(Adam:AMethodforStochasticOptimization)中提出的。Adam具有計算效率高、內(nèi)存占用少等優(yōu)勢,自提出以來得到了廣泛應(yīng)用。Adam和傳統(tǒng)的梯度下降優(yōu)化算法不同,它可以基于訓(xùn)練數(shù)據(jù)的迭代情況來更新神經(jīng)網(wǎng)絡(luò)的權(quán)重,并通過計算梯度的一階矩陣估計和二階矩陣估計來為不同的參數(shù)設(shè)置獨(dú)立的自適應(yīng)學(xué)習(xí)率。Adam適用于解決神經(jīng)網(wǎng)絡(luò)訓(xùn)練中的高噪聲和稀疏梯度問題,它的超參數(shù)簡單、直觀并且只需要少量的調(diào)參就可以達(dá)到理想的效果。官方推薦的最優(yōu)參數(shù)組合為(alpha=0.001,beta_1=0.9,beta_2=0.999,epsilon=10E-8),在使用時可以配置如下參數(shù)。?learning_rate:配置學(xué)習(xí)率,默認(rèn)值是0.001。?beta_1:配置一階矩估計的指數(shù)衰減率,默認(rèn)值是0.9。?beta_2:配置二階矩估計的指數(shù)衰減率,默認(rèn)值是0.999。?epsilon:該參數(shù)是一個非常小的數(shù)值,防止出現(xiàn)除以零的情況。?amsgrad:配置是否使用AMSGrad。?name:配置優(yōu)化器的名稱。3.3項(xiàng)目工程結(jié)構(gòu)設(shè)計如圖3-1所示,整個項(xiàng)目工程結(jié)構(gòu)分為兩部分:文件夾和代碼文件,在編程實(shí)踐中強(qiáng)烈建議采用文件夾和代碼文件的方式來設(shè)計項(xiàng)目工程結(jié)構(gòu)。所謂的文件夾和代碼文件的方式是指把所有的Python代碼文件放在根目錄下,其他靜態(tài)文件、訓(xùn)練數(shù)據(jù)文件和模型文件等都放在文件夾中。圖3-1項(xiàng)目工程結(jié)構(gòu)從Python代碼文件可以看出,這個項(xiàng)目分為四個部分:配置工具、CNN模型、執(zhí)行器和應(yīng)用程序。配置工具提供了將神經(jīng)網(wǎng)絡(luò)超參數(shù)配置動作通過配置文件進(jìn)行調(diào)整的功能;CNN模型是為了完成本項(xiàng)目的需求而設(shè)計的卷積神經(jīng)網(wǎng)絡(luò);執(zhí)行器中定義了訓(xùn)練數(shù)據(jù)讀取、訓(xùn)練模型保存、模型預(yù)測等一系列方法;應(yīng)用程序是一個基于Flask的簡單Web應(yīng)用程序,用于人機(jī)交互。在文件夾中,model_dir存放的是訓(xùn)練結(jié)果模型文件,也是在預(yù)測時加載模型文件的路徑;predict_img存放的是我們上傳的圖像,通過調(diào)用預(yù)測程序進(jìn)行預(yù)測;train_data存放的是訓(xùn)練數(shù)據(jù),包含測試數(shù)據(jù);web_static和web_templates存放的是Web應(yīng)用程序所需的HTML、JS等靜態(tài)文件。3.4項(xiàng)目實(shí)現(xiàn)代碼詳解本章的項(xiàng)目實(shí)現(xiàn)代碼會在GitHub上開源,本節(jié)主要對源代碼進(jìn)行詳細(xì)注釋和講解相應(yīng)的編程知識點(diǎn)。項(xiàng)目實(shí)現(xiàn)代碼包括工具類實(shí)現(xiàn)、cnnModel實(shí)現(xiàn)、執(zhí)行器實(shí)現(xiàn)、Web應(yīng)用實(shí)現(xiàn)的代碼。3.4.1工具類實(shí)現(xiàn)在實(shí)際的項(xiàng)目實(shí)踐中,我們往往需要對參數(shù)進(jìn)行頻繁的調(diào)整,因此定義一個工具類來讀取配置文件中的配置參數(shù),這樣當(dāng)需要調(diào)參時,只需對配置文件中的參數(shù)進(jìn)行調(diào)整即可。對應(yīng)本章項(xiàng)目中的神經(jīng)網(wǎng)絡(luò)超參數(shù)的配置文件如下:3.4.2cnnModel實(shí)現(xiàn)在cnnModel實(shí)現(xiàn)上我們采用了tf.keras這個高階API類,定義了四層卷積神經(jīng)網(wǎng)絡(luò),輸出維度分別是32、64、128和256,最后在輸出層定義了四層全連接神經(jīng)網(wǎng)絡(luò),輸出維度分別是256、128、64和10。在定義卷積神經(jīng)網(wǎng)絡(luò)過程中,按照一個卷積神經(jīng)網(wǎng)絡(luò)標(biāo)準(zhǔn)的結(jié)構(gòu)進(jìn)行定義,使用最大池化(maxpooling)策略進(jìn)行降維特征提取,使用Dropout防止過擬合。3.4.3執(zhí)行器實(shí)現(xiàn)執(zhí)行器的主要作用是讀取訓(xùn)練數(shù)據(jù)、實(shí)例化神經(jīng)網(wǎng)絡(luò)模型、循環(huán)訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型、保存神經(jīng)網(wǎng)絡(luò)模型和調(diào)用模型完成預(yù)測。在執(zhí)行器的實(shí)現(xiàn)上需要定義以下函數(shù):read_data函數(shù)用于讀取訓(xùn)練集數(shù)據(jù);create_model函數(shù)用于進(jìn)行神經(jīng)網(wǎng)絡(luò)的實(shí)例化;train函數(shù)用于進(jìn)行神經(jīng)網(wǎng)絡(luò)模型的循環(huán)訓(xùn)練和保存;predict函數(shù)用于進(jìn)行模型加載和結(jié)果預(yù)測。3.4.4Web應(yīng)用實(shí)現(xiàn)Web應(yīng)用的主要功能包括完成頁面交互、圖片格式判斷、圖片上傳以及預(yù)測結(jié)果的返回展示。這里我們使用Flask這個輕量級Web應(yīng)用框架來實(shí)現(xiàn)簡單的頁面交互和預(yù)測結(jié)果展示功能。第4章基于Seq2Seq的中文聊天機(jī)器人編程實(shí)踐自然語言處理(NLP)中的語言對話一直是機(jī)器學(xué)習(xí)的“圣杯”,也是機(jī)器學(xué)習(xí)挑戰(zhàn)圖靈測試的主力。從人工智能的概念被提出開始,語言對話任務(wù)一直是業(yè)界研究的熱點(diǎn),本章我們通過NLP基礎(chǔ)理論知識、Seq2Seq模型來介紹中文聊天機(jī)器人的原理,并使用TensorFlow2.0的高階API完成編程。4.1NLP基礎(chǔ)理論知識自然語言處理(NLP)是人工智能應(yīng)用比較成熟的領(lǐng)域,本節(jié)我們將通過語言模型、循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)和Seq2Seq模型來介紹NLP基礎(chǔ)理論知識。4.1.1語言模型語言模型其實(shí)是一個打分模型,通過對一句話進(jìn)行打分來判斷這句話是否符合人類的自然語言習(xí)慣。語言模型的發(fā)展歷史久遠(yuǎn),經(jīng)歷了統(tǒng)計語言模型、n-gram語言模型和神經(jīng)網(wǎng)絡(luò)語言模型三個階段。1.統(tǒng)計語言模型統(tǒng)計語言模型是統(tǒng)計每個詞出現(xiàn)的頻次來形成詞頻字典,然后根據(jù)輸入計算下一個輸出詞的概率,最后形成輸出語句的。統(tǒng)計語言模型輸出語句的概率是依據(jù)貝葉斯公式進(jìn)行鏈?zhǔn)椒纸庥嬎愕玫降模嬎愎饺缦拢簆(w1,w2,w3,?,wn)=p(w1)p(w2|w1)p(w3|w1w2)?p(wn|w1w2w3?wn)這樣的計算求解方法雖然直觀、明了,但存在著致命的缺陷。我們細(xì)想一下就會發(fā)現(xiàn),如果字典中有1000個詞,當(dāng)處理一個句子長度為3的語句時,則需要計算輸出語句概率P的數(shù)量是10003;當(dāng)句子長度為10時,需要計算輸出語句概率P的數(shù)量是100010。在計算完輸出語句的概率之后,需要選擇P值輸出語句作為最終的生成語句。以上計算過程在通用算力下幾乎是不可能完成的。2.n-gram語言模型我們發(fā)現(xiàn),利用統(tǒng)計語言模型計算輸出語句概率的數(shù)量大到無法計算,是由依據(jù)貝葉斯公式通過鏈?zhǔn)椒▌t進(jìn)行展開后全量連乘所引起的,那么解決這個問題的方法只有一個,就是縮短連乘的長度,其理論依據(jù)是馬爾可夫假設(shè)。簡單來說,所謂的馬爾可夫假設(shè)就是指當(dāng)前的狀態(tài)只與過去有限時間內(nèi)的狀態(tài)有關(guān)。比如你在路上看到紅燈會停下來,你停下來的狀態(tài)只與過去有限時間內(nèi)紅綠燈是否顯示為紅燈有關(guān),而與上一個顯示燈次甚至更遠(yuǎn)時間內(nèi)的紅綠燈是否顯示為紅燈無關(guān)。基于馬爾可夫假設(shè)的語言模型稱為n-gram,這里的n表示馬爾可夫鏈的長度,表示當(dāng)前狀態(tài)與前n-1個時間點(diǎn)事件有關(guān)。當(dāng)n=1時,表示一個詞出現(xiàn)的概率與其周圍的詞出現(xiàn)的概率是相互獨(dú)立的,稱為unigram。在unigram中,假設(shè)字典大小為1000,我們所需計算的輸出語句概率P的數(shù)量為1000。依此類推,當(dāng)n=2時,表示一個詞出現(xiàn)的概率只與其前一個詞出現(xiàn)的概率有關(guān),稱為bigram。在bigram中,假設(shè)字典大小為1000,我們所需計算的輸出語句概率P的數(shù)量為1000×1000。當(dāng)n=3時,表示一個詞出現(xiàn)的概率只與其前兩個詞出現(xiàn)的概率有關(guān),稱為trigram。在trigram中,假設(shè)字典大小為1000,我們所需計算的輸出語句概率P的數(shù)量為1000×1000×1000。一般我們選擇trigram,因?yàn)槿绻鹡過大的話,則同樣會出現(xiàn)統(tǒng)計語言模型遇到的問題。3.神經(jīng)網(wǎng)絡(luò)語言模型神經(jīng)網(wǎng)絡(luò)語言模型是Begio等人在2003年發(fā)表的ANeuralProbabilisticLanguageModel論文中提出的方法,其在n-gram語言模型的基礎(chǔ)上進(jìn)行了改進(jìn)。神經(jīng)網(wǎng)絡(luò)語言模型采用one-hot(獨(dú)熱編碼)表示每個詞的分布情況,將輸入語句進(jìn)行編碼轉(zhuǎn)換后輸入神經(jīng)網(wǎng)絡(luò),經(jīng)過tanh非線性變換和softmax歸一化后得到一個總和為1的向量,在向量中最大元素的下標(biāo)作為輸出詞的字典編碼,通過字典編碼查詢字典得到最終的輸出詞。以上過程一次可以得到一個輸出詞,如果要輸出一句話就需要循環(huán)以上的過程,這就是我們接下來要講的循環(huán)神經(jīng)網(wǎng)絡(luò)。4.1.2循環(huán)神經(jīng)網(wǎng)絡(luò)循環(huán)神經(jīng)網(wǎng)絡(luò)(RecurrentNeuralNetwork,RNN)是神經(jīng)網(wǎng)絡(luò)專家Jordan、Pineda.Williams、Elman等人于20世紀(jì)80年代末提出的一種神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)模型,這種網(wǎng)絡(luò)的特征是在神經(jīng)元之間既有內(nèi)部的反饋連接又有前饋連接。當(dāng)前主流的NLP應(yīng)用都集中在RNN領(lǐng)域,因此出現(xiàn)了很多RNN的變種。1.RNN存在的缺陷RNN的提出是神經(jīng)網(wǎng)絡(luò)語言模型領(lǐng)域一次非常大的突破,但人們在應(yīng)用的過程中發(fā)現(xiàn)RNN存在兩個致命的缺陷:梯度消失和梯度爆炸。我們可以通過下面的公式推導(dǎo)來說明這兩個缺陷產(chǎn)生的原因?,F(xiàn)代的神經(jīng)網(wǎng)絡(luò)訓(xùn)練全部采用梯度下降法來驅(qū)動神經(jīng)網(wǎng)絡(luò)參數(shù)的更新,而梯度求解是進(jìn)行神經(jīng)網(wǎng)絡(luò)參數(shù)更新的前提。在RNN訓(xùn)練中,梯度是目標(biāo)函數(shù)(ObjectFunction)對神經(jīng)網(wǎng)絡(luò)參數(shù)矩陣求導(dǎo)得到的,公式如下:J是RNN的目標(biāo)函數(shù),訓(xùn)練的目的是將目標(biāo)函數(shù)的值最小化;Wt是RNN的參數(shù)矩陣,其代表當(dāng)前時刻的神經(jīng)網(wǎng)絡(luò)參數(shù)狀態(tài)。在求導(dǎo)的過程中需要用到鏈?zhǔn)椒▌t對求導(dǎo)公式進(jìn)行展開,上面的公式就是通過梯度求解公式的鏈?zhǔn)椒▌t進(jìn)行展開的。在RNN中?t+1=f(?t),f(?t)是神經(jīng)元的激活函數(shù),假設(shè)使用tanh雙曲線激活函數(shù),通過觀察展開后的公式可以發(fā)現(xiàn)規(guī)律:那么最后的梯度求解公式就變成如下:根據(jù)連乘特性,上面的公式可以進(jìn)一步變形,變成如下公式:我們可以發(fā)現(xiàn),最后梯度的大小趨勢與W的值是正相關(guān)的,W是參數(shù)矩陣,那么:?當(dāng)|W|<1時,W趨向于0,導(dǎo)致梯度也趨向于0,由此會產(chǎn)生梯度消失的問題。?當(dāng)|W|>1時,W趨向于∞,導(dǎo)致梯度也趨向于∞,由此會產(chǎn)生梯度爆炸的問題。這兩個缺陷在神經(jīng)網(wǎng)絡(luò)訓(xùn)練過程中到底會帶來哪些問題呢?我們看一下在反向傳播中參數(shù)更新的公式,就會發(fā)現(xiàn)這兩個缺陷帶來的問題。參數(shù)更新的公式如下:θt+1=θt-η?θt在上面的公式中,θt+1是下一個訓(xùn)練循環(huán)時的參數(shù)集,θt是當(dāng)前訓(xùn)練循環(huán)時的參數(shù)集,η是學(xué)習(xí)率,?θt是當(dāng)前循環(huán)訓(xùn)練的梯度。不難發(fā)現(xiàn),當(dāng)梯度?θt趨向于0時,θt+1≈θt,即參數(shù)不會更新,導(dǎo)致模型也無法得到進(jìn)一步優(yōu)化;當(dāng)梯度?θt趨向于∞時,θt+1≈-∞,即一旦出現(xiàn)梯度爆炸,之前訓(xùn)練得到的參數(shù)就消失了。相比于梯度消失,梯度爆炸帶來的后果更嚴(yán)重,但是梯度爆炸的問題卻比較容易處理,可以采用限制梯度最大值或者梯度分割的方式來解決。而梯度消失的問題是非常難以解決的,目前只能從網(wǎng)絡(luò)結(jié)構(gòu)上進(jìn)行優(yōu)化,但也不能完全避免。RNN的變種LSTM就是為了解決梯度消失的問題而進(jìn)行的網(wǎng)絡(luò)結(jié)構(gòu)優(yōu)化。2.RNN的變種為了提高RNN的訓(xùn)練效果以及解決梯度消失的問題,業(yè)界提出了RNN的變種LSTM(長短期記憶神經(jīng)網(wǎng)絡(luò)),LSTM區(qū)別于RNN的地方在于它在算法中加入了一個判斷信息有用與否的“處理器”,這個處理器被稱為cell。在一個cell中被放置了三個門,分別叫作輸入門、遺忘門和輸出門。從圖4-1中我們可以發(fā)現(xiàn),LSTM的表達(dá)式可以寫成如下公式:?t,ct=f(?t-1,ct-1,xt)圖4-1LSTM的內(nèi)部網(wǎng)絡(luò)連接圖LSTM的梯度由兩部分組成:RNN結(jié)構(gòu)的梯度和線性變換函數(shù)的梯度。線性變換函數(shù)的梯度就是函數(shù)的斜率,是一個常數(shù)。由于線性變換函數(shù)梯度的存在,當(dāng)RNN的梯度過小趨近于0時,LSTM的梯度趨向于一個常數(shù)。因此,LSTM通過引入一個梯度常數(shù)的方式避免了梯度消失的問題。在LSTM的演進(jìn)過程中,為了解決LSTM多門結(jié)構(gòu)帶來的訓(xùn)練速度慢的問題,人們提出了精簡結(jié)構(gòu)的LSTM的變種GRU,GRU是當(dāng)前應(yīng)用比較廣泛的一種RNN結(jié)構(gòu)。相比于LSTM的三個門結(jié)構(gòu),只有兩個門(分別是更新門和重置門)的GRU在網(wǎng)絡(luò)結(jié)構(gòu)上更加簡單,因此GRU在訓(xùn)練速度上比LSTM更快。通過實(shí)驗(yàn)發(fā)現(xiàn),LSTM和GRU在訓(xùn)練效果上各有所長,有些任務(wù)使用LSTM的效果更好,有些任務(wù)選擇GRU更好。在實(shí)際使用的過程中,建議對這兩種網(wǎng)絡(luò)結(jié)構(gòu)都進(jìn)行嘗試,最終根據(jù)其實(shí)際效果進(jìn)行選擇。4.1.3Seq2Seq模型Seq2Seq的全稱是SequencetoSequence,它是基于Encoder-Decoder框架的RNN的變種。Seq2Seq引入了Encoder-Decoder框架,提高了神經(jīng)網(wǎng)絡(luò)對長文本信息的提取能力,取得了比單純使用LSTM更好的效果。目前Seq2Seq在各種自然語言處理的任務(wù)中得到大量的應(yīng)用,最常用的是語言翻譯和語言生成。Seq2Seq中有兩個非常重要的概念需要我們掌握,其中一個是Encoder-Decoder框架;另一個是Attention機(jī)制。1.Encoder-Decoder框架Encoder-Decoder是處理輸入、輸出長短不一的多對多文本預(yù)測問題的框架,其提供了有效的文本特征提取、輸出預(yù)測的機(jī)制。Encoder-Decoder框架包含兩部分內(nèi)容,分別是Encoder(編碼器)和Decoder(解碼器)。(1)編碼器編碼器的作用是對輸入的文本信息進(jìn)行有效的編碼后將其作為解碼器的輸入數(shù)據(jù)。編碼器的目標(biāo)是對輸入的文本信息進(jìn)行特征提取,盡量準(zhǔn)確高效地表征該文本的特征信息。(2)解碼器解碼器的作用是從上下文的文本信息中獲取盡可能多的特征,然后輸出預(yù)測文本。根據(jù)對文本信息的獲取方式不同,解碼器一般分為4種結(jié)構(gòu),分別是直譯式解碼、循環(huán)式解碼、增強(qiáng)循環(huán)式解碼和注意力機(jī)制解碼。?直譯式解碼:按照編碼器的方式進(jìn)行逆操作得到預(yù)測文本。?循環(huán)式解碼:將編碼器輸出的編碼向量作為第一時刻的輸入,然后將得到的輸出作為下一個時刻的輸入,以此進(jìn)行循環(huán)解碼。?增強(qiáng)循環(huán)式解碼:在循環(huán)式解碼的基礎(chǔ)上,每一個時刻增加一個編碼器輸出的編碼向量作為輸入。?注意力機(jī)制解碼:在增強(qiáng)循環(huán)式解碼的基礎(chǔ)上增加注意力機(jī)制,這樣可以有效地訓(xùn)練解碼器在繁多的輸入中重點(diǎn)關(guān)注某些有效特征信息,以增加解碼器的特征獲取能力,進(jìn)而得到更好的解碼效果。2.Attention機(jī)制Attention機(jī)制有效地解決了輸入長序列信息時真實(shí)含義獲取難的問題,在進(jìn)行長序列處理的任務(wù)中,影響當(dāng)前時刻狀態(tài)的信息可能隱藏在前面的時刻里,根據(jù)馬爾可夫假設(shè)這些信息有可能就會被忽略掉。舉例說明,在“我快餓死了,我今天做了一天的苦力,我要大吃一頓”這句話中,我們明白“我要大吃一頓”是因?yàn)椤拔铱祓I死了”,但是基于馬爾可夫假設(shè),“我今天做了一天的苦力”和“我要大吃一頓”在時序上離得更近,相比于“我快餓死了”,“我今天做了一天的苦力”對“我要大吃一頓”的影響力更強(qiáng),但是在真實(shí)的自然語言中不是這樣的。從這個例子我們可以看出,神經(jīng)網(wǎng)絡(luò)模型沒有辦法很好地準(zhǔn)確獲取倒裝時序的語言信息,要解決這個問題就需要經(jīng)過訓(xùn)練自動建立起“我要大吃一頓”和“我快餓死了”的關(guān)聯(lián)關(guān)系,這就是Attention機(jī)制。如圖4-2所示是取自AttentionIsAllYouNeed的Attention結(jié)構(gòu)圖。從該圖中我們可以看到,ct是跨過時序序列對輸入的自然語言序列進(jìn)行特征提取得到的信息,放到上面例子的語境中來描述,在ct中就會包含“我快餓死了”這一信息。Attention機(jī)制是一個非常重要的和復(fù)雜的機(jī)制,BERT的大熱也讓Attention機(jī)制受到了空前的熱捧。這里不詳細(xì)討論Attention機(jī)制的原理細(xì)節(jié),只是希望通過上面的例子能夠讓大家在概念上明白Attention機(jī)制的作用。圖4-2Attention結(jié)構(gòu)圖4.2TensorFlow2.0API詳解在基于TensorFlow2.0的編程實(shí)踐中,我們通過調(diào)用其API來完成編程,本節(jié)將詳細(xì)講解在編程實(shí)踐中使用到的API。4.2.1tf.keras.preprocessing.text.Tokenizer在開始介紹Tokenizer之前,我們先看一下tf.keras.preprocessing.text這個API庫下的方法類,在以后的編程中有可能會用到這些方法類。我們從官方文檔中可以看到,在tf.keras.preprocessing.text這個API庫下包含的API有hashing_trick、one_hot、text_to_word_sequence以及本節(jié)要講的Tokenizer。(1)hashing_trick,對文本或者字符串進(jìn)行哈希計算,將計算所得的哈希值作為存儲該文本或者字符串的索引。(2)one_hot,對字符串序列進(jìn)行獨(dú)熱編碼。所謂的獨(dú)熱編碼就是在整個文本中,根據(jù)字符出現(xiàn)的次數(shù)進(jìn)行排序,以序號作為字符的索引構(gòu)成詞頻字典,在一個字典長度的全零序列中將序號對應(yīng)的元素置1來表示序號的編碼。比如“我”的序號是5,全字典長度為10,那么“我”的獨(dú)熱編碼為[0,0,0,0,1,0,0,0,0,0]。(3)text_to_word_sequence,將文本轉(zhuǎn)換為一個字符序列。(4)Tokenizer,一個將文本進(jìn)行數(shù)字符號化的方法類,在進(jìn)行神經(jīng)網(wǎng)絡(luò)訓(xùn)練時需要輸入的數(shù)據(jù)是數(shù)值,因此需要將文本字符轉(zhuǎn)換為可進(jìn)行數(shù)學(xué)計算的數(shù)值。在這個方法類中提供了fit_on_sequences、fit_on_texts、get_config、sequences_to_matrix、sequences_to_texts和sequences_to_texts_generator等方法。在使用Tokenizer時,可以配置如下參數(shù)。?num_words:配置符號化的最大數(shù)量。?filters:配置需要過濾的文本符號,比如逗號、中括號等。?lower:配置是否需要將大寫全部轉(zhuǎn)換為小寫。這個配置是相對于英文來說的,中文不存在大小寫的問題。?split:配置進(jìn)行分割的分隔符。?char_level:配置字符串的級別。如果配置為True,那么每個字符都會作為一個token。?oov_token:配置不在字典中的字符的替換數(shù)字,一般使用“3”這個數(shù)字來代替在字典中找不到的字符。4.2.2tf.keras.preprocessing.sequence.pad_sequences在進(jìn)行自然語言處理的任務(wù)中,輸入的自然語言語句是長短不一的,為了能夠處理長短不一的數(shù)據(jù)就需要構(gòu)建輸入維度不同的計算子圖,繁多的計算子圖會導(dǎo)致訓(xùn)練速度和效果大大下降。因此,在進(jìn)行訓(xùn)練前可以將訓(xùn)練數(shù)據(jù)填充成有限數(shù)量的維度類別,這樣就可以大幅度降低整個網(wǎng)絡(luò)規(guī)模以提高訓(xùn)練速度和效果,這一數(shù)據(jù)處理的過程稱為Padding。p

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論