การใช้ PyTorch เบื้องต้น
การเขียน Machine Learning ในปัจจุบันก็จะมีเครื่องมือนึงที่ให้เราสามารถเขียน Machine Learning ได้สะดวกซึ่งปัจจุบันก็มีหลายตัวให้เลือก หนึ่งในนั้นก็คือเครื่องมือที่ชื่อว่า PyTorch ที่ถูกพัฒนาโดย Facebook ซึ่งมีจุดเด่นก็คือ Pytorch สามารถเขียนเพื่อให้ GPU ใช้ในการคำนวณได้
“การปฎิบัติเป็นการเรียนรู้ที่ดี งั้นเรามาใช้ PyTorch กัน“
ผมได้ทำการเขียน PyTorch ไว้ใน Colab เรียบร้อยแล้ว หากใครอยากลองเล่นจริงสามารถเข้าไปได้ที่ลิงค์
https://github.com/CakeNuthep/Pytorch_Learning/blob/main/PytorchBegin.ipynb
หรือจะสร้างไปด้วยกันได้ดังนี้ครับ
ตั้งค่า Colab
ก่อนแรกก็ทำการ เปิดเว็บ https://colab.research.google.com/ แล้วคลิกคำว่า NEW NOTEBOOK ตามรูปด้านล่างครับ
หลังจากเปิดมาแล้วก่อนแรกนั้นต้องทำการ ตั้งค่าให้ใช้ GPU ในการคำนวณก่อน โดยการคลิกที่ Menu ที่ชื่อว่า RunTime -> Change Runtime type
เลือก Hardware accelerator เป็น GPU แล้วกด save
ลองใช้ PyTorch กัน
หลังจากเราตั้งค่าให้ Colab รองรับการใช้ GPU ในการคำนวณเรียบร้อยแล้วต่อมาเรามาลองใช้กันเลยครับ
ตอนแรกก็ต้อง Import Torch
หากต้องการอยากรู้ว่าตอนนี้เราใช้ Pytorch version อะไรสามารถใช้คำสั่ง torch.__version__ เพื่อเป็นการเอาค่า Version ออกมาได้
หากต้องการตรวจสอบว่าตอนนี้ PyTorch สามารถใช้ GPU ได้หรือไม่ให้ใช้คำสั่ง torch.cuda.is_available() ถ้าได้ค่าเป็น True แสดงว่าสามารถใช้ PyTorch ให้คำนวณใน GPU ได้
Tensor ของ PyTorch
ในการที่จะคำนวณค่าใน PyTorch ได้ เราจะทำการแปลงให้อยู่ในรูปของ Tensor ซึ่ง Tensor ก็คือค่าที่เป็น Vector กับ Matrix ในทางคณิตศาสตร์ ซึ่งเราสามารถสร้าง Tensor ได้ดังนี้
จากรูปจะมีคำสั่ง
x = torch.rand(3,4,dtype= torch.float32)
คือการสร้าง Tensor ที่มี Type เป็น float32 ที่มีขนาดเป็น 3 Rows x 4 Columns แล้วทำการ Random ค่าใน Tensor
x = torch.zeros(5,3, dtype= torch.long)
คือการสร้าง Tensor ที่มี Type เป็น long ที่มีขนาดเป็น 5 Rows x 3 Columns แล้วทำการกำหนดค่า 0 ทุกตัวใน Tensor
x = x.new_ones(5,3,dtype=torch.float64)
คือการสร้าง Tensor ที่มี Type เป็น float64 ที่มีขนาดเป็น 5 Rows x 3 Columns แล้วทำการกำหนดค่า 0 ทุกตัวใน Tensor
x = torch.tensor([4.123,3])
คือการสร้าง Tensor ที่มี Type เป็น float32 (หากเราไม่กำหนด Typ eโดย Default แล้ว Type จะเป็น float32 ) ที่มีข้อมูลเป็น [4.123, 3]
x = torch.randn_like(x, dtype=torch.float32)
คือการสร้าง Tensor ที่มี Type เป็น float32 ที่มีขนาดเหมือนกับ Tensor ที่ต้องการ (ในที่นี้คือตัวแปร x) แล้วทำการ Random ค่าใน Tensor
x = torch.Tensor(5,3).fill_(7)
คือการสร้าง Tensor ที่มี Type เป็น float32 (หากเราไม่กำหนด Type โดย Default แล้ว Type จะเป็น float32) ที่มีขนาดเป็น 5 Rows x 3Columns แล้วทำการกำหนดค่า 7 ทุกตัวใน Tensor
จากโคดจะเห็นว่าเราสามารถ กำหนด Type ของ Tensor ได้ หากอยากรู้ว่า Type ของ Tensor มี Type อะไรบ้างสามารถดูได้ที่ ลิงค์ https://pytorch.org/docs/stable/tensors.html
หากเราต้องการเปลี่ยน Type Tensor เราสามารถใส่ .type(tourch.[type ที่ต้องการเปลี่ยน]) ได้
หรือในการ Random ค่า ใน Tensor แต่ละครั้งไม่ต้องการให้ค่าเปลี่ยนแปลง เราสามารถกำหนดค่า Seed โดยการใช้คำสั่ง torch.manual_seed([ตัวเลขอะไรก็ได้])
การแปลงค่าไปมาระหว่าง Numpy กับ Tensor
ในการใช้ Tensor บางครั้งต้องการเอาค่าใน Numpy มาใส่ใน Tensor หรือเอาค่าใน Tensor มาใส่ใน Numpy ซึ่งตัว Pytorch ก็มีเครื่องมือนี้ให้ โดยเราสามารถใช้ได้ดังนี้ครับ
- การแปลงค่าจาก numpy มาใส่ใน Tensor
จากรูปเราจะใช้คำสั่ง from_numpy([ตัวแปร numpy]) เพื่อทำการเอาค่าจาก numpy มาใส่ใน Tensor แต่วิธีนี้หากเรามีการแก้ไขค่าใน Tensor ค่าใน numpy จะมีการแก้ไขตามไปด้วย (จากรูปด้านบนเราได้ทำการแก้ไขค่า t += 1 แต่ค่า a ก็จะเปลี่ยนตามไปด้วย) ซึ่งหากไม่ต้องการให้ numpy แก้ไขตามเราสามารถทำได้โดยการใช้คำสั่งให้แปลง numpy เป็น array ก่อนแล้วค่อยเข้า Tensor ดังนี้ครับ
- การแปลงค่าจาก Tensor มาใส่ใน Numpy
จากรูปเราจะใช้คำสั่ง .numpy() ในการแปลงค่าจาก Tensor มาเป็น numpy แต่หากเราใช้วิธีนี้จะทำให้ หากเรามีการแก้ไขค่าใน numpy ค่าใน Tensor ก็จะมีการแก้ไขตามไปด้วย(จากรูปด้านบนเราได้แก้ไขค่า b+=1 แต่ค่า t ก็จะเปลี่ยนตามไปด้วย) ซึ่งหากเราไม่ต้องการให้มีการแก้ไข เราสามารถเขียนโคดได้ดังนี้
การคำนวณค่าใน Tensor
หลังจากเราได้ Tensor มาแล้วเราสามารถนำ Tesnor มาคำนวณทางคณิตศาสตร์เบื้องต้น (+ , - , * ) ได้เลย
หรือถ้าต้องการ Dot Product Matrix เราสามารถทำได้โดยการใช้คำสั่ง torch.matmul([tensor1],[tensor2])
นอกเหนือจากนั้น Pytorch ก็ยังให้เครื่องมือที่ช่วยคำนวณ ค่าเฉลี่ย, ผลรวม, ค่าเบี่ยงเบน, หาค่า max, หาค่า min และอื่นๆอีกเพียบ
การเปลี่ยนรูปร่างของ Tensor
บางครั้งเราต้องการเปลี่ยนขนาดของ Tensor จากที่มีอยู่ให้เป็นขนาดที่ต้องการเช่น ต้องการเปลี่ยน Tensor ขนาด 5 x 3 ให้เป็นขนาด 1 x 15 หรือ 3 x 5 ซึ่งมีข้อแม้ว่าในการเปลี่ยนขนาดควรมีจำนวณข้อมูลทั้งหมดเท่ากัน เช่น จาก 5 x 3 คือ มีทั้งหมด 15 ค่า เราสามารถเปลี่ยนเป็นขนาดอะไรก็ได้ที่มีจำนวนข้อมูลทั้งหมด 15 ค่าเหมือนกัน เช่น 1 x 15 และ 3 x 5 (เนื่องจาก 1 x 15 = 15 และ 3 x 5 = 15)
ในการใช้คำสั่งเปลี่ยนขนาด Tensor เราสามารถใช้ คำสั่ง .view([row],[column]) ดังนี้
หรือหากเราจะเปลี่ยนขนาดเป็น 1 มิติเลยเราสามารถใช้คำสั่ง Flatten() ได้เลย
การใช้ GPU
การทำให้ Pytorch สามารถคำนวณ Tensor โดยใช้ GPU ได้นั้นก็จะมีการเขียนเพิ่มเติมนิดนึงดังนี้
จากรูปเราจะต้องประกาศ device ก่อนเสร็จแล้วเลือก device เป็น “cuda” หลังจากนั้นเวลาใช้ Tensor ก็ทำการใส่คำสั่ง .to(device) ได้เลย
หลังจากนั้นเมื่อมีการคำนวณค่า Tensor ที่เติมด้วย .to(device) ก็จะทำการคำนวณใน GPU ทันที
การหาอนุพันธ์
ใน PyTorch นั้นได้ทำส่วนของการคำนวณอนุพันธ์ ให้เรา โดยการที่จะทำให้ Pytorch คำนวณอนุพันธ์ให้เราได้นั้น ก่อนอื่นจำเป็นต้องตั้งค่า .requires_grad ให้เป็น True เพราะหากไม่กำหนดค่า โดย Default จะเป็น False และจะไม่สามารถคำนวณอนุพันธ์ได้
เมื่อตั้งค่า .requires_grad = True เรียบร้อย เราสามารถคำนวณอนุพันธ์ได้โดยการพิมพ์คำสั่ง .backward เพื่อคำนวณ แล้วค่าอนุพันธ์ที่คำนวนได้จะอยู่ในแอตทริบิวต์ที่ชื่อว่า .grad ดังนี้
จากรูปด้านบนเราสร้างตัวแปร x และ ตัวแปร w เพื่อมาทำการ dot product กัน แล้วเราก็ใส่คำสั่ง y.backward() เพื่อต้องการหาอนุพันธ์ y เทียบกับ w (เนื่องจากเราได้ใช้คำสั่ง w.requres_grad = True ไป) ดังนั้นอนุพันธ์ y เทียบกับ w จึงต้องมีค่าเท่ากับ x มาเก็บไว้ในแอตทริบิวต์ w.grad
เพื่อให้เข้าใจได้ง่ายขึ้นสามารถดูเป็นสมการคณิตศาสต์ดังนี้
Neural Network
เมื่อเรารู้วิธีการใช้ Tensor ใน Pytorch กันแล้ว ต่อมาลองใช้ Pytorch ในการสร้าง Neural Network กัน
Layer
ในการสร้าง Neural Network นั้นสิ่งที่ควรมีใน Neural Network คือ Layer ที่ใช้ในการคำนวณค่า ซึ่งแต่ละ Layer เราสามารถเลือกประเภทของ Layer ได้ เช่น Linear Layer, Convolution Layers, Pooling layers, Dropout Layers เป็นต้น
โดยการเขียนโคดเพื่อสร้าง Layer ใน Neural Network นั้นจะขอยกตัวอย่างการสร้าง Linear ซึ่งใช้คำสั่ง torch.nn.Linear([input],[output]) ดังนี้
จากโคดตัวอย่างด้านบน ในการสร้าง Linear Layer เราจะใช้คำสั่ง torch.nn.Linear(2,3) เพื่อสร้าง Linear Layer ที่รับข้อมูล Input 2 ข้อมูล และ ส่ง outpu 3 ข้อมูลดังรูป
หากเราอยากรู้ว่าที่เราสร้าง Layer ขึ้นมาจะมี Weight ทั้งหมดกี่ค่าสามารถพิมพ์คำสั่ง .weight ได้
จากตัวอย่างจะเห็นว่า Linear Layer ที่เราสร้างมี Weight ทั้งหมด 6 ค่า เนื่องจากก่อนหน้าเราได้สร้าง Linear Layer ให้รับ Input 2 ค่าและ ส่ง Output 3 ค่าซึ่งก็จะมี Weight ได้ทั้งหมด 2 x 3 = 6 ค่านั่นเอง
Neural Network
การสร้าง Neural Network ใน Pytorch นั้นจะสร้าง Neural Network ไว้ในคลาสที่สืบทอดมาจาก torch.nn.Module ซึ่งภายในคลาสจะต้องมี 2 method คือ methos ที่ชื่อว่า __init__ และ forward ดังนี้
__init__ จะเป็นการประกาศ Layer ว่าจะใช้ Layer ประเภทอะไรบ้าง
forward จะเป็นตัวกำหนดการไหลของการคำนวณใน Neural Network
ยกตัวอย่างเช่นหากเราต้องการสร้าง Neural Network ที่มี Linear Layer อยู่ 3 ชั้น และมี ReLU Activation อยู่ดังรูป
สามารถเขียนเป็นโคดได้ดังนี้
จากตัวอย่างโคดจะเห็นว่า ใน Method __init__ จะมีไว้สำหรับกำหนด Layer ที่ต้องการ ซึ่งในที่นี้คือ Linear Layer ส่วน Method ที่ชื่อว่า forward จะเป็นการบอกว่าให้เราเอาค่าจาก Layer ใหนไปเข้า Layer ใหนก่อนหลังหรือก็คือการไหลของข้อมูลจาก Input ไปยัง Ouput
เมื่อเรากำหนดการ Layer และการไหลของข้อมูลเรียบร้อยแล้วเราสามารถใช้งานได้โดยการสร้าง Object จาก Class ที่เราสร้างขึ้นมาและใช้งานผ่าน Object ที่สร้างขึ้นก็จะทำการเรียก Method ที่ชื่อว่า Forward ให้เองเลย
Optimizer
Optimizer คือวิธีการที่ช่วยในการปรับค่า Weight
ในปัจจุบันจะมีวิธี Optimizer ที่มีชื่อเรียกต่างกันเช่น SGD, Adam, Adamax, RMSprop เป็นต้น ซึ่งเราสามารถเรียกใช้คำสั่งได้เลย
เพื่อให้เข้าใจมากขึ้นขอยกตัวอย่างโคด ในโจทย์เรื่อง การจำแนกข้อมูลออกมาเป็น 2 กลุ่ม
สมมุติเราจำลองข้อมูลได้ดังรูป
เราสามารถเขียนโคด สร้าง Neural Network เพื่อทำการเรียนรู้และจำแนกข้อมูลได้ดังนี้
จะเห็นว่าจากตัวอย่างเราได้สร้าง Optimizer แบบวิธี Adam เข้าไป และทุกครั้งที่จะให้ Optimizer ทำการปรับค่า Weight เราก็เพียงใช้คำสั่ง .step() ก็จะทำให้ปรับค่า Weight ได้ตามที่ต้องการ
ก็จบแล้วครับกับการใช้ Pytorch เบื้องต้นหวังว่าโพสน์นี้จะมีประโยชน์นะครับ
Contact
Reference