Truyền ngược
Truyền ngược (hay còn gọi là lan truyền ngược, Tiếng Anh: back-propagation), là một từ viết tắt cho "backward propagation of errors" tức là "truyền ngược của sai số", là một phương pháp phổ biến để huấn luyện các mạng thần kinh nhân tạo được sử dụng kết hợp với một phương pháp tối ưu hóa như gradient descent. Phương pháp này tính toán gradient của hàm tổn thất với tất cả các trọng số có liên quan trong mạng nơ ron đó. Gradient này được đưa vào phương pháp tối ưu hóa, sử dụng nó để cập nhật các trọng số, để cực tiểu hóa hàm tổn thất.
Truyền ngược yêu cầu một đầu ra mong muốn, đã biết cho mỗi giá trị đầu vào để tính toán gradient hàm tổn thất. Do đó, nó thường được xem là một phương pháp học có giám sát, mặc dù nó cũng được sử dụng trong một số mạng không có giám sát như autoencoders. Nó là một tổng quát hóa của quy tắc delta cho các mạng nuôi tiến đa tầng, có thể thực hiện bằng cách sử dụng quy tắc dây chuyền để tính toán lặp đi lặp lại các gradient cho mỗi lớp. Truyền ngược yêu cầu các hàm kích hoạt được sử dụng bởi cácnơ-ron nhân tạo (hay "nút") khả vi.
Động lực
[sửa | sửa mã nguồn]Mục tiêu của bất kỳ thuật toán học có giám sát nào cũng là phải tìm ra được một hàm ánh xạ tốt nhất một tập hợp các yếu tố đầu vào tới đầu ra chính xác của nó. Một ví dụ đó là một tác vụ phân loại đơn giản, trong đó đầu vào là một hình ảnh của một con vật, và đầu ra chính xác sẽ là tên của con vật đo.
Mục tiêu và động lực cho sự phát triển của các thuật toán truyền ngược là tìm ra được một cách để huấn luyện một mạng thần kinh nhiều lớp để nó có thể học được đại diện nội bộ thích hợp, cho phép nó học được bất kỳ ánh xạ nào của đầu vào đến đầu ra.[1]
Tóm lược
[sửa | sửa mã nguồn]Thuật toán học truyền ngược có thể được chia thành hai giai đoạn: lan truyền, cập nhật trọng số.
Giai đoạn 1: Lan truyền
[sửa | sửa mã nguồn]Mỗi lan truyền bao gồm các bước sau đây:
- Lan truyền thuận của một đầu vào của mô hình huấn luyện thông qua mạng nơ-ron để tạo ra các kích hoạt đầu ra của lan truyền này.
- Truyền ngược của các kích hoạt đầu ra của lan truyền thông qua mạng lưới nơ-ron sử dụng mục tiêu huấn luyện mô hình để tạo ra các delta (sai lệch giữa giá trị mục tiêu và giá trị đầu ra thực tế) và tất cả đầu ra và các nơ-ron ẩn.
Giai đoạn 2: cập nhật trọng số
[sửa | sửa mã nguồn]Đối với mỗi khớp thần kinh-trọng số thực hiện theo các bước sau:
- Nhân các delta đầu ra và kích hoạt đầu vào để có được gradient của trọng số của nó.
- Trừ một tỷ lệ (tỷ lệ phần trăm) từ gradient của trọng số.
Tỷ lệ này (tỷ lệ phần trăm) ảnh hưởng đến tốc độ và chất lượng học; nó được gọi là tốc độ học. Tỷ lệ này càng lớn, thì tốc độ huấn luyện nơron càng nhanh; tỷ lệ này càng thấp, thì việc huấn luyện càng chậm. Dấu của gradient của một trọng số chỉ ra chỗ mà sai số đang gia tăng, đây là lý do tại sao trọng số phải được cập nhật theo hướng ngược lại.
Lặp lại giai đoạn 1 và 2 cho đến khi đáp ứng của mạng nơ-ron chấp nhận được.
Thuật toán
[sửa | sửa mã nguồn]Sau đây là một thuật toán gradient descent ngẫu nhiên dành cho việc huấn luyện một mạng ba lớp (chỉ có một lớp ẩn):
khởi tạo các trọng số của mạng (thường là các giá trị ngẫu nhiên nhỏ) do forEach ví dụ huấn luyện được đặt tên là ex dự đoán = neural-net-output(mạng, ex) // forward pass actual = teacher-output(ex) tính sai số (dự đoán - thực tế) tại các đơn vị đầu ra tính cho tất cả các trọng số từ lớp ẩn cho tới lớp đầu ra // backward pass tính cho tất cả các trọng số từ lớp đầu vào cho tới lớp ẩn // backward pass continued cập nhật tất cả các trọng số của mạng // lớp đầu vào không được chỉnh sửa bởi ước lượng sai số until tất cả các ví dụ được phân loại chính xác hoặc một tiêu chí dừng được thỏa mãn return the network
Các dòng có gắn nhãn "backward pass" có thể được thực hiện bằng cách sử dụng thuật toán truyền ngược, thuật toán này sẽ tính toán gradient của sai số của mạng đó liên quan đến các trọng số có thể chỉnh sửa của mạng đó.[2] Thuật ngữ "truyền ngược" thường được sử dụng theo nghĩa tổng quát hơn, đó là để nói đến toàn bộ thủ tục bao gồm cả việc tính toán gradient và sử dụng của nó trong gradient descent ngẫu nhiên, nhưng truyền ngược thích hợp có thể được sử dụng với bất kỳ bộ tối ưu hóa dựa trên gradient nào, chẳng hạn như L-BFGS hoặc Newton cắt ngắn.
Các mạng truyền ngược cần các perceptron nhiều lớp (thường là với một đầu vào, nhiều lớp ẩn, và một lớp ra). Để cho lớp ẩn phục vụ cho bất kỳ hàm hữu ích nào, nhiều mạng đa lớp phải có có các hàm kích hoạt phi tuyến cho các lớp trùng nhau: một mạng đa lớp chỉ sử dụng các hàm kích hoạt tuyến tính tương đương với một số mạng tuyến tính, một lớp. Các hàm kích hoạt phi tuyến được sử dụng phổ biến bao gồm hàm rectifier, Hàm Lôgit, hàm softmax (hàm mũ chuẩn hóa), và hàm Gauss.
Thuật toán truyền ngược cho việc tính toán một gradient đã được tái phát hiện một số lần, và là một trường hợp đặc biệt của một kỹ thuật tổng quát được gọi là phép lấy vi phân tự động ở chế độ tích lũy ngược.
Nó cũng liên quan chặt chẽ đến thuật toán Gauss-Newton, và cũng là một phần của nghiên cứu liên tục trong truyền ngược thần kinh.
Trực giác
[sửa | sửa mã nguồn]Học như là một bài toán tối ưu hóa
[sửa | sửa mã nguồn]Trước khi chỉ ra nguồn gốc toán học của thuật toán truyền ngược, cần phải phát triển một số trực giác về mối quan hệ giữa đầu ra thực tế của một nơ-ron và đầu ra chính xác cho một trường hợp huấn luyện cụ thể. Hãy xem xét một mạng nơ-ron đơn giản với hai đơn vị đầu vào, một đơn vị đầu ra và không có đơn vị ẩn. Mỗi nơ-ron sử dụng một đầu ra tuyến tính[note 1] là tổng trọng số của đầu vào của nó.
![](http://178.128.105.246/content-http-upload.wikimedia.org/wikipedia/commons/thumb/4/42/A_simple_neural_network_with_two_input_units_and_one_output_unit.png/250px-A_simple_neural_network_with_two_input_units_and_one_output_unit.png)
Ban đầu, trước khi huấn luyện, các trọng số sẽ được thiết lập một cách ngẫu nhiên. Sau đó, các nơ-ron học từ các ví dụ huấn luyện, trong trường hợp này bao gồm một tập dữ liệu (, , ) trong đó và là các đầu vào của mạng và là đầu ra đúng (là đầu ra mà mạng tạo ra cuối cùng cho các đầu vào giống hệt nhau). Mạng đã cho và sẽ tính toán một đầu ra (Do trọng số ban đầu là ngẫu nhiên). Một phương pháp phổ biến để đo lường sự chênh lệch giữa đầu ra dự kiến và đầu ra thực tế là sử dụng phương pháp sai số bình phương:
- ,
trong đó là sự khác biệt hoặc sai số.
Ví dụ, hãy xem xét mạng nơ-ron trên một trường hợp đào tạo duy nhất: , theo đó đầu vào và tương ứng là 1 và 1 và đầu ra đúng, là 0. Bây giờ nếu đầu ra thực tế được vẽ trên trục x đối với sai số , kết quả là một hình parabol. Điểm cực tiểu của hình parabol đó tương ứng với đầu ra được cực tiểu hóa sai số . Đối với một trường hợp huấn luyện duy nhất, cực tiểu này có thể chạm tới trục zero và mạng nơ-ron đó có thể tạo ra một đầu ra có thể khớp chính xác với đầu ra mong muốn . Vì vậy, bài toán của ánh xạ các đầu vào đến các đầu ra có thể được giảm về bài toán tối ưu hóa tìm kiếm một hàm mà sẽ tạo ra sai số tối thiểu.
![](http://178.128.105.246/content-http-upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Error_surface_of_a_linear_neuron_for_a_single_training_case.png/250px-Error_surface_of_a_linear_neuron_for_a_single_training_case.png)
Tuy nhiên, đầu ra của một nơ-ron phụ thuộc vào tổng trọng số của tất cả các đầu vào của nó:
- ,
trong đó và là các trọng số nằm trên kết nối từ các đơn vị đầu vào đến đơn vị đầu ra. Vì vậy, sai số này cũng phụ thuộc vào các trọng số đưa nơ-ron đó, rút cuộc đó là những gì cần thiết để thay đổi trong mạng này để cho phép việc học. Nếu mỗi trọng số được vẽ trên trục hoành và sai số nằm trên trục tung, thì kết quả là một chảo parabolic (Nếu một nơ-ron có trọng số, thì chiều của bề mặt sai số sẽ là , vì vậy một nơ ron có trọng số sẽ tương đương với parabol 2D).
![](http://178.128.105.246/content-http-upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Error_surface_of_a_linear_neuron_with_two_input_weights.png/250px-Error_surface_of_a_linear_neuron_with_two_input_weights.png)
thuật toán truyền ngược nhằm tìm ra tập trọng số để cực tiểu hóa sai số này. Có rất nhiều phương pháp để tìm kiếm cực tiểu của một hàm parabol hay bất kỳ hàm nào trong bất kỳ chiều không gian nào. Có một cách đó là giải hệ phương trình theo phương pháp giải tích, tuy nhiên điều này chỉ thực hiện được nếu mạng nơ-ron là một hệ thống tuyến tính, và mục đích là để có thể huấn luyện được các mạng nơ-ron nhiều lớp, phi tuyến (do một mạng nơ-ron tuyến tính đa tầng thì tương đương với một mạng nơ-ron đơn lớp). Phương pháp được sử dụng trong truyền ngược là gradient descent.
Giải tích để hiểu về gradient descent
[sửa | sửa mã nguồn]Trực giác cơ bản đằng sau gradient descent có thể được minh họa bằng một kịch bản giả định. Một người đang bị mắc kẹt trên núi và đang cố gắng để đi xuống (nghĩa là cố gắng để tìm điểm cực tiểu). Trời đang sương mù nặng cho nên tầm nhìn bị hạn chế rất nhiều. Vì vậy, đường xuống núi không thể nhìn thấy được, vì vậy anh ta phải sử dụng thông tin cục bộ (địa phương) để tìm ra điểm cực tiểu. Anh ta có thể sử dụng phương pháp gradient descent, bao gồm việc nhìn vào độ dốc của ngọn đồi tại vị trí hiện tại của mình, sau đó di chuyển theo hướng dốc nhất đi xuống(cụ thể là xuống dốc). Nếu anh ta đã cố gắng để tìm thấy đỉnh núi (tức là điểm cực đại), thì anh ta sẽ tiếp tục đi theo hướng dốc nhất đi lên (tức là lên dốc). Sử dụng phương pháp này, anh ta sẽ dần dần tìm thấy đường đi xuống núi. Tuy nhiên, giả định cũng đưa ra rằng độ dốc của ngọn đồi không phải là rõ ràng ngay lập tức với các quan sát đơn giản, mà thay vào đó nó đòi hỏi một dụng cụ tinh vi để đo lường, mà người đó vô tình có được tại thời điểm đó. Phải mất khá nhiều thời gian để đo độ dốc của ngọn đồi với dụng cụ này, như vậy anh ta nên giảm thiểu việc sử dụng dụng cụ này nếu muốn xuống tới chân núi trước khi hoàng hôn ập tới. Khó khăn sau đó là lựa chọn tần suất đo độ dốc của ngọn đồi để không phải đi ra khỏi lộ trình cần phải đi.
Trong phép giải tích này, người tham gia đại diện cho thuật toán truyền ngược và đường đi dẫn xuống núi đại diện cho chuỗi cài đặt tham số mà thuật toán sẽ khám phá. Độ dốc của ngọn đồi tượng trưng cho độ dốc của bề mặt sai số vào thời điểm đó. Dụng cụ dùng để đo độ dốc chính là đạo hàm (độ dốc của bề mặt sai số có thể được tính bằng cách lấy đạo hàm của hàm sai số bình phương tại thời điểm đó). Hướng mà anh ta chọn để đi di chuyển gắn với gradient của bề mặt sai số vào thời điểm đó. Lượng thời gian mà anh ta di chuyển trước khi thực hiện một đo lường khác chính là tốc độ học của thuật toán. Xem phần giới hạn để xem thảo luận về những hạn chế của thuật toán "leo núi" loại này.
Phép lấy đạo hàm
[sửa | sửa mã nguồn]Do truyền ngược sử dụng phương pháp gradient descent, ta cần phải tính đạo hàm của hàm sai số bình phương với các trọng số của mạng. Giả sử có một nơ-ron đầu ra,[note 2] hàm sai số bình phương sẽ là:
- ,
Trong đó
- là sai số bình phương,
- là mục tiêu đầu ra cho huấn luyện mẫu, và
- là đầu ra thực tế của nơ-ron đầu ra.
Hệ số được đưa vào để loại bỏ số mũ khi lấy vi phân. Sau đó, biểu thức này sẽ được nhân với một tỷ lệ học tùy ý, vì vậy sẽ không quan trọng nếu một hệ số không đổi được được đưa vào.
Đối với mỗi nơ-ron , đầu ra của nó được định nghĩa như sau
- .
Đầu vào đưa vào một nơ-ron là tổng trọng số của đầu ra của các nơ-ron trước đó. Nếu nơ-ron này là lớp đầu tiên nằm sau lớp đầu vào, của lớp đầu vào sẽ đơn giản là các đầu vào của mạng nơ-ron đó. Số các đơn vị đầu vào đưa vào nơ-ron là . Biến biểu thị trọng số giữa các nơ-ron và .
nói chung là phi tuyến và khả vi. Một hàm kích hoạt được ứng dụng phổ biến đó là hàm sigmoid:
nó có một vi phân rất đẹp:
Tìm đạo hàm của sai số
[sửa | sửa mã nguồn]Tính toán đạo hàm riêng của sai số đối với một trọng số được thực hiện bằng cách sử dụng quy tắc chuỗi đến 2 lần:
Trong cụm cuối cùng nằm bên phải của công thức sau đây, chỉ một số hạng trong tổng phụ thuộc vào ,do đo
- .
Nếu nơ-ron này nằm trong lớp đầu tiên sau khi lớp đầu vào, thì sẽ là .
Đạo hàm của đầu ra của nơ ron đối với đầu vào của nó đơn giản là đạo hàm riêng của hàm kích hoạt (giả sử ở đây là hàm logistic được sử dụng):
Đây là lý do tại sao truyền ngược yêu cầu hàm kích hoạt phải khả vi.
Số hạng đầu tiên sẽ đơn giản để đánh giá nếu nơ-ron này nằm trong lớp đầu ra, bởi vì sau đó và
Tuy nhiên, nếu là một lớp bên trong bất kỳ, việc tìm vi phân đối với sẽ ít rõ ràng hơn.
Xem xét như là hàm của các đầu vào của tất cả các nơ-ron nhận đầu vào từ nơ-ron ,
và lấy tổng đạo hàm đối với , một biểu thức đệ quy cho đạo hàm này thu được:
Vì vậy, đạo hàm đối với có thể được tính toán nếu tất cả các đạo hàm đối với các đầu ra của lớp kế tiếp – lớp nằm gần với nơ-ron đàu ra hơn - được biết.
Đặt tất cả chúng với nhau:
Với
Để cập nhật trọng số sử dụng gradient descent, ta phải chọn một tốc độ học, . Sự thay đổi trong trọng số, sẽ được thêm vào trọng số cũ, bằng với tích của tốc độ học với gradient, được nhân bởi :
được nhân vào để cập nhật hướng cực tiểu, chứ không phải hướng cực đại, của hàm sai số.
Đối với một mạng đơn lớp, biểu thức này trở thành Quy tắc Delta. Để hiểu rõ hơn về cách thức truyền ngược làm việc, hãy xem ví dụ để minh họa sau đây: https://web.archive.org/web/20150317210621/https://www4.rgu.ac.uk/files/chapter3%20-%20bp.pdf, trang 20.
Các chế độ học
[sửa | sửa mã nguồn]Có hai chế độ học để lựa chọn: một loạt và ngẫu nhiên. Trong chế độ học ngẫu nhiên, mỗi một lan truyền được theo sau ngay bởi một cập nhật trọng số. Trong học một loạt, nhiều lan truyền xảy ra trước khi cập nhật các trọng số, các sai số tích lũy trên các mẫu nằm trong một gói. Học Ngẫu nhiên đưa vào các "nhiễu" vào quá trình gradient descent, sử dụng gradient địa phương tính từ một điểm dữ liệu. Điều này sẽ giúp giảm khả năng bị mắc kẹt trong một cực tiểu cục bộ cho mạng lưới. Tuy nhiên, học một loạt thường đạt được độ dốc nhanh hơn, ổn định hơn với một cực tiểu địa phương, vì mỗi cập nhật được thực hiện theo hướng sai số trung bình của các mẫu một loạt. Trong các ứng dụng hiện đại, một lựa chọn thỏa hiệp phổ biến là sử dụng các "mini-batch", nghĩa là học một loạt, nhưng với một gói có kích thước nhỏ và mẫu được lựa chọn ngẫu nhiên.
Bộ sưu tập dữ liệu huấn luyện
[sửa | sửa mã nguồn]Học trực tuyến được sử dụng cho các môi trường động, cung cấp một dòng liên tục các mẫu dữ liệu huấn luyện mới. Học ngoại tuyến tận dụng tốt một tập huấn luyện các mô hình tĩnh.
Các hạn chế
[sửa | sửa mã nguồn]![](http://178.128.105.246/content-http-upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Extrema_example.svg/250px-Extrema_example.svg.png)
- Gradient descent với truyền ngược không bảo đảm sẽ tìm ra cực tiểu toàn cục của hàm sai số, mà chỉ ở mức cực tiểu địa phương; also, it has trouble crossing plateaus in the error function landscape. This issue, caused by the non-convexity of error functions in neural networks, was long thought to be a major drawback, but in a 2015 review article, Yann LeCun et al. argue that in many practical problems, it is not.[3]
- Học truyền ngược không đòi hỏi việc chuẩn hóa các vectơ đầu vào; Tuy nhiên, việc chuẩn hóa có thể cải thiện hiệu suất.[4]
Lịch sử
[sửa | sửa mã nguồn]Theo các nguồn khác nhau,[5][6][7][7] vấn đề cơ bản của truyền ngược liên tục được bắt nguồn từ trong bối cảnh của lý thuyết điều khiển bởi Henry J. Kelley[8] trong năm 1960 và bởi Arthur E. Bryson vào năm 1961,[9] sử dụng các nguyên tắc của quy hoạch động. Năm 1962, Stuart Dreyfus xuất bản một dẫn xuất đơn giản chỉ dựa trên quy tắc dây chuyền.[10] Vapnik trích dẫn tham khảo[11] trong quyể sách của ông về Máy véc tơ hỗ trợ. Arthur E. Bryson và Yu-Chi Ho mô tả nó như là một phương pháp tối ưu hóa nhiều-giai đoạn vào năm 1969.[12][13]
Năm 1970,Seppo Linnainmaa cuối cùng đã xuất bản phương pháp tổng quát để tính vi phân tự động (AD) rời rạc kết nối các mạng của hàm khả vi lồng nhau.[14][15] Điều này tương ứng với phiên bản hiện đại của truyền ngược có hiệu quả ngay cả khi các mạng không nhiều.[7][7][16][17]
Năm 1973, Stuart Dreyfus sử dụng truyền ngược để tương thích với các tham số của các bộ điều khiển tỉ lệ với các gradient sai số.[18] Năm 1974, Paul Werbos đề cập đến khả năng áp dụng nguyên tắc này cho các mạng nơ-ron nhân tạo,[19] và trong năm 1982, ông đã áp dụng phương pháp AD của Linnainmaa cho các mạng nơ-ron theo cách mà chúng ta sử dụng rộng rãi ngày nay[7][20]
Năm 1986,David E. Rumelhart, Geoffrey E. Hinton và Ronald J. Williams cho thấy thông qua các thí nghiệm máy tính rằng phương pháp này có thể tạo ra các đại diện bên trong hữu ích của dữ liệu vào trong các lớp ẩn của mạng nơ-ron.[1] [21] Vào năm 1993, Eric A. Wan là người đầu tiên[7] chiến th��ng một cuộc thi nhận dạng mẫu quốc tế thông qua phương pháp truyền ngược.[22] Trong những năm 2000 nó không còn được ưa thích nữa nhưng đã được sử dụng trở lại trong những năm 2010, hiện tại có thể huấn luyện nhiều mạng lớn hơn nhiều bằng cách sử sức mạnh tính toán hiện đại khổng lồ như GPU. Ví dụ, vào năm 2013 những chương trình nhận dạng giọng nói tốt nhất có sử dụng các mạng nơ-ron được huấn luyện theo phương pháp truyền ngược này. [citation needed]
Ghi chú
[sửa | sửa mã nguồn]Xem thêm
[sửa | sửa mã nguồn]- Mạng nơ-ron nhân tạo
- Mạng nơ-ron sinh học
- Catastrophic interference
- Ensemble learning
- AdaBoost
- Overfitting
- Neural backpropagation
- Backpropagation through time
Tham khảo
[sửa | sửa mã nguồn]- ^ a b Rumelhart, David E.; Hinton, Geoffrey E.; Williams, Ronald J. (ngày 8 tháng 10 năm 1986).
- ^ Paul J. Werbos (1994).
- ^ LeCun, Yann; Bengio, Yoshua; Hinton, Geoffrey (2015).
- ^ ISBN 1-931841-08-X,
- ^ Stuart Dreyfus (1990).
- ^ Eiji Mizutani, Stuart Dreyfus, Kenichi Nishio (2000).
- ^ a b c d e f Jürgen Schmidhuber (2015).
- ^ Henry J. Kelley (1960).
- ^ Arthur E. Bryson (1961, April).
- ^ Stuart Dreyfus (1962).
- ^ Bryson, A.E.; W.F. Denham; S.E. Dreyfus.
- ^ Stuart Russell; Peter Norvig.
- ^ Arthur Earl Bryson, Yu-Chi Ho (1969).
- ^ Seppo Linnainmaa (1970).
- ^ Seppo Linnainmaa (1976).
- ^ Griewank, Andreas (2012).
- ^ Griewank, Andreas and Walther, A..
- ^ Stuart Dreyfus (1973).
- ^ Paul Werbos (1974).
- ^ Paul Werbos (1982).
- ^ Alpaydın, Ethem (2010).
- ^ Eric A. Wan (1993).
Liên kết ngoài
[sửa | sửa mã nguồn]- A Gentle Introduction to Backpropagation - An intuitive tutorial by Shashi Sathyanarayana Lưu trữ 2016-02-06 tại Wayback Machine The article contains pseudocode ("Training Wheels for Training Neural Networks") for implementing the algorithm.
- Neural Network Back-Propagation for Programmers (a tutorial)
- Backpropagation for mathematicians
- Chapter 7 The backpropagation algorithm of Neural Networks - A Systematic Introduction by Raúl Rojas (ISBN 978-3540605058)
- Quick explanation of the backpropagation algorithm Lưu trữ 2013-02-10 tại Wayback Machine
- Graphical explanation of the backpropagation algorithm
- Concise explanation of the backpropagation algorithm using math notation Lưu trữ 2016-03-26 tại Wayback Machine by Anand Venkataraman
- Visualization of a learning process using backpropagation algorithm
- Backpropagation neural network tutorial at the Wikiversity