Một ví dụ về mạng nơron trong mã Python. Python và mạng lưới thần kinh

  • Dịch

Bài viết nói về cái gì?

Cá nhân tôi học tốt nhất với mã làm việc nhỏ mà tôi có thể sử dụng. Trong hướng dẫn này, chúng ta sẽ tìm hiểu thuật toán lan truyền ngược bằng cách sử dụng mạng thần kinh nhỏ được triển khai bằng Python làm ví dụ.

Đưa tôi mã số!

X = np.array([ ,,, ]) y = np.array([]).T syn0 = 2*np.random.random((3,4)) - 1 syn1 = 2*np.random.random ((4,1)) - 1 cho j trong xrange(60000): l1 = 1/(1+np.exp(-(np.dot(X,syn0)))) l2 = 1/(1+np. exp(-(np.dot(l1,syn1)))) l2_delta = (y - l2)*(l2*(1-l2)) l1_delta = l2_delta.dot(syn1.T) * (l1 * (1-l1 )) syn1 += l1.T.dot(l2_delta) syn0 += X.T.dot(l1_delta)

Quá nén? Hãy chia nó thành những phần đơn giản hơn.

Phần 1: Mạng nơ-ron đồ chơi nhỏ

Mạng nơ-ron được đào tạo thông qua lan truyền ngược nhằm sử dụng dữ liệu đầu vào để dự đoán dữ liệu đầu ra.

Giả sử chúng ta cần dự đoán cột đầu ra sẽ trông như thế nào dựa trên dữ liệu đầu vào. Vấn đề này có thể được giải quyết bằng cách tính toán sự tương ứng thống kê giữa chúng. Và chúng ta sẽ thấy rằng cột bên trái tương quan 100% với đầu ra.

Trên thực tế, lan truyền ngược trường hợp đơn giản, tính toán số liệu thống kê tương tự để tạo mô hình. Hãy thử.

Mạng nơ-ron hai lớp

import numpy as np # Sigmoid def nonlin(x,deriv=False): if(deriv==True): return f(x)*(1-f(x)) return 1/(1+np.exp(-x )) # tập dữ liệu đầu vào X = np.array([ , , , ]) # dữ liệu đầu ra y = np.array([]).T # do Số ngẫu nhiên cụ thể hơn np.random.seed(1) # khởi tạo trọng số ngẫu nhiên với trung bình 0 syn0 = 2*np.random.random((3,1)) - 1 for iter in xrange(10000): # lan truyền thuận l0 = X l1 = nonlin(np.dot(l0,syn0)) # chúng ta đã sai như thế nào? l1_error = y - l1 # nhân số này với độ dốc của sigmoid # dựa trên các giá trị trong l1 l1_delta = l1_error * nonlin(l1,True) # !!! # cập nhật trọng số syn0 += np.dot(l0.T,l1_delta) # !!! print "Kết quả sau khi huấn luyện:" print l1

Đầu ra sau khi đào tạo: [[ 0,00966449] [ 0,00786506] [ 0,99358898] [ 0,99211957]]

Các biến và mô tả của chúng.






"*" - phép nhân theo phần tử - hai vectơ có cùng kích thước nhân các giá trị tương ứng và đầu ra là một vectơ có cùng kích thước
"-" – phép trừ vectơ theo phần tử
x.dot(y) – nếu x và y là vectơ thì đầu ra sẽ là tích vô hướng. Nếu đây là ma trận thì kết quả là phép nhân ma trận. Nếu ma trận chỉ là một trong số đó thì đó là phép nhân của một vectơ và một ma trận.

  • so sánh l1 sau lần lặp đầu tiên và sau lần lặp cuối cùng
  • nhìn vào hàm nonlin.
  • hãy xem l1_error thay đổi như thế nào
  • dòng phân tích 36 - các thành phần bí mật chính được thu thập ở đây (được đánh dấu!!!)
  • dòng phân tích 39 - toàn bộ mạng đang chuẩn bị chính xác cho thao tác này (được đánh dấu!!!)

Hãy chia nhỏ từng dòng mã

nhập numpy dưới dạng np

Nhập numpy, một thư viện đại số tuyến tính. Chứng nghiện duy nhất của chúng tôi.

Def nonlin(x,deriv=False):

Tính phi tuyến của chúng tôi. Hàm đặc biệt này tạo ra một “sigmoid”. Nó khớp với bất kỳ số nào có giá trị từ 0 đến 1 và chuyển đổi số thành xác suất, đồng thời có một số thuộc tính khác hữu ích cho việc đào tạo mạng lưới thần kinh.

Nếu(đạo hàm==Đúng):

Hàm này cũng có thể tạo ra đạo hàm của sigmoid (deriv=True). Đây là một trong những cái của cô ấy đặc tính có lợi. Nếu đầu ra của hàm là biến out thì đạo hàm sẽ là out * (1-out). Hiệu quả.

X = np.array([ , …

Đang khởi tạo mảng dữ liệu đầu vào dưới dạng ma trận gọn gàng. Mỗi dòng là một ví dụ đào tạo. Cột là các nút đầu vào. Chúng tôi kết thúc với 3 nút đầu vào trong mạng và 4 ví dụ đào tạo.

Y = np.array([]).T

Khởi tạo dữ liệu đầu ra. ".T" – hàm truyền. Sau khi dịch, ma trận y có 4 hàng một cột. Giống như dữ liệu đầu vào, mỗi hàng là một ví dụ huấn luyện và mỗi cột (trong trường hợp của chúng tôi là một cột) là một nút đầu ra. Hóa ra mạng có 3 đầu vào và 1 đầu ra.

Np.random.seed(1)

Nhờ đó, việc phân phối ngẫu nhiên sẽ giống nhau ở mọi thời điểm. Điều này sẽ cho phép chúng tôi giám sát mạng dễ dàng hơn sau khi thực hiện các thay đổi đối với mã.

Syn0 = 2*np.random.random((3,1)) – 1

Ma trận trọng số mạng. syn0 có nghĩa là "khớp thần kinh số 0". Vì chúng ta chỉ có hai lớp, đầu vào và đầu ra, nên chúng ta cần một ma trận trọng số để kết nối chúng. Kích thước của nó là (3, 1), vì chúng ta có 3 đầu vào và 1 đầu ra. Nói cách khác, l0 có kích thước 3 và l1 có kích thước 1. Vì chúng ta đang kết nối tất cả các nút trong l0 với tất cả các nút trong l1, nên chúng ta cần một ma trận có chiều (3, 1).

Lưu ý rằng nó được khởi tạo ngẫu nhiên và giá trị trung bình bằng 0. Có một lý thuyết khá phức tạp đằng sau điều này. Hiện tại chúng tôi sẽ chỉ coi đây là một đề xuất. Cũng lưu ý rằng mạng lưới thần kinh của chúng ta chính là ma trận này. Chúng tôi có "lớp" l0 và l1, nhưng đây là các giá trị tạm thời dựa trên tập dữ liệu. Chúng tôi không lưu trữ chúng. Tất cả đào tạo được lưu trữ trong syn0.

Đối với lần lặp trong xrange (10000):

Đây là nơi mã đào tạo mạng chính bắt đầu. Vòng mã được lặp lại nhiều lần và tối ưu hóa mạng cho tập dữ liệu.

Lớp đầu tiên, l0, chỉ là dữ liệu. X chứa 4 mẫu huấn luyện. Chúng tôi sẽ xử lý tất cả chúng cùng một lúc - đây được gọi là đào tạo nhóm. Tổng cộng chúng ta có 4 dòng l0 khác nhau, nhưng chúng có thể được coi là một ví dụ đào tạo - ở giai đoạn này điều đó không thành vấn đề (bạn có thể tải 1000 hoặc 10000 dòng trong số đó mà không có bất kỳ thay đổi nào trong mã).

L1 = nonlin(np.dot(l0,syn0))

Đây là bước dự đoán. Chúng tôi để mạng cố gắng dự đoán đầu ra dựa trên đầu vào. Sau đó, chúng ta sẽ xem cô ấy làm như thế nào để có thể điều chỉnh nó để cải thiện.

Có hai bước trên mỗi dòng. Cái đầu tiên thực hiện phép nhân ma trận của l0 và syn0. Cái thứ hai chuyển đầu ra qua sigmoid. Kích thước của chúng như sau:

(4 x 3) chấm (3 x 1) = (4 x 1)

Phép nhân ma trận yêu cầu các kích thước ở giữa phương trình phải giống nhau. Ma trận cuối cùng có cùng số hàng với ma trận đầu tiên và cùng số cột với ma trận thứ hai.

Chúng tôi đã tải 4 ví dụ đào tạo và nhận được 4 lần đoán (ma trận 4x1). Mỗi đầu ra tương ứng với dự đoán của mạng đối với một đầu vào nhất định.

L1_error = y - l1

Vì l1 chứa các dự đoán nên chúng ta có thể so sánh sự khác biệt của chúng với thực tế bằng cách trừ l1 khỏi câu trả lời đúng y. l1_error – vectơ dương và số âm, đặc trưng cho sự “bỏ lỡ” của mạng.

Và đây là thành phần bí mật. Dòng này cần được phân tích từng phần một.

Phần thứ nhất: phái sinh

Nonlin(l1,True)

L1 đại diện cho ba điểm này và mã tạo ra độ dốc của các đường hiển thị bên dưới. Lưu ý rằng khi giá trị lớn như x=2.0 (chấm màu xanh lá cây) và những đường rất nhỏ như x=-1.0 (màu tím) có độ dốc nhẹ. Góc lớn nhất tại điểm x=0 (màu xanh). Nó có tầm quan trọng lớn. Cũng lưu ý rằng tất cả các dẫn xuất nằm trong khoảng từ 0 đến 1.

Biểu thức đầy đủ: đạo hàm có trọng số lỗi

L1_delta = l1_error * nonlin(l1,True)

Về mặt toán học có nhiều hơn cách chính xác, nhưng trong trường hợp của chúng tôi cái này cũng phù hợp. l1_error là ma trận (4,1). nonlin(l1,True) trả về ma trận (4,1). Ở đây chúng ta nhân chúng với từng phần tử và ở đầu ra chúng ta cũng thu được ma trận (4.1), l1_delta.

Bằng cách nhân đạo hàm với sai số, chúng tôi giảm thiểu sai sót trong các dự đoán được đưa ra với độ tin cậy cao. Nếu độ dốc của đường nhỏ thì mạng chứa giá trị rất lớn hoặc rất nhỏ. Nếu dự đoán của mạng gần bằng 0 (x=0, y=0,5) thì mạng đó không có độ tin cậy đặc biệt. Chúng tôi cập nhật những dự đoán không chắc chắn này và chỉ để lại những dự đoán có độ tin cậy cao bằng cách nhân chúng với các giá trị gần bằng 0.

Syn0 += np.dot(l0.T,l1_delta)

Chúng tôi đã sẵn sàng cập nhật mạng. Hãy xem xét một ví dụ đào tạo. Trong đó chúng tôi sẽ cập nhật trọng số. Cập nhật trọng lượng ngoài cùng bên trái (9,5)

Trọng lượng_update = giá trị đầu vào * l1_delta

Đối với trọng lượng ngoài cùng bên trái, nó sẽ là 1,0 * l1_delta. Có lẽ điều này sẽ chỉ tăng 9,5 một chút. Tại sao? Bởi vì dự đoán đã khá tự tin và trên thực tế những dự đoán đó đã chính xác. Một lỗi nhỏ và độ dốc nhẹ của đường có nghĩa là một bản cập nhật rất nhỏ.

Nhưng vì chúng ta đang thực hiện huấn luyện nhóm nên chúng ta lặp lại bước trên cho cả bốn ví dụ huấn luyện. Vì vậy, nó trông rất giống với hình ảnh trên. Vậy đường dây của chúng tôi làm gì? Nó đếm số lần cập nhật trọng lượng cho từng mức tạ, cho từng ví dụ tập luyện, tổng hợp chúng và cập nhật tất cả trọng lượng - tất cả trên một dòng.

Sau khi quan sát cập nhật mạng, hãy quay lại dữ liệu đào tạo của chúng tôi. Khi cả đầu vào và đầu ra đều bằng 1, chúng ta tăng trọng số giữa chúng. Khi đầu vào là 1 và đầu ra là 0, chúng ta giảm trọng số.

Đầu vào Đầu ra 0 0 1 0 1 1 1 1 1 0 1 1 0 1 1 0

Vì vậy, trong bốn ví dụ huấn luyện dưới đây của chúng tôi, trọng số của đầu vào đầu tiên so với đầu ra sẽ tăng hoặc không đổi, còn hai trọng số còn lại sẽ tăng và giảm tùy thuộc vào ví dụ. Hiệu ứng này góp phần vào việc học mạng dựa trên mối tương quan giữa dữ liệu đầu vào và đầu ra.

Phần 2: một nhiệm vụ khó khăn hơn

Đầu vào Đầu ra 0 0 1 0 0 1 1 1 1 0 1 1 1 1 1 0

Hãy thử dự đoán dữ liệu đầu ra trên dựa trên ba cột dữ liệu đầu vào. Không có cột đầu vào nào tương quan 100% với đầu ra. Cột thứ ba hoàn toàn không được kết nối với bất kỳ thứ gì vì nó chứa tất cả các cột. Tuy nhiên, ở đây bạn có thể thấy mẫu - nếu một trong hai cột đầu tiên (nhưng không phải cả hai cùng một lúc) chứa 1, thì kết quả cũng sẽ bằng 1.

Đây là thiết kế phi tuyến tính vì không có sự tương ứng trực tiếp một-một giữa các cột. Việc so khớp dựa trên sự kết hợp của các yếu tố đầu vào, cột 1 và 2.

Điều thú vị là nhận dạng mẫu là một nhiệm vụ rất giống nhau. Nếu bạn có 100 bức ảnh cùng cỡ, mô tả xe đạp và tẩu thuốc, sự hiện diện của một số pixel nhất định ở một số vị trí nhất định trên chúng không tương quan trực tiếp với sự hiện diện của xe đạp hoặc tẩu thuốc trong ảnh. Theo thống kê, màu sắc của chúng có thể xuất hiện ngẫu nhiên. Nhưng một số kết hợp pixel không phải là ngẫu nhiên - những kết hợp tạo thành hình ảnh của một chiếc xe đạp (hoặc ống).


Chiến lược

Để kết hợp các pixel thành một thứ có thể tương ứng một-một với đầu ra, bạn cần thêm một lớp khác. Lớp đầu tiên kết hợp đầu vào, lớp thứ hai gán kết quả khớp với đầu ra bằng cách sử dụng đầu ra của lớp thứ nhất làm đầu vào. Hãy chú ý đến cái bàn.

Đầu vào (l0) Trọng số ẩn (l1) Đầu ra (l2) 0 0 1 0,1 0,2 0,5 0,2 0 0 1 1 0,2 0,6 0,7 0,1 1 1 0 1 0,3 0,2 0,3 0,9 1 1 1 1 0,2 0,1 0,3 0,8 0

Ngẫu nhiên Bằng cách gán trọng số, chúng ta sẽ nhận được các giá trị ẩn cho lớp số 1. Điều thú vị là cột thứ hai trọng lượng ẩnđã có một mối tương quan nhỏ với sản lượng. Không lý tưởng, nhưng ở đó. Và đây cũng là phần quan trọng quá trình huấn luyện mạng. Đào tạo sẽ chỉ tăng cường mối tương quan này. Nó sẽ cập nhật syn1 để gán ánh xạ của nó cho dữ liệu đầu ra và syn0 để thu được dữ liệu đầu vào tốt hơn.

Mạng nơ-ron ba lớp

nhập numpy dưới dạng np def nonlin(x,deriv=False): if(deriv==True): return f(x)*(1-f(x)) return 1/(1+np.exp(-x)) X = np.array([, , , ]) y = np.array([, , , ]) np.random.seed(1) # khởi tạo ngẫu nhiên các trọng số, trung bình - 0 syn0 = 2*np.random. ngẫu nhiên ((3,4)) - 1 syn1 = 2*np.random.random((4,1)) - 1 for j in xrange(60000): # đi tiếp qua các lớp 0, 1 và 2 l0 = X l1 = nonlin(np.dot(l0,syn0)) l2 = nonlin(np.dot(l1,syn1)) # chúng ta đã sai bao nhiêu về giá trị bắt buộc? l2_error = y - l2 if (j% 10000) == 0: print "Error:" + str(np.mean(np.abs(l2_error))) # bạn nên di chuyển theo hướng nào? # nếu chúng ta tin tưởng vào dự đoán thì không cần thay đổi nhiều l2_delta = l2_error*nonlin(l2,deriv=True) # các giá trị của l1 ảnh hưởng đến các lỗi trong l2 đến mức nào? l1_error = l2_delta.dot(syn1.T) # chúng ta nên di chuyển theo hướng nào để đến l1? # nếu đã tự tin vào dự đoán thì không cần thay đổi nhiều l1_delta = l1_error * nonlin(l1,deriv=True) syn1 += l1.T.dot(l2_delta) syn0 += l0.T.dot (l1_delta)

Lỗi: 0,496410031903 Lỗi: 0,00858452565325 Lỗi: 0,00578945986251 Lỗi: 0,00462917677677 Lỗi: 0,00395876528027 Lỗi: 0,00351012256786

Các biến và mô tả của chúng

X là ma trận của tập dữ liệu đầu vào; chuỗi - ví dụ đào tạo
y – ma trận của tập dữ liệu đầu ra; chuỗi - ví dụ đào tạo
l0 – lớp mạng đầu tiên được xác định bởi dữ liệu đầu vào
l1 – lớp thứ hai của mạng hoặc lớp ẩn
l2 là lớp cuối cùng, đây là giả thuyết của chúng tôi. Khi luyện tập, bạn sẽ tiến gần hơn đến câu trả lời đúng.
syn0 – lớp trọng số đầu tiên, Synapse 0, kết hợp l0 với l1.
syn1 – Lớp trọng số thứ hai, Synapse 1, kết hợp l1 với l2.
l2_error – lỗi mạng về mặt định lượng
l2_delta – lỗi mạng, tùy thuộc vào độ tin cậy của dự đoán. Hầu như giống hệt với lỗi, ngoại trừ những dự đoán tự tin
l1_error – bằng cách cân l2_delta với các trọng số từ syn1, chúng tôi tính toán lỗi ở lớp giữa/ẩn
l1_delta – lỗi mạng từ l1, được chia tỷ lệ theo độ tin cậy của dự đoán. Gần giống với l1_error, ngoại trừ những dự đoán chắc chắn

Mã phải khá rõ ràng - đó chỉ là quá trình triển khai mạng trước đó, được xếp thành hai lớp, lớp này chồng lên lớp kia. Đầu ra của lớp thứ nhất l1 là đầu vào của lớp thứ hai. Có một cái gì đó mới chỉ ở dòng tiếp theo.

L1_error = l2_delta.dot(syn1.T)

Sử dụng sai số được tính theo độ tin cậy của dự đoán từ l2 để tính sai số cho l1. Người ta có thể nói, chúng tôi nhận được một lỗi được tính theo mức độ đóng góp - chúng tôi tính toán xem các giá trị tại các nút l1 đóng góp bao nhiêu vào các lỗi trong l2. Bước này được gọi là lan truyền ngược. Sau đó, chúng tôi cập nhật syn0 bằng thuật toán tương tự như mạng nơ-ron hai lớp.

Phần này chứa các liên kết đến các bài viết từ RuNet về mạng lưới thần kinh là gì. Nhiều bài viết được viết bằng ngôn ngữ nguyên bản, sinh động và rất dễ hiểu. Tuy nhiên, ở đây, phần lớn chỉ xem xét những điều cơ bản nhất, những thiết kế đơn giản nhất. Tại đây bạn cũng có thể tìm thấy các liên kết đến tài liệu trên mạng lưới thần kinh. Sách giáo khoa và sách, lẽ ra phải như vậy, được viết bằng ngôn ngữ học thuật hoặc ngôn ngữ tương tự và chứa các ví dụ trừu tượng, khó hiểu về việc xây dựng mạng lưới thần kinh, quá trình đào tạo của chúng, v.v. Cần lưu ý rằng thuật ngữ trong các bài viết khác nhau “nổi” cũng như có thể được nhìn thấy từ các ý kiến ​​​​đến các bài viết. Bởi vì điều này, lúc đầu có thể có một “lộn xộn trong đầu”.

  • Cách một nông dân Nhật Bản sắp xếp dưa chuột bằng cách sử dụng deep learning và TensorFlow
  • Mạng lưới thần kinh trong hình ảnh: từ một nơron đơn lẻ đến kiến ​​trúc sâu
  • Một ví dụ về chương trình mạng nơron với mã nguồn bằng C++.
  • Triển khai mạng nơ-ron một lớp - perceptron cho bài toán phân loại phương tiện
  • Tải sách về mạng lưới thần kinh. Khỏe mạnh!
  • Công nghệ thị trường chứng khoán: 10 quan niệm sai lầm về mạng lưới thần kinh
  • Thuật toán huấn luyện mạng nơron nhiều lớp bằng phương pháp lan truyền ngược

Mạng lưới thần kinh trong Python

Bạn có thể đọc ngắn gọn về những thư viện tồn tại cho Python. Từ đây tôi sẽ lấy các ví dụ kiểm tra để đảm bảo rằng gói yêu cầu được cài đặt chính xác.

dòng chảy căng thẳng

Đối tượng trung tâm của TensorFlow là biểu đồ luồng dữ liệu biểu thị quá trình tính toán. Các đỉnh của đồ thị biểu thị các phép toán và các cạnh biểu thị các tensor (tensor) ( mảng đa chiều, là cơ sở của TensorFlow). Toàn bộ biểu đồ luồng dữ liệu là mô tả đầy đủ các phép tính được triển khai trong một phiên và được thực hiện trên các thiết bị (CPU hoặc GPU). Giống như nhiều người khác hệ thống hiện đạiĐối với tính toán khoa học và học máy, TensorFlow có API được ghi chép đầy đủ cho Python, trong đó các tensor được biểu diễn dưới dạng mảng NumPy ndarray quen thuộc. TensorFlow thực hiện các phép tính bằng cách sử dụng C++ được tối ưu hóa cao và cũng hỗ trợ các API gốc cho C và C++.
  • Giới thiệu về học máy với tensorflow. Cho đến nay, chỉ có bài báo đầu tiên trong số bốn bài được công bố đã được xuất bản.
  • TensorFlow thật đáng thất vọng. Deep learning của Google thiếu "chiều sâu"
  • Sơ lược về học máy: Phân loại văn bản với Mạng thần kinh và TensorFlow
  • Thư viện máy học Google TensorFlow – ấn tượng đầu tiên và so sánh với cách triển khai của chúng tôi

Việc cài đặt tensorflow được mô tả rõ ràng trong bài viết ở liên kết đầu tiên. Tuy nhiên, Python 3.6.1 hiện đã được phát hành. Sẽ không thể sử dụng được nó. Ít nhất có lưu huỳnh trên khoảnh khắc này(03/06/2017). Yêu cầu phiên bản 3.5.3, có thể tải xuống. Dưới đây tôi sẽ đưa ra trình tự phù hợp với tôi (hơi khác một chút so với bài viết của Habr). Không rõ tại sao, nhưng Python 64-bit được tạo ra cho bộ xử lý AMD theo đó, mọi thứ khác đều đi theo nó. Sau khi cài đặt Phyton, đừng quên thiết lập quyền truy cập đầy đủ cho người dùng nếu Python được cài đặt cho tất cả mọi người.

cài đặt pip -- nâng cấp pip
cài đặt pip -U công cụ thiết lập pip
cài đặt pip3 - nâng cấp tenorflow
cài đặt pip3 -- nâng cấp tensorflow-gpu
pip install matplotlib /*Tải xuống 8,9 MB và một vài tệp nhỏ khác */
pip cài đặt jupyter

"Trăn khỏa thân" có vẻ không thú vị. Vì vậy, dưới đây là hướng dẫn cài đặt trong môi trường Anaconda. Đây là một bản dựng thay thế. Python đã được tích hợp vào nó.

Trang web lại giới thiệu phiên bản mới dành cho Python 3.6 mà sản phẩm mới của Google chưa hỗ trợ. Vì vậy, tôi đã ngay lập tức lấy một phiên bản cũ hơn từ kho lưu trữ, cụ thể là Anaconda3-4.2.0 - nó phù hợp. Đừng quên chọn hộp đăng ký Python 3.5. Cụ thể, trước khi cài đặt Anaconda, tốt hơn hết bạn nên đóng terminal, nếu không nó sẽ tiếp tục hoạt động với PATH lỗi thời. Ngoài ra, đừng quên thay đổi quyền truy cập của người dùng, nếu không sẽ không có gì hiệu quả.

conda tạo -n tenorflow
kích hoạt dòng chảy căng
cài đặt pip --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/windows/cpu/tensorflow-1.1.0-cp35-cp35m-win_amd64.whl /*Đã tải xuống từ Internet 19,4 MB, sau đó là 7 MB , 7 MB và 0,317 MB khác*/
cài đặt pip --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/windows/gpu/tensorflow_gpu-1.1.0-cp35-cp35m-win_amd64.whl /*Tải xuống 48,6 MB */

Ảnh chụp màn hình cài đặt: mọi thứ đều diễn ra tốt đẹp ở Anaconda.

Tương tự như vậy với tập tin thứ hai.

Chà, tóm lại: để tất cả những thứ này hoạt động, bạn cần cài đặt gói CUDA Toolkits từ NVIDEA (trong trường hợp sử dụng GPU). Phiên bản được hỗ trợ hiện tại là 8.0. Bạn cũng sẽ cần tải xuống và giải nén thư viện cuDNN v5.1 vào thư mục CUDA, nhưng không được nữa phiên bản mới! Sau tất cả các thao tác này, TensorFlow sẽ hoạt động.

Theano

  • Mạng lưới thần kinh định kỳ gồm 10 dòng mã đã đánh giá phản hồi từ người xem tập mới của “Chiến tranh giữa các vì sao”

Gói Theano được bao gồm trong PyPI của Python. Bản thân nó nhỏ - 3,1 MB, nhưng nó kéo thêm 15 MB phụ thuộc - scipy. Để cài đặt cái sau, bạn cũng cần có mô-đun lapack... Nói chung, cài đặt gói theano trong Windows sẽ có nghĩa là “nhảy múa với tambourine”. Dưới đây tôi sẽ cố gắng hiển thị chuỗi hành động để gói hoạt động.

Khi sử dụng Anaconda, việc "nhảy múa với tambourine" trong quá trình cài đặt là không liên quan. Lệnh là đủ:

conda cài đặt theano

và quá trình này diễn ra tự động. Nhân tiện, các gói GCC cũng được tải.

Scikit-Tìm hiểu

Trong Python 3.5.3, chỉ hơn phiên bản đầu 0.17.1 mà bạn có thể lấy. Có một trình cài đặt bình thường. Tuy nhiên, nó sẽ không hoạt động trực tiếp trong Windows - bạn cần có thư viện scipy.

Cài đặt gói trợ giúp

Để hai gói trên hoạt động (chúng ta đang nói về Phyton “trần trụi”), bạn cần thực hiện một số bước sơ bộ.

khoa học viễn tưởng

Để khởi chạy Scikit-Learn và Theano, như đã nói rõ ở trên, bạn sẽ cần phải “nhảy với tambourine”. Điều đầu tiên Yandex mang lại cho chúng ta là một kho trí tuệ, mặc dù bằng tiếng Anh, tài nguyên stackoverflow.com, nơi chúng ta tìm thấy liên kết đến kho lưu trữ tuyệt vời của hầu hết tất cả các gói Python hiện có được biên dịch cho Windows - lfd.uci.edu

Tại đây có các tập hợp sẵn sàng để cài đặt của các gói mà bạn hiện đang quan tâm, được biên dịch cho phiên bản khác nhau Trăn. Trong trường hợp của chúng tôi, cần có phiên bản tệp, chứa dòng "-cp35-win_amd64" trong tên của nó vì đây chính xác là những gì Gói Pythonđã được sử dụng để cài đặt. Trên stakowerflow, nếu tìm kiếm, bạn cũng có thể tìm thấy “hướng dẫn” cài đặt các gói cụ thể của chúng tôi.

cài đặt pip -- nâng cấp -- bỏ qua cài đặt http://www.lfd.uci.edu/~gohlke/pythonlibs/vu0h7y4r/numpy-1.12.1+mkl-cp35-cp35m-win_amd64.whl
cài đặt pip -- nâng cấp -- bỏ qua http://www.lfd.uci.edu/~gohlke/pythonlibs/vu0h7y4r/scipy-0.19.0-cp35-cp35m-win_amd64.whl
pip --upgrade --ignore-cài đặt gấu trúc
cài đặt pip -- nâng cấp -- bỏ qua matplotlib đã cài đặt

Hai gói mới nhất phát sinh trong chuỗi của tôi vì việc người khác “khiêu vũ với trống lục lạc”. Tôi không nhận thấy chúng trong phần phụ thuộc của các gói đã cài đặt, nhưng rõ ràng một số thành phần của chúng cần thiết cho quá trình cài đặt thông thường.

Lapack/Blas

Cần có hai thư viện cấp thấp liên quan này, được viết bằng Fortran, để cài đặt gói Theano. Scikit-Learn cũng có thể hoạt động trên những gói đã được cài đặt “ẩn” trong các gói khác (xem ở trên). Trên thực tế, nếu Theano phiên bản 0.17 được cài đặt từ tệp exe, nó cũng sẽ hoạt động. Ít nhất là ở Anaconda. Tuy nhiên, những thư viện này cũng có thể được tìm thấy trên Internet. Ví dụ . Các bản dựng gần đây hơn. Để gói hoàn thiện có thể hoạt động phiên bản trước Nó phù hợp. Xây dựng một gói mới sẽ yêu cầu các phiên bản mới.

Cũng cần lưu ý rằng trong bản dựng Anaconda hoàn toàn mới, gói Theano được cài đặt dễ dàng hơn nhiều - chỉ với một lệnh, nhưng thành thật mà nói, tôi không quan tâm ở giai đoạn này(không) làm chủ mạng lưới thần kinh, tôi thích TensorFlow hơn, nhưng nó vẫn chưa thân thiện với các phiên bản Python mới.

Một số bạn gần đây có thể đã tham gia các khóa học của Stanford, đặc biệt là ai-class và ml-class. Tuy nhiên, việc xem một số bài giảng video, trả lời các câu hỏi trắc nghiệm và viết hàng tá chương trình trong Matlab / Octave là một việc. dụng kiến ​​thức đã học vào thực tế. Để kiến ​​thức nhận được từ Andrew Ng không đọng lại trong góc tối trong não tôi, nơi dft, Thuyết tương đối đặc biệt và Phương trình Lagrange của Euler, tôi quyết định không lặp lại những sai lầm của viện và trong khi kiến ​​thức vẫn còn mới mẻ trong trí nhớ của tôi, hãy luyện tập càng nhiều càng tốt.

Và ngay sau đó DDoS đã xuất hiện trên trang web của chúng tôi. Có thể chống lại nó bằng các phương pháp quản trị/lập trình (grep/awk/etc) hoặc sử dụng công nghệ học máy.

Một ví dụ về xây dựng từ điển và vectơ đặc trưng

Giả sử chúng ta huấn luyện mạng lưới thần kinh của mình chỉ với hai ví dụ: một tốt và một xấu. Sau đó, chúng tôi sẽ thử kích hoạt nó trên bản ghi thử nghiệm.

Mục nhập từ nhật ký "xấu":
0.0.0.0 - - "POST /forum/index.php HTTP/1.1" 503 107 "http://www.mozilla-europe.org/" "-"

Mục nhập từ nhật ký “tốt”:
0.0.0.0 - - "GET /forum/rss.php?topic=347425 HTTP/1.0" 200 1685 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9) Gecko/2008052906 Firefox/ 3.0"

Từ điển kết quả:
["__UA___OS_U", "__UA_EMPTY", "__REQ___METHOD_POST", "__REQ___HTTP_VER_HTTP/1.0", "__REQ___URL___NETLOC_", "__REQ___URL___PATH_/forum/rss.php", "__REQ___URL___PATH_/forum/index.php", "__REQ___URL___SCHEME_ ", "__REQ___HTTP_VER_HTTP/ 1.1 "," __ua ___ Ver_firefox/3.0 "," __refer___netloc_www.mozilla-europe.org "," __ua___os_windows "," __ua ___mozilla/5.0 "," __code_503 "," __ua___os_os l "," __refer ___ path_/"," __refer___scheme_http "," __no_refer__ ", "__REQ___METHOD_GET", "__UA___OS_Windows NT 5.1", "__UA___OS_rv:1.9", "__REQ___URL___QS_topic", "__UA___VER_Gecko/2008052906"]

Ghi thử nghiệm:
0.0.0.0 - - "GET /forum/viewtopic.php?t=425550 HTTP/1.1" 502 107 "-" "BTWebClient/3000(25824)"

Vector đặc trưng của nó:

Lưu ý mức độ "thưa thớt" của vectơ đặc trưng - hành vi này sẽ được quan sát cho tất cả các truy vấn.

Phân chia tập dữ liệu

Một cách thực hành tốt là chia tập dữ liệu thành nhiều phần. Tôi chia nó thành hai phần theo tỷ lệ 70/30:
  • Tập huấn luyện. Chúng tôi đào tạo mạng lưới thần kinh của chúng tôi trên đó.
  • Tập kiểm tra. Chúng tôi sử dụng nó để kiểm tra xem mạng lưới thần kinh của chúng tôi được đào tạo tốt như thế nào.
Sự phân chia này là do mạng nơ-ron có sai số huấn luyện nhỏ nhất (lỗi trên tập huấn luyện) sẽ tạo ra b lỗi lớn hơn đối với dữ liệu mới, bởi vì chúng tôi đã "đào tạo lại" mạng, làm sắc nét nó trong tập huấn luyện.
Trong tương lai, nếu phải chọn các hằng số tối ưu, tập dữ liệu sẽ cần được chia thành 3 phần theo tỷ lệ 60/20/20: Tập huấn luyện, Tập kiểm tra và Xác thực chéo. Cái sau sẽ dùng để chọn thông số tối ưu mạng lưới thần kinh (ví dụ như Weightdecay).

Mạng nơ-ron nói riêng

Bây giờ chúng ta không còn có bất kỳ nhật ký văn bản nào trong tay mà chỉ có ma trận từ các vectơ đặc trưng, ​​​​chúng ta có thể bắt đầu xây dựng mạng lưới thần kinh.

Hãy bắt đầu với việc chọn một cấu trúc. Tôi đã chọn một mạng gồm một lớp ẩn có kích thước gấp đôi lớp đầu vào. Tại sao? Thật đơn giản: đây là những gì Andrew Ng để lại trong trường hợp bạn không biết bắt đầu từ đâu. Tôi nghĩ bạn có thể tận dụng điều này trong tương lai bằng cách vẽ biểu đồ huấn luyện.
Hàm kích hoạt cho lớp ẩn là sigmoid chịu đựng lâu dài và lớp đầu ra là Softmax. Cái cuối cùng được chọn trong trường hợp nó phải được thực hiện
phân loại nhiều lớp với các lớp loại trừ lẫn nhau. Ví dụ: gửi yêu cầu “tốt” đến chương trình phụ trợ, yêu cầu “xấu” sẽ bị cấm trên tường lửa và yêu cầu “xám” để giải hình ảnh xác thực.

Mạng thần kinh có xu hướng đạt đến mức tối thiểu cục bộ, vì vậy trong mã của mình, tôi xây dựng một số mạng và chọn mạng có lỗi Kiểm tra nhỏ nhất (Lưu ý, đó là lỗi trên tập kiểm tra, không phải tập huấn luyện).

Tuyên bố miễn trừ trách nhiệm

Tôi không phải là thợ hàn thực sự. Tôi chỉ biết về Machine Learning những gì tôi đã học được từ ml-class và ai-class. Tôi bắt đầu lập trình bằng Python tương đối gần đây và đoạn mã bên dưới được viết trong khoảng 30 phút (thời gian, như bạn hiểu, đã hết) và sau đó chỉ được lưu một chút vào một tệp.

Ngoài ra, mã này không khép kín. Anh ấy vẫn cần một kịch bản khai thác. Ví dụ: nếu một IP thực hiện N yêu cầu xấu trong vòng X phút thì hãy cấm IP đó trên tường lửa.

Hiệu suất

  • lfu_cache. Được chuyển từ ActiveState để tăng tốc đáng kể việc xử lý các yêu cầu tần số cao. Mặt trái tăng tiêu dùng ký ức.
  • Tất nhiên, PyBrain được viết bằng python và do đó không nhanh lắm, tuy nhiên, nó có thể sử dụng mô-đun arac dựa trên ATLAS nếu bạn chỉ định Fast=True khi tạo mạng. Bạn có thể đọc thêm về điều này trong tài liệu PyBrain.
  • Song song hóa. Tôi đã đào tạo mạng lưới thần kinh của mình trên một máy chủ khá “dày” Nehalem, tuy nhiên, ngay cả ở đó cũng có những nhược điểm của đào tạo đơn luồng. Bạn có thể nghĩ về chủ đề đào tạo mạng lưới thần kinh song song. Một giải pháp đơn giản là đào tạo một số mạng lưới thần kinh trong đó. song song và chọn cái tốt nhất từ ​​​​chúng, nhưng điều này sẽ tạo thêm tải cho bộ nhớ, điều này cũng không tốt lắm. giải pháp phổ quát. Có lẽ sẽ hợp lý hơn khi viết lại mọi thứ trong C, vì toàn bộ cơ sở lý thuyết trong lớp ml đã bị nghiền nát.
  • Mức tiêu thụ bộ nhớ và số lượng tính năng. Tối ưu hóa bộ nhớ tốt là sự chuyển đổi từ mảng Python tiêu chuẩn sang mảng gọn gàng. Ngoài ra, việc giảm kích thước của từ điển và/hoặc sử dụng PCA có thể giúp ích rất nhiều, hãy nói thêm về điều đó bên dưới.

Cho tương lai

  • Các trường bổ sung trong nhật ký. Bạn có thể thêm nhiều thông tin khác vào nhật ký tổng hợp; bạn nên suy nghĩ xem trường nào sẽ giúp xác định bot. Có thể hợp lý khi tính đến octet đầu tiên của địa chỉ IP, vì trong một dự án web không phải quốc tế, rất có thể người dùng Trung Quốc là bot.

Lần này tôi quyết định học mạng lưới thần kinh. Tôi đã có thể có được những kỹ năng cơ bản về vấn đề này trong mùa hè và mùa thu năm 2015. Theo các kỹ năng cơ bản, ý tôi là tôi có thể tự tạo một mạng lưới thần kinh đơn giản ngay từ đầu. Bạn có thể tìm thấy các ví dụ trong kho GitHub của tôi. Trong bài viết này, tôi sẽ đưa ra một số giải thích và chia sẻ các tài nguyên mà bạn có thể thấy hữu ích trong quá trình học tập của mình.

Bước 1. Neuron và phương pháp tiếp liệu

Vậy “mạng lưới thần kinh” là gì? Chúng ta hãy chờ đợi điều này và xử lý một nơ-ron trước.

Một nơ-ron giống như một hàm: nó lấy một số giá trị làm đầu vào và trả về một giá trị.

Vòng tròn dưới đây tượng trưng nơ-ron nhân tạo. Nó nhận 5 và trả về 1. Đầu vào là tổng của ba khớp thần kinh được kết nối với nơ-ron (ba mũi tên ở bên trái).

Ở phía bên trái của hình ảnh chúng ta thấy 2 giá trị đầu vào ( Màu xanh lá) và offset (được đánh dấu màu nâu).

Dữ liệu đầu vào có thể là biểu diễn số của hai thuộc tính khác nhau. Ví dụ: khi tạo bộ lọc thư rác, chúng có thể có nghĩa là sự hiện diện của nhiều từ được viết bằng CHỮ HOA và sự hiện diện của từ "Viagra".

Các giá trị đầu vào được nhân với cái gọi là "trọng số" của chúng, 7 và 3 (được đánh dấu màu xanh lam).

Bây giờ chúng ta cộng các giá trị kết quả với phần bù và nhận được một số, trong trường hợp của chúng ta là 5 (được đánh dấu màu đỏ). Đây là đầu vào của nơ-ron nhân tạo của chúng tôi.

Sau đó, nơ-ron thực hiện một số phép tính và tạo ra giá trị đầu ra. Chúng tôi có 1 vì giá trị làm tròn của sigmoid tại điểm 5 là 1 (chúng ta sẽ nói về hàm này chi tiết hơn sau).

Nếu đây là một bộ lọc thư rác thì thực tế là đầu ra 1 có nghĩa là văn bản đã bị nơ-ron đánh dấu là thư rác.

Minh họa mạng lưới thần kinh từ Wikipedia.

Nếu bạn kết hợp các nơ-ron này, bạn sẽ có được một mạng lưới thần kinh lan truyền trực tiếp - quá trình đi từ đầu vào đến đầu ra, thông qua các nơ-ron được kết nối bằng các khớp thần kinh, như trong hình bên trái.

Bước 2. Sigmoid

Sau khi xem các bài học của Welch Labs, bạn nên xem lại Tuần 4 của khóa học máy học trên mạng thần kinh của Coursera để giúp bạn hiểu cách chúng hoạt động. Khóa học đi sâu vào toán học và dựa trên Octave, trong khi tôi thích Python hơn. Vì điều này mà tôi đã bỏ qua các bài tập và học được mọi thứ kiến thức cần thiết từ video.

Sigmoid chỉ ánh xạ giá trị của bạn (trên trục hoành) vào phạm vi từ 0 đến 1.

Ưu tiên hàng đầu của tôi là nghiên cứu sigmoid, vì nó đã xuất hiện trong nhiều khía cạnh của mạng lưới thần kinh. Tôi đã biết đôi điều về nó từ tuần thứ ba của khóa học nói trên nên tôi đã xem video từ đó.

Nhưng bạn sẽ không thể tiến xa chỉ với video. Để hiểu đầy đủ, tôi quyết định tự mình viết mã. Vì vậy, tôi bắt đầu viết phần triển khai thuật toán hồi quy logistic (sử dụng sigmoid).

Phải mất cả ngày và kết quả khó có thể như ý. Nhưng điều đó không thành vấn đề, vì tôi đã hiểu mọi thứ diễn ra như thế nào. Mã có thể được nhìn thấy.

Bạn không cần phải tự mình làm việc này vì nó đòi hỏi kiến ​​​​thức đặc biệt - điều chính là bạn hiểu cách hoạt động của sigmoid.

Bước 3. Phương pháp lan truyền ngược

Hiểu cách mạng nơ-ron hoạt động từ đầu vào đến đầu ra không phải là điều khó khăn. Việc hiểu cách mạng lưới thần kinh học từ các tập dữ liệu khó hơn nhiều. Nguyên tắc tôi đã sử dụng được gọi là

James Loy, Georgia Tech. Hướng dẫn dành cho người mới bắt đầu tạo mạng lưới thần kinh của riêng bạn bằng Python.

Động lực: tập trung vào kinh nghiệm cá nhân trong học tập học kĩ càng, Tôi quyết định tạo một mạng lưới thần kinh từ đầu mà không phức tạp thư viện giáo dục, chẳng hạn như, ví dụ, . Tôi tin rằng đối với một Nhà khoa học dữ liệu mới bắt đầu, điều quan trọng là phải hiểu cấu trúc bên trong.

Bài viết này chứa đựng những gì tôi đã học được và hy vọng nó cũng sẽ hữu ích cho bạn! Các bài viết hữu ích khác về chủ đề này:

Mạng lưới thần kinh là gì?

Hầu hết các bài viết về mạng lưới thần kinh đều có sự tương đồng với bộ não khi mô tả chúng. Tôi dễ dàng hơn khi mô tả mạng lưới thần kinh như hàm toán học, ánh xạ đầu vào nhất định tới đầu ra mong muốn mà không đi sâu vào chi tiết.

Mạng lưới thần kinh bao gồm các thành phần sau:

  • lớp đầu vào, x
  • số lượng tùy ý lớp ẩn
  • lớp đầu ra, ŷ
  • bộ dụng cụ quy môchuyển vị giữa mỗi lớp W b
  • lựa chọn cho từng lớp ẩn σ ; trong công việc này chúng tôi sẽ sử dụng hàm kích hoạt Sigmoid

Sơ đồ bên dưới thể hiện kiến ​​trúc của mạng nơ-ron hai lớp (lưu ý rằng lớp đầu vào thường bị loại trừ khi đếm số lớp trong mạng nơ-ron).

Tạo một lớp Mạng thần kinh trong Python rất đơn giản:

Đào tạo mạng lưới thần kinh

Lối ra ŷ Mạng nơ-ron hai lớp đơn giản:

Trong phương trình trên, trọng số W và độ lệch b là các biến duy nhất ảnh hưởng đến đầu ra ŷ.

Đương nhiên, các giá trị chính xác cho trọng số và độ lệch sẽ xác định độ chính xác của dự đoán. Quá trình tinh chỉnh trọng số và độ lệch từ dữ liệu đầu vào được gọi là .

Mỗi lần lặp lại của quá trình học tập bao gồm các bước sau

  • tính toán đầu ra dự đoán ŷ, được gọi là lan truyền thuận
  • cập nhật trọng số và độ lệch, được gọi là

Biểu đồ tuần tự dưới đây minh họa quá trình:

Phân phối trực tiếp

Như chúng ta đã thấy trong biểu đồ trên, việc lan truyền tiến chỉ là một phép tính đơn giản và đối với mạng nơ-ron 2 lớp cơ bản, đầu ra của mạng nơ-ron được cho bởi:

Hãy thêm hàm lan truyền thuận vào mã Python của chúng ta để thực hiện việc này. Lưu ý rằng để đơn giản, chúng tôi giả định độ lệch là 0.

Tuy nhiên, chúng tôi cần một cách để đánh giá mức độ “tốt” của các dự báo của mình, tức là dự báo của chúng tôi sai đến mức nào). Mất chức năng chỉ cho phép chúng tôi làm điều này.

Mất chức năng

Có nhiều chức năng có sẵn tổn thất và bản chất của vấn đề sẽ quyết định sự lựa chọn của chúng ta về hàm tổn thất. Trong công việc này chúng tôi sẽ sử dụng tổng các sai số bình phương như một hàm mất mát.

Tổng sai số bình phương là giá trị trung bình của chênh lệch giữa mỗi giá trị dự đoán và giá trị thực tế.

Mục tiêu của việc học là tìm ra một tập các trọng số và độ lệch làm giảm thiểu hàm mất mát.

Lan truyền ngược

Bây giờ chúng ta đã đo được sai số trong dự báo (mất mát), chúng ta cần tìm cách truyền lại lỗi và cập nhật trọng số và thành kiến ​​của chúng tôi.

Để biết mức độ thích hợp để điều chỉnh trọng số và độ lệch, chúng ta cần biết đạo hàm của hàm mất mát đối với trọng số và độ lệch.

Chúng ta hãy nhớ lại từ phân tích rằng Đạo hàm của hàm số là độ dốc của hàm số.

Nếu chúng ta có đạo hàm thì chúng ta có thể chỉ cần cập nhật trọng số và độ lệch bằng cách tăng/giảm chúng (xem sơ đồ ở trên). Nó được gọi là .

Tuy nhiên, chúng ta không thể tính trực tiếp đạo hàm của hàm mất mát theo trọng số và độ lệch vì phương trình hàm mất mát không chứa trọng số và độ lệch. Vì vậy, chúng ta cần một quy tắc dây chuyền để hỗ trợ tính toán.

Phù! Điều này thật phức tạp, nhưng nó cho phép chúng tôi có được những gì chúng tôi cần — đạo hàm (độ dốc) của hàm mất đối với các trọng số. Bây giờ chúng ta có thể điều chỉnh trọng số cho phù hợp.

Hãy thêm hàm lan truyền ngược vào mã Python của chúng ta:

Kiểm tra hoạt động của mạng lưới thần kinh

Bây giờ chúng tôi có mã đầy đủ trong Python để thực hiện lan truyền tiến và lùi, hãy xem mạng nơ-ron của chúng ta làm ví dụ và xem nó hoạt động như thế nào.


Bộ cân lý tưởng

Mạng lưới thần kinh của chúng ta phải học tập trọng số lý tưởng để biểu diễn hàm này.

Hãy huấn luyện mạng lưới thần kinh trong 1500 lần lặp và xem điều gì sẽ xảy ra. Nhìn vào biểu đồ tổn thất lặp lại bên dưới, chúng ta có thể thấy rõ rằng tổn thất giảm dần đến mức tối thiểu. Điều này phù hợp với thuật toán giảm độ dốc mà chúng ta đã thảo luận trước đó.

Hãy xem dự đoán cuối cùng (đầu ra) từ mạng lưới thần kinh sau 1500 lần lặp.

Chúng ta làm được rồi! Thuật toán lan truyền tiến và lan truyền ngược của chúng tôi đã chỉ ra rằng mạng thần kinh hoạt động thành công và các dự đoán hội tụ về giá trị thực.

Lưu ý rằng có một chút khác biệt giữa dự đoán và giá trị thực tế. Điều này là mong muốn vì nó ngăn chặn việc trang bị quá mức và cho phép mạng lưới thần kinh khái quát hóa tốt hơn đối với dữ liệu không nhìn thấy được.

suy nghĩ cuối cùng

Tôi đã học được rất nhiều điều trong quá trình viết mạng lưới thần kinh của riêng mình từ đầu. Mặc dù các thư viện học kĩ càng, chẳng hạn như TensorFlow và Keras, cho phép tạo mạng lưới sâu không có sự hiểu biết đầy đủ công việc nội bộ mạng lưới thần kinh, tôi thấy nó hữu ích cho những Nhà khoa học dữ liệu đầy tham vọng hiểu sâu hơn về chúng.

Tôi đã đầu tư rất nhiều thời gian cá nhân của mình vào công việc này, và tôi hy vọng bạn thấy nó hữu ích!