Mạng thần kinh Softmax từ đầu

Sổ ghi chép này tạo lại các thuật toán mạng thần kinh chỉ bằng thư viện đại số tuyến tính

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
8 (sử dụng các thư viện khác để đánh giá hiệu suất và trực quan hóa). Dữ liệu mẫu là dữ liệu 2 chiều có ba lớp ở dạng xoắn ốc

Nội dung bao gồm các khía cạnh sau của mạng lưới thần kinh

  • Khởi tạo trọng lượng
  • chức năng mất
    • Mất entropy chéo
    • mất bản lề
    • Mất chính quy
  • lớp
    • tuyến tính
    • sigmoid
    • tánh
    • tái lu
    • huênh hoang
    • Softmax
    • SVM
    • Rơi ra ngoài
    • Chuẩn hóa hàng loạt
    • Tích chập (TBD)
    • LSTM (TBD)
    • Phần nhúng (TBD)
  • Đào tạo
    • Tuyến tính > Softmax
    • Tuyến tính > SVM
    • [Tuyến tính > Kích hoạt]++ > [Tuyến tính > Đầu ra]
  • Tối ưu hóa (TBD)
  • Xác thực (TBD)

Trong bài đăng này, chúng tôi sẽ triển khai một mạng lưới thần kinh nhiều lớp từ đầu. Bạn có thể coi số lớp và kích thước của mỗi lớp là tham số. Ví dụ:

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
0 đại diện cho đầu vào có 2 chiều, một lớp ẩn có 3 chiều và đầu ra có 2 chiều (phân loại nhị phân) (sử dụng softmax làm đầu ra)

Chúng tôi sẽ không rút ra tất cả các phép toán cần thiết, nhưng tôi sẽ cố gắng đưa ra lời giải thích trực quan về những gì chúng tôi đang làm. Tôi cũng sẽ trỏ đến các tài nguyên để bạn đọc chi tiết

Tạo tập dữ liệu

Hãy bắt đầu bằng cách tạo một tập dữ liệu mà chúng ta có thể sử dụng. May mắn thay, scikit-learning có một số trình tạo tập dữ liệu hữu ích, vì vậy chúng tôi không cần phải tự viết mã. Chúng ta sẽ sử dụng hàm make_moons

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)

Mạng thần kinh Softmax từ đầu

Tập dữ liệu chúng tôi đã tạo có hai lớp, được biểu thị dưới dạng các điểm màu đỏ và xanh lam. Mục tiêu của chúng tôi là đào tạo một trình phân loại Machine Learning dự đoán đúng lớp được cung cấp tọa độ x và y-. Lưu ý rằng dữ liệu không thể phân tách tuyến tính, chúng ta không thể vẽ một đường thẳng phân tách hai lớp. Điều này có nghĩa là các trình phân loại tuyến tính, chẳng hạn như Hồi quy logistic, sẽ không thể điều chỉnh dữ liệu trừ khi bạn tự tay thiết kế các tính năng phi tuyến tính (chẳng hạn như đa thức) hoạt động tốt cho tập dữ liệu đã cho

Trên thực tế, đó là một trong những lợi thế chính của Mạng nơ-ron. Bạn không cần phải lo lắng về kỹ thuật tính năng. Lớp ẩn của mạng thần kinh sẽ học các tính năng cho bạn

mạng lưới thần kinh

Kiến trúc mạng nơ-ron

Bạn có thể đọc hướng dẫn này (http. //cs231n. github. io/neural-networks-1/) để tìm hiểu các khái niệm cơ bản về mạng nơ-ron. Giống như các chức năng kích hoạt, tính toán chuyển tiếp nguồn cấp dữ liệu, v.v.

Bởi vì chúng tôi muốn mạng của mình đưa ra xác suất, hàm kích hoạt cho lớp đầu ra sẽ là softmax, đây chỉ đơn giản là một cách để chuyển đổi điểm thô thành xác suất. Nếu bạn đã quen thuộc với chức năng logistic, bạn có thể coi softmax là khái quát hóa của nó cho nhiều lớp

Khi bạn chọn softmax làm đầu ra, bạn có thể sử dụng (còn được gọi là khả năng nhật ký âm) làm hàm mất mát. Thông tin thêm về Chức năng mất mát có thể được tìm thấy trong

Học các thông số

Tìm hiểu các tham số cho mạng của chúng tôi có nghĩa là tìm các tham số (chẳng hạn như (W_1, b_1, W_2, b_2)) để giảm thiểu lỗi trên dữ liệu đào tạo của chúng tôi (hàm mất mát)

Chúng ta có thể sử dụng tính năng giảm độ dốc để tìm mức tối thiểu và tôi sẽ triển khai phiên bản gốc nhất của tính năng giảm độ dốc, còn được gọi là giảm độ dốc hàng loạt với tốc độ học cố định. Các biến thể như SGD (giảm độ dốc ngẫu nhiên) hoặc giảm độ dốc minibatch thường hoạt động tốt hơn trong thực tế. Vì vậy, nếu bạn thực sự nghiêm túc, bạn sẽ muốn sử dụng một trong những thứ này và lý tưởng nhất là bạn cũng sẽ

Mấu chốt của phương pháp giảm độ dốc là cách tính độ dốc của hàm mất mát theo các tham số. Một cách tiếp cận được gọi là Back Propagation. Bạn có thể tìm hiểu thêm từ http. // cola. github. io/posts/2015-08-Backprop/ và http. //cs231n. github. io/optimization-2/

Thực hiện

Chúng tôi bắt đầu bằng cách đưa ra biểu đồ tính toán của mạng lưới thần kinh.

Mạng thần kinh Softmax từ đầu

Trong biểu đồ tính toán, bạn có thể thấy rằng nó chứa ba thành phần (_______01,

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
2 và
import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
3), có hai loại cổng (
import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
4 và
import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
5), và bạn có thể sử dụng đầu ra lớp
import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
6 và lớp
import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
7

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
1,
import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
2 và
import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
3 đều có thể được coi là đơn vị hoạt động của đồ thị tính toán, vì vậy chúng sẽ triển khai đạo hàm bên trong của đầu vào (chúng tôi gọi là
# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
21) và sử dụng quy tắc dây chuyền theo đồ thị tính toán. Bạn có thể xem hình sau để giải thích tốt.
Mạng thần kinh Softmax từ đầu

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
22

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
23

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
2

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
24

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
8

Chúng ta có thể triển khai mạng nơ-ron bằng một lớp

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
25 và khởi tạo các tham số trong hàm
# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
26. Bạn có thể truyền tham số
# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
27, đại diện cho đầu vào có 2 chiều, một lớp ẩn có 3 chiều và đầu ra có 2 chiều

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
2

Trước tiên, hãy triển khai hàm mất mát mà chúng ta đã xác định ở trên. Nó chỉ là một tính toán lan truyền về phía trước của mạng lưới thần kinh. Chúng tôi sử dụng điều này để đánh giá mô hình của chúng tôi hoạt động tốt như thế nào

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
3

Chúng tôi cũng triển khai chức năng trợ giúp để tính toán đầu ra của mạng. Nó thực hiện lan truyền về phía trước như đã định nghĩa ở trên và trả về lớp có xác suất cao nhất

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
4

Cuối cùng, đây là chức năng đào tạo Mạng lưới thần kinh của chúng ta. Nó thực hiện giảm độ dốc hàng loạt bằng cách sử dụng các thuật toán lan truyền ngược mà chúng ta đã học ở trên

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
5

Mạng có lớp ẩn kích thước 3

Hãy xem điều gì sẽ xảy ra nếu chúng ta huấn luyện một mạng có kích thước lớp ẩn là 3

import numpy as np

class MultiplyGate:
    def forward(self,W, X):
        return np.dot(X, W)

    def backward(self, W, X, dZ):
        dW = np.dot(np.transpose(X), dZ)
        dX = np.dot(dZ, np.transpose(W))
        return dW, dX

class AddGate:
    def forward(self, X, b):
        return X + b

    def backward(self, X, b, dZ):
        dX = dZ * np.ones_like(X)
        db = np.dot(np.ones((1, dZ.shape[0]), dtype=np.float64), dZ)
        return db, dX
6

Mạng thần kinh Softmax từ đầu

Điều này có vẻ khá tốt. Mạng thần kinh của chúng tôi đã có thể tìm thấy ranh giới quyết định phân tách thành công các lớp

Hàm

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
28 được tham chiếu bởi http. //www. hoang dã. com/2015/09/implementing-a-neural-network-from-scratch