1. 程式人生 > >聽它爹說他孩兒:Keras 學習筆記 4.3

聽它爹說他孩兒:Keras 學習筆記 4.3

對電影評論進行分類:二分法的範例

把一批資料分成兩類,可能是機器學習應用最為廣泛的分類方法。

因特網電影資料庫( IMDB )的資料集
該資料集有 50,000 條影評,訓練與測試各用 25,000 條,而正面與負面評價各佔 50 %。

與資料集 MNIST 相伴,IMDB 資料集也被打包進 Keras。影評已經預處理,文字序列轉換成為數字序列,每個數字表示字典中的一個單詞。下面的程式碼首次執行,會把約 80 MB 的資料下載到你的計算機。

 載入資料集 IMDB 

from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

變數 train_data 和 test_data 是影評列表。影評是單詞索引的列表,單詞索引是單詞序列的編碼。train_labels 和 test_labels 是由數字 0 和 1 組成的列表,0 代表負面評論,1 代表正面評論:

>>> train_data[0]
[1, 14, 22, 16, ... 178, 32]
>>> train_labels[0]
1

影評的詞彙量為 10,000 個常用詞,其索引最大值不超過 10,000:

>>> max([max(sequence) for sequence in train_data])
9999

把影評解碼成英文單詞,這樣做:

word_index = imdb.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])
準備資料

神經網路不能食用數字列表,必須把它們轉成張量。有 2 個辦法:

  •  把列表變成形狀為(樣例,單詞索引)的張量,作為網路的第一層。
  •  二值編碼(One-hot encode 直譯“獨熱編碼”不知所云),把列表變成值為 0 或 1 的向量。例如,把序列 [3, 5] 放入維度為 10,000 的向量,索引 3 和 5 對應值是 1,其他都是 0 。將其作為全連線網路的第一層,處理浮點型資料。

 把整數序列編成二值矩陣 

import numpy as np

def vectorize_sequences(sequences, dimension=10000):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1.
    return results

x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

# 樣本現在的樣子:
>>> x_train[0]
array([ 0., 1., 1., ..., 0., 0., 0.])

# 向量化你的標籤:
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

# 現在資料準備進入神經網路。

輸入資料是向量,標籤是標量(1 和 0):這是最容易的一步。這種網路是簡單的多層疊加的全連線網路,用函式 relu 啟用: 

Dense(16,activation='relu')。

傳遞給 Dense 層的引數 16 是隱藏單元的數目。隱藏單元是本層表達空間的維度。Dense 層的啟用函式 relu 實現以下張量運算:

output = relu(dot(W, input) + b)

16 個隱藏單元意味著權重矩陣 W 的形狀是(輸入維度,16):W 的點積運算在 16 維度的表達空間內產生資料(然後,加上偏置向量 b,進行 relu 運算)。更多的表達空間可使網路學習更復雜的表示式,但也要付出更多的計算代價,甚至導致不需要的學習模式(模式可以提高訓練成績,但不能提高測試成績)。

決定 Dense 層架構的有兩個要素:

  • 要用多少層
  • 每個層有多少隱藏單元

在第 4 章,你將學習確定 Dense 層架構的指導原則。目前的選擇是:

  • 2 箇中間層,每層 16 個隱藏單元
  • 第 3 層產生標量資料,對當前影評的預測

中間層用 relu 作為啟用函式,最後一層用 S 型函式啟用輸出一概率值(0 至 1),表示樣本屬於正面影評的似然度。

 定義模型 

from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
為什麼啟用函式必不可少?

如果沒有啟用函式,比如 relu,Dense 層成了兩個線性運算 — 點積和加法:

output = dot(W, input) + b

於是,Danse 層只會學習對輸入資料進行線性轉換。多層網路因此失去意義。

最後,你需要選擇一個損失函式。因為正在處理的二值分類問題,最好使用損失函式  binary_crossentropy。

 編譯模型 

model.compile(optimizer='rmsprop',        # 優化器
              loss='binary_crossentropy', # 損失函式
              metrics=['accuracy'])       # 測控指標

優化器、損失函式、測控指標均可自行設定。例如:

 設定優化器 

from keras import optimizers
model.compile(optimizer=optimizers.RMSprop(lr=0.001),
              loss='binary_crossentropy',
              metrics=['accuracy'])

 使用者定義損失函式和測控指標 

from keras import losses
from keras import metrics
model.compile(optimizer=optimizers.RMSprop(lr=0.001),
              loss=losses.binary_crossentropy,
              metrics=[metrics.binary_accuracy])
驗證你的方法

為了測控模型處理資料的精度,從初始的訓練資料中分割出 10,000 條樣本,作為驗證用資料集:

x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]

你將訓練模型 20 輪次。也就是說,你要對張量 x_train 和 y_train 中的全部樣本,迭代訓練 20 次。同時,你將對分割的 10,000 個樣本產生的損失和精度進行測控。為此,你要使用變參  validation_data 輸入驗證用樣本。

 訓練你的模型 

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['acc'])

history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=20,
                    batch_size=512,
                    validation_data=(x_val, y_val))

注意, model.fit() 返回的物件 history 是個字典,儲存著訓練過程中的各種資料:

>>> history_dict = history.history
>>> history_dict.keys()
[u'acc', u'loss', u'val_acc', u'val_loss']

字典包括監測到的 4 個指標:前 2 個是訓練的精度和損失;後 2 個是驗證的精度和損失。可用 Matplotlib 畫出這些指標。

 畫出訓練和驗證的損失 

import matplotlib.pyplot as plt
history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, loss_values, 'bo', label='Training loss')
plt.plot(epochs, val_loss_values, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

 畫出訓練和驗證的精度 

plt.clf()
acc_values = history_dict['acc']
val_acc_values = history_dict['val_acc']
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

你會看到,隨著每次迭代訓練的損失下降,訓練的精度上升。這正是你所期待的梯度下降優化。不過,損失和精度的驗證是另外一回事:它們似乎在第 4 次迭代時達到峰值。這個例子正是我們曾經警告過的:訓練成績好的模型,使用未曾見過的資料時,表現未必好。確切地說,這種現象是過度擬合。

在此,為了阻止過度擬合,第 3 次迭代後你應該停止訓練。可以用些技術減緩過度擬合,具體見第 4 章。

讓我們只迭代 4 次,接著用測試資料進行評估:

model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=4, batch_size=512)

results = model.evaluate(x_test, y_test)

# 最終結果如下:
>>> results
[0.2929924130630493, 0.88327999999999995]

用稚樸的辦法可達到 88% 的精度。 用最先進的技術可接近 95% 的精度。

用訓練過的網路對新資料進行預測

你可以用 predict 方法預測影評屬於正面的可能性:

>>> model.predict(x_test)
array([[ 0.98006207]
       [ 0.99758697]
       [ 0.99975556]
       ...,
       [ 0.82167041]
       [ 0.02885115]
       [ 0.65371346]], dtype=float32)

如你所見,網路對一些樣本的確信度高,如 0.99 或 0.01 等;也有的確信度低,如 0.6, 0.4 等。

進一步的實驗

以下的實驗會幫你確信,以上網路架構雖有改進空間但已相當合理:

  • 使用 2 個隱藏層。試著用 1 或 3 個隱藏層,觀察對驗證精度和測試精度的影響。
  • 試著用更多或更少的隱藏單元,32 個、64 個等。
  • 試著用損失函式 mse 代替 binary_crossentropy。
  • 試著用啟用函式 tanh 代替 relu。(在神經網路早期流行使用 tanh)
小結

以下是你應該從本範例學到的:

  • 通常需要對初始資料做大量預處理,以形成張量供給神經網路。文字序列可以編成二值向量或其他編碼形式。
  • 疊加的 Dense 層和啟用函式 relu 可解決大量問題(包括情緒分類),你會經常用到它們。
  • 二值分類問題(有兩類輸出),你的網路末端應該是具有一個單元的 Dense 層,和一個 S 型啟用函式;網路輸出應該是概率編碼後的標量,值從 0 至 1。
  • 用 S 型函式標量輸出的二值分類問題,網路的損失函式應該用 binary_crossentropy。
  • 無論你處理何種問題,用優化器 rmsprop 通常是很好的選擇,它讓你沒有後顧之憂。
  • 神經網路訓練時會取得好成績,但最終會出現過度擬合,處理未見過的新資料時效果越來越差。要切實監測網路處理訓練集以外的資料時的表現。

相關推薦

孩兒Keras 學習筆記 4.3

對電影評論進行分類:二分法的範例把一批資料分成兩類,可能是機器學習應用最為廣泛的分類方法。因特網電影資料庫( IMDB )的資料集該資料集有 50,000 條影評,訓練與測試各用 25,000 條,而正面與負面評價各佔 50 %。與資料集 MNIST 相伴,IMDB 資料集也

孩兒Keras 學習筆記 2

本書有30多個範例,幫你學會解決具體問題。這些範例開發工具,用的是 Keras 及其底層 TensorFlow。你將學會使用 Keras 處理實際問題,如機器視覺、自然語言、影象分類、時間序列預測、情緒分析、影象和文字生成等。Keras 的老家在 https://keras.

TCP-IP詳解卷1協議 學習筆記(4) ARP

參考:TCP-IP詳解卷1:協議 ARP(地址解析協議)和RARP(逆地址解析協議) ARP為IP地址到對應的硬體地址之間提供動態對映,這個過程是自動完成的,一般應用程式使用者或者系統管理員不必關心。 RARP是被那些沒有磁碟驅動器的系統使用(一般是無盤工作站或X終端),需

Deep learning基於theano的keras學習筆記3)-網路層

1. 常用層 1.1 Dense層 keras.layers.core.Dense(output_dim, init='glorot_uniform', activation='linear', w

深度學習keras學習

Keras TensorFlow教程 :如何從零開發一個複雜深度學習模型:https://segmentfault.com/a/1190000012645225 keras概念解釋:http://www.zhiding.cn/techwalker/documents/J9UpWRDfV

keras 學習筆記從頭開始構建網路處理 mnist

全文參考 《 基於 python 的深度學習實戰》   import numpy as np from keras.datasets import mnist from keras.models import Sequential from keras.layers import Den

Keras學習筆記Chapter1-Keras入門

Keras Keras是一個高層神經網路庫。Keras是由Python編寫而成的,後端實現是基於Tensorflow,CNTK或Theano(Keras是一個庫,可以理解為一個基於多種不同機器學習庫提供相同api的庫)。 Keras發展的要義是:將想

ESP8266學習筆記4ESP8266的SmartConfig

rtc 訂閱號 new 例程 detail smart ted tracking 不能 今天花了將近一天的時間來研究ESP8266的SmartConfig功能,這個應該算是wifi雲產品的標配。這篇文章先把SmartConfig操作一遍,我還寫了還有一篇文章梳理了物理層

深度學習 Deep Learning UFLDL 最新Tutorial 學習筆記 4Debugging: Gradient Checking

style inline add tom radi posit math size tutorial 1 Gradient Checking 說明前面我們已經實現了Linear Regression和Logistic Regression。關鍵在於代價函數Cost Fun

Spark學習筆記4數據讀取與保存

讀取數據 chapter byte hadoop tar .lib 文件中 api sequence Spark對很多種文件格式的讀取和保存方式都很簡單。Spark會根據文件擴展名選擇對應的處理方式。 Spark支持的一些常見文件格式如下:  1、文本文件    使用文件

將js進行到底node學習筆記2

客戶端 系統 用戶 是個 down 語言 計算 rmi 地址 node重要API之FS——CLI編程初體驗 所謂的“fs”就是file system! 當下幾乎任何一門編程語言都會提供對文件系統讀寫的API,比如c語言的open()函數。 而文件系統讀寫API最廣泛的用處就

將js進行到底node學習筆記5

引用 form all com 錯誤頁面 cnblogs 框架 isp 註意 HTTP開發之Connect工具集——中間件 繼學習node.js的TCP API和HTTP API之後,node.js web開發進入了正軌,但這就好像Java的servlet一樣,我們不可能使

hibernate框架學習筆記4主鍵生成策略、對象狀態

alt rri gen 線程安全 理論 微軟 unit conf lose 創建一個實體類: package domain; public class Customer { private Long cust_id; private Stri

struts2框架學習筆記4獲取參數

map pre spa xtend 新的 get cti port row 第一種參數獲取方式: 編寫一個前端頁面,提交表單,做示例: <form action="${pageContext.request.contextPath}/Demo1Actio

spring框架學習筆記4SpringAOP實現原理

odin 就是 sets 使用 point 攔截 ceo oca ssl AOP AOP(Aspect Oriented Programming),即面向切面編程,可以說是OOP(Object Oriented Programming,面向對象編程)的補充和完善。OOP引入

設計模式學習筆記(4)——建造者模式

receiver temp pla his AI 技術 bubuko 電子 中一 設計模式:學習筆記(4)——建造者模式 概述 建造者模式   建造者模式是較為復雜的創建型模式,它將客戶端與包含多個組成部分(或部件)的復雜對象的創建過程分離,客戶端無須知道復雜對象的內部組成

Scratchcoding4fun學習筆記1

所有 style 基礎上 基礎 通過 共享 作業 下載 歡迎來到 大家好,歡迎來到xxx的Scratch初級入門課程系列 首先感謝來自臺灣的coding4fun提供開源和共享的課程教案,我們在這基礎上開始我們的版本。 課程簡介 課程文檔下載 第一課 課程說明 開始之前,

JqueryUI學習筆記-自動完成autocomplete

find 不知道 quest term prevent 修改 combobox itl new <html><head><meta charset="UTF-8"><title>Insert title here</ti

Git入門學習筆記

1.安裝完成後需要設定一下 git config –global user.name “Your Name” git config –global user.email “[email protected]” 2. 初始化版本庫 git init 加到暫存區與

分散式版本控制系統Git學習筆記

文章目錄 概述 Git是什麼 Git的安裝 建立版本庫 編寫檔案上傳 使用GitHub 概述 身為DBA的我前夕確實對於程式碼比較陌生啊,Git也是很少聽過。