Một thẻ đã tồn tại với tên chi nhánh được cung cấp. Nhiều lệnh Git chấp nhận cả tên thẻ và tên nhánh, vì vậy việc tạo nhánh này có thể gây ra hành vi không mong muốn. Bạn có chắc chắn muốn tạo nhánh này không? Show Vì hồi quy softmax rất cơ bản nên chúng tôi tin rằng bạn nên biết cách tự thực hiện nó. Ở đây, chúng tôi giới hạn bản thân trong việc xác định các khía cạnh dành riêng cho softmax của mô hình và sử dụng lại các thành phần khác từ phần hồi quy tuyến tính của chúng tôi, bao gồm cả vòng đào tạo import torch from d2l import torch as d2l from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np() from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.) import tensorflow as tf from d2l import tensorflow as d2l 4. 4. 1. SoftmaxHãy bắt đầu với phần quan trọng nhất. ánh xạ từ vô hướng sang xác suất. Để ôn lại, hãy nhớ lại hoạt động của toán tử tổng theo các thứ nguyên cụ thể trong một tenxơ, như đã thảo luận trong và. Cho một ma trận (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))9, chúng ta có thể tính tổng trên tất cả các phần tử (theo mặc định) hoặc chỉ trên các phần tử trong cùng một trục. Biến X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)0 cho phép chúng ta tính tổng hàng và cột X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True) (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]])) X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True) (array([[5., 7., 9.]]), array([[ 6.], [15.]])) X = jnp.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True) from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()0 from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()1 from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()2 Tính toán softmax yêu cầu ba bước. (i) lũy thừa của mỗi số hạng; (4. 4. 1) \[\mathrm{softmax}(\mathbf{X})_{ij} = \frac{\exp(\mathbf{X}_{ij})}{\sum_k . \] Mẫu số (logarit của) được gọi là hàm phân hoạch (log). Nó được giới thiệu trong vật lý thống kê để tổng hợp tất cả các trạng thái có thể có trong một quần thể nhiệt động lực học. Việc thực hiện là đơn giản from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()3 from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()4 from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()5 from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()6 Đối với bất kỳ đầu vào (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))9 nào, chúng tôi biến từng phần tử thành một số không âm. Mỗi hàng có tổng bằng 1, theo yêu cầu đối với xác suất. thận trọng. đoạn mã trên không mạnh đối với các đối số rất lớn hoặc rất nhỏ. Mặc dù điều này đủ để minh họa những gì đang xảy ra, nhưng bạn không nên sử dụng nguyên văn mã này cho bất kỳ mục đích nghiêm trọng nào. Các khung học sâu có tích hợp các biện pháp bảo vệ như vậy và chúng tôi sẽ sử dụng softmax tích hợp trong tương lai from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()7 from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()8 from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2l npx.set_np()9 from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l0 from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l1 from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l2 from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l3 from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l4 4. 4. 2. Mô hìnhBây giờ chúng ta có mọi thứ cần thiết để triển khai mô hình hồi quy softmax. Như trong ví dụ hồi quy tuyến tính của chúng tôi, mỗi trường hợp sẽ được biểu thị bằng một vectơ có độ dài cố định. Vì dữ liệu thô ở đây bao gồm \(28 \times 28\) ảnh pixel nên chúng tôi làm phẳng từng ảnh, coi chúng là các vectơ có độ dài 784. Trong các chương sau, chúng tôi sẽ giới thiệu các mạng thần kinh tích chập, khai thác cấu trúc không gian theo cách thỏa mãn hơn. Trong hồi quy softmax, số lượng đầu ra từ mạng của chúng tôi phải bằng số lượng lớp. Vì tập dữ liệu của chúng tôi có 10 lớp nên mạng của chúng tôi có kích thước đầu ra là 10. Do đó, các trọng số của chúng ta tạo thành một ma trận \(784 \times 10\) cộng với một \(1 \times 10 . Như với hồi quy tuyến tính, chúng tôi khởi tạo các trọng số X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)2 with Gaussian noise. The biases are initialized as zeros. from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l5 from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l6 from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l7 from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l8 Mã bên dưới xác định cách mạng ánh xạ từng đầu vào thành đầu ra. Lưu ý rằng chúng tôi làm phẳng từng \(28 \times 28\) ảnh pixel trong lô thành một vectơ bằng cách sử dụng X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)3 trước khi chuyển dữ liệu qua mô hình của chúng tôi. from functools import partial import jax from flax import linen as nn from jax import numpy as jnp from d2l import jax as d2l9 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)0 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)1 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)2 4. 4. 3. Mất Entropy chéoTiếp theo, chúng ta cần triển khai hàm mất entropy chéo (được giới thiệu trong ). Đây có thể là hàm mất mát phổ biến nhất trong tất cả các phương pháp học sâu. Hiện tại, các ứng dụng của học sâu dễ dàng tạo ra các vấn đề phân loại vượt xa những vấn đề được coi là vấn đề hồi quy tốt hơn Hãy nhớ lại rằng entropy chéo có khả năng ghi nhật ký âm của xác suất dự đoán được gán cho nhãn thực. Để đạt hiệu quả, chúng tôi tránh các vòng lặp Python và thay vào đó sử dụng lập chỉ mục. Cụ thể, mã hóa một lần nóng trong \(\mathbf{y}\) cho phép chúng tôi chọn các thuật ngữ phù hợp trong \(\hat{\mathbf{y}}\). Để thấy điều này trong thực tế, chúng tôi tạo dữ liệu mẫu X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)4 với 2 ví dụ về xác suất dự đoán trên 3 lớp và nhãn tương ứng của chúng X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)5. Các nhãn chính xác là \(0\) và \(2\) respectively (i.e., the first and third class). Using X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)5 as the indices of the probabilities in X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)4, we can pick out terms efficiently. No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)3 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)4 Bây giờ chúng ta có thể triển khai hàm mất entropy chéo bằng cách lấy trung bình trên logarit của các xác suất đã chọn No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)5 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)6 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)7 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)8 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)9 Bây giờ chúng ta có thể triển khai hàm mất entropy chéo bằng cách lấy trung bình trên logarit của các xác suất đã chọn import tensorflow as tf from d2l import tensorflow as d2l0 import tensorflow as tf from d2l import tensorflow as d2l1 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)7 import tensorflow as tf from d2l import tensorflow as d2l3 import tensorflow as tf from d2l import tensorflow as d2l4 Bây giờ chúng ta có thể triển khai hàm mất entropy chéo bằng cách lấy trung bình trên logarit của các xác suất đã chọn Lưu ý rằng để sử dụng X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)8 nhằm tăng tốc độ triển khai JAX và để đảm bảo rằng X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)9 là một hàm thuần túy, thì hàm (array([[5., 7., 9.]]), array([[ 6.], [15.]]))0 được xác định lại bên trong X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)9 để tránh việc sử dụng bất kỳ biến hoặc hàm toàn cục nào có thể khiến hàm X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)9 không thuần túy. Chúng tôi giới thiệu những độc giả quan tâm đến trên X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)8 và các hàm thuần túy import tensorflow as tf from d2l import tensorflow as d2l5 import tensorflow as tf from d2l import tensorflow as d2l6 import tensorflow as tf from d2l import tensorflow as d2l7 import tensorflow as tf from d2l import tensorflow as d2l8 import tensorflow as tf from d2l import tensorflow as d2l9 Bây giờ chúng ta có thể triển khai hàm mất entropy chéo bằng cách lấy trung bình trên logarit của các xác suất đã chọn X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)0 X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)1 No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)7 4. 4. 4. Đào tạoChúng tôi sử dụng lại phương pháp (array([[5., 7., 9.]]), array([[ 6.], [15.]]))4 được xác định trong để đào tạo mô hình với 10 kỷ nguyên. Lưu ý rằng cả số lượng kỷ nguyên ( (array([[5., 7., 9.]]), array([[ 6.], [15.]]))5), kích thước lô nhỏ ( (array([[5., 7., 9.]]), array([[ 6.], [15.]]))6) và tốc độ học tập ( (array([[5., 7., 9.]]), array([[ 6.], [15.]]))7) đều là các siêu tham số có thể điều chỉnh. Điều đó có nghĩa là mặc dù các giá trị này không được học trong vòng đào tạo chính của chúng tôi, nhưng chúng vẫn ảnh hưởng đến hiệu suất của mô hình, đào tạo bot trực quan và hiệu suất tổng quát hóa. Trong thực tế, bạn sẽ muốn chọn các giá trị này dựa trên phân tách xác thực của dữ liệu và sau đó để đánh giá cuối cùng mô hình cuối cùng của bạn trên phân tách thử nghiệm. Như đã thảo luận trong phần , chúng tôi sẽ coi dữ liệu thử nghiệm của Fashion-MNIST là bộ xác thực, do đó báo cáo độ chính xác của việc mất xác thực và độ chính xác của quá trình xác thực trong lần phân chia này X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)3 X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)3 X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)3 X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)3 4. 4. 5. Dự đoánBây giờ quá trình đào tạo đã hoàn tất, mô hình của chúng tôi đã sẵn sàng để phân loại một số hình ảnh X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)7 X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)8 X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) X.sum(0, keepdims=True), X.sum(1, keepdims=True)7 (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))0 (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))1 (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))0 (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))3 (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))4 Chúng tôi quan tâm nhiều hơn đến những hình ảnh chúng tôi dán nhãn không chính xác. Chúng tôi trực quan hóa chúng bằng cách so sánh nhãn thực tế của chúng (dòng đầu tiên của văn bản đầu ra) với các dự đoán từ mô hình (dòng đầu ra văn bản thứ hai) (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))5 (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))6 (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))6 (tensor([[5., 7., 9.]]), tensor([[ 6.], [15.]]))8 4. 4. 6. Tóm tắtBây giờ chúng ta bắt đầu có một số kinh nghiệm với việc giải các bài toán phân loại và hồi quy tuyến tính. Với nó, chúng tôi đã đạt được thứ được cho là đỉnh cao của nghệ thuật mô hình thống kê những năm 1960-1970. Trong phần tiếp theo, chúng tôi sẽ chỉ cho bạn cách tận dụng các framework deep learning để triển khai mô hình này hiệu quả hơn nhiều 4. 4. 7. Bài tập
|