實戰篇:如何用Keras建立神經網路(附全部程式碼)

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

摘要: 機器學習實戰篇:用簡單的程式碼打造屬於自己的神經網路模型~

Keras是目前最受歡迎的深度學習庫之一,對人工智慧的商業化做出了巨大貢獻。它使用起來非常簡單,它使你能夠通過幾行程式碼就可以構建強大的神經網路。在這篇文章中,你將瞭解如何通過Keras構建神經網路,並且將使用者評論分為兩類:積極或消極來預測使用者評論的情感。這就是社交媒體所謂的情感分析,我們會用著名的imdb評論資料集來做。我們構建的模型只需進行一些更改,就可以應用於其他機器學習問題。

請注意,我們不會深入Keras或深度學習的細節,這對於想要進入人工智慧領域卻沒有深厚的數學功底的程式設計師來說是件好事。

目錄:

1.Keras是什麼?

2.什麼是情緒分析?

3.imdb資料集。

4.匯入依賴關係並獲取資料。

5.探索資料。

6.資料準備。

7.建立和訓練模型。

Keras是什麼?

Keras是一個開源的python庫,可以讓你輕鬆構建神經網路。該庫能夠在TensorFlow、Microsoft Cognitive Toolkit、Theano和MXNet上執行。Tensorflow和Theano是Python中用來構建深度學習演算法的最常用的平臺,但它們可能相當複雜且難以使用。相比之下,Keras提供了一種簡單方便的方法來構建深度學習模型。它的創造者FrançoisChollet開發了它,使人們能夠儘可能快速和簡單地構建神經網路。他專注於可擴充套件性、模組化、極簡主義和python的支援。Keras可以與GPU和CPU一起使用,並支援Python 2和Python 3。Google Keras為深度學習和人工智慧的商業化做出了巨大貢獻,越來越多的人正在使用它們。

什麼是情緒分析?

藉助情感分析,我們想要確定例如演講者或作家對於文件或事件的態度(例如情感)。因此,這是一個自然語言處理問題,需要理解文字,以預測潛在的意圖。情緒主要分為積極的,消極的和中立的類別。通過使用情緒分析,我們希望根據他撰寫的評論,預測客戶對產品的意見和態度。因此,情緒分析廣泛應用於諸如評論,調查,文件等等。

imdb資料集

imdb情緒分類資料集由來自imdb使用者的50,000個電影評論組成,標記為positive(1)或negative(0)。評論是預處理的,每一個都被編碼為一個整數形式的單詞索引序列。評論中的單詞按照它們在資料集中的總體頻率進行索引。例如,整數“2”編碼資料中第二個最頻繁的詞。50,000份評論分為25,000份訓練和25,000份測試。該資料集由斯坦福大學的研究人員建立,並在2011年發表在一篇論文中,他們的準確性達到了88.89%。它也被用在2011年Kaggle競賽的“Bag of Words Meets Bags of Popcorn”方案中,並且取得了非常好的效果。

匯入依賴關係並獲取資料

我們首先匯入所需的依賴關係來預處理資料並構建我們的模型。

%matplotlib inline 
import matplotlib 
import matplotlib.pyplot as plt
import numpy as np 
from keras.utils import to_categorical 
from keras import keras import models 
from keras import layers

我們繼續下載imdb資料集,幸好它已經被內建到Keras中。這樣我們就不用將他進行5/5測試拆分,但我們也會在下載後立即將資料合併到資料和目標中,以便稍後進行80/20的拆分。

from keras.datasets import imdb
(training_data, training_targets), (testing_data, testing_targets) = imdb.load_data(num_words=10000)
data = np.concatenate((training_data, testing_data), axis=0)
targets = np.concatenate((training_targets, testing_targets), axis=0)

探索資料

現在我們可以開始探索資料集了:

print("Categories:", np.unique(targets))
print("Number of unique words:", len(np.unique(np.hstack(data))))
Categories: [0 1]
Number of unique words: 9998
length = [len(i) for i in data]
print("Average Review length:", np.mean(length))
print("Standard Deviation:", round(np.std(length)))
Average Review length: 234.75892
Standard Deviation: 173.0

你可以在上面的輸出中看到資料集被標記為兩個類別,分別代表0或1,表示評論的情感。整個資料集包含9998個獨特單詞,平均評論長度為234個單詞,標準差為173個單詞。

現在我們來看一個訓練樣例:

print("Label:", targets[0])
Label: 1
print(data[0])
[1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670
, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50
, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 
515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16,
38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 
117, 5952, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381
, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 
36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345,
19, 178, 32]

在上方,你會看到標記為肯定(1)的資料集評論。下面的程式碼檢索字典對映詞索引回到原來的單詞,以便我們可以閱讀它們,它用“#”替換每個未知的單詞。它可以通過使用get_word_index()函式來完成這一操作。

index = imdb.get_word_index()
reverse_index = dict([(value, key) for (key, value) in index.items()]) 
decoded = " ".join( [reverse_index.get(i - 3, "#") for i in data[0]] )
print(decoded) 
# this film was just brilliant casting location scenery story direction everyone's really suited the part they played and you could 
just imagine being there robert # is an amazing actor and now the same being director # father came from the same scottish island as
myself so i loved the fact there was a real connection with this film the witty remarks throughout the film were great it was just 
brilliant so much that i bought the film as soon as it was released for # and would recommend it to everyone to watch and the fly 
fishing was amazing really cried at the end it was so sad and you know what they say if you cry at a film it must have been good and 
this definitely was also # to the two little boy's that played the # of norman and paul they were just brilliant children are often 
left out of the # list i think because the stars that play them all grown up are such a big profile for the whole film but these 
children are amazing and should be praised for what they have done don't you think the whole story was so lovely because it was 
true and was someone's life after all that was shared with us all

資料準備

現在是準備我們的資料的時候了。我們將向量化每個評論並填充零,以便它包含正好一萬個數字。這意味著我們用零填充每個比10,000短的評論。我們這樣做是因為大多數的評論長度差不多都在這個長度,並且我們的神經網路的每次輸入都需要具有相同的大小。

def vectorize(sequences, dimension = 10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
results[i, sequence] = 1
return results
data = vectorize(data)
targets = np.array(targets).astype("float32")

現在我們將資料分成訓練和測試集。訓練集將包含40,000條評論,測試設定為10,000條。

test_x = data[:10000]
test_y = targets[:10000]
train_x = data[10000:]
train_y = targets[10000:]

建立和訓練模型

我們現在可以建立我們簡單的神經網路了,我們首先定義我們想要構建的模型的型別。Keras中有兩種型別的模型可供使用:功能性API使用的Sequential模型和Model類。

然後我們只需新增輸入層,隱藏層和輸出層。在他們之間,我們使用dropout來防止過度擬合。請注意,你應始終使用20%到50%之間的dropout。在每一層,我們使用“密集層”,這意味著單元完全連線。在隱藏層中,我們使用relu函式,因為它總是一個好的開始,並且在大多數情況下會產生令人滿意的結果,當然你也可以隨意嘗試其他啟用功能。在輸出層,我們使用sigmoid函式,它將0和1之間的值進行對映。請注意,我們在輸入層將輸入大小設定為10,000,因為我們的評論長度為10,000個整數。輸入層需要10,000個輸入,並以50的shape輸出。

最後,我們讓Keras列印我們剛剛構建的模型的摘要。

# Input - Layer
model.add(layers.Dense(50, activation = "relu", input_shape=(10000, )))
# Hidden - Layers
model.add(layers.Dropout(0.3, noise_shape=None, seed=None))
model.add(layers.Dense(50, activation = "relu")
model.add(layers.Dropout(0.2, noise_shape=None, seed=None))
model.add(layers.Dense(50, activation = "relu"))
# Output- Layer
model.add(layers.Dense(1, activation = "sigmoid"))model.summary()
model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 50)                500050    
_________________________________________________________________
dropout_1 (Dropout)          (None, 50)                0         
_________________________________________________________________
dense_2 (Dense)              (None, 50)                2550      
_________________________________________________________________
dropout_2 (Dropout)          (None, 50)                0         
_________________________________________________________________
dense_3 (Dense)              (None, 50)                2550      
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 51        
=================================================================
Total params: 505,201
Trainable params: 505,201
Non-trainable params: 0
_________________________________________________________________

現在我們需要優化我們的模型,這只不過是配置訓練模型,我們使用“adam”優化器。優化器是在訓練期間改變權重和偏差的演算法。我們也選擇二進位制–交叉熵作為損失(因為我們處理二進位制分類)和準確性作為我們的評估指標。

model.compile(
optimizer = "adam",
loss = "binary_crossentropy",
metrics = ["accuracy"]
)

我們現在開始訓練我們的模型,我們用batch_size為500來完成這件事,並且只對兩個epochs,因為我認識到如果我們訓練它的時間越長,模型就會過度擬合。批量大小定義了將通過網路傳播的樣本數量,一個epoch是對整個訓練資料的迭代。總的來說,批量大小可以加快訓練速度,但並不總是快速收斂。較小的批量大小是訓練速度較慢,但它可以更快地收斂。這絕對取決於問題性質,所以你需要嘗試一些不同的值。如果你第一次遇到問題,我建議你首先使用批量大小為32。

results = model.fit(
train_x, train_y,
epochs= 2,
batch_size = 500,
validation_data = (test_x, test_y)
)
Train on 40000 samples, validate on 10000 samples
Epoch 1/2
40000/40000 [==============================] - 5s 129us/step - loss: 0.4051 - acc: 0.8212 - val_loss: 0.2635 - val_acc: 0.8945
Epoch 2/2
40000/40000 [==============================] - 4s 90us/step - loss: 0.2122 - acc: 0.9190 - val_loss: 0.2598 - val_acc: 0.8950

現在是評估我們的模型的時候了:

print(np.mean(results.history["val_acc"]))
0.894750000536

真棒!有了這個簡單的模型,我們已經超過了我在開始時提到的2011年論文的準確性。

你可以在下面看到整個模型的程式碼:

import numpy as np
from keras.utils import to_categorical
from keras import models
from keras import layers
from keras.datasets import imdb
(training_data, training_targets), (testing_data, testing_targets) = imdb.load_data(num_words=10000)
data = np.concatenate((training_data, testing_data), axis=0)
targets = np.concatenate((training_targets, testing_targets), axis=0)
def vectorize(sequences, dimension = 10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
results[i, sequence] = 1
return results
test_x = data[:10000]
test_y = targets[:10000]
train_x = data[10000:]
train_y = targets[10000:]
model = models.Sequential()
# Input - Layer
model.add(layers.Dense(50, activation = "relu", input_shape=(10000, )))
# Hidden - Layers
model.add(layers.Dropout(0.3, noise_shape=None, seed=None))
model.add(layers.Dense(50, activation = "relu"))
model.add(layers.Dropout(0.2, noise_shape=None, seed=None))
model.add(layers.Dense(50, activation = "relu"))
# Output- Layer
model.add(layers.Dense(1, activation = "sigmoid"))
model.summary()
# compiling the model
model.compile(
optimizer = "adam",
loss = "binary_crossentropy",
metrics = ["accuracy"]
)
results = model.fit(
train_x, train_y,
epochs= 2,
batch_size = 500,
validation_data = (test_x, test_y)
)
print("Test-Accuracy:", np.mean(results.history["val_acc"]))

總結
在本文中,你瞭解到了什麼是情感分析的內容,以及為什麼Keras是最常用的深度學習庫之一。最重要的是,你瞭解到Keras對深度學習和人工智慧的商業化做出了巨大貢獻。你學會了如何建立一個簡單的六層神經網路,可以預測電影評論的情感,其準確率達到89%。現在,你可以使用此模型對其他文字來源進行情感分析,但需要將其全部更改為10,000的長度,或者更改輸入圖層的輸入大小。你也可以將此模型應用於其他相關機器學習問題,只需進行一些更改。

文章標題《how-to-build-a-neural-network-with-keras》

作者:Niklas Donges

相關文章

人工智慧 最新文章