Sinh viên cho các điều khoản thiên vị trong backpropagation


13

Tôi đã cố gắng thực hiện mạng lưới thần kinh từ đầu để hiểu các toán học đằng sau nó. Vấn đề của tôi hoàn toàn liên quan đến backpropagation khi chúng tôi lấy đạo hàm liên quan đến sai lệch) và tôi đã rút ra tất cả các phương trình được sử dụng trong backpropagation. Bây giờ mọi phương trình đều khớp với mã cho mạng nơ ron ngoại trừ đạo hàm đó liên quan đến các sai lệch.

z1=x.dot(theta1)+b1

h1=1/(1+np.exp(-z1))
z2=h1.dot(theta2)+b2
h2=1/(1+np.exp(-z2))

dh2=h2-y
#back prop

dz2=dh2*(1-dh2)
H1=np.transpose(h1)
dw2=np.dot(H1,dz2)
db2=np.sum(dz2,axis=0,keepdims=True)

Tôi đã tra cứu trực tuyến mã và tôi muốn biết tại sao chúng ta cộng ma trận và sau đó vô hướng db2=np.sum(dz2,axis=0,keepdims=True)bị trừ khỏi sai lệch ban đầu, tại sao toàn bộ ma trận không bị trừ. Bất cứ ai có thể giúp tôi đưa ra một số trực giác đằng sau nó. Nếu tôi lấy đạo hàm một phần của sai lệch đối với sai lệch, nó sẽ chỉ cho tôi độ dốc trên là dz2 vì z2=h1.dot(theta2)+b2h1 và theta sẽ là 0 và b2 sẽ là 1. Vì vậy, thuật ngữ trên sẽ bị bỏ lại.

b2+=-alpha*db2

Câu trả lời:


6

Thuật ngữ thiên vị rất đơn giản, đó là lý do tại sao bạn thường không thấy nó được tính toán. Trong thực tế

db2 = dz2

Vì vậy, quy tắc cập nhật của bạn cho sự thiên vị trên một mục là:

b2 += -alpha * dz2

b1 += -alpha * dz1

Về mặt toán học, nếu bạn thua lỗ Jvà bạn biết JzTôi cho một tế bào thần kinh nhất định Tôi trong đó có thuật ngữ thiên vị bTôi. . .

JbTôi= =JzTôizTôibTôi

zTôibTôi= =1

bởi vì zTôi= =(một cái gì đó không bị ảnh hưởng bởi bTôi)+bTôi


Có vẻ như mã bạn đã sao chép sử dụng biểu mẫu

db2=np.sum(dz2,axis=0,keepdims=True)

bởi vì mạng được thiết kế để xử lý các ví dụ theo lô (mini-) và do đó, bạn có độ dốc được tính cho nhiều hơn một ví dụ cùng một lúc. Tổng số đang làm giảm kết quả xuống một bản cập nhật duy nhất. Điều này sẽ dễ dàng hơn để xác nhận nếu bạn cũng hiển thị mã cập nhật cho trọng lượng.


vâng, chính xác đó là suy nghĩ của tôi, bởi vì nó trông giống như toán học. Nhưng mã tôi thấy họ đã tóm tắt ma trận và sau đó thêm nó vào b1.
user34042

theta1=theta1-alpha*dw1 theta2=theta2-alpha*dw2 tôi vẫn không hiểu được. Cách đó cùng một thuật ngữ sẽ được thêm vào tất cả các thuật ngữ khác nhau trong vectơ 'b' mà nếu không sẽ có các trọng số khác nhau cho mỗi điều khoản duy nhất. Điều đó sẽ tạo ra sự khác biệt đáng kể cho mạng thần kinh để đạt được cực tiểu.
user34042

@ user34042: Một cái gì đó có vẻ không phù hợp với tôi - bạn có thể liên kết nguồn mà bạn có mã đó không? Tôi tự hỏi nếu nguồn đã sai vì nó đã trộn và khớp mã mini-batch với độ dốc gradient trực tuyến đơn giản.
Neil Slater


Tôi nghĩ rằng nguồn có nó sai. NN vẫn sẽ làm việc với tất cả các giá trị sai lệch như nhau, vì vậy họ có thể không nhận thấy. Và như tôi đã đề cập, bạn thực sự có thể sử dụng mã đó trong một kịch bản dựa trên lô, vì vậy nó có thể chỉ là lỗi cắt và dán.
Neil Slater

10

Tôi muốn giải thích ý nghĩa của db2=np.sum(dz2,axis=0,keepdims=True)nó vì nó cũng làm tôi bối rối một lần và nó không được trả lời.

Đạo hàm của L(mất) wrt bđạo hàm ngược dòng nhân với đạo hàm cục bộ :

Lb= =LZZb

Nếu chúng ta có nhiều mẫu ZLcả hai ma trận. b vẫn là một vectơ.

Đạo hàm địa phương chỉ đơn giản là một vectơ của những cái :

Zb= =bW×X+b= =1

Điều đó có nghĩa là đạo hàm hoàn chỉnh của chúng tôi là phép nhân ma trận, trông như sau (ví dụ 2 mẫu có 3 đầu ra) :

LZ×1= =[......][111]

Lưu ý rằng đây là tổng của các hàng .

Và đó là nơi db2=np.sum(dz2, axis=0, keepdims=True)đến từ. Nó chỉ đơn giản là một từ viết tắt cho phép nhân ma trận của các đạo hàm cục bộ và ngược dòng.


0

trước tiên, bạn phải sửa công thức của bạn cho độ dốc của hàm sigmoid.

Đạo hàm đầu tiên của hàm sigmoid là: (1−σ(x))σ(x)

Công thức của bạn cho dz2 sẽ trở thành: dz2 = (1-h2)*h2 * dh2

Bạn phải sử dụng đầu ra của hàm sigmoid σ(x)chứ không phải gradient.

Bạn phải tính tổng độ dốc cho độ lệch vì độ dốc này đến từ nhiều đầu vào đơn (số lượng đầu vào = kích thước lô). Vì vậy, chúng ta phải tích lũy chúng để cập nhật các độ lệch của lớp 2. Tuy nhiên, đối với các gradient đến lớp 1, vì chúng đến từ nhiều nút của lớp 2, bạn phải tổng hợp tất cả các gradient để cập nhật các độ lệch và trọng số trong lớp 1 Trường hợp này khác với tổng số sai lệch trong lớp 2.

Việc triển khai của tôi cho hai lớp được kết nối đầy đủ với các chức năng kích hoạt là các hàm sigmoid:

lr = 1e-3
f = lambda x: 1.0/(1.0 + np.exp(-x))
# pass through layer 1
out_l1 = np.dot(x, W_1) + b_1

out_s1 = f(out_l1)

# pass through layer 2
out_l2 = np.dot(x, W_2) + b_2

out_s2 = f(out_l2)

loss = get_loss(out_s2, y)

# BACKWARD PASS
grad = out_s2 - y

d_h2 = (1 - out_s2) * out_s2 * grad

# Accumulate the gradient come from all examples
d_W2 = out_s1.T.dot(d_h2)
d_b2 = np.sum(d_h2, axis=0, keepdims=True)

# sum of gradient come out from prev node:
grad_1 = np.sum(d_W2.T, axis=0, keepdims=True)
d_h1 = (1 - out_l1) * out_l1 * grad_1

d_W1 = x.T.dot(d_h1)
d_b1 = np.sum(d_h1, axis=0, keepdims=True)

W_1 -= d_W1 * lr
b_1 -= d_b1 * lr

W_2 -= d_W2 * lr
b_2 -= d_b2 * lr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.