寫給程式設計師的機器學習入門 (八) - 卷積神經網路 (CNN) - 圖片分類和驗證碼識別
阿新 • • 發佈:2020-07-21
這一篇將會介紹卷積神經網路 (CNN),CNN 模型非常適合用來進行圖片相關的學習,例如圖片分類和驗證碼識別,也可以配合其他模型實現 OCR。
使用 Python 處理圖片
在具體介紹 CNN 之前,我們先來看看怎樣使用 Python 處理圖片。Python 處理圖片最主要使用的類庫是 Pillow (Python2 PIL 的 fork),使用以下命令即可安裝:
pip3 install Pillow
一些簡單操作的例子如下,如果你想了解更多可以參考 Pillow 的文件:
# 開啟圖片 >>> from PIL import Image >>> img = Image.open("1.png") # 檢視圖片資訊 >>> img.size (175, 230) >>> img.mode 'RGB' >>> img <PIL.PngImagePlugin.PngImageFile image mode=RGB size=175x230 at 0x10B807B50> # 縮放圖片 >>> img1 = img.resize((20, 30)) >>> img1 <PIL.Image.Image image mode=RGB size=20x30 at 0x106426FD0> # 裁剪圖片 >>> img2 = img.crop((0, 0, 16, 16)) >>> img2 <PIL.Image.Image image mode=RGB size=16x16 at 0x105E0EFD0> # 儲存圖片 >>> img1.save("11.png") >>> img2.save("12.png")
使用 pytorch 處理圖片時要首先獲取圖片的資料,即各個畫素對應的顏色值,例如大小為 175 * 230,模式是 RGB 的圖片會擁有 175 * 230 * 3 的資料,3 分別代表紅綠藍的值,範圍是 0 ~ 255,把圖片轉換為 pytorch 的 tensor 物件需要經過 numpy 中轉,以下是轉換的例子:
>>> import numpy >>> import torch >>> v = numpy.asarray(img) >>> t = torch.tensor(v) >>> t tensor([[[255, 253, 254], [255, 253, 254], [255, 253, 254], ..., [255, 253, 254], [255, 253, 254], [255, 253, 254]], [[255, 253, 254], [255, 253, 254], [255, 253, 254], ..., [255, 253, 254], [255, 253, 254], [255, 253, 254]], [[255, 253, 254], [255, 253, 254], [255, 253, 254], ..., [255, 253, 254], [255, 253, 254], [255, 253, 254]], ..., [[255, 253, 254], [255, 253, 254], [255, 253, 254], ..., [255, 253, 254], [255, 253, 254], [255, 253, 254]], [[255, 253, 254], [255, 253, 254], [255, 253, 254], ..., [255, 253, 254], [255, 253, 254], [255, 253, 254]], [[255, 253, 254], [255, 253, 254], [255, 253, 254], ..., [255, 253, 254], [255, 253, 254], [255, 253, 254]]], dtype=torch.uint8) >>> t.shape torch.Size([230, 175, 3])
可以看到 tensor 的維度是 高度 x 寬度 x 通道數
(RGB 圖片為 3,黑白圖片為 1),可是 pytorch 的 CNN 模型會要求維度為 通道數 x 寬度 x 高度
,並且數值應該正規化到 0 ~ 1 的範圍內,使用以下程式碼可以實現:
# 交換維度 0 (高度) 和 維度 2 (通道數) >>> t1 = t.transpose(0, 2) >>> t1.shape torch.Size([3, 175, 230]) >>> t2 = t1 / 255.0 >>> t2 tensor([[[1.0000, 1.0000, 1.0000, ..., 1.0000, 1.0000, 1.0000], [1.0000, 1.0000, 1.0000, ..., 1.0000, 1.0000, 1.0000], [1.0000, 1.0000, 1.0000, ..., 1.0000, 1.0000, 1.0000], ..., [1.0000, 1.0000, 1.0000, ..., 1.0000, 1.0000, 1.0000], [1.0000, 1.0000, 1.0000, ..., 1.0000, 1.0000, 1.0000], [1.0000, 1.0000, 1.0000, ..., 1.0000, 1.0000, 1.0000]], [[0.9922, 0.9922, 0.9922, ..., 0.9922, 0.9922, 0.9922], [0.9922, 0.9922, 0.9922, ..., 0.9922, 0.9922, 0.9922], [0.9922, 0.9922, 0.9922, ..., 0.9922, 0.9922, 0.9922], ..., [0.9922, 0.9922, 0.9922, ..., 0.9922, 0.9922, 0.9922], [0.9922, 0.9922, 0.9922, ..., 0.9922, 0.9922, 0.9922], [0.9922, 0.9922, 0.9922, ..., 0.9922, 0.9922, 0.9922]], [[0.9961, 0.9961, 0.9961, ..., 0.9961, 0.9961, 0.9961], [0.9961, 0.9961, 0.9961, ..., 0.9961, 0.9961, 0.9961], [0.9961, 0.9961, 0.9961, ..., 0.9961, 0.9961, 0.9961], ..., [0.9961, 0.9961, 0.9961, ..., 0.9961, 0.9961, 0.9961], [0.9961, 0.9961, 0.9961, ..., 0.9961, 0.9961, 0.9961], [0.9961, 0.9961, 0.9961, ..., 0.9961, 0.9961, 0.9961]]])
之後就可以圍繞類似上面例子中 t2
這樣的 tensor 物件做文章了