Cách áp dụng độ dốc của softmax trong backprop


8

Gần đây tôi đã làm một bài tập về nhà, nơi tôi phải học một mô hình cho phân loại 10 chữ số của MNIST. CTNH có một số mã giàn giáo và tôi phải làm việc trong bối cảnh của mã này.

Bài tập về nhà của tôi hoạt động / vượt qua các bài kiểm tra nhưng bây giờ tôi đang cố gắng làm tất cả từ đầu (khung nn của riêng tôi, không có mã giàn giáo hw) và tôi bị mắc kẹt khi áp dụng phương pháp softmax trong bước backprop, và thậm chí nghĩ gì về hw mã giàn giáo có thể không chính xác.

Hw đã cho tôi sử dụng cái mà họ gọi là "mất softmax" làm nút cuối cùng trong nn. Điều đó có nghĩa là, vì một số lý do, họ đã quyết định tham gia kích hoạt softmax với mất entropy chéo tất cả trong một, thay vì coi softmax là một hàm kích hoạt và entropy chéo như một hàm mất riêng.

Sau đó, hw loss func trông như thế này (được chỉnh sửa tối thiểu bởi tôi):

class SoftmaxLoss:
    """
    A batched softmax loss, used for classification problems.
    input[0] (the prediction) = np.array of dims batch_size x 10
    input[1] (the truth) = np.array of dims batch_size x 10
    """
    @staticmethod
    def softmax(input):
        exp = np.exp(input - np.max(input, axis=1, keepdims=True))
        return exp / np.sum(exp, axis=1, keepdims=True)

    @staticmethod
    def forward(inputs):
        softmax = SoftmaxLoss.softmax(inputs[0])
        labels = inputs[1]
        return np.mean(-np.sum(labels * np.log(softmax), axis=1))

    @staticmethod
    def backward(inputs, gradient):
        softmax = SoftmaxLoss.softmax(inputs[0])
        return [
            gradient * (softmax - inputs[1]) / inputs[0].shape[0],
            gradient * (-np.log(softmax)) / inputs[0].shape[0]
        ]

Như bạn có thể thấy, về phía trước, nó có softmax (x) và sau đó mất entropy chéo.

Nhưng trên backprop, nó dường như chỉ làm đạo hàm của entropy chéo chứ không phải của softmax. Softmax là trái như vậy.

Không phải nó cũng nên lấy đạo hàm của softmax đối với đầu vào thành softmax sao?

Giả sử rằng nó nên lấy đạo hàm của softmax, tôi không chắc hw này thực sự vượt qua các bài kiểm tra như thế nào ...

Bây giờ, trong quá trình thực hiện của riêng tôi từ đầu, tôi đã tạo ra các nút riêng biệt mềm và chéo entropy, như vậy (p và t là viết tắt của dự đoán và sự thật):

class SoftMax(NetNode):
    def __init__(self, x):
        ex = np.exp(x.data - np.max(x.data, axis=1, keepdims=True))
        super().__init__(ex / np.sum(ex, axis=1, keepdims=True), x)

    def _back(self, x):
        g = self.data * (np.eye(self.data.shape[0]) - self.data)
        x.g += self.g * g
        super()._back()

class LCE(NetNode):
    def __init__(self, p, t):
        super().__init__(
            np.mean(-np.sum(t.data * np.log(p.data), axis=1)),
            p, t
        )

    def _back(self, p, t):
        p.g += self.g * (p.data - t.data) / t.data.shape[0]
        t.g += self.g * -np.log(p.data) / t.data.shape[0]
        super()._back()

Như bạn có thể thấy, mất entropy chéo của tôi (LCE) có cùng đạo hàm với một trong hw, bởi vì đó là đạo hàm cho chính sự mất mát, mà chưa đi vào softmax.

Nhưng sau đó, tôi vẫn sẽ phải thực hiện đạo hàm của softmax để xâu chuỗi nó với đạo hàm của sự mất mát. Đây là nơi tôi bị mắc kẹt.

Đối với softmax được định nghĩa là:

một

Đạo hàm thường được định nghĩa là:

b

Nhưng tôi cần một công cụ phái sinh dẫn đến một tenxơ có cùng kích thước với đầu vào thành softmax, trong trường hợp này, batch_size x 10. Vì vậy, tôi không chắc cách áp dụng ở trên chỉ cho 10 thành phần, vì nó ngụ ý rằng tôi sẽ khác biệt cho tất cả các đầu vào đối với tất cả các đầu ra (tất cả các kết hợp) hoặc cở dạng ma trận.


Tôi nghĩ bạn nên đăng bài này trong lượt xem mã hóa hoặc stackoverflow
DuttaA 27/03/18

tại sao? đó là một mạng lưới thần kinh, câu hỏi backprop. Nó thuộc về trao đổi ngăn xếp AI.

bất cứ ai bầu chọn tôi có lẽ không rành về AI ... hãy xem, câu hỏi là về việc áp dụng một đạo hàm riêng trong bối cảnh truyền bá ngược, trong bối cảnh mạng lưới thần kinh, trong bối cảnh học máy, trong bối cảnh học máy học có giám sát, trong bối cảnh 'AI'. Phần nào của điều này: 1- cho thấy thiếu nghiên cứu 2 - không liên quan đến 'AI', 3- là câu hỏi 'gửi cho tôi đoạn mã', 4 - là câu hỏi về ý kiến ​​5- là câu hỏi quá rộng ?

Từ ai.se faq "và nó không phải là ... việc thực hiện học máy"
mico

@mico ok tôi hiểu rồi, vâng, theo như faq bạn nói đúng. Nhưng tôi thấy nó bất ngờ. Ý tôi là, thảo luận về toán học và triển khai các thuật toán AI là thực tiễn phổ biến trong lĩnh vực này (bao gồm cả ở cấp độ học thuật).
SaldaVonSchwartz

Câu trả lời:


5

Sau khi tiếp tục làm việc này, tôi phát hiện ra rằng:

  1. Việc thực hiện bài tập về nhà kết hợp softmax với mất entropy chéo là một vấn đề được lựa chọn, trong khi lựa chọn giữ softmax riêng biệt như một chức năng kích hoạt cũng có hiệu lực.

  2. Việc thực hiện bài tập về nhà thực sự thiếu dẫn xuất của softmax cho backprop pass.

  3. Độ dốc của softmax đối với các đầu vào của nó thực sự là một phần của mỗi đầu ra đối với từng đầu vào:

độ dốc1

Vì vậy, đối với dạng vector (gradient): gradient2

Mà trong mã numpy vector hóa của tôi chỉ đơn giản là:

self.data * (1. - self.data)

Trường hợp self.datasoftmax của đầu vào, được tính toán trước từ đường chuyền phía trước.


3
Tôi không nghĩ rằng điều này là chính xác. Bạn cũng phải tính toán smax (x_i) / x_j, trong đó j ≠ i và tổng tất cả các gradient riêng lẻ lên. Điều này là do khi tính toán softmax cho x_i, tất cả các tham số khác cũng được sử dụng để xác định giá trị của softmax.
harveyslash
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.