這次會介紹我在Kaggle上進行的貓狗辨認程式,我最終的測試結果得準確率可以高達90%,此部份會使用Pytorch這個深度學習框架。
1. 準備資料
在進行訓練前需要先準備好資料,我們先從Kaggle上下載圖片下來,再做資料的分配,這邊使用貓1000張及狗1000張當作訓練資料,使用貓500張及狗500張當作驗證資料,最後使用100張貓狗照片當作測試資料,我不使用Kaggle給的所有照片,因為我的電腦要跑很久,所以這邊取比較少張照片做訓練。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68import os
import shutil
train_all_path = "/home/chisc/workspace/wuzhenrong"
train_dir = "/home/chisc/workspace/wuzhenrong/train"
validation_dir = "/home/chisc/workspace/wuzhenrong/validation"
test_dir = "/home/chisc/workspace/wuzhenrong/test"
train_cat = "/home/chisc/workspace/wuzhenrong/train/cat"
train_dog = "/home/chisc/workspace/wuzhenrong/train/dog"
val_cat = "/home/chisc/workspace/wuzhenrong/validation/cat"
val_dog = "/home/chisc/workspace/wuzhenrong/validation/dog"
test_cat = "/home/chisc/workspace/wuzhenrong/test/cat"
test_dog = "/home/chisc/workspace/wuzhenrong/test/dog"
if not os.path.exists(train_dir):
os.mkdir(train_dir)
if not os.path.exists(validation_dir):
os.mkdir(validation_dir)
if not os.path.exists(test_dir):
os.mkdir(test_dir)
if not os.path.exists(train_cat):
os.mkdir(train_cat)
if not os.path.exists(train_dog):
os.mkdir(train_dog)
if not os.path.exists(val_cat):
os.mkdir(val_cat)
if not os.path.exists(val_dog):
os.mkdir(val_dog)
if not os.path.exists(test_cat):
os.mkdir(test_cat)
if not os.path.exists(test_dog):
os.mkdir(test_dog)
for i in range(0, 2000):
addr = f"/home/chisc/workspace/wuzhenrong/train_all/cat.{i}.jpg"
to_add = f"/home/chisc/workspace/wuzhenrong/train/cat/cat.{i}.jpg"
shutil.copyfile(addr, to_add)
for i in range(0, 2000):
addr = f"/home/chisc/workspace/wuzhenrong/train_all/dog.{i}.jpg"
to_add = f"/home/chisc/workspace/wuzhenrong/train/dog/dog.{i}.jpg"
shutil.copyfile(addr, to_add)
for i in range(2000, 2500):
addr = f"/home/chisc/workspace/wuzhenrong/train_all/cat.{i}.jpg"
to_add = f"/home/chisc/workspace/wuzhenrong/validation/cat/cat.{i}.jpg"
shutil.copyfile(addr, to_add)
for i in range(2000, 2500):
addr = f"/home/chisc/workspace/wuzhenrong/train_all/dog.{i}.jpg"
to_add = f"/home/chisc/workspace/wuzhenrong/validation/dog/dog.{i}.jpg"
shutil.copyfile(addr, to_add)
for i in range(2500, 3000):
addr = f"/home/chisc/workspace/wuzhenrong/train_all/cat.{i}.jpg"
to_add = f"/home/chisc/workspace/wuzhenrong/test/cat/cat.{i}.jpg"
shutil.copyfile(addr, to_add)
for i in range(2500, 3000):
addr = f"/home/chisc/workspace/wuzhenrong/train_all/dog.{i}.jpg"
to_add = f"/home/chisc/workspace/wuzhenrong/test/cat/dog.{i}.jpg"
shutil.copyfile(addr, to_add)
2. 引入函式庫
1 | import matplotlib.pyplot as plt |
為了畫函數圖形,所以引入matplotlib,接著numpy和pandas是常用的工具,所以提前引入以防不備之需,torch.nn裡包含很多神經網路的類別。再來是torchvision,引入後可以做資料的提取及準備。由於pytorch沒有訓練進度條,所以引入tqdm可以顯示進度條。
3. 引入資料
1 | train_trans = transforms.Compose( |
接著就是讀入資料,transforms.Compose可以放入data augmentation的資訊,ImageFolder是從目錄裡讀取資料,會依據不同資料夾來當作不同label,而DataLoader會彙整剛剛兩個的資訊。
4. 看圖片
1 | images, labels = next(iter(train_loader)) |
這邊的程式可以看到貓與狗的圖片,由於我們的train data有做normalize,所以要做denormalize,才能看到原圖。
5. CNN架構
1 | class CatDpg(nn.Module): |
CNN的架構如下: 1. Input layer 2. Convolutional layer 3. ReLU layer 4. Pooling layer 5. Fully-connected layer 我們首先先建立卷積層,再一層激勵函數,然後再來一個池化層,記住padding等於kernel_size / 2,這樣做5層即可,然後在forward李需要加入flatten(),這樣才能做fully-connected。
6. 開始訓練
1 | device = "cuda" if train_on_gpu else "cpu" |
首先要判斷是否有CUDA,如果有就使用CUDA訓練,如果沒有,就用CPU訓練,我們這邊使用Adam當作optimizer,Adam相對SGD還要來的穩定,且沒有梯度消失及梯度爆炸的問題,loss function是使用cross entropy,接著進入訓練,記得訓練的的地方需要加入model.train()。
7. 查看模型效能
1 | plt.figure(1) |
最後把圖形輸出就完成了,而測試的最高準確率可以達到91%,而平均測試準確率是88%,
總程式碼
1 | import matplotlib.pyplot as plt |