1. 程式人生 > >Python深度學習案例1--電影評論分類(二分類問題)

Python深度學習案例1--電影評論分類(二分類問題)

我覺得把課本上的案例先自己抄一遍,然後將書看一遍。最後再寫一篇部落格記錄自己所學過程的感悟。雖然與課本有很多相似之處。但自己寫一遍感悟會更深

電影評論分類(二分類問題)

本節使用的是IMDB資料集,使用Jupyter作為編譯器。這是我剛開始使用Jupyter,不得不說它的自動補全真的不咋地(以前一直用pyCharm)但是看在能夠分塊執行程式碼的份上,忍了。用pyCharm敲程式碼確實很爽,但是除錯不好除錯(可能我沒怎麼用心學),而且如果你完全不懂程式碼含義的話,就算你執行成功也不知道其中的含義,程式碼有點白敲的感覺,如果中途出現錯誤,有的時候很不好找。但是Jupyter就好一點,你可以使用多個cell,建議如果不列印一些東西,cell還是少一點,不然聯想功能特別弱,敲程式碼特別難受。

1. 載入IMDB資料集

僅保留前10000個最常出現的單詞,低頻單詞被捨棄

from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
train_data[0]
train_labels[0]
max([max(sequence) for sequence in train_data])

下面這段程式碼:將某條評論迅速解碼為英文單詞

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. 將整數序列編碼為二進位制矩陣

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]

標籤向量化

y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

3. 模型定義

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'))

4. 編譯模型

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

5. 配置優化器

from keras import optimizers

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

6. 使用自定義的損失和指標

from keras import losses
from keras import metrics

model.compile(optimizer=optimizers.RMSprop(lr=0.001), loss=losses.binary_crossentropy, metrics=[metrics.binary_crossentropy])

7. 留出驗證集

x_val = x_train[:10000]
partial_x_train = x_train[10000:]

y_val = y_train[:10000]
partial_y_train = y_train[10000:]

8. 訓練模型

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))

history_dict = history.history
history_dict.keys()

9. 繪製訓練損失和驗證損失

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(loss_values) + 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()

損失降得太狠了,訓練的損失和精度不太重要,反應訓練集的訓練程度。重點是驗證精度

10. 繪製訓練精度和驗證精度

plt.clf()     # 清除影象
acc = history_dict['acc']
val_acc = 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('Accuracy')
plt.legend()

plt.show()

可以看到驗證的精度並不高,只有80%左右。而訓練的精度達到幾乎100%,兩者精度相差太大,出現了過擬合

11. 從頭開始訓練一個模型

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.28940243008613586, 0.88488]

得到了88%的精度,還有待優化的空間

12. 使用訓練好的模型在新資料上生成預測結果

model.predict(x_test)
array([[0.20151292],
       [0.9997969 ],
       [0.9158534 ],
       ...,
       [0.1382984 ],
       [0.0817486 ],
       [0.69964325]], dtype=float32)
可見。網路對某些樣本的結果是非常確信(大於等於0.99),但對其他結果卻不怎麼確信

13. 總結

載入資料集->對資料集進行預處理->模型定義->編譯模型->配置優化器->使用自定義的損失和指標->留出驗證集->訓練模型->繪製圖像