รหัสเดิมที่ฉันไม่พบในเว็บไซต์ PyTorch อีกต่อไป
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)
ปัญหาเกี่ยวกับโค้ดด้านบนไม่มีฟังก์ชันที่ใช้คำนวณการไล่ระดับสี ซึ่งหมายความว่าเราไม่ทราบว่ามีกี่พารามิเตอร์ (อาร์กิวเมนต์ที่ฟังก์ชันใช้) และมิติของพารามิเตอร์
เพื่อให้เข้าใจอย่างถ่องแท้ฉันได้สร้างตัวอย่างที่ใกล้เคียงกับต้นฉบับ:
ตัวอย่างที่ 1:
a = torch.tensor([1.0, 2.0, 3.0], requires_grad = True)
b = torch.tensor([3.0, 4.0, 5.0], requires_grad = True)
c = torch.tensor([6.0, 7.0, 8.0], requires_grad = True)
y=3*a + 2*b*b + torch.log(c)
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients,retain_graph=True)
print(a.grad) # tensor([3.0000e-01, 3.0000e+00, 3.0000e-04])
print(b.grad) # tensor([1.2000e+00, 1.6000e+01, 2.0000e-03])
print(c.grad) # tensor([1.6667e-02, 1.4286e-01, 1.2500e-05])
ฉันคิดว่าฟังก์ชันของเราคือy=3*a + 2*b*b + torch.log(c)
และพารามิเตอร์คือเทนเซอร์ที่มีสามองค์ประกอบอยู่ภายใน
คุณสามารถคิดว่าgradients = torch.FloatTensor([0.1, 1.0, 0.0001])
นี่คือตัวสะสม
ดังที่คุณอาจได้ยินการคำนวณระบบอัตโนมัติของ PyTorch นั้นเทียบเท่ากับผลิตภัณฑ์จาโคเบียน
ในกรณีที่คุณมีฟังก์ชันเหมือนที่เราทำ:
y=3*a + 2*b*b + torch.log(c)
[3, 4*b, 1/c]
จาโคเบียนจะเป็น อย่างไรก็ตามจาโคเบียนนี้ไม่ใช่วิธีที่ PyTorch ทำสิ่งต่างๆเพื่อคำนวณการไล่ระดับสี ณ จุดหนึ่ง
PyTorch ใช้การส่งต่อไปข้างหน้าและโหมดย้อนกลับความแตกต่างอัตโนมัติ (AD) ควบคู่กัน
ไม่มีคณิตศาสตร์เชิงสัญลักษณ์ที่เกี่ยวข้องและไม่มีความแตกต่างของตัวเลข
ความแตกต่างของตัวเลขที่จะคำนวณδy/δb
สำหรับb=1
และb=1+ε
ที่εมีขนาดเล็ก
หากคุณไม่ใช้การไล่ระดับสีในy.backward()
:
ตัวอย่าง 2
a = torch.tensor(0.1, requires_grad = True)
b = torch.tensor(1.0, requires_grad = True)
c = torch.tensor(0.1, requires_grad = True)
y=3*a + 2*b*b + torch.log(c)
y.backward()
print(a.grad) # tensor(3.)
print(b.grad) # tensor(4.)
print(c.grad) # tensor(10.)
คุณจะง่ายได้รับผลที่จุดขึ้นอยู่กับวิธีการตั้งค่าของคุณa
, b
, c
เทนเซอร์แรก
ระวังว่าคุณเริ่มต้นของคุณa
, b
, c
:
ตัวอย่างที่ 3:
a = torch.empty(1, requires_grad = True, pin_memory=True)
b = torch.empty(1, requires_grad = True, pin_memory=True)
c = torch.empty(1, requires_grad = True, pin_memory=True)
y=3*a + 2*b*b + torch.log(c)
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(a.grad) # tensor([3.3003])
print(b.grad) # tensor([0.])
print(c.grad) # tensor([inf])
หากคุณใช้torch.empty()
และไม่ใช้pin_memory=True
คุณอาจได้ผลลัพธ์ที่แตกต่างกันในแต่ละครั้ง
นอกจากนี้การไล่ระดับสีของโน้ตก็เหมือนกับตัวสะสมดังนั้นจึงเป็นศูนย์เมื่อจำเป็น
ตัวอย่างที่ 4:
a = torch.tensor(1.0, requires_grad = True)
b = torch.tensor(1.0, requires_grad = True)
c = torch.tensor(1.0, requires_grad = True)
y=3*a + 2*b*b + torch.log(c)
y.backward(retain_graph=True)
y.backward()
print(a.grad) # tensor(6.)
print(b.grad) # tensor(8.)
print(c.grad) # tensor(2.)
เคล็ดลับสุดท้ายเกี่ยวกับเงื่อนไขการใช้ PyTorch:
PyTorch สร้างกราฟการคำนวณแบบไดนามิกเมื่อคำนวณการไล่ระดับสีในการส่งต่อ ดูเหมือนต้นไม้มาก
ดังนั้นคุณมักจะได้ยินใบของต้นไม้นี้tensors การป้อนข้อมูลและรากเป็นเมตริกซ์เอาท์พุท
การไล่ระดับสีที่มีการคำนวณโดยการติดตามกราฟจากรากใบและคูณลาดในทางที่ทุกคนใช้กฎลูกโซ่ การคูณนี้เกิดขึ้นในการส่งย้อนกลับ