ในปัจจุบันการเทรน Deep Neural Network ใช้พื้นฐานอัลกอริทึมมาจาก Mini-Batch Stochastic Gradient Optimization เป็นส่วนใหญ่ และจำนวนตัวอย่างข้อมูลที่เราป้อนให้โมเดลในหนึ่งครั้ง หรือ 1 Mini-Batch คือ Hyperparameter สำคัญตัวหนึ่งที่เราต้องปรับจูน ซึ่งใน Library ต่าง ๆ จะใช้ชื่อว่า Batch Size

ในเคสที่เรามีข้อมูลขนาดใหญ่ เช่น รูปมีความละเอียดสูง ด้วยข้อจำกัดเรื่องขนาด Memory ของ GPU ทำให้เราต้องลด Batch Size ลง เพื่อให้เทรนโมเดลได้โดยที่ไม่ Out of Memory Error

การเพิ่มลดขนาด Batch Size นี้เอง ไม่ได้แค่มีผลให้โมเดลสามารถเทรนได้เท่านั้น แต่ยังมีผลในเรื่องอื่น ๆ อีก เช่น

  • เวลาที่ใช้เทรน – Batch Size เล็กช้ากว่า
  • Memory ที่ใช้ – Batch Size เล็กใช้น้อยกว่า
  • และที่สำคัญ ความแม่นยำของโมเดล – Batch Size ขนาด <=32 แม่นยำกว่า

สรุปว่า การใช้ Batch Size ขนาดยิ่งใหญ่ยิ่งดี ให้เต็ม GPU Memory ที่สุด จะได้ใช้ GPU คุ้ม ๆ เทรน Deep Neural Network เร็ว ๆ ได้ผลลัพธ์ดี ๆ แต่ในทางปฏิบัติกลับไม่เป็นเช่นนั้น ขนาดของ Batch Size มีผลต่อความแม่นยำของโมเดล และเวลาที่ใช้ในการเทรนด้วย ดังตัวอย่าง Notebook ด้านล่าง

เรามาเริ่มกันเลยดีกว่า

Open In Colab

0. Magic Commands

In [1]:
%reload_ext autoreload
%autoreload 2
%matplotlib inline

1. Import Library

In [2]:
from fastai import *
from fastai.vision import *
from fastai.metrics import accuracy

2. ข้อมูล

ใช้ชุดข้อมูล Dataset พันธุ์หมาแมว Oxford-IIIT Pet Dataset by O. M. Parkhi et al., 2012

In [3]:
path = untar_data(URLs.PETS)
path_images = path/'images'
filenames = get_image_files(path_images)

3. เตรียมข้อมูล

เพื่อความสะดวก เราจะประกาศฟังก์ชัน แล้วไปเรียกสร้างก่อน fit ด้วย Batch Size แต่ละแบบ

In [4]:
batchsize = 64
epoch = 16
np.random.seed(55)
regex_pattern = r'/([^/]+)_\d+.jpg$'

def get_databunch():
    return ImageDataBunch.from_name_re(path_images, filenames, 
                                   regex_pattern, ds_tfms=get_transforms(), 
                                   size=224, bs=batchsize).normalize(imagenet_stats)

4. สร้างโมเดล

เพื่อความสะดวก เราจะประกาศฟังก์ชัน แล้วไปเรียกสร้างก่อน fit ด้วย Batch Size แต่ละแบบ

  • เคสนี้เราจะใช้โมเดล models.resnet34
  • pretrained=False หมายถึง เราจะเริ่มเทรนตั้งแต่ต้น ไม่เอา Weight ที่เคยเทรนกับ ImageNet มาแล้วมาใช้
In [5]:
def get_learner(databunch):
    return cnn_learner(databunch, models.resnet34, 
                      pretrained=False, 
                      metrics=accuracy, callback_fns=ShowGraph).to_fp16()

5. เริ่มต้นเทรนโมเดล

ปกติ Batch Size จะมีค่า Default เท่ากับ 64 เราจะลองเทรนด้วย Batch Size สูงมาก และต่ำมาก เปรียบเทียบกับ Image Classification ep.3 ดูว่าจะเป็นอย่างไร

ลองเทรนด้วย Batch Size ใหญ่ ๆ เช่น 512

In [6]:
batchsize = 512

learner = get_learner(get_databunch())
learner.fit_one_cycle(epoch)
Total time: 08:35

epochtrain_lossvalid_lossaccuracytime
04.0859123.6199460.02571000:38
14.0170743.7393580.02977000:32
23.9368023.5802840.05480400:31
33.8618533.7424370.07848400:32
43.7797133.5289490.08795700:31
53.6999313.4800610.10554800:31
63.6082143.5173580.10351800:31
73.5191603.1113080.15020300:31
83.4352613.0786670.17320700:32
93.3563903.0390010.18065000:31
103.2809452.9948980.21447900:30
113.2031582.8792660.21177300:32
123.1347892.8053410.21786200:31
133.0737052.7858990.23410000:31
143.0178752.7441190.24830900:31
152.9715632.7489120.24560200:31

ลองเทรนด้วย Batch Size เล็ก ๆ เช่น 2

In [7]:
batchsize = 2

learner = get_learner(get_databunch())
learner.fit_one_cycle(epoch)
Total time: 34:00

epochtrain_lossvalid_lossaccuracytime
03.9699533.9961360.03044702:05
13.7079314.4208480.03585902:05
23.7926993.8501580.03180002:06
33.7182203.7092030.02706402:06
43.7701274.8418620.02977002:07
53.8036703.8564620.02435702:07
63.73286214.4171710.01894502:06
73.7295896.8430730.02841702:07
83.72358316.3859880.03382902:06
93.6745794.6186070.02029802:07
103.62817412.0864060.03315302:08
113.6137186.0334650.02841702:08
123.5848474.1645480.03856602:07
133.6157328.1557470.02977002:07
143.6146776.9516210.03247602:08
153.6329395.9395670.02841702:07

ลองเทรนด้วย Default Batch Size 64

In [8]:
batchsize = 64

learner = get_learner(get_databunch())
learner.fit_one_cycle(epoch)
Total time: 07:09

epochtrain_lossvalid_lossaccuracytime
03.9957343.6199720.04600800:27
13.8336323.5086200.06698200:26
23.6750383.4518950.09269300:26
33.4925103.4573550.10690100:26
43.3312893.2330110.11975600:26
53.1350103.6096820.13125800:26
62.9003622.9953880.19824100:26
72.7144732.7809900.24898500:26
82.5035392.5032820.29161000:26
92.2833862.2595690.32544000:26
102.0490822.1675940.35926900:26
111.8521271.8712780.42219200:26
121.6546261.6961310.47496600:26
131.4961261.5221460.53247600:26
141.4017341.4708230.54600800:26
151.3421381.4622580.54803800:26

ลองเทรนด้วย Batch Size 32 ตาม Paper

In [9]:
batchsize = 32

learner = get_learner(get_databunch())
learner.fit_one_cycle(epoch)
Total time: 07:23

epochtrain_lossvalid_lossaccuracytime
03.9444963.5936060.05412700:28
13.7626943.5222970.07713100:27
23.5843663.5490430.06698200:27
33.4363133.2821660.13193500:27
43.2317863.0451660.16170500:27
53.0370774.4959250.08389700:27
62.8241282.9149800.21853900:27
72.5761042.4217030.29364000:27
82.3760282.3386580.29364000:27
92.1627151.9376950.41136700:27
101.8599471.8218640.44722600:27
111.6747881.5556830.51691500:27
121.4790831.3738370.55751000:27
131.3219121.2757320.59607600:27
141.2693051.2358680.60960800:27
151.2474661.2321360.61908000:27

6. สรุป

เปรียบเทียบ การเทรนแต่ละ Batch Size ในตารางดังนี้

Batch SizeTimeAccuracyMemory
51208:3524%Large
234:002%Small
6407:0954%Medium
3207:2362%Medium

หมายเหตุ

  • อันนี้เป็นการทดสอบแบบคร่าว ๆ ให้พอเห็นภาพ มีตัวแปรอีกหลายอย่าง
  • ใน Framework มีการใช้อีกหลายอัลกอริทึมโดย Default อาจทำให้ผลลัพธ์แตกต่างกันไป
  • แต่ละ learner มีการ Initial Weight ที่แตกต่างกัน
In [ ]:
 
In [ ]:
 

แชร์ให้เพื่อน:

Keng Surapong on FacebookKeng Surapong on GithubKeng Surapong on Linkedin
Keng Surapong
Project Manager at Bua Labs
The ultimate test of your knowledge is your capacity to convey it to another.

Published by Keng Surapong

The ultimate test of your knowledge is your capacity to convey it to another.

Enable Notifications    Ok No thanks