Mục lục[Ẩn giấu][Chỉ]
Bộ não có thể so sánh với mạng lưới thần kinh. Đây là phép loại suy thường được sử dụng để hỗ trợ người mới làm quen với chủ đề này hiểu được ý tưởng đằng sau việc học máy và mạng nơ-ron nhân tạo.
Bởi vì có một số lớp tính toán toán học và thống kê đang diễn ra ở hậu trường, việc xác định các mạng này như một hàm toán học là một phương pháp tiên tiến hơn.
Điều này dành cho những người thực sự quan tâm đến học máy và muốn xem mã mạng thần kinh Python được viết như thế nào.
Trong bài viết này, chúng tôi sẽ trình bày cách xây dựng một mạng nơ-ron sâu (DNN) được kết nối đầy đủ ngay từ đầu Python 3.
Tổng quan về cấu trúc tệp cho mã mạng thần kinh Python của chúng tôi
Sẽ có ba tệp được tạo ở đây. Đầu tiên là tệp nn.py đơn giản, sẽ được thảo luận trong “Thiết lập chức năng của người trợ giúp” và “Xây dựng mạng thần kinh từ Scratch”.
Chúng tôi cũng sẽ có một tệp có tên mnist loader.py để tải dữ liệu thử nghiệm, như được mô tả trong “Tải dữ liệu MNIST”.
Cuối cùng, chúng tôi sẽ có một tệp có tên test.py sẽ được khởi chạy trong thiết bị đầu cuối để kiểm tra mạng nơ-ron của chúng tôi.
Tệp này được mô tả chi tiết trong “Chạy thử nghiệm”.
của DINTEK
Thư viện NumPy Python phải được tải xuống để làm theo hướng dẫn này. Bạn có thể thực hiện điều này bằng cách sử dụng lệnh sau trên thiết bị đầu cuối:
Nhập Mô-đun và thiết lập chức năng Người trợ giúp
Hai thư viện duy nhất chúng tôi yêu cầu là ngẫu nhiên và NumPy, chúng tôi sẽ nhập ngay lập tức. Đối với trọng số ban đầu của mạng nơ-ron của chúng tôi, chúng tôi sẽ xáo trộn chúng bằng cách sử dụng thư viện ngẫu nhiên.
Để tăng tốc độ tính toán của chúng tôi, chúng tôi sẽ sử dụng NumPy hoặc np (theo quy ước, nó thường được nhập dưới dạng np). Hai chức năng trợ giúp của chúng tôi sẽ được thực hiện sau khi chúng tôi nhập khẩu. Hai hàm sigmoid: một và nguyên tố sigmoid.
Hồi quy logistic sẽ phân loại dữ liệu bằng cách sử dụng hàm sigmoid, trong khi truyền ngược sẽ tính toán delta hoặc gradient bằng cách sử dụng hàm nguyên tố sigmoid.
Tạo lớp mạng
Xây dựng một mạng nơ-ron được liên kết đầy đủ là trọng tâm duy nhất của phần này. Lớp mạng sẽ bao gồm tất cả các chức năng sau đó. Hàm Object () {[native code]} sẽ được tạo ban đầu trong lớp mạng của chúng ta.
Một đối số, kích thước, được yêu cầu bởi hàm Object () {[mã gốc]}. Biến kích thước là một tập hợp các giá trị số thể hiện số lượng các nút đầu vào có trong mỗi lớp của mạng nơ-ron của chúng ta.
Chúng tôi khởi tạo bốn thuộc tính trong phương thức __init__ của chúng tôi. Các biến đầu vào, kích thước, được sử dụng để thiết lập danh sách kích thước lớp và số lớp, num lớp, tương ứng.
Bước đầu tiên là chỉ định ngẫu nhiên các thành kiến ban đầu của mạng của chúng tôi cho mỗi lớp theo sau lớp đầu vào.
Cuối cùng, mỗi liên kết giữa các lớp đầu vào và đầu ra có trọng số của nó được tạo ngẫu nhiên. Np.Random.Randn () đưa ra một mẫu ngẫu nhiên được rút ra từ phân phối chuẩn cho ngữ cảnh.
Chức năng chuyển tiếp nguồn cấp dữ liệu
Trong mạng nơ-ron, thông tin được gửi về phía trước bởi chức năng chuyển tiếp cấp dữ liệu. Một đối số, a, cho biết vectơ kích hoạt hiện tại, sẽ được hàm này yêu cầu.
Hàm này ước tính các kích hoạt ở mỗi lớp bằng cách lặp lại tất cả các thành phần và trọng số trong mạng. Câu trả lời được đưa ra là dự đoán, là các kích hoạt của lớp cuối cùng.
Đổ dốc màu theo lô nhỏ
Workhorse của lớp Network của chúng tôi là Gradient Descent. Trong phiên bản này, chúng tôi sử dụng gradient descent theo lô nhỏ (ngẫu nhiên), một biến thể đã sửa đổi của gradient descent.
Điều này cho thấy rằng một loạt nhỏ các điểm dữ liệu sẽ được sử dụng để cập nhật mô hình của chúng tôi. Bốn đối số bắt buộc và một đối số tùy chọn được chuyển cho phương thức này. Bốn biến bắt buộc là tập dữ liệu đào tạo, số kỷ nguyên, kích thước của các lô nhỏ và tỷ lệ học tập (eta).
Dữ liệu thử nghiệm có sẵn theo yêu cầu. Chúng tôi sẽ cung cấp dữ liệu thử nghiệm khi cuối cùng chúng tôi đánh giá mạng này. Số lượng mẫu trong hàm này ban đầu được đặt thành độ dài của danh sách sau khi dữ liệu huấn luyện đã được chuyển thành một loại danh sách.
Chúng tôi cũng áp dụng quy trình tương tự để kiểm tra dữ liệu được cung cấp. Điều này là do thay vì được trả lại cho chúng tôi dưới dạng danh sách, chúng thực sự là danh sách nén. Khi chúng tôi tải các mẫu dữ liệu MNIST sau, chúng tôi sẽ tìm hiểu thêm về điều này.
Nếu chúng ta có thể đảm bảo rằng chúng ta cung cấp cả hai loại dữ liệu dưới dạng danh sách, thì kiểu truyền kiểu này không nhất thiết phải cần thiết.
Khi chúng tôi có dữ liệu, chúng tôi xem xét các kỷ nguyên đào tạo trong một vòng lặp. Một thời gian đào tạo chỉ là một vòng đào tạo mạng nơ-ron. Đầu tiên, chúng tôi xáo trộn dữ liệu trong mỗi kỷ nguyên để đảm bảo tính ngẫu nhiên trước khi tạo danh sách các lô nhỏ.
Chức năng lô nhỏ cập nhật, được thảo luận bên dưới, sẽ được gọi cho từng lô nhỏ. Độ chính xác của thử nghiệm cũng sẽ được trả về nếu dữ liệu thử nghiệm có sẵn.
Hàm trợ giúp phái sinh chi phí
Hãy phát triển một hàm trợ giúp được gọi là dẫn xuất chi phí trước khi chúng ta thực sự tạo mã lan truyền ngược. Nếu chúng ta mắc lỗi trong lớp đầu ra của mình, hàm dẫn xuất chi phí sẽ hiển thị điều đó.
Nó yêu cầu hai đầu vào: mảng kích hoạt đầu ra và tọa độ y của các giá trị đầu ra dự đoán.
Chức năng nhân giống ngược
Vectơ kích hoạt hiện tại của chúng tôi, kích hoạt, cũng như bất kỳ vectơ kích hoạt, kích hoạt và vectơ z, zs nào khác, đều phải được lưu ý. Một lớp được gọi là lớp đầu vào được kích hoạt đầu tiên.
Chúng tôi sẽ lặp lại từng độ lệch và trọng lượng sau khi đưa chúng lên. Mỗi vòng lặp bao gồm việc tính toán vectơ z dưới dạng tích số chấm của trọng số và kích hoạt, thêm nó vào danh sách z, tính toán lại kích hoạt và thêm kích hoạt cập nhật vào danh sách kích hoạt.
Cuối cùng là toán học. Delta, bằng với sai số từ lớp trước nhân với số nguyên tố sigmoid của phần tử cuối cùng của vectơ zs, được tính toán trước khi chúng ta bắt đầu chuyển ngược lại.
Lớp cuối cùng của nabla b được đặt là delta và lớp cuối cùng của nabla w được đặt là tích số chấm của delta và lớp kích hoạt thứ hai đến cuối cùng (được chuyển đổi để chúng ta thực sự có thể làm toán) .
Chúng tôi tiếp tục như trước, bắt đầu với lớp thứ hai và kết thúc với lớp cuối cùng, và lặp lại quy trình sau khi hoàn thành các lớp cuối cùng này. Các nablas sau đó được trả lại dưới dạng một bộ tuple.
Đang cập nhật giảm độ dốc gradient theo lô nhỏ
Phương pháp SGD (stochastic gradient descent) của chúng tôi trước đây đã kết hợp cập nhật hàng loạt nhỏ. Vì nó được sử dụng trong SGD nhưng cũng yêu cầu backprop, tôi đã tranh luận về nơi đặt chức năng này.
Cuối cùng, tôi đã lựa chọn đăng nó ở đây. Nó bắt đầu bằng cách tạo ra 0 vectơ của nablas 'thiên vị và trọng số', giống như hàm backprop của chúng ta đã làm.
Nó yêu cầu mini-batch và eta learning rate là hai đầu vào của nó. Trong mini-batch, sau đó chúng ta sử dụng hàm backprop để lấy delta của mỗi mảng nabla cho mỗi đầu vào, x và đầu ra, y. Các danh sách nabla sau đó được cập nhật với các delta này.
Cuối cùng, chúng tôi sử dụng tỷ lệ học tập và giá trị nablas để cập nhật trọng số và độ lệch của mạng. Mỗi giá trị được cập nhật thành giá trị gần đây nhất, trừ đi tỷ lệ học tập, nhân với kích thước minibatch, sau đó được thêm vào giá trị nabla.
Đánh giá chức năng
Hàm đánh giá là hàm cuối cùng mà chúng ta cần viết. Dữ liệu kiểm tra là đầu vào duy nhất cho chức năng này. Trong chức năng này, chúng tôi chỉ so sánh kết quả đầu ra của mạng với kết quả dự đoán, y. Bằng cách cung cấp đầu vào, x, chuyển tiếp, đầu ra của mạng được xác định.
Hoàn thành mã
Khi chúng tôi kết hợp tất cả các mã, đây là cách nó xuất hiện.
Kiểm tra mạng thần kinh
Đang tải dữ liệu MNIST
Sản phẩm Dữ liệu MNIST có định dạng .pkl.gz, chúng tôi sẽ mở định dạng này bằng GZIP và tải bằng pickle. Hãy viết một phương thức nhanh để tải dữ liệu này dưới dạng một bộ ba kích thước, được chia thành dữ liệu huấn luyện, xác thực và thử nghiệm.
Để quản lý dữ liệu của chúng tôi dễ dàng hơn, chúng tôi sẽ viết một hàm khác để mã hóa y thành một mảng 10 mục. Mảng sẽ là tất cả các số 0 ngoại trừ số 1 khớp với chữ số thích hợp của hình ảnh.
Chúng tôi sẽ sử dụng dữ liệu tải cơ bản và một phương pháp mã hóa nóng để tải dữ liệu của chúng tôi sang định dạng có thể đọc được. Một hàm khác sẽ được viết sẽ chuyển đổi các giá trị x của chúng ta thành một danh sách có kích thước 784, khớp với 784 pixel của hình ảnh và các giá trị y của chúng ta thành dạng vectơ được mã hóa nóng duy nhất của chúng.
Sau đó, chúng tôi sẽ kết hợp các giá trị x và y sao cho một chỉ mục khớp với chỉ mục kia. Điều này áp dụng cho các tập dữ liệu đào tạo, xác nhận và thử nghiệm. Sau đó, chúng tôi trả lại dữ liệu đã thay đổi.
Chạy thử nghiệm
Chúng tôi sẽ tạo một tệp mới có tên “trình tải mnist” sẽ nhập cả mạng nơ-ron mà chúng tôi đã thiết lập trước đó (nn đơn giản) và trình tải tập dữ liệu MNIST trước khi chúng tôi bắt đầu thử nghiệm.
Trong tệp này, tất cả những gì chúng ta cần làm là nhập dữ liệu, xây dựng mạng với kích thước lớp đầu vào là 784 và kích thước lớp đầu ra là 10, chạy chức năng SGD của mạng trên dữ liệu đào tạo, sau đó kiểm tra nó bằng cách sử dụng dữ liệu thử nghiệm.
Hãy nhớ rằng đối với danh sách các lớp đầu vào của chúng ta, không có gì khác biệt so với bất kỳ con số nào nằm trong khoảng từ 784 đến 10. Chúng ta có thể thay đổi các lớp khác theo bất kỳ cách nào chúng ta muốn; chỉ có kích thước đầu vào và đầu ra là cố định.
Ba lớp là không cần thiết; chúng ta có thể sử dụng bốn, năm hoặc thậm chí chỉ hai. Hãy thử nghiệm vui vẻ với nó.
Kết luận
Ở đây, bằng cách sử dụng Python 3, chúng tôi tạo một mạng nơ-ron từ đầu. Cùng với toán cấp cao, chúng tôi cũng thảo luận về các chi tiết cụ thể của việc thực hiện.
Chúng tôi đã bắt đầu bằng cách triển khai các chức năng trợ giúp. Để các tế bào thần kinh hoạt động, các chức năng chính của sigmoid và sigmoid là rất quan trọng. Sau đó, chúng tôi đưa vào thực tế chức năng truyền tải dữ liệu, đây là quy trình cơ bản để cung cấp dữ liệu vào mạng nơ-ron.
Tiếp theo, chúng tôi đã tạo chức năng giảm độ dốc trong Python, công cụ điều khiển mạng thần kinh của chúng tôi. Để xác định vị trí “cực tiểu cục bộ” và tối ưu hóa trọng số cũng như độ lệch của chúng, mạng nơ-ron của chúng tôi sử dụng phương pháp giảm dần độ dốc. Chúng tôi đã tạo chức năng lan truyền ngược bằng cách sử dụng xuống dốc.
Bằng cách cung cấp các bản cập nhật khi đầu ra không khớp với các nhãn thích hợp, chức năng này cho phép mạng nơ-ron “học”.
Cuối cùng, chúng tôi đặt Python hoàn toàn mới của mình mạng lưới thần kinh để kiểm tra bằng cách sử dụng tập dữ liệu MNIST. Mọi thứ hoạt động trơn tru.
Chúc bạn mã hóa vui vẻ!
Bình luận