Machine learningPython

使用CNN對MNIST手寫數據集進行訓練(CPU或GPU運算)

電腦硬體

處理器(CPU):Intel® Core™ i5-10300H CPU @ 2.50GHz
顯示晶片(GPU):NVIDIA® GeForce GTX 1650 Ti

Python程式環境

  • Tensorflow-gpu-1.15.0
  • Keras 2.3.1

MNIST手寫數據集

mnist為手寫數字0-9的黑白圖片數據集。
圖片與對應標籤方面,數量為training data:55000筆,validation data:5000; 僅有圖片的test data:10000筆; 每張黑白圖片大小為[1,28,28,1](張,寬,長,通道),有784個像素(pixels),每個像素值都是數字0-255(0黑255白)。
標籤與圖片的手寫數字對應,如圖片內為手寫數字5,標籤就設5,0-9種手寫圖片就有10個標籤,可用list儲存,如圖片1,5,8,6,4對應標籤就是label=[1,5,8,6,4]

虛擬碼

  1. 下載mnist數據集,分成training data 跟test data
  2. 先處理圖片,將其轉換成列表形式,並透過標準化將所有像素值變成0-1之間
  3. 標籤處理成one hot encoding 形式
  4. 建立CNN網路
  5. 編譯模型
  6. 訓練模型
  7. 衡量模型訓練誤差

CNN網路架構

問題

因為下載的是Tensorflow-gpu-1.15.0,相對的版本使用Keras 2.3.1,若直接跑Keras寫的CNN程式碼,會產生以下錯誤(部份節錄)

Epoch 1/1
2020-08-14 18:01:49.576948: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10.0
2020-08-14 18:01:49.775817: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7
2020-08-14 18:01:50.056149: E tensorflow/stream_executor/cuda/cuda_dnn.cc:329] Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
2020-08-14 18:01:50.062654: E tensorflow/stream_executor/cuda/cuda_dnn.cc:329] Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
Traceback (most recent call last):
File “test.py", line 49, in
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1)
File “/home/leodflag5/.local/lib/python3.6/site-packages/keras/engine/training.py", line 1239, in fit
validation_freq=validation_freq)
File “/home/leodflag5/.local/lib/python3.6/site-packages/keras/engine/training_arrays.py", line 196, in fit_loop
outs = fit_function(ins_batch)
File “/home/leodflag5/.local/lib/python3.6/site-packages/tensorflow_core/python/keras/backend.py", line 3476, in call
run_metadata=self.run_metadata)
File “/home/leodflag5/.local/lib/python3.6/site-packages/tensorflow_core/python/client/session.py", line 1472, in call
run_metadata_ptr)
tensorflow.python.framework.errors_impl.UnknownError: 2 root error(s) found.
(0) Unknown: Failed to get convolution algorithm. This is probably because cuDNN failed to initialize, so try looking to see if a warning log message was printed above.
[[{{node conv2d_1/convolution}}]]
(1) Unknown: Failed to get convolution algorithm. This is probably because cuDNN failed to initialize, so try looking to see if a warning log message was printed above.
[[{{node conv2d_1/convolution}}]]
[[metrics/accuracy/Identity/_91]]
0 successful operations.
0 derived errors ignored.

關閉GPU,使用CPU運算

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"

使用GPU運算

import tensorflow as tf
config = tf.ConfigProto()
config.gpu_options.allow_growth=True
session=tf.InteractiveSession(config=config)

CPU運算時間

GPU 運算時間

大約差4倍,GPU還有使用CUDA加速運算

Machine learning

K-NN K最鄰近法

英文全名為:K-Nearest Neighbors algorithm ,機器學習裡最簡單的演算法之一 ,以最簡單的概念解釋,你身邊的近K個朋友是什麼人,你就是什麼人,換而言之,就是給機器人預設一個整數K,看標的數據樣本最近的K個數據樣本是什麼類別,可參考下圖

當K設為3時,左圖離綠圓圈最近的3個是2個紅三角跟1個藍正方,2>1,因此綠圓圈分成紅三角類;
當K設為5時,左圖離綠圓圈最近的5個是2個紅三角跟3個藍正方,3>2,因此綠圓圈分成藍正方類

紅三角、藍正方是已經分類好的資料,由此可知KNN是監督式學習

這個演算法簡單易懂,順著思考可以提出一些問題:

Q:少數服從多數的話,k的選擇不就很重要了嗎?
A:摘錄維基百科:"如何選擇一個最佳的K值取決於資料。一般情況下,在分類時較大的K值能夠減小噪聲的影響,但會使類別之間的界限變得模糊。",翻譯成白話文的話意思是K值(選離自己最近的K個)越大,可以參照的對象就越多,比較容易清楚知道自己是什麼類別而較少爭議,但是各個類別之間的資料會容易在另外一個類別也出現,分類的界線也就變模糊了。有種解決辦法是加上跟距離呈反比的權重,越近越重要,越遠越不重要,這樣可以重新檢視各個最近類別的影響,讓分類更準些

Q:是不是所有點都需要跟綠圓圈算距離? 這樣運算量會很大嗎?
有沒有減少運算量的方法?
A:KNN會計算所有點跟標的資料的距離,計算量大的確是缺點,而且排序出距離最小也很耗時,有特徵投影法、貪婪法、可調整權重的K最近鄰居法、考量已分類的資料數量不一樣以選取不一樣的K值

Q:如果今天是不同單位,比如身高跟體重,那要怎麼比距離?
A:用標準化、歸一化將身高壓縮10倍,分類上就不會差太多

參考資料:
https://www.joinquant.com/post/2227?f=zh
https://zhuanlan.zhihu.com/p/23191325
https://www.datacamp.com/community/tutorials/scikit-learn-python
https://morvanzhou.github.io/tutorials/machine-learning/sklearn/2-3-database/
https://zh.wikipedia.org/wiki/%E6%9C%80%E8%BF%91%E9%84%B0%E5%B1%85%E6%B3%95


https://zhuanlan.zhihu.com/p/23191325
https://www.datacamp.com/community/tutorials/scikit-learn-python
https://morvanzhou.github.io/tutorials/machine-learning/sklearn/2-3-database/
https://zh.wikipedia.org/wiki/%E6%9C%80%E8%BF%91%E9%84%B0%E5%B1%85%E6%B3%95