Bộ công cụ nhận thức của Microsoft - Hướng dẫn nhanh
Trong chương này, chúng ta sẽ tìm hiểu CNTK là gì, các tính năng của nó, sự khác biệt giữa phiên bản 1.0 và 2.0 và những điểm nổi bật quan trọng của phiên bản 2.7.
Bộ công cụ nhận thức của Microsoft (CNTK) là gì?
Bộ công cụ nhận thức của Microsoft (CNTK), trước đây được gọi là Bộ công cụ mạng tính toán, là một bộ công cụ cấp thương mại miễn phí, dễ sử dụng, mã nguồn mở, cho phép chúng tôi đào tạo các thuật toán học sâu để học giống như não người. Nó cho phép chúng tôi tạo một số hệ thống học sâu phổ biến nhưfeed-forward neural network time series prediction systems and Convolutional neural network (CNN) image classifiers.
Để có hiệu suất tối ưu, các hàm khung của nó được viết bằng C ++. Mặc dù chúng ta có thể gọi hàm của nó bằng C ++, nhưng cách tiếp cận phổ biến nhất được sử dụng cho hàm tương tự là sử dụng một chương trình Python.
Các tính năng của CNTK
Sau đây là một số tính năng và khả năng được cung cấp trong phiên bản mới nhất của Microsoft CNTK:
Các thành phần tích hợp
CNTK có các thành phần tích hợp được tối ưu hóa cao để có thể xử lý dữ liệu dày đặc hoặc thưa thớt đa chiều từ Python, C ++ hoặc BrainScript.
Chúng tôi có thể triển khai CNN, FNN, RNN, Batch Normalization và Sequence-to-Sequence với sự chú ý.
Nó cung cấp cho chúng tôi chức năng để thêm các thành phần lõi mới do người dùng xác định trên GPU từ Python.
Nó cũng cung cấp khả năng điều chỉnh siêu thông số tự động.
Chúng tôi có thể triển khai học tập củng cố, Mạng đối thủ chung (GAN), Học tập có giám sát cũng như không giám sát.
Đối với các bộ dữ liệu lớn, CNTK đã tích hợp sẵn các trình đọc tối ưu hóa.
Sử dụng tài nguyên hiệu quả
CNTK cung cấp cho chúng ta tính năng song song với độ chính xác cao trên nhiều GPU / máy thông qua SGD 1 bit.
Để phù hợp với các mô hình lớn nhất trong bộ nhớ GPU, nó cung cấp tính năng chia sẻ bộ nhớ và các phương pháp tích hợp khác.
Dễ dàng thể hiện mạng lưới của chúng tôi
CNTK có đầy đủ các API để xác định mạng, người học, người đọc, đào tạo và đánh giá của riêng bạn từ Python, C ++ và BrainScript.
Sử dụng CNTK, chúng ta có thể dễ dàng đánh giá các mô hình bằng Python, C ++, C # hoặc BrainScript.
Nó cung cấp cả API cấp cao và cấp thấp.
Dựa trên dữ liệu của chúng tôi, nó có thể tự động định hình suy luận.
Nó có các vòng lặp Mạng thần kinh tái diễn (RNN) tượng trưng được tối ưu hóa đầy đủ.
Đo lường hiệu suất mô hình
CNTK cung cấp các thành phần khác nhau để đo hiệu suất của mạng nơ-ron mà bạn xây dựng.
Tạo dữ liệu nhật ký từ mô hình của bạn và trình tối ưu hóa liên quan, chúng tôi có thể sử dụng dữ liệu này để theo dõi quá trình đào tạo.
Phiên bản 1.0 so với Phiên bản 2.0
Bảng sau so sánh CNTK Phiên bản 1.0 và 2.0:
Phiên bản 1.0 | Phiên bản 2.0 |
---|---|
Nó được phát hành vào năm 2016. | Đây là một bản viết lại đáng kể của Phiên bản 1.0 và được phát hành vào tháng 6 năm 2017. |
Nó sử dụng một ngôn ngữ kịch bản độc quyền được gọi là BrainScript. | Các hàm khung của nó có thể được gọi bằng C ++, Python. Chúng ta có thể dễ dàng tải các mô-đun của mình bằng C # hoặc Java. BrainScript cũng được hỗ trợ bởi Phiên bản 2.0. |
Nó chạy trên cả hệ thống Windows và Linux nhưng không chạy trực tiếp trên Mac OS. | Nó cũng chạy trên cả Windows (Win 8.1, Win 10, Server 2012 R2 trở lên) và hệ thống Linux nhưng không chạy trực tiếp trên Mac OS. |
Điểm nổi bật quan trọng của phiên bản 2.7
Version 2.7là phiên bản chính được phát hành cuối cùng của Bộ công cụ nhận thức của Microsoft. Nó có hỗ trợ đầy đủ cho ONNX 1.4.1. Sau đây là một số điểm nổi bật quan trọng của phiên bản CNTK được phát hành cuối cùng này.
Hỗ trợ đầy đủ cho ONNX 1.4.1.
Hỗ trợ CUDA 10 cho cả hệ thống Windows và Linux.
Nó hỗ trợ vòng lặp Mạng thần kinh tái phát (RNN) nâng cao trong xuất ONNX.
Nó có thể xuất hơn 2GB mô hình ở định dạng ONNX.
Nó hỗ trợ FP16 trong hành động đào tạo của ngôn ngữ kịch bản BrainScript.
Ở đây, chúng ta sẽ hiểu về cài đặt CNTK trên Windows và trên Linux. Hơn nữa, chương giải thích cài đặt gói CNTK, các bước cài đặt tệp Anaconda, CNTK, cấu trúc thư mục và tổ chức thư viện CNTK.
Điều kiện tiên quyết
Để cài đặt CNTK, chúng ta phải cài đặt Python trên máy tính của mình. Bạn có thể vào liên kếthttps://www.python.org/downloads/và chọn phiên bản mới nhất cho hệ điều hành của bạn, tức là Windows và Linux / Unix. Để có hướng dẫn cơ bản về Python, bạn có thể tham khảo liên kếthttps://www.tutorialspoint.com/python3/index.htm.
CNTK được hỗ trợ cho Windows cũng như Linux, vì vậy chúng tôi sẽ giới thiệu cho các bạn về cả hai.
Cài đặt trên Windows
Để chạy CNTK trên Windows, chúng tôi sẽ sử dụng Anaconda versioncủa Python. Chúng tôi biết rằng, Anaconda là một bản phân phối lại của Python. Nó bao gồm các gói bổ sung nhưScipy vàScikit-learn được CNTK sử dụng để thực hiện các phép tính hữu ích khác nhau.
Vì vậy, trước tiên hãy xem các bước cài đặt Anaconda trên máy của bạn -
Step 1−Trước tiên tải xuống các tệp thiết lập từ trang web công cộng https://www.anaconda.com/distribution/.
Step 2 - Sau khi bạn tải xuống các tệp thiết lập, hãy bắt đầu cài đặt và làm theo hướng dẫn từ liên kết https://docs.anaconda.com/anaconda/install/.
Step 3- Sau khi cài đặt, Anaconda cũng sẽ cài đặt thêm một số tiện ích khác, tiện ích này sẽ tự động đưa tất cả các tệp thực thi Anaconda vào biến PATH máy tính của bạn. Chúng tôi có thể quản lý môi trường Python của mình từ lời nhắc này, có thể cài đặt các gói và chạy các tập lệnh Python.
Cài đặt gói CNTK
Sau khi cài đặt Anaconda hoàn tất, bạn có thể sử dụng cách phổ biến nhất để cài đặt gói CNTK thông qua tệp thực thi pip bằng cách sử dụng lệnh sau:
pip install cntk
Có nhiều phương pháp khác để cài đặt Bộ công cụ nhận thức trên máy của bạn. Microsoft có một bộ tài liệu gọn gàng giải thích chi tiết các phương pháp cài đặt khác. Vui lòng theo liên kếthttps://docs.microsoft.com/en-us/cognitive-toolkit/Setup-CNTK-on-your-machine.
Cài đặt trên Linux
Cài đặt CNTK trên Linux hơi khác so với cài đặt trên Windows. Ở đây, đối với Linux, chúng tôi sẽ sử dụng Anaconda để cài đặt CNTK, nhưng thay vì trình cài đặt đồ họa cho Anaconda, chúng tôi sẽ sử dụng trình cài đặt dựa trên thiết bị đầu cuối trên Linux. Mặc dù, trình cài đặt sẽ hoạt động với hầu hết tất cả các bản phân phối Linux, chúng tôi giới hạn mô tả cho Ubuntu.
Vì vậy, trước tiên hãy xem các bước cài đặt Anaconda trên máy của bạn -
Các bước cài đặt Anaconda
Step 1- Trước khi cài đặt Anaconda, hãy đảm bảo rằng hệ thống đã được cập nhật đầy đủ. Để kiểm tra, trước tiên hãy thực hiện hai lệnh sau bên trong một thiết bị đầu cuối:
sudo apt update
sudo apt upgrade
Step 2 - Sau khi máy tính được cập nhật, hãy lấy URL từ trang web công cộng https://www.anaconda.com/distribution/ cho các tệp cài đặt Anaconda mới nhất.
Step 3 - Khi URL được sao chép, hãy mở cửa sổ dòng lệnh và thực hiện lệnh sau:
wget -0 anaconda-installer.sh url SHAPE \* MERGEFORMAT
y
f
x
| }
Thay thế cái url trình giữ chỗ có URL được sao chép từ trang web Anaconda.
Step 4 - Tiếp theo, với sự trợ giúp của lệnh sau, chúng ta có thể cài đặt Anaconda -
sh ./anaconda-installer.sh
Lệnh trên sẽ được cài đặt mặc định Anaconda3 bên trong thư mục chính của chúng tôi.
Cài đặt gói CNTK
Sau khi cài đặt Anaconda hoàn tất, bạn có thể sử dụng cách phổ biến nhất để cài đặt gói CNTK thông qua tệp thực thi pip bằng cách sử dụng lệnh sau:
pip install cntk
Kiểm tra tệp CNTK & cấu trúc thư mục
Sau khi CNTK được cài đặt dưới dạng một gói Python, chúng ta có thể kiểm tra cấu trúc tệp và thư mục của nó. Nó ởC:\Users\
Xác minh cài đặt CNTK
Sau khi CNTK được cài đặt dưới dạng một gói Python, bạn nên xác minh rằng CNTK đã được cài đặt chính xác. Từ trình bao lệnh Anaconda, khởi động trình thông dịch Python bằng cách nhậpipython. Sau đó, nhập CNTK bằng cách nhập lệnh sau.
import cntk as c
Sau khi được nhập, hãy kiểm tra phiên bản của nó với sự trợ giúp của lệnh sau:
print(c.__version__)
Trình thông dịch sẽ trả lời với phiên bản CNTK đã cài đặt. Nếu nó không phản hồi, sẽ có vấn đề với quá trình cài đặt.
Tổ chức thư viện CNTK
Về mặt kỹ thuật, CNTK, một gói python, được tổ chức thành 13 gói con cấp cao và 8 gói con nhỏ hơn. Bảng sau bao gồm 10 gói được sử dụng thường xuyên nhất:
Sr.No | Tên & Mô tả gói |
---|---|
1 | cntk.io Chứa các chức năng để đọc dữ liệu. Ví dụ: next_minibatch () |
2 | cntk.layers Chứa các chức năng cấp cao để tạo mạng nơ-ron. Ví dụ: Dense () |
3 | cntk.learners Chứa các chức năng để đào tạo. Ví dụ: sgd () |
4 | cntk.losses Chứa các chức năng để đo lỗi đào tạo. Ví dụ: squared_error () |
5 | cntk.metrics Chứa các chức năng đo lỗi mô hình. Ví dụ: classificatoin_error |
6 | cntk.ops Chứa các chức năng cấp thấp để tạo mạng nơ-ron. Ví dụ: tanh () |
7 | cntk.random Chứa hàm tạo số ngẫu nhiên. Ví dụ: normal () |
số 8 | cntk.train Chứa các chức năng đào tạo. Ví dụ: train_minibatch () |
9 | cntk.initializer Chứa các bộ khởi tạo tham số mô hình. Ví dụ: normal () và Uniform () |
10 | cntk.variables Chứa các cấu trúc cấp thấp. Ví dụ: Tham số () và Biến () |
Bộ công cụ nhận thức của Microsoft cung cấp hai phiên bản xây dựng khác nhau, cụ thể là chỉ dành cho CPU và chỉ dành cho GPU.
Phiên bản xây dựng chỉ dành cho CPU
Phiên bản xây dựng chỉ dành cho CPU của CNTK sử dụng Intel MKLML được tối ưu hóa, trong đó MKLML là tập con của MKL (Thư viện hạt nhân toán học) và được phát hành cùng với Intel MKL-DNN dưới dạng phiên bản kết thúc của Intel MKL cho MKL-DNN.
Phiên bản xây dựng chỉ GPU
Mặt khác, phiên bản xây dựng chỉ dành cho GPU của CNTK sử dụng các thư viện NVIDIA được tối ưu hóa cao như CUB và cuDNN. Nó hỗ trợ đào tạo phân tán trên nhiều GPU và nhiều máy. Để đào tạo phân tán nhanh hơn trong CNTK, phiên bản xây dựng GPU cũng bao gồm:
SGD lượng tử hóa 1bit do MSR phát triển.
Các thuật toán đào tạo song song khối-đà SGD.
Bật GPU với CNTK trên Windows
Trong phần trước, chúng ta đã xem cách cài đặt phiên bản CNTK cơ bản để sử dụng với CPU. Bây giờ chúng ta hãy thảo luận về cách chúng ta có thể cài đặt CNTK để sử dụng với GPU. Tuy nhiên, trước khi đi sâu vào nó, trước tiên bạn nên có một card đồ họa được hỗ trợ.
Hiện tại, CNTK hỗ trợ card đồ họa NVIDIA với ít nhất hỗ trợ CUDA 3.0. Để chắc chắn hơn, bạn có thể kiểm tra tạihttps://developer.nvidia.com/cuda-gpus GPU của bạn có hỗ trợ CUDA hay không.
Vì vậy, chúng ta hãy xem các bước để kích hoạt GPU với CNTK trên HĐH Windows -
Step 1 - Tùy thuộc vào card đồ họa bạn đang sử dụng, trước tiên bạn cần có trình điều khiển GeForce hoặc Quadro mới nhất cho card đồ họa của mình.
Step 2 - Sau khi tải xuống trình điều khiển, bạn cần cài đặt bộ công cụ CUDA Phiên bản 9.0 cho Windows từ trang web NVIDIA https://developer.nvidia.com/cuda-90-download-archive?target_os=Windows&target_arch=x86_64. Sau khi cài đặt, hãy chạy trình cài đặt và làm theo hướng dẫn.
Step 3 - Tiếp theo, bạn cần cài đặt nhị phân cuDNN từ trang web NVIDIA https://developer.nvidia.com/rdp/form/cudnn-download-survey. Với phiên bản CUDA 9.0, cuDNN 7.4.1 hoạt động tốt. Về cơ bản, cuDNN là một lớp trên cùng của CUDA, được sử dụng bởi CNTK.
Step 4 - Sau khi tải xuống các tệp nhị phân cuDNN, bạn cần giải nén tệp zip vào thư mục gốc của cài đặt bộ công cụ CUDA của bạn.
Step 5- Đây là bước cuối cùng sẽ cho phép sử dụng GPU bên trong CNTK. Thực thi lệnh sau bên trong lời nhắc Anaconda trên Windows OS:
pip install cntk-gpu
Bật GPU với CNTK trên Linux
Hãy để chúng tôi xem cách chúng tôi có thể kích hoạt GPU với CNTK trên hệ điều hành Linux -
Tải xuống bộ công cụ CUDA
Trước tiên, bạn cần cài đặt bộ công cụ CUDA từ trang web của NVIDIA https://developer.nvidia.com/cuda-90-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1604&target_type= runfilelocal .
Chạy trình cài đặt
Bây giờ, khi bạn có mã nhị phân trên đĩa, hãy chạy trình cài đặt bằng cách mở một thiết bị đầu cuối và thực hiện lệnh sau và hướng dẫn trên màn hình:
sh cuda_9.0.176_384.81_linux-run
Sửa đổi tập lệnh hồ sơ Bash
Sau khi cài đặt bộ công cụ CUDA trên máy Linux, bạn cần sửa đổi tập lệnh cấu hình BASH. Đối với điều này, trước tiên hãy mở tệp $ HOME / .bashrc trong trình soạn thảo văn bản. Bây giờ, ở cuối script, hãy bao gồm các dòng sau:
export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}} export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64\ ${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
Installing
Cài đặt thư viện cuDNN
Cuối cùng, chúng ta cần cài đặt các tệp nhị phân cuDNN. Nó có thể được tải xuống từ trang web NVIDIAhttps://developer.nvidia.com/rdp/form/cudnn-download-survey. Với phiên bản CUDA 9.0, cuDNN 7.4.1 hoạt động tốt. Về cơ bản, cuDNN là một lớp trên cùng của CUDA, được sử dụng bởi CNTK.
Sau khi tải xuống phiên bản cho Linux, hãy giải nén nó vào /usr/local/cuda-9.0 thư mục bằng cách sử dụng lệnh sau:
tar xvzf -C /usr/local/cuda-9.0/ cudnn-9.0-linux-x64-v7.4.1.5.tgz
Thay đổi đường dẫn đến tên tệp theo yêu cầu.
Trong chương này, chúng ta sẽ tìm hiểu chi tiết về các trình tự trong CNTK và cách phân loại của nó.
Hàng căng
Khái niệm mà CNTK hoạt động là tensor. Về cơ bản, đầu vào, đầu ra cũng như các tham số của CNTK được tổ chức nhưtensors, thường được coi là một ma trận tổng quát. Mỗi tensor có mộtrank -
Tensor của hạng 0 là một đại lượng vô hướng.
Tensor của hạng 1 là một vectơ.
Tensor của hạng 2 là amatrix.
Ở đây, các kích thước khác nhau này được gọi là axes.
Trục tĩnh và trục động
Như tên của nó, các trục tĩnh có cùng độ dài trong suốt vòng đời của mạng. Mặt khác, độ dài của các trục động có thể thay đổi theo từng trường hợp. Trên thực tế, độ dài của chúng thường không được biết trước khi mỗi minibatch được giới thiệu.
Các trục động giống như các trục tĩnh vì chúng cũng xác định một nhóm có ý nghĩa của các số chứa trong tensor.
Thí dụ
Để làm rõ hơn, hãy xem cách thể hiện một loạt video clip ngắn trong CNTK. Giả sử rằng độ phân giải của tất cả các video clip là 640 * 480. Và, các clip cũng được quay bằng màu thường được mã hóa bằng ba kênh. Hơn nữa, nó có nghĩa là minibatch của chúng tôi có những thứ sau:
3 trục tĩnh có độ dài lần lượt là 640, 480 và 3.
Hai trục động lực học; thời lượng của video và trục minibatch.
Có nghĩa là nếu một minibatch có 16 video, mỗi video dài 240 khung hình, sẽ được biểu thị là 16*240*3*640*480 dây căng.
Làm việc với các chuỗi trong CNTK
Hãy để chúng tôi hiểu các trình tự trong CNTK bằng cách tìm hiểu trước về Mạng bộ nhớ dài hạn.
Mạng bộ nhớ dài hạn (LSTM)
Mạng bộ nhớ ngắn hạn (LSTM) được giới thiệu bởi Hochreiter & Schmidhuber. Nó giải quyết vấn đề nhận được một lớp lặp lại cơ bản để ghi nhớ mọi thứ trong một thời gian dài. Kiến trúc của LSTM được đưa ra ở trên trong sơ đồ. Như chúng ta có thể thấy, nó có các tế bào thần kinh đầu vào, các tế bào bộ nhớ và các tế bào thần kinh đầu ra. Để chống lại vấn đề độ dốc biến mất, các mạng bộ nhớ ngắn hạn sử dụng một ô nhớ rõ ràng (lưu trữ các giá trị trước đó) và các cổng sau:
Forget gate- Như tên của nó, nó báo cho ô nhớ quên các giá trị trước đó. Ô nhớ lưu trữ các giá trị cho đến khi cổng tức là 'cổng quên' yêu cầu nó quên chúng.
Input gate - Như tên của nó, nó thêm những thứ mới vào ô.
Output gate - Như tên của nó, cổng xuất quyết định thời điểm truyền các vectơ từ ô sang trạng thái ẩn tiếp theo.
Nó rất dễ dàng để làm việc với các trình tự trong CNTK. Hãy xem nó với sự trợ giúp của ví dụ sau:
import sys
import os
from cntk import Trainer, Axis
from cntk.io import MinibatchSource, CTFDeserializer, StreamDef, StreamDefs,\
INFINITELY_REPEAT
from cntk.learners import sgd, learning_parameter_schedule_per_sample
from cntk import input_variable, cross_entropy_with_softmax, \
classification_error, sequence
from cntk.logging import ProgressPrinter
from cntk.layers import Sequential, Embedding, Recurrence, LSTM, Dense
def create_reader(path, is_training, input_dim, label_dim):
return MinibatchSource(CTFDeserializer(path, StreamDefs(
features=StreamDef(field='x', shape=input_dim, is_sparse=True),
labels=StreamDef(field='y', shape=label_dim, is_sparse=False)
)), randomize=is_training,
max_sweeps=INFINITELY_REPEAT if is_training else 1)
def LSTM_sequence_classifier_net(input, num_output_classes, embedding_dim,
LSTM_dim, cell_dim):
lstm_classifier = Sequential([Embedding(embedding_dim),
Recurrence(LSTM(LSTM_dim, cell_dim)),
sequence.last,
Dense(num_output_classes)])
return lstm_classifier(input)
def train_sequence_classifier():
input_dim = 2000
cell_dim = 25
hidden_dim = 25
embedding_dim = 50
num_output_classes = 5
features = sequence.input_variable(shape=input_dim, is_sparse=True)
label = input_variable(num_output_classes)
classifier_output = LSTM_sequence_classifier_net(
features, num_output_classes, embedding_dim, hidden_dim, cell_dim)
ce = cross_entropy_with_softmax(classifier_output, label)
pe = classification_error(classifier_output, label)
rel_path = ("../../../Tests/EndToEndTests/Text/" +
"SequenceClassification/Data/Train.ctf")
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), rel_path)
reader = create_reader(path, True, input_dim, num_output_classes)
input_map = {
features: reader.streams.features,
label: reader.streams.labels
}
lr_per_sample = learning_parameter_schedule_per_sample(0.0005)
progress_printer = ProgressPrinter(0)
trainer = Trainer(classifier_output, (ce, pe),
sgd(classifier_output.parameters, lr=lr_per_sample),progress_printer)
minibatch_size = 200
for i in range(255):
mb = reader.next_minibatch(minibatch_size, input_map=input_map)
trainer.train_minibatch(mb)
evaluation_average = float(trainer.previous_minibatch_evaluation_average)
loss_average = float(trainer.previous_minibatch_loss_average)
return evaluation_average, loss_average
if __name__ == '__main__':
error, _ = train_sequence_classifier()
print(" error: %f" % error)
average since average since examples
loss last metric last
------------------------------------------------------
1.61 1.61 0.886 0.886 44
1.61 1.6 0.714 0.629 133
1.6 1.59 0.56 0.448 316
1.57 1.55 0.479 0.41 682
1.53 1.5 0.464 0.449 1379
1.46 1.4 0.453 0.441 2813
1.37 1.28 0.45 0.447 5679
1.3 1.23 0.448 0.447 11365
error: 0.333333
Phần giải thích chi tiết của chương trình trên sẽ được đề cập trong các phần tiếp theo, đặc biệt là khi chúng ta sẽ xây dựng các mạng Neural tái diễn.
Chương này đề cập đến việc xây dựng mô hình hồi quy logistic trong CNTK.
Khái niệm cơ bản về mô hình hồi quy logistic
Hồi quy logistic, một trong những kỹ thuật ML đơn giản nhất, là một kỹ thuật đặc biệt để phân loại nhị phân. Nói cách khác, để tạo một mô hình dự đoán trong các tình huống mà giá trị của biến cần dự đoán có thể chỉ là một trong hai giá trị phân loại. Một trong những ví dụ đơn giản nhất của Logistic Regression là dự đoán một người là nam hay nữ, dựa trên tuổi tác, giọng nói, kiểu tóc của người đó, v.v.
Thí dụ
Chúng ta hãy hiểu khái niệm hồi quy logistic về mặt toán học với sự trợ giúp của một ví dụ khác -
Giả sử, chúng ta muốn dự đoán mức độ tín dụng của một đơn xin vay; 0 có nghĩa là từ chối và 1 có nghĩa là chấp thuận, dựa trên người nộp đơndebt , income và credit rating. Chúng tôi đại diện cho nợ với X1, thu nhập với X2 và xếp hạng tín dụng với X3.
Trong hồi quy logistic, chúng tôi xác định một giá trị trọng số, được đại diện bởi w, cho mọi tính năng và một giá trị thiên vị duy nhất, được đại diện bởi b.
Bây giờ, giả sử,
X1 = 3.0
X2 = -2.0
X3 = 1.0
Và giả sử chúng ta xác định trọng lượng và độ chệch như sau:
W1 = 0.65, W2 = 1.75, W3 = 2.05 and b = 0.33
Bây giờ, để dự đoán lớp, chúng ta cần áp dụng công thức sau:
Z = (X1*W1)+(X2*W2)+(X3+W3)+b
i.e. Z = (3.0)*(0.65) + (-2.0)*(1.75) + (1.0)*(2.05) + 0.33
= 0.83
Tiếp theo, chúng ta cần tính toán P = 1.0/(1.0 + exp(-Z)). Ở đây, hàm exp () là số của Euler.
P = 1.0/(1.0 + exp(-0.83)
= 0.6963
Giá trị P có thể được hiểu là xác suất mà lớp là 1. Nếu P <0,5, dự đoán là lớp = 0 còn dự đoán (P> = 0,5) là lớp = 1.
Để xác định các giá trị của trọng số và độ chệch, chúng ta phải có được một bộ dữ liệu huấn luyện có các giá trị dự đoán đầu vào đã biết và các giá trị nhãn lớp chính xác đã biết. Sau đó, chúng ta có thể sử dụng một thuật toán, nói chung là Gradient Descent, để tìm các giá trị của trọng số và độ chệch.
Ví dụ triển khai mô hình LR
Đối với mô hình LR này, chúng ta sẽ sử dụng tập dữ liệu sau:
1.0, 2.0, 0
3.0, 4.0, 0
5.0, 2.0, 0
6.0, 3.0, 0
8.0, 1.0, 0
9.0, 2.0, 0
1.0, 4.0, 1
2.0, 5.0, 1
4.0, 6.0, 1
6.0, 5.0, 1
7.0, 3.0, 1
8.0, 5.0, 1
Để bắt đầu triển khai mô hình LR này trong CNTK, trước tiên chúng ta cần nhập các gói sau:
import numpy as np
import cntk as C
Chương trình được cấu trúc với hàm main () như sau:
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
Bây giờ, chúng ta cần tải dữ liệu huấn luyện vào bộ nhớ như sau:
data_file = ".\\dataLRmodel.txt"
print("Loading data from " + data_file + "\n")
features_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",", skiprows=0, usecols=[0,1])
labels_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",", skiprows=0, usecols=[2], ndmin=2)
Bây giờ, chúng tôi sẽ tạo một chương trình đào tạo tạo mô hình hồi quy logistic tương thích với dữ liệu đào tạo -
features_dim = 2
labels_dim = 1
X = C.ops.input_variable(features_dim, np.float32)
y = C.input_variable(labels_dim, np.float32)
W = C.parameter(shape=(features_dim, 1)) # trainable cntk.Parameter
b = C.parameter(shape=(labels_dim))
z = C.times(X, W) + b
p = 1.0 / (1.0 + C.exp(-z))
model = p
Bây giờ, chúng ta cần tạo Lerner và huấn luyện viên như sau:
ce_error = C.binary_cross_entropy(model, y) # CE a bit more principled for LR
fixed_lr = 0.010
learner = C.sgd(model.parameters, fixed_lr)
trainer = C.Trainer(model, (ce_error), [learner])
max_iterations = 4000
Đào tạo mô hình LR
Khi chúng ta đã tạo xong mô hình LR, tiếp theo, đã đến lúc bắt đầu quá trình đào tạo -
np.random.seed(4)
N = len(features_mat)
for i in range(0, max_iterations):
row = np.random.choice(N,1) # pick a random row from training items
trainer.train_minibatch({ X: features_mat[row], y: labels_mat[row] })
if i % 1000 == 0 and i > 0:
mcee = trainer.previous_minibatch_loss_average
print(str(i) + " Cross-entropy error on curr item = %0.4f " % mcee)
Bây giờ, với sự trợ giúp của đoạn mã sau, chúng ta có thể in trọng số và độ lệch của mô hình -
np.set_printoptions(precision=4, suppress=True)
print("Model weights: ")
print(W.value)
print("Model bias:")
print(b.value)
print("")
if __name__ == "__main__":
main()
Đào tạo mô hình hồi quy logistic - Toàn bộ ví dụ
import numpy as np
import cntk as C
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
data_file = ".\\dataLRmodel.txt" # provide the name and the location of data file
print("Loading data from " + data_file + "\n")
features_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",", skiprows=0, usecols=[0,1])
labels_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",", skiprows=0, usecols=[2], ndmin=2)
features_dim = 2
labels_dim = 1
X = C.ops.input_variable(features_dim, np.float32)
y = C.input_variable(labels_dim, np.float32)
W = C.parameter(shape=(features_dim, 1)) # trainable cntk.Parameter
b = C.parameter(shape=(labels_dim))
z = C.times(X, W) + b
p = 1.0 / (1.0 + C.exp(-z))
model = p
ce_error = C.binary_cross_entropy(model, y) # CE a bit more principled for LR
fixed_lr = 0.010
learner = C.sgd(model.parameters, fixed_lr)
trainer = C.Trainer(model, (ce_error), [learner])
max_iterations = 4000
np.random.seed(4)
N = len(features_mat)
for i in range(0, max_iterations):
row = np.random.choice(N,1) # pick a random row from training items
trainer.train_minibatch({ X: features_mat[row], y: labels_mat[row] })
if i % 1000 == 0 and i > 0:
mcee = trainer.previous_minibatch_loss_average
print(str(i) + " Cross-entropy error on curr item = %0.4f " % mcee)
np.set_printoptions(precision=4, suppress=True)
print("Model weights: ")
print(W.value)
print("Model bias:")
print(b.value)
if __name__ == "__main__":
main()
Đầu ra
Using CNTK version = 2.7
1000 cross entropy error on curr item = 0.1941
2000 cross entropy error on curr item = 0.1746
3000 cross entropy error on curr item = 0.0563
Model weights:
[-0.2049]
[0.9666]]
Model bias:
[-2.2846]
Dự đoán sử dụng Mô hình LR được đào tạo
Khi mô hình LR đã được đào tạo, chúng ta có thể sử dụng nó để dự đoán như sau:
Trước hết, chương trình đánh giá của chúng tôi nhập gói numpy và tải dữ liệu đào tạo vào ma trận tính năng và ma trận nhãn lớp theo cách tương tự như chương trình đào tạo mà chúng tôi thực hiện ở trên -
import numpy as np
def main():
data_file = ".\\dataLRmodel.txt" # provide the name and the location of data file
features_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",",
skiprows=0, usecols=(0,1))
labels_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",",
skiprows=0, usecols=[2], ndmin=2)
Tiếp theo, đã đến lúc đặt các giá trị của trọng số và độ lệch đã được xác định bởi chương trình đào tạo của chúng tôi -
print("Setting weights and bias values \n")
weights = np.array([0.0925, 1.1722], dtype=np.float32)
bias = np.array([-4.5400], dtype=np.float32)
N = len(features_mat)
features_dim = 2
Tiếp theo, chương trình đánh giá của chúng tôi sẽ tính toán xác suất hồi quy logistic bằng cách xem qua từng mục đào tạo như sau:
print("item pred_prob pred_label act_label result")
for i in range(0, N): # each item
x = features_mat[i]
z = 0.0
for j in range(0, features_dim):
z += x[j] * weights[j]
z += bias[0]
pred_prob = 1.0 / (1.0 + np.exp(-z))
pred_label = 0 if pred_prob < 0.5 else 1
act_label = labels_mat[i]
pred_str = ‘correct’ if np.absolute(pred_label - act_label) < 1.0e-5 \
else ‘WRONG’
print("%2d %0.4f %0.0f %0.0f %s" % \ (i, pred_prob, pred_label, act_label, pred_str))
Bây giờ hãy để chúng tôi trình bày cách thực hiện dự đoán -
x = np.array([9.5, 4.5], dtype=np.float32)
print("\nPredicting class for age, education = ")
print(x)
z = 0.0
for j in range(0, features_dim):
z += x[j] * weights[j]
z += bias[0]
p = 1.0 / (1.0 + np.exp(-z))
print("Predicted p = " + str(p))
if p < 0.5: print("Predicted class = 0")
else: print("Predicted class = 1")
Hoàn thành chương trình đánh giá dự đoán
import numpy as np
def main():
data_file = ".\\dataLRmodel.txt" # provide the name and the location of data file
features_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",",
skiprows=0, usecols=(0,1))
labels_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",",
skiprows=0, usecols=[2], ndmin=2)
print("Setting weights and bias values \n")
weights = np.array([0.0925, 1.1722], dtype=np.float32)
bias = np.array([-4.5400], dtype=np.float32)
N = len(features_mat)
features_dim = 2
print("item pred_prob pred_label act_label result")
for i in range(0, N): # each item
x = features_mat[i]
z = 0.0
for j in range(0, features_dim):
z += x[j] * weights[j]
z += bias[0]
pred_prob = 1.0 / (1.0 + np.exp(-z))
pred_label = 0 if pred_prob < 0.5 else 1
act_label = labels_mat[i]
pred_str = ‘correct’ if np.absolute(pred_label - act_label) < 1.0e-5 \
else ‘WRONG’
print("%2d %0.4f %0.0f %0.0f %s" % \ (i, pred_prob, pred_label, act_label, pred_str))
x = np.array([9.5, 4.5], dtype=np.float32)
print("\nPredicting class for age, education = ")
print(x)
z = 0.0
for j in range(0, features_dim):
z += x[j] * weights[j]
z += bias[0]
p = 1.0 / (1.0 + np.exp(-z))
print("Predicted p = " + str(p))
if p < 0.5: print("Predicted class = 0")
else: print("Predicted class = 1")
if __name__ == "__main__":
main()
Đầu ra
Đặt trọng số và giá trị thiên vị.
Item pred_prob pred_label act_label result
0 0.3640 0 0 correct
1 0.7254 1 0 WRONG
2 0.2019 0 0 correct
3 0.3562 0 0 correct
4 0.0493 0 0 correct
5 0.1005 0 0 correct
6 0.7892 1 1 correct
7 0.8564 1 1 correct
8 0.9654 1 1 correct
9 0.7587 1 1 correct
10 0.3040 0 1 WRONG
11 0.7129 1 1 correct
Predicting class for age, education =
[9.5 4.5]
Predicting p = 0.526487952
Predicting class = 1
Chương này đề cập đến các khái niệm về Mạng thần kinh liên quan đến CNTK.
Như chúng ta đã biết, một số lớp tế bào thần kinh được sử dụng để tạo ra một mạng lưới thần kinh. Nhưng, một câu hỏi đặt ra là trong CNTK làm thế nào chúng ta có thể mô hình hóa các tầng của một NN? Nó có thể được thực hiện với sự trợ giúp của các chức năng lớp được xác định trong mô-đun lớp.
Chức năng lớp
Trên thực tế, trong CNTK, làm việc với các lớp có một cảm giác lập trình chức năng khác biệt đối với nó. Hàm lớp trông giống như một hàm thông thường và nó tạo ra một hàm toán học với một tập hợp các tham số được xác định trước. Hãy xem cách chúng ta có thể tạo kiểu lớp cơ bản nhất, Dense, với sự trợ giúp của chức năng lớp.
Thí dụ
Với sự trợ giúp của các bước cơ bản sau, chúng ta có thể tạo kiểu lớp cơ bản nhất -
Step 1 - Đầu tiên, chúng ta cần nhập hàm lớp dày đặc từ gói các lớp của CNTK.
from cntk.layers import Dense
Step 2 - Tiếp theo từ gói gốc CNTK, chúng ta cần nhập hàm input_variable.
from cntk import input_variable
Step 3- Bây giờ, chúng ta cần tạo một biến đầu vào mới bằng cách sử dụng hàm input_variable. Chúng tôi cũng cần cung cấp kích thước của nó.
feature = input_variable(100)
Step 4 - Cuối cùng, chúng ta sẽ tạo một lớp mới bằng cách sử dụng hàm Dense cùng với việc cung cấp số lượng tế bào thần kinh mà chúng ta muốn.
layer = Dense(40)(feature)
Bây giờ, chúng ta có thể gọi hàm lớp Dense đã cấu hình để kết nối lớp dày đặc với đầu vào.
Hoàn thành ví dụ triển khai
from cntk.layers import Dense
from cntk import input_variable
feature= input_variable(100)
layer = Dense(40)(feature)
Tùy chỉnh các lớp
Như chúng ta đã thấy CNTK cung cấp cho chúng ta một bộ giá trị mặc định khá tốt để xây dựng NN. Dựa trênactivationchức năng và các cài đặt khác mà chúng tôi chọn, hành vi cũng như hiệu suất của NN là khác nhau. Đó là một thuật toán tạo gốc rất hữu ích khác. Đó là lý do, thật tốt để hiểu những gì chúng ta có thể cấu hình.
Các bước để định cấu hình một lớp dày đặc
Mỗi lớp trong NN có các tùy chọn cấu hình riêng và khi chúng ta nói về lớp Dày, chúng ta có các cài đặt quan trọng sau để xác định:
shape - Như tên của nó, nó xác định hình dạng đầu ra của lớp, xác định thêm số lượng tế bào thần kinh trong lớp đó.
activation - Nó xác định chức năng kích hoạt của lớp đó, vì vậy nó có thể biến đổi dữ liệu đầu vào.
init- Nó xác định chức năng khởi tạo của lớp đó. Nó sẽ khởi tạo các tham số của lớp khi chúng ta bắt đầu đào tạo NN.
Hãy xem các bước với sự trợ giúp của chúng tôi có thể định cấu hình Dense lớp -
Step1 - Đầu tiên, chúng ta cần nhập Dense chức năng lớp từ gói các lớp của CNTK.
from cntk.layers import Dense
Step2 - Tiếp theo từ gói hoạt động CNTK, chúng ta cần nhập sigmoid operator. Nó sẽ được sử dụng để cấu hình như một chức năng kích hoạt.
from cntk.ops import sigmoid
Step3 - Bây giờ, từ gói khởi tạo, chúng ta cần nhập glorot_uniform bộ khởi tạo.
from cntk.initializer import glorot_uniform
Step4 - Cuối cùng, chúng ta sẽ tạo một lớp mới bằng cách sử dụng hàm Dense cùng với việc cung cấp số lượng tế bào thần kinh làm đối số đầu tiên. Ngoài ra, cung cấpsigmoid nhà điều hành như activation chức năng và glorot_uniform như là init chức năng cho lớp.
layer = Dense(50, activation = sigmoid, init = glorot_uniform)
Hoàn thành ví dụ triển khai -
from cntk.layers import Dense
from cntk.ops import sigmoid
from cntk.initializer import glorot_uniform
layer = Dense(50, activation = sigmoid, init = glorot_uniform)
Tối ưu hóa các thông số
Cho đến bây giờ, chúng ta đã thấy cách tạo cấu trúc của NN và cách cấu hình các cài đặt khác nhau. Ở đây, chúng ta sẽ thấy, làm thế nào chúng ta có thể tối ưu hóa các tham số của NN. Với sự giúp đỡ của sự kết hợp của hai thành phần cụ thể làlearners và trainers, chúng ta có thể tối ưu hóa các tham số của NN.
thành phần huấn luyện viên
Thành phần đầu tiên được sử dụng để tối ưu hóa các tham số của NN là trainerthành phần. Về cơ bản, nó thực hiện quá trình nhân giống ngược. Nếu chúng ta nói về hoạt động của nó, nó sẽ chuyển dữ liệu qua NN để có được một dự đoán.
Sau đó, nó sử dụng một thành phần khác được gọi là người học để lấy các giá trị mới cho các tham số trong NN. Khi nhận được các giá trị mới, nó sẽ áp dụng các giá trị mới này và lặp lại quy trình cho đến khi đáp ứng tiêu chí thoát.
thành phần người học
Thành phần thứ hai được sử dụng để tối ưu hóa các tham số của NN là learner thành phần, về cơ bản chịu trách nhiệm thực hiện thuật toán giảm độ dốc.
Người học được đưa vào thư viện CNTK
Sau đây là danh sách một số học viên thú vị có trong thư viện CNTK -
Stochastic Gradient Descent (SGD) - Người học này đại diện cho sự xuống dốc ngẫu nhiên cơ bản, không có bất kỳ tính năng bổ sung nào.
Momentum Stochastic Gradient Descent (MomentumSGD) - Với SGD, người học này vận dụng động lượng để vượt qua bài toán cực đại cục bộ.
RMSProp - Người học này, để kiểm soát tỷ lệ xuống cấp, sử dụng tỷ lệ học giảm dần.
Adam - Người học này, để giảm tỷ lệ xuống dốc theo thời gian, sử dụng động lượng giảm dần.
Adagrad - Người học này, đối với các tính năng thường xuyên cũng như không thường xuyên, sử dụng các tỷ lệ học tập khác nhau.
CNTK - Tạo mạng thần kinh đầu tiên
Chương này sẽ trình bày chi tiết về cách tạo mạng nơ-ron trong CNTK.
Xây dựng cấu trúc mạng
Để áp dụng các khái niệm CNTK để xây dựng NN đầu tiên, chúng ta sẽ sử dụng NN để phân loại các loài hoa iris dựa trên các đặc tính vật lý của chiều rộng và chiều dài lá đài, chiều rộng và chiều dài của cánh hoa. Tập dữ liệu mà chúng tôi sẽ sử dụng tập dữ liệu iris mô tả các đặc tính vật lý của các giống hoa iris khác nhau -
- Chiều dài Sepal
- Chiều rộng vách ngăn
- Chiều dài cánh hoa
- Chiều rộng cánh hoa
- Loại iris setosa hoặc iris versicolor hoặc iris virginica
Ở đây, chúng ta sẽ xây dựng một NN thông thường được gọi là NN chuyển tiếp. Chúng ta cùng xem các bước thực hiện để xây dựng cấu trúc NN -
Step 1 - Đầu tiên, chúng ta sẽ nhập các thành phần cần thiết như kiểu lớp, hàm kích hoạt và một hàm cho phép chúng ta xác định một biến đầu vào cho NN của chúng ta, từ thư viện CNTK.
from cntk import default_options, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import log_softmax, relu
Step 2- Sau đó, chúng ta sẽ tạo mô hình của mình bằng cách sử dụng hàm tuần tự. Sau khi được tạo, chúng tôi sẽ cung cấp cho nó các lớp mà chúng tôi muốn. Ở đây, chúng ta sẽ tạo ra hai lớp riêng biệt trong NN của chúng ta; một với bốn nơ-ron và một với ba nơ-ron.
model = Sequential([Dense(4, activation=relu), Dense(3, activation=log_sogtmax)])
Step 3- Cuối cùng, để biên dịch NN, chúng ta sẽ gắn mạng với biến đầu vào. Nó có một lớp đầu vào với bốn tế bào thần kinh và một lớp đầu ra với ba tế bào thần kinh.
feature= input_variable(4)
z = model(feature)
Áp dụng chức năng kích hoạt
Có rất nhiều chức năng kích hoạt để lựa chọn và việc chọn đúng chức năng kích hoạt chắc chắn sẽ tạo ra sự khác biệt lớn đối với mô hình học sâu của chúng tôi sẽ hoạt động tốt như thế nào.
Ở lớp đầu ra
Chọn một activation chức năng ở lớp đầu ra sẽ phụ thuộc vào loại vấn đề mà chúng ta sẽ giải quyết với mô hình của mình.
Đối với vấn đề hồi quy, chúng ta nên sử dụng linear activation function trên lớp đầu ra.
Đối với vấn đề phân loại nhị phân, chúng ta nên sử dụng sigmoid activation function trên lớp đầu ra.
Đối với vấn đề phân loại nhiều lớp, chúng ta nên sử dụng softmax activation function trên lớp đầu ra.
Ở đây, chúng ta sẽ xây dựng một mô hình để dự đoán một trong ba lớp. Nó có nghĩa là chúng ta cần sử dụngsoftmax activation function ở lớp đầu ra.
Tại lớp ẩn
Chọn một activation chức năng ở lớp ẩn yêu cầu một số thử nghiệm để theo dõi hiệu suất để xem chức năng kích hoạt nào hoạt động tốt.
Trong một bài toán phân loại, chúng ta cần dự đoán xác suất một mẫu thuộc về một lớp cụ thể. Đó là lý do tại sao chúng ta cần mộtactivation functioncung cấp cho chúng tôi các giá trị xác suất. Để đạt được mục tiêu này,sigmoid activation function có thể giúp chúng tôi.
Một trong những vấn đề lớn liên quan đến chức năng sigmoid là vấn đề gradient biến mất. Để khắc phục sự cố như vậy, chúng ta có thể sử dụngReLU activation function phủ tất cả các giá trị âm thành 0 và hoạt động như một bộ lọc chuyển qua cho các giá trị dương.
Chọn một chức năng mất mát
Khi đã có cấu trúc cho mô hình NN của mình, chúng ta phải tối ưu hóa nó. Để tối ưu hóa, chúng tôi cần mộtloss function. không giốngactivation functions, chúng tôi có rất ít chức năng mất mát để lựa chọn. Tuy nhiên, việc chọn một hàm mất mát sẽ phụ thuộc vào loại vấn đề mà chúng ta sẽ giải quyết với mô hình của mình.
Ví dụ, trong một bài toán phân loại, chúng ta nên sử dụng một hàm tổn thất có thể đo lường sự khác biệt giữa một lớp dự đoán và một lớp thực tế.
thiếu chức năng
Đối với vấn đề phân loại, chúng tôi sẽ giải quyết bằng mô hình NN của chúng tôi, categorical cross entropychức năng mất mát là ứng cử viên tốt nhất. Trong CNTK, nó được thực hiện nhưcross_entropy_with_softmax có thể được nhập khẩu từ cntk.losses gói, như sau
label= input_variable(3)
loss = cross_entropy_with_softmax(z, label)
Số liệu
Với việc có cấu trúc cho mô hình NN của chúng tôi và một hàm mất mát để áp dụng, chúng tôi có tất cả các yếu tố để bắt đầu đưa ra công thức tối ưu hóa mô hình học sâu của mình. Tuy nhiên, trước khi đi sâu vào vấn đề này, chúng ta nên tìm hiểu về các chỉ số.
cntk.metrics
CNTK có gói được đặt tên cntk.metricstừ đó chúng tôi có thể nhập các số liệu mà chúng tôi sẽ sử dụng. Khi chúng tôi đang xây dựng một mô hình phân loại, chúng tôi sẽ sử dụngclassification_error matric sẽ tạo ra một số từ 0 đến 1. Số từ 0 đến 1 cho biết phần trăm mẫu được dự đoán chính xác -
Trước tiên, chúng tôi cần nhập số liệu từ cntk.metrics gói -
from cntk.metrics import classification_error
error_rate = classification_error(z, label)
Hàm trên thực sự cần đầu ra của NN và nhãn mong đợi làm đầu vào.
CNTK - Đào tạo mạng lưới thần kinh
Ở đây, chúng ta sẽ hiểu về việc đào tạo Neural Network trong CNTK.
Đào tạo một mô hình trong CNTK
Trong phần trước, chúng ta đã xác định tất cả các thành phần cho mô hình học sâu. Bây giờ là lúc để đào tạo nó. Như đã thảo luận trước đó, chúng ta có thể đào tạo một mô hình NN trong CNTK bằng cách sử dụng kết hợplearner và trainer.
Chọn người học và thiết lập chương trình đào tạo
Trong phần này, chúng tôi sẽ xác định learner. CNTK cung cấp một sốlearnersđể lựa chọn. Đối với mô hình của chúng tôi, được xác định trong các phần trước, chúng tôi sẽ sử dụngStochastic Gradient Descent (SGD) learner.
Để đào tạo mạng nơ-ron, chúng ta hãy định cấu hình learner và trainer với sự trợ giúp của các bước sau -
Step 1 - Đầu tiên, chúng ta cần nhập sgd chức năng từ cntk.lerners gói hàng.
from cntk.learners import sgd
Step 2 - Tiếp theo, chúng ta cần nhập Trainer chức năng từ cntk.traingói .trainer.
from cntk.train.trainer import Trainer
Step 3 - Bây giờ, chúng ta cần tạo một learner. Nó có thể được tạo ra bằng cách gọisgd cùng với việc cung cấp các tham số của mô hình và giá trị cho tốc độ học.
learner = sgd(z.parametrs, 0.01)
Step 4 - Cuối cùng, chúng ta cần khởi tạo trainer. Nó phải được cung cấp mạng, sự kết hợp củaloss và metric cùng với learner.
trainer = Trainer(z, (loss, error_rate), [learner])
Tỷ lệ học tập kiểm soát tốc độ tối ưu hóa phải là một số nhỏ trong khoảng từ 0,1 đến 0,001.
Chọn người học và thiết lập khóa đào tạo - Hoàn thành ví dụ
from cntk.learners import sgd
from cntk.train.trainer import Trainer
learner = sgd(z.parametrs, 0.01)
trainer = Trainer(z, (loss, error_rate), [learner])
Cung cấp dữ liệu vào giảng viên
Khi chúng tôi đã chọn và định cấu hình trình đào tạo, đã đến lúc tải tập dữ liệu. Chúng tôi đã lưuiris tập dữ liệu như một.CSV tệp và chúng tôi sẽ sử dụng gói dữ liệu bao bọc có tên pandas để tải tập dữ liệu.
Các bước để tải tập dữ liệu từ tệp .CSV
Step 1 - Đầu tiên, chúng ta cần nhập pandas gói hàng.
from import pandas as pd
Step 2 - Bây giờ, chúng ta cần gọi hàm có tên read_csv chức năng tải tệp .csv từ đĩa.
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’,
‘petal_length’, ‘petal_width’, index_col=False)
Khi chúng tôi tải tập dữ liệu, chúng tôi cần chia nó thành một tập hợp các tính năng và một nhãn.
Các bước để chia tập dữ liệu thành các tính năng và nhãn
Step 1- Đầu tiên, chúng ta cần chọn tất cả các hàng và bốn cột đầu tiên từ tập dữ liệu. Nó có thể được thực hiện bằng cách sử dụngiloc chức năng.
x = df_source.iloc[:, :4].values
Step 2- Tiếp theo chúng ta cần chọn cột loài từ tập dữ liệu iris. Chúng tôi sẽ sử dụng thuộc tính giá trị để truy cập vàonumpy mảng.
x = df_source[‘species’].values
Các bước để mã hóa cột loài thành biểu diễn vectơ số
Như chúng ta đã thảo luận trước đó, mô hình của chúng tôi dựa trên phân loại, nó yêu cầu các giá trị đầu vào dạng số. Do đó, ở đây chúng ta cần mã hóa cột loài thành biểu diễn vectơ số. Hãy xem các bước để làm điều đó -
Step 1- Đầu tiên, chúng ta cần tạo một biểu thức danh sách để lặp trên tất cả các phần tử trong mảng. Sau đó, thực hiện tra cứu trong từ điển ánh xạ nhãn cho từng giá trị.
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
Step 2- Tiếp theo, chuyển đổi giá trị số đã chuyển đổi này thành vectơ được mã hóa một nóng. Chúng tôi sẽ sử dụngone_hot chức năng như sau -
def one_hot(index, length):
result = np.zeros(length)
result[index] = 1
return result
Step 3 - Cuối cùng, chúng ta cần chuyển danh sách đã chuyển đổi này thành một numpy mảng.
y = np.array([one_hot(label_mapping[v], 3) for v in y])
Các bước để phát hiện trang bị quá mức
Tình huống, khi mô hình của bạn nhớ các mẫu nhưng không thể suy ra các quy tắc từ các mẫu đào tạo, là quá mức. Với sự trợ giúp của các bước sau, chúng tôi có thể phát hiện trang bị quá mức trên mô hình của mình -
Step 1 - Đầu tiên, từ sklearn gói, nhập train_test_split chức năng từ model_selection mô-đun.
from sklearn.model_selection import train_test_split
Step 2 - Tiếp theo, chúng ta cần gọi hàm train_test_split với các tính năng x và nhãn y như sau:
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0-2,
stratify=y)
Chúng tôi đã chỉ định test_size là 0,2 để dành 20% tổng số dữ liệu.
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
Các bước để cung cấp bộ đào tạo và bộ xác thực cho mô hình của chúng tôi
Step 1 - Để đào tạo mô hình của chúng tôi, trước tiên, chúng tôi sẽ gọi train_minibatchphương pháp. Sau đó, cung cấp cho nó một từ điển ánh xạ dữ liệu đầu vào đến biến đầu vào mà chúng ta đã sử dụng để xác định NN và hàm mất mát liên quan của nó.
trainer.train_minibatch({ features: X_train, label: y_train})
Step 2 - Tiếp theo, hãy gọi train_minibatch bằng cách sử dụng vòng lặp for sau:
for _epoch in range(10):
trainer.train_minbatch ({ feature: X_train, label: y_train})
print(‘Loss: {}, Acc: {}’.format(
trainer.previous_minibatch_loss_average,
trainer.previous_minibatch_evaluation_average))
Cung cấp dữ liệu vào giảng viên - Hoàn thành ví dụ
from import pandas as pd
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, index_col=False)
x = df_source.iloc[:, :4].values
x = df_source[‘species’].values
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
def one_hot(index, length):
result = np.zeros(length)
result[index] = 1
return result
y = np.array([one_hot(label_mapping[v], 3) for v in y])
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0-2, stratify=y)
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
trainer.train_minibatch({ features: X_train, label: y_train})
for _epoch in range(10):
trainer.train_minbatch ({ feature: X_train, label: y_train})
print(‘Loss: {}, Acc: {}’.format(
trainer.previous_minibatch_loss_average,
trainer.previous_minibatch_evaluation_average))
Đo lường hiệu quả hoạt động của NN
Để tối ưu hóa mô hình NN của chúng tôi, bất cứ khi nào chúng tôi chuyển dữ liệu qua trình đào tạo, nó sẽ đo lường hiệu suất của mô hình thông qua số liệu mà chúng tôi đã định cấu hình cho giảng viên. Việc đo lường hiệu suất của mô hình NN trong quá trình đào tạo dựa trên dữ liệu đào tạo. Nhưng mặt khác, để phân tích đầy đủ hiệu suất của mô hình, chúng ta cũng cần sử dụng dữ liệu thử nghiệm.
Vì vậy, để đo lường hiệu suất của mô hình bằng cách sử dụng dữ liệu thử nghiệm, chúng ta có thể gọi test_minibatch phương pháp trên trainer như sau -
trainer.test_minibatch({ features: X_test, label: y_test})
Dự đoán cùng NN
Khi bạn đã đào tạo một mô hình học sâu, điều quan trọng nhất là đưa ra dự đoán bằng cách sử dụng mô hình đó. Để đưa ra dự đoán từ NN được đào tạo ở trên, chúng ta có thể làm theo các bước đã cho
Step 1 - Đầu tiên, chúng ta cần chọn một mục ngẫu nhiên từ bộ thử nghiệm bằng cách sử dụng chức năng sau:
np.random.choice
Step 2 - Tiếp theo, chúng ta cần chọn dữ liệu mẫu từ bộ thử nghiệm bằng cách sử dụng sample_index.
Step 3 - Bây giờ, để chuyển đầu ra số cho NN thành một nhãn thực, hãy tạo một ánh xạ ngược.
Step 4 - Bây giờ, sử dụng sampledữ liệu. Đưa ra dự đoán bằng cách gọi NN z dưới dạng một hàm.
Step 5- Bây giờ, khi bạn đã có kết quả dự đoán, hãy lấy chỉ số của nơ-ron có giá trị cao nhất làm giá trị dự đoán. Nó có thể được thực hiện bằng cách sử dụngnp.argmax chức năng từ numpy gói hàng.
Step 6 - Cuối cùng, chuyển đổi giá trị chỉ mục thành nhãn thực bằng cách sử dụng inverted_mapping.
Dự đoán với NN - Hoàn thành ví dụ
sample_index = np.random.choice(X_test.shape[0])
sample = X_test[sample_index]
inverted_mapping = {
1:’Iris-setosa’,
2:’Iris-versicolor’,
3:’Iris-virginica’
}
prediction = z(sample)
predicted_label = inverted_mapping[np.argmax(prediction)]
print(predicted_label)
Đầu ra
Sau khi đào tạo mô hình học sâu ở trên và chạy nó, bạn sẽ nhận được kết quả sau:
Iris-versicolor
CNTK - Bộ nhớ trong và bộ dữ liệu lớn
Trong chương này, chúng ta sẽ tìm hiểu về cách làm việc với bộ nhớ trong và bộ dữ liệu lớn trong CNTK.
Đào tạo với bộ dữ liệu bộ nhớ nhỏ
Khi chúng ta nói về việc cung cấp dữ liệu vào trình huấn luyện CNTK, có thể có nhiều cách, nhưng nó sẽ phụ thuộc vào kích thước của tập dữ liệu và định dạng của dữ liệu. Tập dữ liệu có thể là tập dữ liệu trong bộ nhớ nhỏ hoặc tập dữ liệu lớn.
Trong phần này, chúng ta sẽ làm việc với các tập dữ liệu trong bộ nhớ. Đối với điều này, chúng tôi sẽ sử dụng hai khuôn khổ sau:
- Numpy
- Pandas
Sử dụng mảng Numpy
Ở đây, chúng tôi sẽ làm việc với một tập dữ liệu được tạo ngẫu nhiên dựa trên numpy trong CNTK. Trong ví dụ này, chúng ta sẽ mô phỏng dữ liệu cho một bài toán phân loại nhị phân. Giả sử, chúng ta có một tập hợp các quan sát với 4 đặc điểm và muốn dự đoán hai nhãn có thể có bằng mô hình học sâu của chúng ta.
Ví dụ triển khai
Đối với điều này, trước tiên chúng ta phải tạo một tập hợp các nhãn có chứa biểu diễn vector một nóng của các nhãn, chúng ta muốn dự đoán. Nó có thể được thực hiện với sự trợ giúp của các bước sau:
Step 1 - Nhập numpy gói như sau -
import numpy as np
num_samples = 20000
Step 2 - Tiếp theo, tạo ánh xạ nhãn bằng cách sử dụng np.eye chức năng như sau -
label_mapping = np.eye(2)
Step 3 - Bây giờ bằng cách sử dụng np.random.choice chức năng, thu thập 20000 mẫu ngẫu nhiên như sau:
y = label_mapping[np.random.choice(2,num_samples)].astype(np.float32)
Step 4 - Bây giờ cuối cùng bằng cách sử dụng hàm np.random.random, tạo một mảng các giá trị dấu chấm động ngẫu nhiên như sau:
x = np.random.random(size=(num_samples, 4)).astype(np.float32)
Sau khi, chúng tôi tạo ra một mảng các giá trị dấu phẩy động ngẫu nhiên, chúng tôi cần chuyển đổi chúng thành số dấu phẩy động 32 bit để nó có thể khớp với định dạng mà CNTK mong đợi. Hãy làm theo các bước dưới đây để làm điều này -
Step 5 - Nhập các chức năng lớp dày đặc và tuần tự từ mô-đun cntk.layers như sau:
from cntk.layers import Dense, Sequential
Step 6- Bây giờ, chúng ta cần nhập hàm kích hoạt cho các lớp trong mạng. Hãy để chúng tôi nhậpsigmoid như chức năng kích hoạt -
from cntk import input_variable, default_options
from cntk.ops import sigmoid
Step 7- Bây giờ, chúng ta cần nhập hàm tổn thất để huấn luyện mạng. Hãy để chúng tôi nhập khẩubinary_cross_entropy như hàm mất mát -
from cntk.losses import binary_cross_entropy
Step 8- Tiếp theo, chúng ta cần xác định các tùy chọn mặc định cho mạng. Ở đây, chúng tôi sẽ cung cấpsigmoidchức năng kích hoạt như một cài đặt mặc định. Ngoài ra, tạo mô hình bằng cách sử dụng chức năng lớp Tuần tự như sau:
with default_options(activation=sigmoid):
model = Sequential([Dense(6),Dense(2)])
Step 9 - Tiếp theo, khởi tạo một input_variable với 4 tính năng đầu vào đóng vai trò là đầu vào cho mạng.
features = input_variable(4)
Step 10 - Bây giờ, để hoàn thành nó, chúng ta cần kết nối biến tính năng với NN.
z = model(features)
Vì vậy, bây giờ chúng ta có một NN, với sự trợ giúp của các bước sau, chúng ta hãy đào tạo nó bằng cách sử dụng tập dữ liệu trong bộ nhớ -
Step 11 - Để đào tạo NN này, trước tiên chúng ta cần nhập người học từ cntk.learnersmô-đun. Chúng tôi sẽ nhập khẩusgd người học như sau -
from cntk.learners import sgd
Step 12 - Cùng với đó nhập khẩu ProgressPrinter từ cntk.logging cũng như mô-đun.
from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)
Step 13 - Tiếp theo, xác định một biến đầu vào mới cho các nhãn như sau:
labels = input_variable(2)
Step 14 - Để đào tạo mô hình NN, tiếp theo, chúng ta cần xác định lỗ bằng cách sử dụng binary_cross_entropychức năng. Ngoài ra, cung cấp mô hình z và biến nhãn.
loss = binary_cross_entropy(z, labels)
Step 15 - Tiếp theo, khởi tạo sgd người học như sau -
learner = sgd(z.parameters, lr=0.1)
Step 16- Cuối cùng, gọi phương thức train trên hàm mất mát. Ngoài ra, cung cấp cho nó dữ liệu đầu vào,sgd người học và progress_printer.−
training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer])
Hoàn thành ví dụ triển khai
import numpy as np
num_samples = 20000
label_mapping = np.eye(2)
y = label_mapping[np.random.choice(2,num_samples)].astype(np.float32)
x = np.random.random(size=(num_samples, 4)).astype(np.float32)
from cntk.layers import Dense, Sequential
from cntk import input_variable, default_options
from cntk.ops import sigmoid
from cntk.losses import binary_cross_entropy
with default_options(activation=sigmoid):
model = Sequential([Dense(6),Dense(2)])
features = input_variable(4)
z = model(features)
from cntk.learners import sgd
from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)
labels = input_variable(2)
loss = binary_cross_entropy(z, labels)
learner = sgd(z.parameters, lr=0.1)
training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer])
Đầu ra
Build info:
Built time: *** ** **** 21:40:10
Last modified date: *** *** ** 21:08:46 2019
Build type: Release
Build target: CPU-only
With ASGD: yes
Math lib: mkl
Build Branch: HEAD
Build SHA1:ae9c9c7c5f9e6072cc9c94c254f816dbdc1c5be6 (modified)
MPI distribution: Microsoft MPI
MPI version: 7.0.12437.6
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.52 1.52 0 0 32
1.51 1.51 0 0 96
1.48 1.46 0 0 224
1.45 1.42 0 0 480
1.42 1.4 0 0 992
1.41 1.39 0 0 2016
1.4 1.39 0 0 4064
1.39 1.39 0 0 8160
1.39 1.39 0 0 16352
Sử dụng Pandas DataFrames
Mảng khó hiểu rất hạn chế về những gì chúng có thể chứa và là một trong những cách lưu trữ dữ liệu cơ bản nhất. Ví dụ, một mảng n chiều có thể chứa dữ liệu của một kiểu dữ liệu duy nhất. Nhưng mặt khác, đối với nhiều trường hợp trong thế giới thực, chúng ta cần một thư viện có thể xử lý nhiều hơn một kiểu dữ liệu trong một tập dữ liệu.
Một trong những thư viện Python có tên là Pandas giúp làm việc với loại tập dữ liệu như vậy dễ dàng hơn. Nó giới thiệu khái niệm về DataFrame (DF) và cho phép chúng ta tải các tập dữ liệu từ đĩa được lưu trữ ở các định dạng khác nhau dưới dạng DF. Ví dụ: chúng ta có thể đọc các DF được lưu trữ dưới dạng CSV, JSON, Excel, v.v.
Bạn có thể tìm hiểu thư viện Python Pandas chi tiết hơn tại https://www.tutorialspoint.com/python_pandas/index.htm.
Ví dụ triển khai
Trong ví dụ này, chúng tôi sẽ sử dụng ví dụ phân loại ba loài hoa iris có thể có dựa trên bốn đặc tính. Chúng tôi cũng đã tạo ra mô hình học sâu này trong các phần trước. Mô hình như sau:
from cntk.layers import Dense, Sequential
from cntk import input_variable, default_options
from cntk.ops import sigmoid, log_softmax
from cntk.losses import binary_cross_entropy
model = Sequential([
Dense(4, activation=sigmoid),
Dense(3, activation=log_softmax)
])
features = input_variable(4)
z = model(features)
Mô hình trên chứa một lớp ẩn và một lớp đầu ra với ba tế bào thần kinh để phù hợp với số lượng lớp mà chúng ta có thể dự đoán.
Tiếp theo, chúng tôi sẽ sử dụng train phương pháp và losschức năng huấn luyện mạng. Đối với điều này, trước tiên chúng ta phải tải và xử lý trước tập dữ liệu mống mắt, để nó khớp với bố cục và định dạng dữ liệu mong đợi cho NN. Nó có thể được thực hiện với sự trợ giúp của các bước sau:
Step 1 - Nhập numpy và Pandas gói như sau -
import numpy as np
import pandas as pd
Step 2 - Tiếp theo, sử dụng read_csv chức năng tải tập dữ liệu vào bộ nhớ -
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’,
‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
Step 3 - Bây giờ, chúng ta cần tạo một từ điển sẽ ánh xạ các nhãn trong tập dữ liệu với biểu diễn số tương ứng của chúng.
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
Step 4 - Bây giờ, bằng cách sử dụng iloc trình lập chỉ mục trên DataFrame, chọn bốn cột đầu tiên như sau:
x = df_source.iloc[:, :4].values
Step 5−Tiếp theo, chúng ta cần chọn các cột loài làm nhãn cho tập dữ liệu. Nó có thể được thực hiện như sau:
y = df_source[‘species’].values
Step 6 - Bây giờ, chúng ta cần ánh xạ các nhãn trong tập dữ liệu, có thể được thực hiện bằng cách sử dụng label_mapping. Ngoài ra, sử dụngone_hot mã hóa để chuyển đổi chúng thành mảng mã hóa một nóng.
y = np.array([one_hot(label_mapping[v], 3) for v in y])
Step 7 - Tiếp theo, để sử dụng các tính năng và nhãn được ánh xạ với CNTK, chúng ta cần chuyển đổi cả hai thành float -
x= x.astype(np.float32)
y= y.astype(np.float32)
Như chúng ta biết rằng, các nhãn được lưu trữ trong tập dữ liệu dưới dạng chuỗi và CNTK không thể hoạt động với các chuỗi này. Đó là lý do, nó cần các vectơ được mã hóa một nóng đại diện cho các nhãn. Đối với điều này, chúng ta có thể xác định một hàm nóione_hot như sau -
def one_hot(index, length):
result = np.zeros(length)
result[index] = index
return result
Bây giờ, chúng ta có mảng numpy ở định dạng chính xác, với sự trợ giúp của các bước sau, chúng ta có thể sử dụng chúng để đào tạo mô hình của mình -
Step 8- Đầu tiên, chúng ta cần nhập hàm tổn thất để luyện mạng. Hãy để chúng tôi nhập khẩubinary_cross_entropy_with_softmax như hàm mất mát -
from cntk.losses import binary_cross_entropy_with_softmax
Step 9 - Để đào tạo NN này, chúng ta cũng cần nhập người học từ cntk.learnersmô-đun. Chúng tôi sẽ nhập khẩusgd người học như sau -
from cntk.learners import sgd
Step 10 - Cùng với đó nhập khẩu ProgressPrinter từ cntk.logging cũng như mô-đun.
from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)
Step 11 - Tiếp theo, xác định một biến đầu vào mới cho các nhãn như sau:
labels = input_variable(3)
Step 12 - Để đào tạo mô hình NN, tiếp theo, chúng ta cần xác định lỗ bằng cách sử dụng binary_cross_entropy_with_softmaxchức năng. Đồng thời cung cấp mô hình z và biến nhãn.
loss = binary_cross_entropy_with_softmax (z, labels)
Step 13 - Tiếp theo, khởi tạo sgd người học như sau -
learner = sgd(z.parameters, 0.1)
Step 14- Cuối cùng, gọi phương thức train trên hàm mất mát. Ngoài ra, cung cấp cho nó dữ liệu đầu vào,sgd người học và progress_printer.
training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=
[progress_writer],minibatch_size=16,max_epochs=5)
Hoàn thành ví dụ triển khai
from cntk.layers import Dense, Sequential
from cntk import input_variable, default_options
from cntk.ops import sigmoid, log_softmax
from cntk.losses import binary_cross_entropy
model = Sequential([
Dense(4, activation=sigmoid),
Dense(3, activation=log_softmax)
])
features = input_variable(4)
z = model(features)
import numpy as np
import pandas as pd
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
x = df_source.iloc[:, :4].values
y = df_source[‘species’].values
y = np.array([one_hot(label_mapping[v], 3) for v in y])
x= x.astype(np.float32)
y= y.astype(np.float32)
def one_hot(index, length):
result = np.zeros(length)
result[index] = index
return result
from cntk.losses import binary_cross_entropy_with_softmax
from cntk.learners import sgd
from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)
labels = input_variable(3)
loss = binary_cross_entropy_with_softmax (z, labels)
learner = sgd(z.parameters, 0.1)
training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer],minibatch_size=16,max_epochs=5)
Đầu ra
Build info:
Built time: *** ** **** 21:40:10
Last modified date: *** *** ** 21:08:46 2019
Build type: Release
Build target: CPU-only
With ASGD: yes
Math lib: mkl
Build Branch: HEAD
Build SHA1:ae9c9c7c5f9e6072cc9c94c254f816dbdc1c5be6 (modified)
MPI distribution: Microsoft MPI
MPI version: 7.0.12437.6
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.1 1.1 0 0 16
0.835 0.704 0 0 32
1.993 1.11 0 0 48
1.14 1.14 0 0 112
[………]
Đào tạo với bộ dữ liệu lớn
Trong phần trước, chúng ta đã làm việc với các tập dữ liệu nhỏ trong bộ nhớ bằng Numpy và gấu trúc, nhưng không phải tất cả các tập dữ liệu đều nhỏ như vậy. Đặc biệt bộ dữ liệu chứa hình ảnh, video, âm thanh mẫu có dung lượng lớn.MinibatchSourcelà một thành phần, có thể tải dữ liệu theo khối, được cung cấp bởi CNTK để làm việc với các tập dữ liệu lớn như vậy. Một số tính năng củaMinibatchSource các thành phần như sau:
MinibatchSource có thể ngăn NN khỏi trang bị quá mức bằng cách tự động lấy mẫu ngẫu nhiên được đọc từ nguồn dữ liệu.
Nó có đường ống chuyển đổi tích hợp có thể được sử dụng để tăng cường dữ liệu.
Nó tải dữ liệu trên một luồng nền tách biệt với quá trình đào tạo.
Trong các phần sau, chúng ta sẽ khám phá cách sử dụng nguồn minibatch có dữ liệu hết bộ nhớ để làm việc với các tập dữ liệu lớn. Chúng tôi cũng sẽ khám phá, làm thế nào chúng tôi có thể sử dụng nó để nuôi để đào tạo một NN.
Tạo phiên bản MinibatchSource
Trong phần trước, chúng ta đã sử dụng ví dụ về hoa iris và làm việc với tập dữ liệu nhỏ trong bộ nhớ bằng cách sử dụng Pandas DataFrames. Ở đây, chúng tôi sẽ thay thế mã sử dụng dữ liệu từ DF của gấu trúc bằngMinibatchSource. Đầu tiên, chúng ta cần tạo một phiên bản củaMinibatchSource với sự trợ giúp của các bước sau -
Ví dụ triển khai
Step 1 - Đầu tiên, từ cntk.io nhập các thành phần cho minibatchsource như sau:
from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer,
INFINITY_REPEAT
Step 2 - Bây giờ, bằng cách sử dụng StreamDef lớp, đóng thùng một định nghĩa luồng cho các nhãn.
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
Step 3 - Tiếp theo, tạo để đọc các tính năng được gửi từ tệp đầu vào, tạo một phiên bản khác của StreamDef như sau.
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
Step 4 - Bây giờ, chúng tôi cần cung cấp iris.ctf tập tin làm đầu vào và khởi tạo deserializer như sau -
deserializer = CTFDeserializer(‘iris.ctf’, StreamDefs(labels=
label_stream, features=features_stream)
Step 5 - Cuối cùng, chúng ta cần tạo phiên bản của minisourceBatch bằng cách sử dụng deserializer như sau -
Minibatch_source = MinibatchSource(deserializer, randomize=True)
Tạo phiên bản MinibatchSource - Hoàn thành ví dụ triển khai
from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer, INFINITY_REPEAT
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
deserializer = CTFDeserializer(‘iris.ctf’, StreamDefs(labels=label_stream, features=features_stream)
Minibatch_source = MinibatchSource(deserializer, randomize=True)
Tạo tệp MCTF
Như bạn đã thấy ở trên, chúng tôi đang lấy dữ liệu từ tệp 'iris.ctf'. Nó có định dạng tệp được gọi là CNTK Text Format (CTF). Bắt buộc phải tạo tệp CTF để lấy dữ liệu choMinibatchSourceví dụ chúng tôi đã tạo ở trên. Hãy để chúng tôi xem cách chúng tôi có thể tạo tệp CTF.
Ví dụ triển khai
Step 1 - Đầu tiên, chúng ta cần nhập các gói gấu trúc và numpy như sau:
import pandas as pd
import numpy as np
Step 2- Tiếp theo, chúng ta cần tải tệp dữ liệu của mình, tức là iris.csv vào bộ nhớ. Sau đó, lưu trữ nó trongdf_source Biến đổi.
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
Step 3 - Bây giờ, bằng cách sử dụng ilocindexer như các tính năng, lấy nội dung của bốn cột đầu tiên. Ngoài ra, hãy sử dụng dữ liệu từ cột loài như sau:
features = df_source.iloc[: , :4].values
labels = df_source[‘species’].values
Step 4- Tiếp theo, chúng ta cần tạo một ánh xạ giữa tên nhãn và biểu diễn số của nó. Nó có thể được thực hiện bằng cách tạolabel_mapping như sau -
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
Step 5 - Bây giờ, chuyển đổi các nhãn thành một tập hợp các vectơ được mã hóa một nóng như sau:
labels = [one_hot(label_mapping[v], 3) for v in labels]
Bây giờ, như chúng ta đã làm trước đây, hãy tạo một hàm tiện ích có tên one_hotđể mã hóa các nhãn. Nó có thể được thực hiện như sau:
def one_hot(index, length):
result = np.zeros(length)
result[index] = 1
return result
Vì chúng tôi đã tải và xử lý trước dữ liệu, đã đến lúc lưu trữ nó trên đĩa ở định dạng tệp CTF. Chúng tôi có thể làm điều đó với sự trợ giúp của mã Python sau:
With open(‘iris.ctf’, ‘w’) as output_file:
for index in range(0, feature.shape[0]):
feature_values = ‘ ‘.join([str(x) for x in np.nditer(features[index])])
label_values = ‘ ‘.join([str(x) for x in np.nditer(labels[index])])
output_file.write(‘features {} | labels {} \n’.format(feature_values, label_values))
Tạo tệp MCTF - Hoàn thành ví dụ triển khai
import pandas as pd
import numpy as np
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
features = df_source.iloc[: , :4].values
labels = df_source[‘species’].values
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
labels = [one_hot(label_mapping[v], 3) for v in labels]
def one_hot(index, length):
result = np.zeros(length)
result[index] = 1
return result
With open(‘iris.ctf’, ‘w’) as output_file:
for index in range(0, feature.shape[0]):
feature_values = ‘ ‘.join([str(x) for x in np.nditer(features[index])])
label_values = ‘ ‘.join([str(x) for x in np.nditer(labels[index])])
output_file.write(‘features {} | labels {} \n’.format(feature_values, label_values))
Cung cấp dữ liệu
Sau khi bạn tạo MinibatchSource,ví dụ, chúng ta cần đào tạo nó. Chúng ta có thể sử dụng cùng một logic huấn luyện như được sử dụng khi chúng ta làm việc với các tập dữ liệu nhỏ trong bộ nhớ. Ở đây, chúng tôi sẽ sử dụngMinibatchSource ví dụ như đầu vào cho phương thức train trên hàm mất mát như sau:
Ví dụ triển khai
Step 1 - Để ghi lại kết quả của phiên đào tạo, trước tiên hãy nhập ProgressPrinter từ cntk.logging mô-đun như sau -
from cntk.logging import ProgressPrinter
Step 2 - Tiếp theo, để thiết lập phiên đào tạo, nhập trainer và training_session từ cntk.train mô-đun như sau -
from cntk.train import Trainer,
Step 3 - Bây giờ, chúng ta cần xác định một số tập hợp các hằng số như minibatch_size, samples_per_epoch và num_epochs như sau -
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
Step 4 - Tiếp theo, để biết CNTK đọc dữ liệu như thế nào trong quá trình huấn luyện, chúng ta cần xác định ánh xạ giữa biến đầu vào cho mạng và các luồng trong nguồn minibatch.
input_map = {
features: minibatch.source.streams.features,
labels: minibatch.source.streams.features
}
Step 5 - Tiếp theo, để ghi đầu ra của quá trình đào tạo, hãy khởi tạo progress_printer biến với một mới ProgressPrinter ví dụ như sau -
progress_writer = ProgressPrinter(0)
Step 6 - Cuối cùng, chúng ta cần gọi phương thức tàu khi lỗ như sau:
train_history = loss.train(minibatch_source,
parameter_learners=[learner],
model_inputs_to_streams=input_map,
callbacks=[progress_writer],
epoch_size=samples_per_epoch,
max_epochs=num_epochs)
Cung cấp dữ liệu - Hoàn thành ví dụ triển khai
from cntk.logging import ProgressPrinter
from cntk.train import Trainer, training_session
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
input_map = {
features: minibatch.source.streams.features,
labels: minibatch.source.streams.features
}
progress_writer = ProgressPrinter(0)
train_history = loss.train(minibatch_source,
parameter_learners=[learner],
model_inputs_to_streams=input_map,
callbacks=[progress_writer],
epoch_size=samples_per_epoch,
max_epochs=num_epochs)
Đầu ra
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.21 1.21 0 0 32
1.15 0.12 0 0 96
[………]
CNTK - Hiệu suất đo lường
Chương này sẽ giải thích cách đo lường hiệu suất của mô hình trong CNKT.
Chiến lược xác thực hiệu suất mô hình
Sau khi xây dựng mô hình ML, chúng tôi đã sử dụng để đào tạo nó bằng cách sử dụng một bộ mẫu dữ liệu. Vì quá trình đào tạo này, mô hình ML của chúng tôi học và rút ra một số quy tắc chung. Hiệu suất của mô hình ML quan trọng khi chúng tôi cung cấp các mẫu mới, tức là các mẫu khác với mẫu được cung cấp tại thời điểm đào tạo, cho mô hình. Mô hình hoạt động khác nhau trong trường hợp đó. Việc đưa ra dự đoán tốt về những mẫu mới đó có thể tệ hơn.
Nhưng mô hình cũng phải hoạt động tốt đối với các mẫu mới vì trong môi trường sản xuất, chúng tôi sẽ nhận được đầu vào khác với dữ liệu mẫu chúng tôi sử dụng cho mục đích đào tạo. Đó là lý do, chúng ta nên xác nhận mô hình ML bằng cách sử dụng một tập hợp các mẫu khác với các mẫu chúng ta đã sử dụng cho mục đích đào tạo. Ở đây, chúng ta sẽ thảo luận về hai kỹ thuật khác nhau để tạo tập dữ liệu để xác thực NN.
Tập dữ liệu tạm dừng
Đây là một trong những phương pháp đơn giản nhất để tạo tập dữ liệu để xác thực NN. Như tên của nó, trong phương pháp này, chúng tôi sẽ giữ lại một bộ mẫu từ quá trình đào tạo (giả sử 20%) và sử dụng nó để kiểm tra hiệu suất của mô hình ML của chúng tôi. Biểu đồ sau đây cho thấy tỷ lệ giữa các mẫu đào tạo và xác nhận:
Mô hình tập dữ liệu tạm dừng đảm bảo rằng chúng tôi có đủ dữ liệu để đào tạo mô hình ML của mình và đồng thời chúng tôi sẽ có một số lượng mẫu hợp lý để có được phép đo tốt về hiệu suất của mô hình.
Để đưa vào tập huấn luyện và tập thử nghiệm, bạn nên chọn các mẫu ngẫu nhiên từ tập dữ liệu chính. Nó đảm bảo sự phân bổ đồng đều giữa tập huấn luyện và tập kiểm tra.
Sau đây là một ví dụ trong đó chúng tôi đang tạo tập dữ liệu tạm dừng riêng bằng cách sử dụng train_test_split chức năng từ scikit-learn thư viện.
Thí dụ
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
# Here above test_size = 0.2 represents that we provided 20% of the data as test data.
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics
classifier_knn = KNeighborsClassifier(n_neighbors=3)
classifier_knn.fit(X_train, y_train)
y_pred = classifier_knn.predict(X_test)
# Providing sample data and the model will make prediction out of that data
sample = [[5, 5, 3, 2], [2, 4, 3, 5]]
preds = classifier_knn.predict(sample)
pred_species = [iris.target_names[p] for p in preds] print("Predictions:", pred_species)
Đầu ra
Predictions: ['versicolor', 'virginica']
Trong khi sử dụng CNTK, chúng ta cần ngẫu nhiên hóa thứ tự của tập dữ liệu mỗi khi chúng ta đào tạo mô hình của mình vì -
Các thuật toán học sâu bị ảnh hưởng nhiều bởi các bộ tạo số ngẫu nhiên.
Thứ tự mà chúng tôi cung cấp mẫu cho NN trong quá trình đào tạo ảnh hưởng rất nhiều đến hoạt động của NN.
Nhược điểm lớn của việc sử dụng kỹ thuật tập dữ liệu tạm dừng là nó không đáng tin cậy vì đôi khi chúng ta nhận được kết quả rất tốt nhưng đôi khi, chúng ta lại nhận được kết quả xấu.
Xác thực chéo K-lần
Để làm cho mô hình ML của chúng tôi đáng tin cậy hơn, có một kỹ thuật được gọi là xác thực chéo K-lần. Về bản chất, kỹ thuật xác nhận chéo K-lần giống như kỹ thuật trước, nhưng nó lặp lại nhiều lần - thường là khoảng 5 đến 10 lần. Sơ đồ sau thể hiện khái niệm của nó -
Làm việc của xác nhận chéo K-lần
Hoạt động của xác thực chéo K-lần có thể được hiểu với sự trợ giúp của các bước sau:
Step 1- Giống như trong kỹ thuật tập dữ liệu Hand-out, trong kỹ thuật xác nhận chéo K-fold, trước tiên chúng ta cần chia tập dữ liệu thành một tập huấn luyện và kiểm tra. Lý tưởng nhất, tỷ lệ là 80-20, tức là 80% tập huấn luyện và 20% tập kiểm tra.
Step 2 - Tiếp theo, chúng ta cần huấn luyện mô hình của mình bằng cách sử dụng tập huấn luyện.
Step 3− Cuối cùng, chúng tôi sẽ sử dụng bộ thử nghiệm để đo lường hiệu suất của mô hình của chúng tôi. Sự khác biệt duy nhất giữa kỹ thuật tập dữ liệu Hold-out và kỹ thuật xác nhận k-cross là quá trình trên thường được lặp lại từ 5 đến 10 lần và cuối cùng, giá trị trung bình được tính trên tất cả các chỉ số hiệu suất. Mức trung bình đó sẽ là số liệu hiệu suất cuối cùng.
Hãy để chúng tôi xem một ví dụ với một tập dữ liệu nhỏ -
Thí dụ
from numpy import array
from sklearn.model_selection import KFold
data = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
kfold = KFold(5, True, 1)
for train, test in kfold.split(data):
print('train: %s, test: %s' % (data[train],(data[test]))
Đầu ra
train: [0.1 0.2 0.4 0.5 0.6 0.7 0.8 0.9], test: [0.3 1. ]
train: [0.1 0.2 0.3 0.4 0.6 0.8 0.9 1. ], test: [0.5 0.7]
train: [0.2 0.3 0.5 0.6 0.7 0.8 0.9 1. ], test: [0.1 0.4]
train: [0.1 0.3 0.4 0.5 0.6 0.7 0.9 1. ], test: [0.2 0.8]
train: [0.1 0.2 0.3 0.4 0.5 0.7 0.8 1. ], test: [0.6 0.9]
Như chúng ta thấy, do sử dụng kịch bản đào tạo và thử nghiệm thực tế hơn, kỹ thuật xác thực chéo k-lần mang lại cho chúng ta phép đo hiệu suất ổn định hơn nhiều nhưng mặt trái của nó là mất rất nhiều thời gian khi xác thực các mô hình học sâu.
CNTK không hỗ trợ xác thực k-cross, do đó chúng tôi cần viết tập lệnh của riêng mình để làm như vậy.
Phát hiện trang bị thiếu và trang bị quá mức
Cho dù, chúng tôi sử dụng tập dữ liệu Phát tay hay kỹ thuật xác thực chéo k-lần, chúng tôi sẽ phát hiện ra rằng đầu ra cho các chỉ số sẽ khác nhau đối với tập dữ liệu được sử dụng để đào tạo và tập dữ liệu được sử dụng để xác nhận.
Phát hiện overfitting
Hiện tượng được gọi là overfitting là một tình huống trong đó mô hình ML của chúng tôi, mô hình hóa dữ liệu huấn luyện đặc biệt tốt, nhưng không hoạt động tốt trên dữ liệu thử nghiệm, tức là không thể dự đoán dữ liệu thử nghiệm.
Nó xảy ra khi một mô hình ML học một mẫu cụ thể và nhiễu từ dữ liệu đào tạo đến mức độ như vậy, nó tác động tiêu cực đến khả năng tổng quát hóa từ dữ liệu đào tạo thành dữ liệu mới của mô hình đó, tức là dữ liệu không nhìn thấy. Ở đây, nhiễu là thông tin không liên quan hoặc tính ngẫu nhiên trong tập dữ liệu.
Sau đây là hai cách với sự trợ giúp của chúng tôi có thể phát hiện thời tiết mà mô hình của chúng tôi có quá phù hợp hay không -
Mẫu overfit sẽ hoạt động tốt trên cùng mẫu mà chúng tôi đã sử dụng để đào tạo, nhưng nó sẽ hoạt động rất kém trên các mẫu mới, tức là các mẫu khác với mẫu đào tạo.
Mô hình bị thừa trong quá trình xác thực nếu chỉ số trên tập hợp thử nghiệm thấp hơn chỉ số tương tự, chúng tôi sử dụng trên tập hợp đào tạo của mình.
Phát hiện trang bị thiếu
Một tình huống khác có thể phát sinh trong ML của chúng tôi là trang bị kém. Đây là tình huống mà mô hình ML của chúng tôi không mô hình hóa dữ liệu đào tạo tốt và không dự đoán được kết quả đầu ra hữu ích. Khi chúng tôi bắt đầu đào tạo kỷ nguyên đầu tiên, mô hình của chúng tôi sẽ không phù hợp, nhưng sẽ trở nên kém phù hợp hơn theo tiến độ đào tạo.
Một trong những cách để phát hiện mô hình của chúng tôi có phù hợp hay không là xem các chỉ số cho tập huấn luyện và tập thử nghiệm. Mô hình của chúng tôi sẽ không phù hợp nếu chỉ số trên tập thử nghiệm cao hơn chỉ số trên tập huấn luyện.
CNTK - Phân loại mạng thần kinh
Trong chương này, chúng ta sẽ nghiên cứu cách phân loại mạng nơron bằng CNTK.
Giới thiệu
Phân loại có thể được định nghĩa là quá trình dự đoán các nhãn đầu ra phân loại hoặc phản hồi cho dữ liệu đầu vào nhất định. Đầu ra được phân loại, sẽ dựa trên những gì mô hình đã học được trong giai đoạn đào tạo, có thể có dạng như "Đen" hoặc "Trắng" hoặc "thư rác" hoặc "không có thư rác".
Mặt khác, về mặt toán học, nhiệm vụ xấp xỉ một hàm ánh xạ nói f từ biến đầu vào nói X đến biến đầu ra nói Y.
Một ví dụ kinh điển về vấn đề phân loại có thể là phát hiện thư rác trong e-mail. Rõ ràng là chỉ có thể có hai loại đầu ra, "thư rác" và "không có thư rác".
Để thực hiện phân loại như vậy, trước tiên chúng ta cần thực hiện đào tạo bộ phân loại nơi các email "spam" và "không spam" sẽ được sử dụng làm dữ liệu đào tạo. Sau khi đã đào tạo thành công trình phân loại, nó có thể được sử dụng để phát hiện một email không xác định.
Ở đây, chúng ta sẽ tạo 4-5-3 NN bằng cách sử dụng tập dữ liệu hoa iris có những điều sau:
4 nút đầu vào (một nút cho mỗi giá trị dự đoán).
5-nút xử lý ẩn.
3 nút đầu ra (vì có thể có ba loài trong tập dữ liệu mống mắt).
Đang tải tập dữ liệu
Chúng tôi sẽ sử dụng tập dữ liệu hoa iris, từ đó chúng tôi muốn phân loại các loài hoa iris dựa trên các đặc tính vật lý của chiều rộng và chiều dài đài hoa, chiều rộng và chiều dài của cánh hoa. Bộ dữ liệu mô tả các đặc tính vật lý của các giống hoa iris khác nhau -
Chiều dài Sepal
Chiều rộng vách ngăn
Chiều dài cánh hoa
Chiều rộng cánh hoa
Loại iris setosa hoặc iris versicolor hoặc iris virginica
Chúng ta có iris.CSVtệp mà chúng tôi đã sử dụng trước đây trong các chương trước. Nó có thể được tải với sự trợ giúp củaPandasthư viện. Tuy nhiên, trước khi sử dụng nó hoặc tải nó cho bộ phân loại của chúng tôi, chúng ta cần chuẩn bị các tệp đào tạo và thử nghiệm để nó có thể được sử dụng dễ dàng với CNTK.
Chuẩn bị các tệp đào tạo và kiểm tra
Bộ dữ liệu Iris là một trong những bộ dữ liệu phổ biến nhất cho các dự án ML. Nó có 150 mục dữ liệu và dữ liệu thô trông như sau:
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
…
7.0 3.2 4.7 1.4 versicolor
6.4 3.2 4.5 1.5 versicolor
…
6.3 3.3 6.0 2.5 virginica
5.8 2.7 5.1 1.9 virginica
Như đã nói trước đó, bốn giá trị đầu tiên trên mỗi dòng mô tả các đặc tính vật lý của các giống khác nhau, tức là chiều dài Sepal, chiều rộng Sepal, chiều dài cánh hoa, chiều rộng cánh hoa của hoa iris.
Tuy nhiên, chúng ta phải chuyển đổi dữ liệu theo định dạng mà CNTK có thể dễ dàng sử dụng và định dạng đó là tệp .ctf (chúng tôi cũng đã tạo một iris.ctf trong phần trước). Nó sẽ giống như sau:
|attribs 5.1 3.5 1.4 0.2|species 1 0 0
|attribs 4.9 3.0 1.4 0.2|species 1 0 0
…
|attribs 7.0 3.2 4.7 1.4|species 0 1 0
|attribs 6.4 3.2 4.5 1.5|species 0 1 0
…
|attribs 6.3 3.3 6.0 2.5|species 0 0 1
|attribs 5.8 2.7 5.1 1.9|species 0 0 1
Trong dữ liệu trên, thẻ | attribs đánh dấu điểm bắt đầu của giá trị đối tượng và thẻ | loài đánh dấu giá trị nhãn lớp. Chúng tôi cũng có thể sử dụng bất kỳ tên thẻ nào khác mà chúng tôi muốn, thậm chí chúng tôi cũng có thể thêm ID mặt hàng. Ví dụ, hãy xem dữ liệu sau:
|ID 001 |attribs 5.1 3.5 1.4 0.2|species 1 0 0 |#setosa
|ID 002 |attribs 4.9 3.0 1.4 0.2|species 1 0 0 |#setosa
…
|ID 051 |attribs 7.0 3.2 4.7 1.4|species 0 1 0 |#versicolor
|ID 052 |attribs 6.4 3.2 4.5 1.5|species 0 1 0 |#versicolor
…
Có tổng số 150 mục dữ liệu trong tập dữ liệu mống mắt và đối với ví dụ này, chúng tôi sẽ sử dụng quy tắc tập dữ liệu 80-20, tức là 80% (120 mục) mục dữ liệu cho mục đích đào tạo và 20% (30 mục) còn lại các mục dữ liệu để kiểm tra mục đích.
Xây dựng mô hình phân loại
Đầu tiên, chúng ta cần xử lý các tệp dữ liệu ở định dạng CNTK và chúng ta sẽ sử dụng hàm trợ giúp có tên create_reader như sau -
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='attribs', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='species', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
Bây giờ, chúng ta cần thiết lập các đối số kiến trúc cho NN của chúng ta và cũng cung cấp vị trí của các tệp dữ liệu. Nó có thể được thực hiện với sự trợ giúp của mã python sau:
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 4
hidden_dim = 5
output_dim = 3
train_file = ".\\...\\" #provide the name of the training file(120 data items)
test_file = ".\\...\\" #provide the name of the test file(30 data items)
Bây giờ, với sự trợ giúp của dòng mã sau, chương trình của chúng tôi sẽ tạo ra NN chưa được đào tạo -
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
nnet = oLayer
model = C.ops.softmax(nnet)
Bây giờ, khi chúng ta đã tạo mô hình kép không được đào tạo, chúng ta cần thiết lập đối tượng thuật toán Người học và sau đó sử dụng nó để tạo đối tượng đào tạo Người huấn luyện. Chúng tôi sẽ sử dụng trình học SGD vàcross_entropy_with_softmax mất chức năng -
tr_loss = C.cross_entropy_with_softmax(nnet, Y)
tr_clas = C.classification_error(nnet, Y)
max_iter = 2000
batch_size = 10
learn_rate = 0.01
learner = C.sgd(nnet.parameters, learn_rate)
trainer = C.Trainer(nnet, (tr_loss, tr_clas), [learner])
Mã thuật toán học tập như sau:
max_iter = 2000
batch_size = 10
lr_schedule = C.learning_parameter_schedule_per_sample([(1000, 0.05), (1, 0.01)])
mom_sch = C.momentum_schedule([(100, 0.99), (0, 0.95)], batch_size)
learner = C.fsadagrad(nnet.parameters, lr=lr_schedule, momentum=mom_sch)
trainer = C.Trainer(nnet, (tr_loss, tr_clas), [learner])
Bây giờ, khi chúng ta đã hoàn thành với đối tượng Trainer, chúng ta cần tạo một hàm reader để đọc dữ liệu huấn luyện−
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
iris_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
Bây giờ đã đến lúc đào tạo mô hình NN của chúng ta−
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=iris_input_map) trainer.train_minibatch(curr_batch)
if i % 500 == 0:
mcee = trainer.previous_minibatch_loss_average
macc = (1.0 - trainer.previous_minibatch_evaluation_average) * 100
print("batch %4d: mean loss = %0.4f, accuracy = %0.2f%% " \ % (i, mcee, macc))
Khi chúng ta đã hoàn tất quá trình đào tạo, hãy đánh giá mô hình bằng các mục dữ liệu thử nghiệm -
print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
iris_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 30
all_test = rdr.next_minibatch(num_test, input_map=iris_input_map) acc = (1.0 - trainer.test_minibatch(all_test)) * 100
print("Classification accuracy = %0.2f%%" % acc)
Sau khi đánh giá độ chính xác của mô hình NN được đào tạo của chúng tôi, chúng tôi sẽ sử dụng nó để đưa ra dự đoán về dữ liệu không nhìn thấy -
np.set_printoptions(precision = 1, suppress=True)
unknown = np.array([[6.4, 3.2, 4.5, 1.5]], dtype=np.float32)
print("\nPredicting Iris species for input features: ")
print(unknown[0]) pred_prob = model.eval(unknown)
np.set_printoptions(precision = 4, suppress=True)
print("Prediction probabilities are: ")
print(pred_prob[0])
Mô hình phân loại hoàn chỉnh
Import numpy as np
Import cntk as C
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='attribs', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='species', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 4
hidden_dim = 5
output_dim = 3
train_file = ".\\...\\" #provide the name of the training file(120 data items)
test_file = ".\\...\\" #provide the name of the test file(30 data items)
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
nnet = oLayer
model = C.ops.softmax(nnet)
tr_loss = C.cross_entropy_with_softmax(nnet, Y)
tr_clas = C.classification_error(nnet, Y)
max_iter = 2000
batch_size = 10
learn_rate = 0.01
learner = C.sgd(nnet.parameters, learn_rate)
trainer = C.Trainer(nnet, (tr_loss, tr_clas), [learner])
max_iter = 2000
batch_size = 10
lr_schedule = C.learning_parameter_schedule_per_sample([(1000, 0.05), (1, 0.01)])
mom_sch = C.momentum_schedule([(100, 0.99), (0, 0.95)], batch_size)
learner = C.fsadagrad(nnet.parameters, lr=lr_schedule, momentum=mom_sch)
trainer = C.Trainer(nnet, (tr_loss, tr_clas), [learner])
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
iris_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=iris_input_map) trainer.train_minibatch(curr_batch)
if i % 500 == 0:
mcee = trainer.previous_minibatch_loss_average
macc = (1.0 - trainer.previous_minibatch_evaluation_average) * 100
print("batch %4d: mean loss = %0.4f, accuracy = %0.2f%% " \ % (i, mcee, macc))
print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
iris_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 30
all_test = rdr.next_minibatch(num_test, input_map=iris_input_map) acc = (1.0 - trainer.test_minibatch(all_test)) * 100
print("Classification accuracy = %0.2f%%" % acc)
np.set_printoptions(precision = 1, suppress=True)
unknown = np.array([[7.0, 3.2, 4.7, 1.4]], dtype=np.float32)
print("\nPredicting species for input features: ")
print(unknown[0])
pred_prob = model.eval(unknown)
np.set_printoptions(precision = 4, suppress=True)
print("Prediction probabilities: ")
print(pred_prob[0])
if __name__== ”__main__”:
main()
Đầu ra
Using CNTK version = 2.7
batch 0: mean loss = 1.0986, mean accuracy = 40.00%
batch 500: mean loss = 0.6677, mean accuracy = 80.00%
batch 1000: mean loss = 0.5332, mean accuracy = 70.00%
batch 1500: mean loss = 0.2408, mean accuracy = 100.00%
Evaluating test data
Classification accuracy = 94.58%
Predicting species for input features:
[7.0 3.2 4.7 1.4]
Prediction probabilities:
[0.0847 0.736 0.113]
Lưu mô hình được đào tạo
Tập dữ liệu Iris này chỉ có 150 mục dữ liệu, do đó sẽ chỉ mất vài giây để đào tạo mô hình phân loại NN, nhưng việc đào tạo trên một tập dữ liệu lớn có hàng trăm hoặc nghìn mục dữ liệu có thể mất hàng giờ hoặc thậm chí vài ngày.
Chúng tôi có thể lưu mô hình của mình để không phải giữ lại từ đầu. Với sự trợ giúp của mã Python sau đây, chúng ta có thể lưu NN được đào tạo của mình -
nn_classifier = “.\\neuralclassifier.model” #provide the name of the file
model.save(nn_classifier, format=C.ModelFormat.CNTKv2)
Sau đây là các đối số của save() hàm được sử dụng ở trên -
Tên tệp là đối số đầu tiên của save()chức năng. Nó cũng có thể được ghi cùng với đường dẫn của tệp.
Một tham số khác là format tham số có giá trị mặc định C.ModelFormat.CNTKv2.
Đang tải mô hình được đào tạo
Khi bạn đã lưu mô hình được đào tạo, rất dễ dàng tải mô hình đó. Chúng tôi chỉ cần sử dụngload ()chức năng. Hãy kiểm tra điều này trong ví dụ sau:
import numpy as np
import cntk as C
model = C.ops.functions.Function.load(“.\\neuralclassifier.model”)
np.set_printoptions(precision = 1, suppress=True)
unknown = np.array([[7.0, 3.2, 4.7, 1.4]], dtype=np.float32)
print("\nPredicting species for input features: ")
print(unknown[0])
pred_prob = model.eval(unknown)
np.set_printoptions(precision = 4, suppress=True)
print("Prediction probabilities: ")
print(pred_prob[0])
Lợi ích của mô hình đã lưu là khi bạn tải một mô hình đã lưu, nó có thể được sử dụng chính xác như thể mô hình vừa được đào tạo.
CNTK - Phân loại nhị phân mạng thần kinh
Hãy để chúng tôi hiểu, phân loại nhị phân mạng nơron sử dụng CNTK là gì, trong chương này.
Phân loại nhị phân sử dụng NN giống như phân loại đa lớp, chỉ có điều là chỉ có hai nút đầu ra thay vì ba hoặc nhiều hơn. Ở đây, chúng ta sẽ thực hiện phân loại nhị phân bằng mạng nơron bằng cách sử dụng hai kỹ thuật cụ thể là kỹ thuật một nút và kỹ thuật hai nút. Kỹ thuật một nút phổ biến hơn kỹ thuật hai nút.
Đang tải tập dữ liệu
Để thực hiện cả hai kỹ thuật này bằng NN, chúng tôi sẽ sử dụng bộ dữ liệu tiền giấy. Bộ dữ liệu có thể được tải xuống từ Kho lưu trữ Học máy UCI có sẵn tạihttps://archive.ics.uci.edu/ml/datasets/banknote+authentication.
Ví dụ của chúng tôi, chúng tôi sẽ sử dụng 50 mục dữ liệu xác thực có giả mạo lớp = 0 và 50 mục giả mạo đầu tiên có giả mạo lớp = 1.
Chuẩn bị các tệp đào tạo và kiểm tra
Có 1372 mục dữ liệu trong tập dữ liệu đầy đủ. Tập dữ liệu thô trông như sau:
3.6216, 8.6661, -2.8076, -0.44699, 0
4.5459, 8.1674, -2.4586, -1.4621, 0
…
-1.3971, 3.3191, -1.3927, -1.9948, 1
0.39012, -0.14279, -0.031994, 0.35084, 1
Bây giờ, trước tiên chúng ta cần chuyển đổi dữ liệu thô này sang định dạng CNTK hai nút, như sau:
|stats 3.62160000 8.66610000 -2.80730000 -0.44699000 |forgery 0 1 |# authentic
|stats 4.54590000 8.16740000 -2.45860000 -1.46210000 |forgery 0 1 |# authentic
. . .
|stats -1.39710000 3.31910000 -1.39270000 -1.99480000 |forgery 1 0 |# fake
|stats 0.39012000 -0.14279000 -0.03199400 0.35084000 |forgery 1 0 |# fake
Bạn có thể sử dụng chương trình python sau để tạo dữ liệu định dạng CNTK từ dữ liệu thô:
fin = open(".\\...", "r") #provide the location of saved dataset text file.
for line in fin:
line = line.strip()
tokens = line.split(",")
if tokens[4] == "0":
print("|stats %12.8f %12.8f %12.8f %12.8f |forgery 0 1 |# authentic" % \
(float(tokens[0]), float(tokens[1]), float(tokens[2]), float(tokens[3])) )
else:
print("|stats %12.8f %12.8f %12.8f %12.8f |forgery 1 0 |# fake" % \
(float(tokens[0]), float(tokens[1]), float(tokens[2]), float(tokens[3])) )
fin.close()
Mô hình phân loại nhị phân hai nút
Có rất ít sự khác biệt giữa phân loại hai nút và phân loại nhiều lớp. Ở đây, trước tiên, chúng ta cần xử lý các tệp dữ liệu ở định dạng CNTK và chúng ta sẽ sử dụng hàm trợ giúp có têncreate_reader như sau -
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='stats', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='forgery', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
Bây giờ, chúng ta cần thiết lập các đối số kiến trúc cho NN của chúng ta và cũng cung cấp vị trí của các tệp dữ liệu. Nó có thể được thực hiện với sự trợ giúp của mã python sau:
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 4
hidden_dim = 10
output_dim = 2
train_file = ".\\...\\" #provide the name of the training file
test_file = ".\\...\\" #provide the name of the test file
Bây giờ, với sự trợ giúp của dòng mã sau, chương trình của chúng tôi sẽ tạo ra NN chưa được đào tạo -
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
nnet = oLayer
model = C.ops.softmax(nnet)
Bây giờ, khi chúng ta đã tạo mô hình kép không được đào tạo, chúng ta cần thiết lập đối tượng thuật toán Người học và sau đó sử dụng nó để tạo đối tượng đào tạo Người huấn luyện. Chúng ta sẽ sử dụng SGD learning và hàm mất cross_entropy_with_softmax -
tr_loss = C.cross_entropy_with_softmax(nnet, Y)
tr_clas = C.classification_error(nnet, Y)
max_iter = 500
batch_size = 10
learn_rate = 0.01
learner = C.sgd(nnet.parameters, learn_rate)
trainer = C.Trainer(nnet, (tr_loss, tr_clas), [learner])
Bây giờ, khi chúng ta đã hoàn thành với đối tượng Trainer, chúng ta cần tạo một hàm đọc để đọc dữ liệu đào tạo -
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
banknote_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
Bây giờ, đã đến lúc đào tạo mô hình NN của chúng ta -
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=iris_input_map) trainer.train_minibatch(curr_batch)
if i % 500 == 0:
mcee = trainer.previous_minibatch_loss_average
macc = (1.0 - trainer.previous_minibatch_evaluation_average) * 100
print("batch %4d: mean loss = %0.4f, accuracy = %0.2f%% " \ % (i, mcee, macc))
Sau khi đào tạo xong, hãy để chúng tôi đánh giá mô hình bằng cách sử dụng các mục dữ liệu thử nghiệm -
print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
banknote_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=iris_input_map) acc = (1.0 - trainer.test_minibatch(all_test)) * 100
print("Classification accuracy = %0.2f%%" % acc)
Sau khi đánh giá độ chính xác của mô hình NN được đào tạo của chúng tôi, chúng tôi sẽ sử dụng nó để đưa ra dự đoán về dữ liệu không nhìn thấy -
np.set_printoptions(precision = 1, suppress=True)
unknown = np.array([[0.6, 1.9, -3.3, -0.3]], dtype=np.float32)
print("\nPredicting Banknote authenticity for input features: ")
print(unknown[0])
pred_prob = model.eval(unknown)
np.set_printoptions(precision = 4, suppress=True)
print("Prediction probabilities are: ")
print(pred_prob[0])
if pred_prob[0,0] < pred_prob[0,1]:
print(“Prediction: authentic”)
else:
print(“Prediction: fake”)
Mô hình phân loại hai nút hoàn chỉnh
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='stats', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='forgery', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 4
hidden_dim = 10
output_dim = 2
train_file = ".\\...\\" #provide the name of the training file
test_file = ".\\...\\" #provide the name of the test file
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
withC.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
nnet = oLayer
model = C.ops.softmax(nnet)
tr_loss = C.cross_entropy_with_softmax(nnet, Y)
tr_clas = C.classification_error(nnet, Y)
max_iter = 500
batch_size = 10
learn_rate = 0.01
learner = C.sgd(nnet.parameters, learn_rate)
trainer = C.Trainer(nnet, (tr_loss, tr_clas), [learner])
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
banknote_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=iris_input_map) trainer.train_minibatch(curr_batch)
if i % 500 == 0:
mcee = trainer.previous_minibatch_loss_average
macc = (1.0 - trainer.previous_minibatch_evaluation_average) * 100
print("batch %4d: mean loss = %0.4f, accuracy = %0.2f%% " \ % (i, mcee, macc))
print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
banknote_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=iris_input_map) acc = (1.0 - trainer.test_minibatch(all_test)) * 100
print("Classification accuracy = %0.2f%%" % acc)
np.set_printoptions(precision = 1, suppress=True)
unknown = np.array([[0.6, 1.9, -3.3, -0.3]], dtype=np.float32)
print("\nPredicting Banknote authenticity for input features: ")
print(unknown[0])
pred_prob = model.eval(unknown)
np.set_printoptions(precision = 4, suppress=True)
print("Prediction probabilities are: ")
print(pred_prob[0])
if pred_prob[0,0] < pred_prob[0,1]:
print(“Prediction: authentic”)
else:
print(“Prediction: fake”)
if __name__== ”__main__”:
main()
Đầu ra
Using CNTK version = 2.7
batch 0: mean loss = 0.6928, accuracy = 80.00%
batch 50: mean loss = 0.6877, accuracy = 70.00%
batch 100: mean loss = 0.6432, accuracy = 80.00%
batch 150: mean loss = 0.4978, accuracy = 80.00%
batch 200: mean loss = 0.4551, accuracy = 90.00%
batch 250: mean loss = 0.3755, accuracy = 90.00%
batch 300: mean loss = 0.2295, accuracy = 100.00%
batch 350: mean loss = 0.1542, accuracy = 100.00%
batch 400: mean loss = 0.1581, accuracy = 100.00%
batch 450: mean loss = 0.1499, accuracy = 100.00%
Evaluating test data
Classification accuracy = 84.58%
Predicting banknote authenticity for input features:
[0.6 1.9 -3.3 -0.3]
Prediction probabilities are:
[0.7847 0.2536]
Prediction: fake
Mô hình phân loại nhị phân một nút
Chương trình thực hiện gần giống như chúng ta đã làm ở trên để phân loại hai nút. Sự thay đổi chính là khi sử dụng kỹ thuật phân loại hai nút.
Chúng ta có thể sử dụng hàm phân loại có sẵn trong CNTK, nhưng trong trường hợp phân loại một nút, CNTK không hỗ trợ hàm phân loại (). Đó là lý do chúng ta cần triển khai một hàm do chương trình xác định như sau:
def class_acc(mb, x_var, y_var, model):
num_correct = 0; num_wrong = 0
x_mat = mb[x_var].asarray()
y_mat = mb[y_var].asarray()
for i in range(mb[x_var].shape[0]):
p = model.eval(x_mat[i]
y = y_mat[i]
if p[0,0] < 0.5 and y[0,0] == 0.0 or p[0,0] >= 0.5 and y[0,0] == 1.0:
num_correct += 1
else:
num_wrong += 1
return (num_correct * 100.0)/(num_correct + num_wrong)
Với sự thay đổi đó, hãy xem ví dụ phân loại một nút hoàn chỉnh -
Hoàn thành mô hình phân loại một nút
import numpy as np
import cntk as C
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='stats', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='forgery', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
def class_acc(mb, x_var, y_var, model):
num_correct = 0; num_wrong = 0
x_mat = mb[x_var].asarray()
y_mat = mb[y_var].asarray()
for i in range(mb[x_var].shape[0]):
p = model.eval(x_mat[i]
y = y_mat[i]
if p[0,0] < 0.5 and y[0,0] == 0.0 or p[0,0] >= 0.5 and y[0,0] == 1.0:
num_correct += 1
else:
num_wrong += 1
return (num_correct * 100.0)/(num_correct + num_wrong)
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 4
hidden_dim = 10
output_dim = 1
train_file = ".\\...\\" #provide the name of the training file
test_file = ".\\...\\" #provide the name of the test file
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
model = oLayer
tr_loss = C.cross_entropy_with_softmax(model, Y)
max_iter = 1000
batch_size = 10
learn_rate = 0.01
learner = C.sgd(model.parameters, learn_rate)
trainer = C.Trainer(model, (tr_loss), [learner])
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
banknote_input_map = {X : rdr.streams.x_src, Y : rdr.streams.y_src }
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=iris_input_map) trainer.train_minibatch(curr_batch)
if i % 100 == 0:
mcee=trainer.previous_minibatch_loss_average
ca = class_acc(curr_batch, X,Y, model)
print("batch %4d: mean loss = %0.4f, accuracy = %0.2f%% " \ % (i, mcee, ca))
print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
banknote_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=iris_input_map)
acc = class_acc(all_test, X,Y, model)
print("Classification accuracy = %0.2f%%" % acc)
np.set_printoptions(precision = 1, suppress=True)
unknown = np.array([[0.6, 1.9, -3.3, -0.3]], dtype=np.float32)
print("\nPredicting Banknote authenticity for input features: ")
print(unknown[0])
pred_prob = model.eval({X:unknown})
print("Prediction probability: ")
print(“%0.4f” % pred_prob[0,0])
if pred_prob[0,0] < 0.5:
print(“Prediction: authentic”)
else:
print(“Prediction: fake”)
if __name__== ”__main__”:
main()
Đầu ra
Using CNTK version = 2.7
batch 0: mean loss = 0.6936, accuracy = 10.00%
batch 100: mean loss = 0.6882, accuracy = 70.00%
batch 200: mean loss = 0.6597, accuracy = 50.00%
batch 300: mean loss = 0.5298, accuracy = 70.00%
batch 400: mean loss = 0.4090, accuracy = 100.00%
batch 500: mean loss = 0.3790, accuracy = 90.00%
batch 600: mean loss = 0.1852, accuracy = 100.00%
batch 700: mean loss = 0.1135, accuracy = 100.00%
batch 800: mean loss = 0.1285, accuracy = 100.00%
batch 900: mean loss = 0.1054, accuracy = 100.00%
Evaluating test data
Classification accuracy = 84.00%
Predicting banknote authenticity for input features:
[0.6 1.9 -3.3 -0.3]
Prediction probability:
0.8846
Prediction: fake
CNTK - Hồi quy mạng thần kinh
Chương này sẽ giúp bạn hiểu về hồi quy mạng nơ-ron liên quan đến CNTK.
Giới thiệu
Như chúng ta biết rằng, để dự đoán một giá trị số từ một hoặc nhiều biến dự báo, chúng ta sử dụng hồi quy. Hãy lấy một ví dụ về dự đoán giá trị trung bình của một ngôi nhà ở một trong 100 thị trấn. Để làm như vậy, chúng tôi có dữ liệu bao gồm:
Một thống kê tội phạm cho mỗi thị trấn.
Tuổi của những ngôi nhà ở mỗi thị trấn.
Thước đo khoảng cách từ mỗi thị trấn đến một vị trí đắc địa.
Tỷ lệ học sinh trên giáo viên ở mỗi thị trấn.
Một thống kê nhân khẩu học chủng tộc cho mỗi thị trấn.
Giá trị nhà trung bình ở mỗi thị trấn.
Dựa trên năm biến dự báo này, chúng tôi muốn dự đoán giá trị trung bình của ngôi nhà. Và đối với điều này, chúng ta có thể tạo một mô hình hồi quy tuyến tính dọc theo các đường của
Y = a0+a1(crime)+a2(house-age)+(a3)(distance)+(a4)(ratio)+(a5)(racial)
Trong phương trình trên -
Y là một giá trị trung bình được dự đoán
a0 là hằng số và
a1 qua a5 tất cả đều là hằng số liên quan đến năm yếu tố dự báo mà chúng ta đã thảo luận ở trên.
Chúng tôi cũng có một cách tiếp cận khác là sử dụng mạng nơ-ron. Nó sẽ tạo ra mô hình dự đoán chính xác hơn.
Ở đây, chúng ta sẽ tạo một mô hình hồi quy mạng nơron bằng cách sử dụng CNTK.
Đang tải tập dữ liệu
Để thực hiện hồi quy Mạng thần kinh bằng CNTK, chúng tôi sẽ sử dụng tập dữ liệu giá trị nhà khu vực Boston. Bộ dữ liệu có thể được tải xuống từ Kho lưu trữ Học máy UCI có sẵn tạihttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/. Tập dữ liệu này có tổng số 14 biến và 506 trường hợp.
Tuy nhiên, đối với chương trình triển khai của chúng tôi, chúng tôi sẽ sử dụng sáu trong số 14 biến và 100 trường hợp. Trong số 6, 5 là dự đoán và một là giá trị dự đoán. Từ 100 trường hợp, chúng tôi sẽ sử dụng 80 cho mục đích đào tạo và 20 cho mục đích thử nghiệm. Giá trị mà chúng tôi muốn dự đoán là giá nhà trung bình trong một thị trấn. Hãy xem năm công cụ dự đoán mà chúng tôi sẽ sử dụng -
Crime per capita in the town - Chúng tôi mong đợi các giá trị nhỏ hơn được liên kết với dự đoán này.
Proportion of owner - các đơn vị bị chiếm đóng được xây dựng trước năm 1940 - Chúng tôi mong đợi các giá trị nhỏ hơn được kết hợp với dự đoán này vì giá trị lớn hơn có nghĩa là ngôi nhà cũ hơn.
Weighed distance of the town to five Boston employment centers.
Area school pupil-to-teacher ratio.
An indirect metric of the proportion of black residents in the town.
Chuẩn bị các tệp đào tạo và kiểm tra
Như chúng ta đã làm trước đây, đầu tiên chúng ta cần chuyển đổi dữ liệu thô sang định dạng CNTK. Chúng tôi sẽ sử dụng 80 mục dữ liệu đầu tiên cho mục đích đào tạo, vì vậy định dạng CNTK được phân tách bằng tab như sau:
|predictors 1.612820 96.90 3.76 21.00 248.31 |medval 13.50
|predictors 0.064170 68.20 3.36 19.20 396.90 |medval 18.90
|predictors 0.097440 61.40 3.38 19.20 377.56 |medval 20.00
. . .
20 mục tiếp theo, cũng được chuyển đổi sang định dạng CNTK, sẽ được sử dụng cho mục đích thử nghiệm.
Xây dựng mô hình hồi quy
Đầu tiên, chúng ta cần xử lý các tệp dữ liệu ở định dạng CNTK và để làm điều đó, chúng ta sẽ sử dụng hàm trợ giúp có tên create_reader như sau -
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='predictors', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='medval', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
Tiếp theo, chúng ta cần tạo một hàm trợ giúp chấp nhận đối tượng lô nhỏ CNTK và tính toán số liệu độ chính xác tùy chỉnh.
def mb_accuracy(mb, x_var, y_var, model, delta):
num_correct = 0
num_wrong = 0
x_mat = mb[x_var].asarray()
y_mat = mb[y_var].asarray()
for i in range(mb[x_var].shape[0]):
v = model.eval(x_mat[i])
y = y_mat[i]
if np.abs(v[0,0] – y[0,0]) < delta:
num_correct += 1
else:
num_wrong += 1
return (num_correct * 100.0)/(num_correct + num_wrong)
Bây giờ, chúng ta cần thiết lập các đối số kiến trúc cho NN của chúng ta và cũng cung cấp vị trí của các tệp dữ liệu. Nó có thể được thực hiện với sự trợ giúp của mã python sau:
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 5
hidden_dim = 20
output_dim = 1
train_file = ".\\...\\" #provide the name of the training file(80 data items)
test_file = ".\\...\\" #provide the name of the test file(20 data items)
Bây giờ, với sự trợ giúp của dòng mã sau, chương trình của chúng tôi sẽ tạo ra NN chưa được đào tạo -
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
model = C.ops.alias(oLayer)
Bây giờ, khi chúng ta đã tạo mô hình kép chưa được đào tạo, chúng ta cần thiết lập một đối tượng thuật toán Người học. Chúng tôi sẽ sử dụng trình học SGD vàsquared_error mất chức năng -
tr_loss = C.squared_error(model, Y)
max_iter = 3000
batch_size = 5
base_learn_rate = 0.02
sch=C.learning_parameter_schedule([base_learn_rate, base_learn_rate/2], minibatch_size=batch_size, epoch_size=int((max_iter*batch_size)/2))
learner = C.sgd(model.parameters, sch)
trainer = C.Trainer(model, (tr_loss), [learner])
Bây giờ, khi chúng ta hoàn thành với đối tượng thuật toán Học, chúng ta cần tạo một hàm đọc để đọc dữ liệu huấn luyện -
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
Bây giờ, đã đến lúc đào tạo mô hình NN của chúng ta -
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=boston_input_map) trainer.train_minibatch(curr_batch)
if i % int(max_iter/10) == 0:
mcee = trainer.previous_minibatch_loss_average
acc = mb_accuracy(curr_batch, X, Y, model, delta=3.00)
print("batch %4d: mean squared error = %8.4f, accuracy = %5.2f%% " \ % (i, mcee, acc))
Khi chúng ta đã hoàn tất quá trình đào tạo, hãy đánh giá mô hình bằng cách sử dụng các mục dữ liệu thử nghiệm -
print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=boston_input_map)
acc = mb_accuracy(all_test, X, Y, model, delta=3.00)
print("Prediction accuracy = %0.2f%%" % acc)
Sau khi đánh giá độ chính xác của mô hình NN được đào tạo của chúng tôi, chúng tôi sẽ sử dụng nó để đưa ra dự đoán về dữ liệu không nhìn thấy -
np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[0.09, 50.00, 4.5, 17.00, 350.00], dtype=np.float32)
print("\nPredicting median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])
Hoàn thành mô hình hồi quy
import numpy as np
import cntk as C
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='predictors', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='medval', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
def mb_accuracy(mb, x_var, y_var, model, delta):
num_correct = 0
num_wrong = 0
x_mat = mb[x_var].asarray()
y_mat = mb[y_var].asarray()
for i in range(mb[x_var].shape[0]):
v = model.eval(x_mat[i])
y = y_mat[i]
if np.abs(v[0,0] – y[0,0]) < delta:
num_correct += 1
else:
num_wrong += 1
return (num_correct * 100.0)/(num_correct + num_wrong)
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 5
hidden_dim = 20
output_dim = 1
train_file = ".\\...\\" #provide the name of the training file(80 data items)
test_file = ".\\...\\" #provide the name of the test file(20 data items)
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
model = C.ops.alias(oLayer)
tr_loss = C.squared_error(model, Y)
max_iter = 3000
batch_size = 5
base_learn_rate = 0.02
sch = C.learning_parameter_schedule([base_learn_rate, base_learn_rate/2], minibatch_size=batch_size, epoch_size=int((max_iter*batch_size)/2))
learner = C.sgd(model.parameters, sch)
trainer = C.Trainer(model, (tr_loss), [learner])
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=boston_input_map) trainer.train_minibatch(curr_batch)
if i % int(max_iter/10) == 0:
mcee = trainer.previous_minibatch_loss_average
acc = mb_accuracy(curr_batch, X, Y, model, delta=3.00)
print("batch %4d: mean squared error = %8.4f, accuracy = %5.2f%% " \ % (i, mcee, acc))
print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=boston_input_map)
acc = mb_accuracy(all_test, X, Y, model, delta=3.00)
print("Prediction accuracy = %0.2f%%" % acc)
np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[0.09, 50.00, 4.5, 17.00, 350.00], dtype=np.float32)
print("\nPredicting median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])
if __name__== ”__main__”:
main()
Đầu ra
Using CNTK version = 2.7
batch 0: mean squared error = 385.6727, accuracy = 0.00%
batch 300: mean squared error = 41.6229, accuracy = 20.00%
batch 600: mean squared error = 28.7667, accuracy = 40.00%
batch 900: mean squared error = 48.6435, accuracy = 40.00%
batch 1200: mean squared error = 77.9562, accuracy = 80.00%
batch 1500: mean squared error = 7.8342, accuracy = 60.00%
batch 1800: mean squared error = 47.7062, accuracy = 60.00%
batch 2100: mean squared error = 40.5068, accuracy = 40.00%
batch 2400: mean squared error = 46.5023, accuracy = 40.00%
batch 2700: mean squared error = 15.6235, accuracy = 60.00%
Evaluating test data
Prediction accuracy = 64.00%
Predicting median home value for feature/predictor values:
[0.09 50. 4.5 17. 350.]
Predicted value is:
$21.02(x1000)
Lưu mô hình được đào tạo
Tập dữ liệu giá trị Boston Home này chỉ có 506 mục dữ liệu (trong số đó chúng tôi chỉ kiện 100 mục). Do đó, sẽ chỉ mất vài giây để đào tạo mô hình hồi quy NN, nhưng việc đào tạo trên một tập dữ liệu lớn có hàng trăm hoặc hàng nghìn mục dữ liệu có thể mất hàng giờ hoặc thậm chí vài ngày.
Chúng tôi có thể lưu mô hình của mình để không phải giữ lại từ đầu. Với sự trợ giúp của mã Python sau đây, chúng ta có thể lưu NN được đào tạo của mình -
nn_regressor = “.\\neuralregressor.model” #provide the name of the file
model.save(nn_regressor, format=C.ModelFormat.CNTKv2)
Sau đây là các đối số của hàm save () được sử dụng ở trên:
Tên tệp là đối số đầu tiên của save()chức năng. Nó cũng có thể được viết cùng với đường dẫn của tệp.
Một tham số khác là format tham số có giá trị mặc định C.ModelFormat.CNTKv2.
Đang tải mô hình được đào tạo
Khi bạn đã lưu mô hình được đào tạo, rất dễ dàng tải mô hình đó. Chúng ta chỉ cần sử dụng hàm load (). Hãy kiểm tra điều này trong ví dụ sau:
import numpy as np
import cntk as C
model = C.ops.functions.Function.load(“.\\neuralregressor.model”)
np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[0.09, 50.00, 4.5, 17.00, 350.00], dtype=np.float32)
print("\nPredicting area median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])
Lợi ích của mô hình đã lưu là khi bạn tải một mô hình đã lưu, nó có thể được sử dụng chính xác như thể mô hình vừa được đào tạo.
CNTK - Mô hình phân loại
Chương này sẽ giúp bạn hiểu cách đo lường hiệu suất của mô hình phân loại trong CNTK. Hãy bắt đầu với ma trận nhầm lẫn.
Ma trận hỗn loạn
Ma trận nhầm lẫn - một bảng có đầu ra dự đoán so với đầu ra dự kiến là cách dễ nhất để đo lường hiệu suất của một bài toán phân loại, trong đó đầu ra có thể là hai hoặc nhiều loại lớp.
Để hiểu cách hoạt động của nó, chúng ta sẽ tạo một ma trận nhầm lẫn cho một mô hình phân loại nhị phân dự đoán, liệu một giao dịch thẻ tín dụng là bình thường hay là gian lận. Nó được hiển thị như sau:
Gian lận thực tế | Thực tế bình thường | |
---|---|---|
Predicted fraud |
Thực sự tích cực |
Dương tính giả |
Predicted normal |
Phủ định sai |
Phủ định thực sự |
Như chúng ta có thể thấy, ma trận nhầm lẫn mẫu ở trên chứa 2 cột, một cột dành cho gian lận trong lớp và cột khác dành cho lớp bình thường. Theo cách tương tự, chúng ta có 2 hàng, một hàng được thêm cho gian lận trong lớp và hàng còn lại được thêm cho lớp bình thường. Sau đây là giải thích về các thuật ngữ liên quan đến ma trận nhầm lẫn:
True Positives - Khi cả lớp thực tế và lớp dự đoán của điểm dữ liệu là 1.
True Negatives - Khi cả lớp thực tế và lớp dự đoán của điểm dữ liệu bằng 0.
False Positives - Khi lớp dữ liệu thực tế là 0 và lớp dữ liệu dự đoán là 1.
False Negatives - Khi lớp thực tế của điểm dữ liệu là 1 và lớp dự đoán của điểm dữ liệu là 0.
Hãy xem, làm thế nào chúng ta có thể tính toán số thứ khác nhau từ ma trận nhầm lẫn -
Accuracy- Là số dự đoán đúng được thực hiện bởi mô hình phân loại ML của chúng tôi. Nó có thể được tính toán với sự trợ giúp của công thức sau:
Precision− Nó cho chúng ta biết có bao nhiêu mẫu được dự đoán chính xác trong số tất cả các mẫu chúng ta dự đoán. Nó có thể được tính toán với sự trợ giúp của công thức sau:
Recall or Sensitivity- Nhớ lại là số lượng dương tính được trả về bởi mô hình phân loại ML của chúng tôi. Nói cách khác, nó cho chúng ta biết có bao nhiêu trường hợp gian lận trong tập dữ liệu đã được mô hình thực sự phát hiện. Nó có thể được tính toán với sự trợ giúp của công thức sau:
Specificity- Ngược lại với nhớ lại, nó cung cấp số lượng các phủ định được trả về bởi mô hình phân loại ML của chúng tôi. Nó có thể được tính toán với sự trợ giúp của công thức sau:
Thước đo F
Chúng ta có thể sử dụng F-Measure để thay thế cho ma trận Lẫn lộn. Lý do chính đằng sau điều này, chúng tôi không thể tối đa hóa Nhớ lại và Chính xác cùng một lúc. Có một mối quan hệ rất chặt chẽ giữa các chỉ số này và có thể hiểu được điều đó với sự trợ giúp của ví dụ sau:
Giả sử, chúng ta muốn sử dụng mô hình DL để phân loại các mẫu tế bào là ung thư hay bình thường. Ở đây, để đạt được độ chính xác tối đa, chúng ta cần giảm số lượng dự đoán xuống còn 1. Mặc dù, điều này có thể giúp chúng ta đạt độ chính xác khoảng 100%, nhưng khả năng thu hồi sẽ trở nên thực sự thấp.
Mặt khác, nếu muốn đạt được mức thu hồi tối đa, chúng ta cần đưa ra càng nhiều dự đoán càng tốt. Mặc dù, điều này có thể cung cấp cho chúng ta khoảng thu hồi khoảng 100%, nhưng độ chính xác sẽ trở nên thực sự thấp.
Trên thực tế, chúng ta cần tìm cách cân bằng giữa độ chính xác và khả năng thu hồi. Chỉ số đo F cho phép chúng tôi làm như vậy, vì nó thể hiện mức trung bình hài hòa giữa độ chính xác và thu hồi.
Công thức này được gọi là độ đo F1, trong đó số hạng phụ được gọi là B được đặt thành 1 để có được tỷ lệ chính xác và thu hồi bằng nhau. Để nhấn mạnh sự nhớ lại, chúng ta có thể đặt hệ số B thành 2. Mặt khác, để nhấn mạnh độ chính xác, chúng ta có thể đặt hệ số B thành 0,5.
Sử dụng CNTK để đo lường hiệu suất phân loại
Trong phần trước, chúng tôi đã tạo một mô hình phân loại sử dụng tập dữ liệu hoa Iris. Ở đây, chúng tôi sẽ đo lường hiệu suất của nó bằng cách sử dụng ma trận nhầm lẫn và số liệu F-Measure.
Tạo ma trận nhầm lẫn
Chúng tôi đã tạo mô hình, vì vậy chúng tôi có thể bắt đầu quá trình xác thực, bao gồm confusion matrix, trên cùng một. Đầu tiên, chúng tôi sẽ tạo ma trận nhầm lẫn với sự trợ giúp củaconfusion_matrix chức năng từ scikit-learn. Đối với điều này, chúng tôi cần nhãn thực cho các mẫu thử nghiệm của mình và nhãn dự đoán cho các mẫu thử nghiệm giống nhau.
Hãy tính toán ma trận nhầm lẫn bằng cách sử dụng mã python sau:
from sklearn.metrics import confusion_matrix
y_true = np.argmax(y_test, axis=1)
y_pred = np.argmax(z(X_test), axis=1)
matrix = confusion_matrix(y_true=y_true, y_pred=y_pred)
print(matrix)
Đầu ra
[[10 0 0]
[ 0 1 9]
[ 0 0 10]]
Chúng ta cũng có thể sử dụng chức năng bản đồ nhiệt để hình dung một ma trận nhầm lẫn như sau:
import seaborn as sns
import matplotlib.pyplot as plt
g = sns.heatmap(matrix,
annot=True,
xticklabels=label_encoder.classes_.tolist(),
yticklabels=label_encoder.classes_.tolist(),
cmap='Blues')
g.set_yticklabels(g.get_yticklabels(), rotation=0)
plt.show()
Chúng ta cũng nên có một số hiệu suất duy nhất, chúng ta có thể sử dụng để so sánh mô hình. Đối với điều này, chúng ta cần tính toán lỗi phân loại bằng cách sử dụngclassification_error chức năng, từ gói số liệu trong CNTK như được thực hiện trong khi tạo mô hình phân loại.
Bây giờ để tính toán lỗi phân loại, hãy thực hiện phương pháp kiểm tra trên hàm mất mát với một tập dữ liệu. Sau đó, CNTK sẽ lấy các mẫu mà chúng tôi đã cung cấp làm đầu vào cho chức năng này và đưa ra dự đoán dựa trên các tính năng đầu vào X_test.
loss.test([X_test, y_test])
Đầu ra
{'metric': 0.36666666666, 'samples': 30}
Thực hiện các biện pháp F
Để thực hiện các biện pháp F, CNTK cũng bao gồm chức năng gọi là phương pháp đo lường. Chúng ta có thể sử dụng chức năng này, trong khi đào tạo NN bằng cách thay thế ôcntk.metrics.classification_error, với một cuộc gọi đến cntk.losses.fmeasure khi xác định chức năng nhà máy tiêu chí như sau:
import cntk
@cntk.Function
def criterion_factory(output, target):
loss = cntk.losses.cross_entropy_with_softmax(output, target)
metric = cntk.losses.fmeasure(output, target)
return loss, metric
Sau khi sử dụng hàm cntk.losses.fmeasure, chúng ta sẽ nhận được đầu ra khác nhau cho loss.test cuộc gọi phương thức được đưa ra như sau:
loss.test([X_test, y_test])
Đầu ra
{'metric': 0.83101488749, 'samples': 30}
CNTK - Mô hình hồi quy
Ở đây, chúng ta sẽ nghiên cứu về việc đo lường hiệu suất liên quan đến mô hình hồi quy.
Khái niệm cơ bản về xác thực mô hình hồi quy
Như chúng ta biết rằng mô hình hồi quy khác với mô hình phân loại, theo nghĩa là, không có thước đo nhị phân về đúng hay sai đối với các mẫu của từng cá nhân. Trong mô hình hồi quy, chúng tôi muốn đo lường mức độ gần của dự đoán với giá trị thực tế. Giá trị dự đoán càng gần với sản lượng mong đợi, mô hình càng hoạt động tốt.
Ở đây, chúng ta sẽ đo lường hiệu suất của NN được sử dụng để hồi quy bằng cách sử dụng các hàm tỷ lệ lỗi khác nhau.
Tính toán lề lỗi
Như đã thảo luận trước đó, trong khi xác thực mô hình hồi quy, chúng ta không thể nói liệu một dự đoán là đúng hay sai. Chúng tôi muốn dự đoán của chúng tôi càng gần với giá trị thực càng tốt. Tuy nhiên, một biên độ lỗi nhỏ có thể chấp nhận được ở đây.
Công thức tính toán biên sai số như sau:
Đây,
Predicted value = chỉ ra y bằng một cái mũ
Real value = được dự đoán bởi y
Đầu tiên, chúng ta cần tính toán khoảng cách giữa giá trị dự đoán và giá trị thực. Sau đó, để có được tỷ lệ lỗi tổng thể, chúng ta cần tính tổng các khoảng cách bình phương này và tính giá trị trung bình. Đây được gọi làmean squared chức năng lỗi.
Tuy nhiên, nếu chúng ta muốn các số liệu về hiệu suất thể hiện sai số, chúng ta cần một công thức thể hiện sai số tuyệt đối. Công thức chomean absolute chức năng lỗi như sau:
Công thức trên lấy khoảng cách tuyệt đối giữa giá trị dự đoán và giá trị thực.
Sử dụng CNTK để đo lường hiệu suất hồi quy
Ở đây, chúng ta sẽ xem xét cách sử dụng các số liệu khác nhau, chúng ta đã thảo luận kết hợp với CNTK. Chúng tôi sẽ sử dụng một mô hình hồi quy, có thể đoán dặm cho mỗi gallon cho xe ô tô sử dụng các bước đưa ra dưới đây.
Các bước thực hiện−
Step 1 - Đầu tiên, chúng ta cần nhập các thành phần cần thiết từ cntk gói như sau -
from cntk import default_option, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import relu
Step 2 - Tiếp theo, chúng ta cần xác định một chức năng kích hoạt mặc định bằng cách sử dụng default_optionschức năng. Sau đó, tạo một tập hợp lớp Tuần tự mới và cung cấp hai lớp dày đặc với 64 tế bào thần kinh mỗi lớp. Sau đó, chúng tôi thêm một lớp dày đặc bổ sung (sẽ hoạt động như lớp đầu ra) vào tập hợp lớp Tuần tự và tạo ra 1 nơ-ron mà không cần kích hoạt như sau:
with default_options(activation=relu):
model = Sequential([Dense(64),Dense(64),Dense(1,activation=None)])
Step 3- Khi mạng đã được tạo, chúng ta cần tạo một tính năng đầu vào. Chúng ta cần phải đảm bảo rằng, nó có hình dạng giống như các tính năng mà chúng ta sẽ sử dụng để đào tạo.
features = input_variable(X.shape[1])
Step 4 - Bây giờ, chúng ta cần tạo một input_variable với kích thước 1. Nó sẽ được sử dụng để lưu trữ giá trị mong đợi cho NN.
target = input_variable(1)
z = model(features)
Bây giờ, chúng ta cần đào tạo mô hình và để làm như vậy, chúng ta sẽ tách tập dữ liệu và thực hiện tiền xử lý bằng cách sử dụng các bước triển khai sau:
Step 5−Đầu tiên, nhập StandardScaler từ sklearn.preprocessing để nhận các giá trị từ -1 đến +1. Điều này sẽ giúp chúng ta chống lại các vấn đề về gradient bùng nổ trong NN.
from sklearn.preprocessing import StandardScalar
Step 6 - Tiếp theo, nhập train_test_split từ sklearn.model_selection như sau−
from sklearn.model_selection import train_test_split
Step 7 - Thả mpg từ tập dữ liệu bằng cách sử dụng dropphương pháp. Cuối cùng, tách tập dữ liệu thành một tập hợp đào tạo và xác thực bằng cách sử dụngtrain_test_split chức năng như sau -
x = df_cars.drop(columns=[‘mpg’]).values.astype(np.float32)
y=df_cars.iloc[: , 0].values.reshape(-1, 1).astype(np.float32)
scaler = StandardScaler()
X = scaler.fit_transform(x)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
Step 8 - Bây giờ, chúng ta cần tạo một input_variable khác với kích thước 1. Nó sẽ được sử dụng để lưu trữ giá trị mong đợi cho NN.
target = input_variable(1)
z = model(features)
Chúng tôi đã tách cũng như xử lý trước dữ liệu, bây giờ chúng tôi cần đào tạo NN. Như đã làm trong các phần trước khi tạo mô hình hồi quy, chúng ta cần xác định tổ hợp lỗ vàmetric chức năng huấn luyện mô hình.
import cntk
def absolute_error(output, target):
return cntk.ops.reduce_mean(cntk.ops.abs(output – target))
@ cntk.Function
def criterion_factory(output, target):
loss = squared_error(output, target)
metric = absolute_error(output, target)
return loss, metric
Bây giờ, chúng ta hãy xem cách sử dụng mô hình được đào tạo. Đối với mô hình của chúng tôi, chúng tôi sẽ sử dụng tiêu chí chuẩn là sự kết hợp mất mát và chỉ số.
from cntk.losses import squared_error
from cntk.learners import sgd
from cntk.logging import ProgressPrinter
progress_printer = ProgressPrinter(0)
loss = criterion_factory (z, target)
learner = sgd(z.parameters, 0.001)
training_summary=loss.train((x_train,y_train),parameter_learners=[learner],callbacks=[progress_printer],minibatch_size=16,max_epochs=10)
Hoàn thành ví dụ triển khai
from cntk import default_option, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import relu
with default_options(activation=relu):
model = Sequential([Dense(64),Dense(64),Dense(1,activation=None)])
features = input_variable(X.shape[1])
target = input_variable(1)
z = model(features)
from sklearn.preprocessing import StandardScalar
from sklearn.model_selection import train_test_split
x = df_cars.drop(columns=[‘mpg’]).values.astype(np.float32)
y=df_cars.iloc[: , 0].values.reshape(-1, 1).astype(np.float32)
scaler = StandardScaler()
X = scaler.fit_transform(x)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
target = input_variable(1)
z = model(features)
import cntk
def absolute_error(output, target):
return cntk.ops.reduce_mean(cntk.ops.abs(output – target))
@ cntk.Function
def criterion_factory(output, target):
loss = squared_error(output, target)
metric = absolute_error(output, target)
return loss, metric
from cntk.losses import squared_error
from cntk.learners import sgd
from cntk.logging import ProgressPrinter
progress_printer = ProgressPrinter(0)
loss = criterion_factory (z, target)
learner = sgd(z.parameters, 0.001)
training_summary=loss.train((x_train,y_train),parameter_learners=[learner],callbacks=[progress_printer],minibatch_size=16,max_epochs=10)
Đầu ra
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.001
690 690 24.9 24.9 16
654 636 24.1 23.7 48
[………]
Để xác thực mô hình hồi quy của chúng ta, chúng ta cần đảm bảo rằng, mô hình xử lý dữ liệu mới cũng như với dữ liệu huấn luyện. Đối với điều này, chúng ta cần gọitest phương pháp trên loss và metric kết hợp với dữ liệu thử nghiệm như sau:
loss.test([X_test, y_test])
Đầu ra−
{'metric': 1.89679785619, 'samples': 79}
CNTK - Bộ dữ liệu ngoài bộ nhớ
Trong chương này, cách đo lường hiệu suất của bộ dữ liệu ngoài bộ nhớ sẽ được giải thích.
Trong các phần trước, chúng ta đã thảo luận về các phương pháp khác nhau để xác nhận hiệu suất của NN của chúng ta, nhưng các phương pháp mà chúng ta đã thảo luận, là những phương pháp xử lý các bộ dữ liệu phù hợp với bộ nhớ.
Ở đây, câu hỏi đặt ra đối với các bộ dữ liệu hết bộ nhớ, bởi vì trong kịch bản sản xuất, chúng tôi cần rất nhiều dữ liệu để đào tạo NN. Trong phần này, chúng ta sẽ thảo luận về cách đo hiệu suất khi làm việc với nguồn minibatch và vòng lặp minibatch thủ công.
Nguồn minibatch
Trong khi làm việc với tập dữ liệu ngoài bộ nhớ, tức là các nguồn minibatch, chúng tôi cần thiết lập về tổn thất cũng như số liệu hơi khác so với thiết lập chúng tôi đã sử dụng khi làm việc với tập dữ liệu nhỏ, tức là tập dữ liệu trong bộ nhớ. Đầu tiên, chúng ta sẽ xem cách thiết lập cách cung cấp dữ liệu cho giảng viên của mô hình NN.
Sau đây là các bước thực hiện−
Step 1 - Đầu tiên, từ cntk.io module nhập các thành phần để tạo nguồn minibatch như sau−
from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer,
INFINITY_REPEAT
Step 2 - Tiếp theo, tạo một hàm mới có tên say create_datasource. Hàm này sẽ có hai tham số là tên tệp và giới hạn, với giá trị mặc định làINFINITELY_REPEAT.
def create_datasource(filename, limit =INFINITELY_REPEAT)
Step 3 - Bây giờ, trong chức năng, bằng cách sử dụng StreamDeflớp đóng thùng một định nghĩa luồng cho các nhãn đọc từ trường nhãn có ba tính năng. Chúng tôi cũng cần đặtis_sparse đến False như sau
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
Step 4 - Tiếp theo, tạo để đọc các tính năng được gửi từ tệp đầu vào, tạo một phiên bản khác của StreamDef như sau.
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
Step 5 - Bây giờ, khởi tạo CTFDeserializerlớp thể hiện. Chỉ định tên tệp và luồng mà chúng ta cần giải mã hóa như sau:
deserializer = CTFDeserializer(filename, StreamDefs(labels=
label_stream, features=features_stream)
Step 6 - Tiếp theo, chúng ta cần tạo phiên bản của minisourceBatch bằng cách sử dụng deserializer như sau:
Minibatch_source = MinibatchSource(deserializer, randomize=True, max_sweeps=limit)
return minibatch_source
Step 7- Cuối cùng, chúng tôi cần cung cấp nguồn đào tạo và kiểm tra, mà chúng tôi cũng đã tạo trong các phần trước. Chúng tôi đang sử dụng bộ dữ liệu hoa iris.
training_source = create_datasource(‘Iris_train.ctf’)
test_source = create_datasource(‘Iris_test.ctf’, limit=1)
Sau khi bạn tạo MinibatchSourceví dụ, chúng ta cần đào tạo nó. Chúng ta có thể sử dụng cùng một logic đào tạo, như được sử dụng khi chúng ta làm việc với các bộ dữ liệu nhỏ trong bộ nhớ. Ở đây, chúng tôi sẽ sử dụngMinibatchSource ví dụ, làm đầu vào cho phương thức train trên hàm mất mát như sau:
Sau đây là các bước thực hiện−
Step 1 - Để ghi lại đầu ra của phiên đào tạo, trước tiên hãy nhập ProgressPrinter từ cntk.logging mô-đun như sau -
from cntk.logging import ProgressPrinter
Step 2 - Tiếp theo, để thiết lập phiên đào tạo, nhập trainer và training_session từ cntk.train mô-đun như sau
from cntk.train import Trainer, training_session
Step 3 - Bây giờ, chúng ta cần xác định một số tập hợp các hằng số như minibatch_size, samples_per_epoch và num_epochs như sau
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
max_samples = samples_per_epoch * num_epochs
Step 4 - Tiếp theo, để biết cách đọc dữ liệu trong quá trình luyện CNTK, chúng ta cần xác định một ánh xạ giữa biến đầu vào cho mạng và các luồng trong nguồn minibatch.
input_map = {
features: training_source.streams.features,
labels: training_source.streams.labels
}
Step 5 - Tiếp theo để ghi lại kết quả đầu ra của quá trình đào tạo, hãy khởi tạo progress_printer biến với một mới ProgressPrinterví dụ. Ngoài ra, khởi tạotrainer và cung cấp cho nó mô hình như sau
progress_writer = ProgressPrinter(0)
trainer: training_source.streams.labels
Step 6 - Cuối cùng, để bắt đầu quá trình đào tạo, chúng ta cần gọi training_session chức năng như sau -
session = training_session(trainer,
mb_source=training_source,
mb_size=minibatch_size,
model_inputs_to_streams=input_map,
max_samples=max_samples,
test_config=test_config)
session.train()
Khi chúng tôi đã đào tạo mô hình, chúng tôi có thể thêm xác thực vào thiết lập này bằng cách sử dụng TestConfig đối tượng và gán nó cho test_config đối số từ khóa của train_session chức năng.
Sau đây là các bước thực hiện−
Step 1 - Đầu tiên, chúng ta cần nhập TestConfig lớp từ mô-đun cntk.train như sau
from cntk.train import TestConfig
Step 2 - Bây giờ, chúng ta cần tạo một phiên bản mới của TestConfig với test_source như đầu vào
Test_config = TestConfig(test_source)
Hoàn thành ví dụ
from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer, INFINITY_REPEAT
def create_datasource(filename, limit =INFINITELY_REPEAT)
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
deserializer = CTFDeserializer(filename, StreamDefs(labels=label_stream, features=features_stream)
Minibatch_source = MinibatchSource(deserializer, randomize=True, max_sweeps=limit)
return minibatch_source
training_source = create_datasource(‘Iris_train.ctf’)
test_source = create_datasource(‘Iris_test.ctf’, limit=1)
from cntk.logging import ProgressPrinter
from cntk.train import Trainer, training_session
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
max_samples = samples_per_epoch * num_epochs
input_map = {
features: training_source.streams.features,
labels: training_source.streams.labels
}
progress_writer = ProgressPrinter(0)
trainer: training_source.streams.labels
session = training_session(trainer,
mb_source=training_source,
mb_size=minibatch_size,
model_inputs_to_streams=input_map,
max_samples=max_samples,
test_config=test_config)
session.train()
from cntk.train import TestConfig
Test_config = TestConfig(test_source)
Đầu ra
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.57 1.57 0.214 0.214 16
1.38 1.28 0.264 0.289 48
[………]
Finished Evaluation [1]: Minibatch[1-1]:metric = 69.65*30;
Vòng lặp minibatch thủ công
Như chúng ta thấy ở trên, thật dễ dàng để đo lường hiệu suất của mô hình NN của chúng ta trong và sau khi đào tạo, bằng cách sử dụng các số liệu khi đào tạo với các API thông thường trong CNTK. Tuy nhiên, ở khía cạnh khác, mọi thứ sẽ không dễ dàng như vậy khi làm việc với vòng lặp minibatch thủ công.
Ở đây, chúng tôi đang sử dụng mô hình được đưa ra bên dưới với 4 đầu vào và 3 đầu ra từ tập dữ liệu Iris Flower, cũng được tạo trong các phần trước−
from cntk import default_options, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import log_softmax, relu, sigmoid
from cntk.learners import sgd
model = Sequential([
Dense(4, activation=sigmoid),
Dense(3, activation=log_softmax)
])
features = input_variable(4)
labels = input_variable(3)
z = model(features)
Tiếp theo, tổn thất cho mô hình được định nghĩa là sự kết hợp của hàm mất mát entropy chéo và số liệu đo F như được sử dụng trong các phần trước. Chúng tôi sẽ sử dụngcriterion_factory tiện ích, để tạo đối tượng này như một đối tượng hàm CNTK như được hiển thị bên dưới−
import cntk
from cntk.losses import cross_entropy_with_softmax, fmeasure
@cntk.Function
def criterion_factory(outputs, targets):
loss = cross_entropy_with_softmax(outputs, targets)
metric = fmeasure(outputs, targets, beta=1)
return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, 0.1)
label_mapping = {
'Iris-setosa': 0,
'Iris-versicolor': 1,
'Iris-virginica': 2
}
Bây giờ, khi chúng ta đã xác định hàm mất mát, chúng ta sẽ xem cách chúng ta có thể sử dụng nó trong trình đào tạo, để thiết lập một phiên đào tạo thủ công.
Sau đây là các bước thực hiện -
Step 1 - Đầu tiên, chúng ta cần nhập các gói yêu cầu như numpy và pandas để tải và xử lý trước dữ liệu.
import pandas as pd
import numpy as np
Step 2 - Tiếp theo, để ghi lại thông tin trong quá trình đào tạo, hãy nhập ProgressPrinter lớp như sau
from cntk.logging import ProgressPrinter
Step 3 - Sau đó, chúng ta cần nhập mô-đun huấn luyện viên từ mô-đun cntk.train như sau:
from cntk.train import Trainer
Step 4 - Tiếp theo, tạo một phiên bản mới của ProgressPrinter như sau -
progress_writer = ProgressPrinter(0)
Step 5 - Bây giờ, chúng ta cần khởi tạo trainer với các tham số là mất mát, người học và progress_writer như sau -
trainer = Trainer(z, loss, learner, progress_writer)
Step 6−Tiếp theo, để huấn luyện mô hình, chúng ta sẽ tạo một vòng lặp sẽ lặp lại tập dữ liệu ba mươi lần. Đây sẽ là vòng đào tạo bên ngoài.
for _ in range(0,30):
Step 7- Bây giờ, chúng ta cần tải dữ liệu từ đĩa bằng pandas. Sau đó, để tải tập dữ liệu vàomini-batches, đặt chunksize đối số từ khóa đến 16.
input_data = pd.read_csv('iris.csv',
names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
index_col=False, chunksize=16)
Step 8 - Bây giờ, hãy tạo một khóa đào tạo bên trong cho vòng lặp để lặp lại từng mini-batches.
for df_batch in input_data:
Step 9 - Bây giờ bên trong vòng lặp này, hãy đọc bốn cột đầu tiên bằng cách sử dụng iloc người lập chỉ mục, như features để đào tạo từ và chuyển đổi chúng thành float32 -
feature_values = df_batch.iloc[:,:4].values
feature_values = feature_values.astype(np.float32)
Step 10 - Bây giờ, hãy đọc cột cuối cùng là các nhãn để đào tạo, như sau -
label_values = df_batch.iloc[:,-1]
Step 11 - Tiếp theo, chúng ta sẽ sử dụng các vectơ một nóng để chuyển đổi các chuỗi nhãn thành dạng số của chúng như sau:
label_values = label_values.map(lambda x: label_mapping[x])
Step 12- Sau đó, hãy trình bày dạng số của các nhãn. Tiếp theo, chuyển đổi chúng thành một mảng numpy, để làm việc với chúng dễ dàng hơn như sau:
label_values = label_values.values
Step 13 - Bây giờ, chúng ta cần tạo một mảng numpy mới có cùng số hàng với các giá trị nhãn mà chúng ta đã chuyển đổi.
encoded_labels = np.zeros((label_values.shape[0], 3))
Step 14 - Bây giờ, để tạo các nhãn được mã hóa một lần, hãy chọn các cột dựa trên các giá trị nhãn số.
encoded_labels[np.arange(label_values.shape[0]), label_values] = 1.
Step 15 - Cuối cùng, chúng ta cần gọi train_minibatch trên trình đào tạo và cung cấp các tính năng và nhãn đã xử lý cho minibatch.
trainer.train_minibatch({features: feature_values, labels: encoded_labels})
Hoàn thành ví dụ
from cntk import default_options, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import log_softmax, relu, sigmoid
from cntk.learners import sgd
model = Sequential([
Dense(4, activation=sigmoid),
Dense(3, activation=log_softmax)
])
features = input_variable(4)
labels = input_variable(3)
z = model(features)
import cntk
from cntk.losses import cross_entropy_with_softmax, fmeasure
@cntk.Function
def criterion_factory(outputs, targets):
loss = cross_entropy_with_softmax(outputs, targets)
metric = fmeasure(outputs, targets, beta=1)
return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, 0.1)
label_mapping = {
'Iris-setosa': 0,
'Iris-versicolor': 1,
'Iris-virginica': 2
}
import pandas as pd
import numpy as np
from cntk.logging import ProgressPrinter
from cntk.train import Trainer
progress_writer = ProgressPrinter(0)
trainer = Trainer(z, loss, learner, progress_writer)
for _ in range(0,30):
input_data = pd.read_csv('iris.csv',
names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
index_col=False, chunksize=16)
for df_batch in input_data:
feature_values = df_batch.iloc[:,:4].values
feature_values = feature_values.astype(np.float32)
label_values = df_batch.iloc[:,-1]
label_values = label_values.map(lambda x: label_mapping[x])
label_values = label_values.values
encoded_labels = np.zeros((label_values.shape[0], 3))
encoded_labels[np.arange(label_values.shape[0]),
label_values] = 1.
trainer.train_minibatch({features: feature_values, labels: encoded_labels})
Đầu ra
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.45 1.45 -0.189 -0.189 16
1.24 1.13 -0.0382 0.0371 48
[………]
Trong đầu ra ở trên, chúng tôi nhận được cả đầu ra cho sự mất mát và số liệu trong quá trình đào tạo. Đó là vì chúng tôi đã kết hợp số liệu và tổn thất trong một đối tượng chức năng và sử dụng máy in tiến trình trong cấu hình giảng viên.
Bây giờ, để đánh giá hiệu suất của mô hình, chúng ta cần thực hiện tác vụ tương tự như khi huấn luyện mô hình, nhưng lần này, chúng ta cần sử dụng Evaluatorví dụ để kiểm tra mô hình. Nó được hiển thị trong mã Python sau đây
from cntk import Evaluator
evaluator = Evaluator(loss.outputs[1], [progress_writer])
input_data = pd.read_csv('iris.csv',
names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
index_col=False, chunksize=16)
for df_batch in input_data:
feature_values = df_batch.iloc[:,:4].values
feature_values = feature_values.astype(np.float32)
label_values = df_batch.iloc[:,-1]
label_values = label_values.map(lambda x: label_mapping[x])
label_values = label_values.values
encoded_labels = np.zeros((label_values.shape[0], 3))
encoded_labels[np.arange(label_values.shape[0]), label_values] = 1.
evaluator.test_minibatch({ features: feature_values, labels:
encoded_labels})
evaluator.summarize_test_progress()
Bây giờ, chúng ta sẽ nhận được kết quả như sau:
Đầu ra
Finished Evaluation [1]: Minibatch[1-11]:metric = 74.62*143;
CNTK - Giám sát mô hình
Trong chương này, chúng ta sẽ hiểu cách giám sát một mô hình trong CNTK.
Giới thiệu
Trong các phần trước, chúng tôi đã thực hiện một số xác nhận trên các mô hình NN của chúng tôi. Tuy nhiên, có cần thiết và có thể giám sát mô hình của chúng tôi trong quá trình đào tạo không?
Có, chúng tôi đã sử dụng ProgressWriterđể theo dõi mô hình của chúng tôi và có nhiều cách khác để làm như vậy. Trước khi đi sâu vào các cách thức, trước tiên hãy xem cách hoạt động của giám sát trong CNTK và cách chúng ta có thể sử dụng nó để phát hiện các vấn đề trong mô hình NN của mình.
Gọi lại trong CNTK
Trên thực tế, trong quá trình đào tạo và xác thực, CNTK cho phép chúng tôi chỉ định các lệnh gọi lại ở một số vị trí trong API. Trước tiên, chúng ta hãy xem xét kỹ hơn khi CNTK gọi lại.
Khi CNTK gọi lại lệnh gọi?
CNTK sẽ gọi các lệnh gọi lại tại các thời điểm tập hợp đào tạo và thử nghiệm khi−
Một minibatch đã hoàn thành.
Quá trình quét toàn bộ tập dữ liệu được hoàn thành trong quá trình đào tạo.
Một loạt thử nghiệm nhỏ đã hoàn thành.
Quá trình quét toàn bộ tập dữ liệu được hoàn tất trong quá trình thử nghiệm.
Chỉ định gọi lại
Trong khi làm việc với CNTK, chúng tôi có thể chỉ định các lệnh gọi lại ở một số vị trí trong API. Ví dụ:
Khi gọi tàu trên một hàm mất mát?
Ở đây, khi chúng ta gọi train trên một hàm loss, chúng ta có thể chỉ định một tập hợp các lệnh gọi lại thông qua đối số gọi lại như sau:
training_summary=loss.train((x_train,y_train),
parameter_learners=[learner],
callbacks=[progress_writer]),
minibatch_size=16, max_epochs=15)
Khi làm việc với nguồn minibatch hoặc sử dụng vòng lặp minibatch thủ công−
Trong trường hợp này, chúng tôi có thể chỉ định các lệnh gọi lại cho mục đích giám sát trong khi tạo Trainer như sau
from cntk.logging import ProgressPrinter
callbacks = [
ProgressPrinter(0)
]
Trainer = Trainer(z, (loss, metric), learner, [callbacks])
Các công cụ giám sát khác nhau
Hãy để chúng tôi nghiên cứu về các công cụ giám sát khác nhau.
ProgressPrinter
Trong khi đọc hướng dẫn này, bạn sẽ thấy ProgressPrinterlà công cụ giám sát được sử dụng nhiều nhất. Một số đặc điểm củaProgressPrinter công cụ giám sát là
ProgressPrinterlớp thực hiện ghi nhật ký dựa trên giao diện điều khiển cơ bản để giám sát mô hình của chúng tôi. Nó có thể đăng nhập vào đĩa mà chúng tôi muốn.
Đặc biệt hữu ích khi làm việc trong một kịch bản đào tạo phân tán.
Nó cũng rất hữu ích khi làm việc trong trường hợp chúng tôi không thể đăng nhập vào bảng điều khiển để xem kết quả của chương trình Python của chúng tôi.
Với sự trợ giúp của mã sau, chúng ta có thể tạo một phiên bản của ProgressPrinter-
ProgressPrinter(0, log_to_file=’test.txt’)
Chúng ta sẽ nhận được kết quả đầu ra mà chúng ta đã thấy trong các phần trước−
Test.txt
CNTKCommandTrainInfo: train : 300
CNTKCommandTrainInfo: CNTKNoMoreCommands_Total : 300
CNTKCommandTrainBegin: train
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.45 1.45 -0.189 -0.189 16
1.24 1.13 -0.0382 0.0371 48
[………]
TensorBoard
Một trong những nhược điểm của việc sử dụng ProgressPrinter là chúng ta không thể có một cái nhìn rõ ràng về mức độ mất mát và tiến trình số liệu theo thời gian là khó khăn. TensorBoardProgressWriter là một sự thay thế tuyệt vời cho lớp ProgressPrinter trong CNTK.
Trước khi sử dụng, trước tiên chúng ta cần cài đặt nó với sự trợ giúp của lệnh sau:
pip install tensorboard
Bây giờ, để sử dụng TensorBoard, chúng ta cần thiết lập TensorBoardProgressWriter trong mã đào tạo của chúng tôi như sau−
import time
from cntk.logging import TensorBoardProgressWriter
tensorbrd_writer = TensorBoardProgressWriter(log_dir=’logs/{}’.format(time.time()),freq=1,model=z)
Một phương pháp hay là gọi phương thức đóng trên TensorBoardProgressWriter ví dụ sau khi hoàn thành việc đào tạo NNmô hình.
Chúng ta có thể hình dung TensorBoard ghi dữ liệu với sự trợ giúp của lệnh sau:
Tensorboard –logdir logs
CNTK - Mạng nơ-ron hợp pháp
Trong chương này, chúng ta hãy nghiên cứu cách xây dựng Mạng nơ-ron liên kết (CNN) trong CNTK.
Giới thiệu
Mạng nơ-ron chuyển đổi (CNN) cũng được tạo thành từ các nơ-ron, có trọng số và độ lệch có thể học được. Đó là lý do tại sao theo cách này, chúng giống như các mạng nơ-ron thông thường (NN).
Nếu chúng ta nhớ lại hoạt động của các NN thông thường, mỗi tế bào thần kinh nhận được một hoặc nhiều đầu vào, lấy tổng trọng số và nó được chuyển qua một hàm kích hoạt để tạo ra đầu ra cuối cùng. Ở đây, câu hỏi được đặt ra là nếu CNN và NN thông thường có nhiều điểm giống nhau như vậy thì điều gì khiến hai mạng này khác biệt với nhau?
Điều gì làm cho chúng khác nhau là việc xử lý dữ liệu đầu vào và các loại lớp? Cấu trúc của dữ liệu đầu vào được bỏ qua trong NN thông thường và tất cả dữ liệu được chuyển đổi thành mảng 1-D trước khi đưa nó vào mạng.
Tuy nhiên, kiến trúc Mạng nơ ron Convolutions có thể xem xét cấu trúc 2D của hình ảnh, xử lý chúng và cho phép nó trích xuất các thuộc tính đặc trưng cho hình ảnh. Hơn nữa, CNN có lợi thế là có một hoặc nhiều lớp Convolutional và lớp gộp, là các khối xây dựng chính của CNN.
Các lớp này được theo sau bởi một hoặc nhiều lớp được kết nối đầy đủ như trong các NN đa lớp tiêu chuẩn. Vì vậy, chúng ta có thể coi CNN, như một trường hợp đặc biệt của các mạng được kết nối đầy đủ.
Kiến trúc mạng nơ-ron hợp pháp (CNN)
Kiến trúc của CNN về cơ bản là một danh sách các lớp biến đổi 3 chiều, tức là chiều rộng, chiều cao và chiều sâu của khối lượng hình ảnh thành khối lượng đầu ra 3 chiều. Một điểm quan trọng cần lưu ý ở đây là, mọi nơ-ron trong lớp hiện tại được kết nối với một bản vá nhỏ của đầu ra từ lớp trước, điều này giống như phủ một bộ lọc N * N lên hình ảnh đầu vào.
Nó sử dụng bộ lọc M, về cơ bản là các bộ trích xuất tính năng để trích xuất các tính năng như cạnh, góc, v.v. Sau đây là các lớp [INPUT-CONV-RELU-POOL-FC] được sử dụng để xây dựng mạng nơ-ron phù hợp (CNN) -
INPUT- Như tên của nó, lớp này giữ các giá trị pixel thô. Giá trị pixel thô có nghĩa là dữ liệu của hình ảnh như nó vốn có. Ví dụ, INPUT [64 × 64 × 3] là hình ảnh RGB 3 kênh có chiều rộng-64, chiều cao-64 và chiều sâu-3.
CONV- Lớp này là một trong những khối xây dựng của CNN vì hầu hết việc tính toán được thực hiện trong lớp này. Ví dụ - nếu chúng ta sử dụng 6 bộ lọc trên INPUT [64 × 64 × 3] được đề cập ở trên, điều này có thể dẫn đến khối lượng [64 × 64 × 6].
RELU−Còn được gọi là lớp đơn vị tuyến tính được chỉnh lưu, áp dụng một hàm kích hoạt cho đầu ra của lớp trước đó. Theo cách khác, một độ không tuyến tính sẽ được thêm vào mạng bởi RELU.
POOL- Lớp này, tức là lớp Pooling là một khối xây dựng khác của CNN. Nhiệm vụ chính của lớp này là lấy mẫu xuống, có nghĩa là nó hoạt động độc lập trên mọi lát của đầu vào và thay đổi kích thước của nó trong không gian.
FC- Nó được gọi là lớp Kết nối đầy đủ hay cụ thể hơn là lớp đầu ra. Nó được sử dụng để tính điểm lớp đầu ra và kết quả đầu ra là khối lượng có kích thước 1 * 1 * L trong đó L là số tương ứng với điểm lớp.
Sơ đồ dưới đây thể hiện kiến trúc điển hình của CNNs−
Tạo cấu trúc CNN
Chúng tôi đã thấy kiến trúc và những điều cơ bản của CNN, bây giờ chúng tôi sẽ xây dựng mạng phức hợp bằng CNTK. Ở đây, trước tiên chúng ta sẽ xem cách đặt cấu trúc của CNN lại với nhau và sau đó chúng ta sẽ xem xét cách huấn luyện các tham số của nó.
Cuối cùng, chúng ta sẽ thấy, làm thế nào chúng ta có thể cải thiện mạng nơ-ron bằng cách thay đổi cấu trúc của nó với nhiều thiết lập lớp khác nhau. Chúng tôi sẽ sử dụng tập dữ liệu hình ảnh MNIST.
Vì vậy, trước tiên hãy tạo một cấu trúc CNN. Nói chung, khi chúng tôi xây dựng CNN để nhận dạng các mẫu trong hình ảnh, chúng tôi thực hiện như sau:
Chúng tôi sử dụng kết hợp các lớp chập và gộp.
Một hoặc nhiều lớp ẩn ở cuối mạng.
Cuối cùng, chúng tôi kết thúc mạng với một lớp softmax cho mục đích phân loại.
Với sự trợ giúp của các bước sau, chúng ta có thể xây dựng cấu trúc mạng−
Step 1- Đầu tiên, chúng ta cần nhập các lớp cần thiết cho CNN.
from cntk.layers import Convolution2D, Sequential, Dense, MaxPooling
Step 2- Tiếp theo, chúng ta cần nhập các chức năng kích hoạt cho CNN.
from cntk.ops import log_softmax, relu
Step 3- Sau đó, để khởi tạo các lớp phức hợp sau này, chúng ta cần nhập glorot_uniform_initializer như sau
from cntk.initializer import glorot_uniform
Step 4- Tiếp theo, để tạo biến đầu vào, hãy nhập input_variablechức năng. Và nhập khẩudefault_option để làm cho cấu hình NN dễ dàng hơn một chút.
from cntk import input_variable, default_options
Step 5- Bây giờ để lưu trữ các hình ảnh đầu vào, hãy tạo mới input_variable. Nó sẽ chứa ba kênh là đỏ, lục và lam. Nó sẽ có kích thước 28 x 28 pixel.
features = input_variable((3,28,28))
Step 6−Tiếp theo, chúng ta cần tạo một input_variable để lưu trữ các nhãn để dự đoán.
labels = input_variable(10)
Step 7- Bây giờ, chúng ta cần tạo default_optioncho NN. Và, chúng ta cần sử dụngglorot_uniform làm hàm khởi tạo.
with default_options(initialization=glorot_uniform, activation=relu):
Step 8- Tiếp theo, để thiết lập cấu trúc của NN, chúng ta cần tạo một Sequential tập hợp lớp.
Step 9- Bây giờ chúng ta cần thêm một Convolutional2D lớp với một filter_shape của 5 và a strides thiết lập của 1, trong Sequentialtập hợp lớp. Ngoài ra, hãy bật đệm để hình ảnh được đệm để giữ nguyên kích thước ban đầu.
model = Sequential([
Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=8, pad=True),
Step 10- Bây giờ là lúc để thêm một MaxPooling lớp với filter_shape của 2, và a strides cài đặt 2 để nén hình ảnh xuống một nửa.
MaxPooling(filter_shape=(2,2), strides=(2,2)),
Step 11- Bây giờ, như chúng ta đã làm ở bước 9, chúng ta cần thêm một Convolutional2D lớp với một filter_shape của 5 và a stridescài đặt 1, sử dụng 16 bộ lọc. Ngoài ra, hãy bật đệm, để kích thước của hình ảnh được tạo bởi lớp tổng hợp trước đó sẽ được giữ lại.
Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=16, pad=True),
Step 12- Bây giờ, như chúng ta đã làm ở bước 10, hãy thêm một MaxPooling lớp với một filter_shape của 3 và a strides cài đặt 3 để giảm hình ảnh xuống một phần ba.
MaxPooling(filter_shape=(3,3), strides=(3,3)),
Step 13- Cuối cùng, thêm một lớp dày đặc với mười tế bào thần kinh cho 10 lớp có thể, mạng có thể dự đoán. Để biến mạng thành một mô hình phân loại, hãy sử dụnglog_siftmax chức năng kích hoạt.
Dense(10, activation=log_softmax)
])
Toàn bộ ví dụ để tạo cấu trúc CNN
from cntk.layers import Convolution2D, Sequential, Dense, MaxPooling
from cntk.ops import log_softmax, relu
from cntk.initializer import glorot_uniform
from cntk import input_variable, default_options
features = input_variable((3,28,28))
labels = input_variable(10)
with default_options(initialization=glorot_uniform, activation=relu):
model = Sequential([
Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=8, pad=True),
MaxPooling(filter_shape=(2,2), strides=(2,2)),
Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=16, pad=True),
MaxPooling(filter_shape=(3,3), strides=(3,3)),
Dense(10, activation=log_softmax)
])
z = model(features)
Đào tạo CNN bằng hình ảnh
Khi chúng ta đã tạo ra cấu trúc của mạng, đã đến lúc đào tạo mạng. Nhưng trước khi bắt đầu đào tạo mạng của mình, chúng ta cần thiết lập các nguồn minibatch, bởi vì đào tạo NN hoạt động với hình ảnh đòi hỏi nhiều bộ nhớ hơn hầu hết các máy tính có.
Chúng tôi đã tạo các nguồn minibatch trong các phần trước. Sau đây là mã Python để thiết lập hai nguồn minibatch:
Như chúng ta có create_datasource , bây giờ chúng ta có thể tạo hai nguồn dữ liệu riêng biệt (đào tạo và kiểm tra một) để đào tạo mô hình.
train_datasource = create_datasource('mnist_train')
test_datasource = create_datasource('mnist_test', max_sweeps=1, train=False)
Bây giờ, khi chúng ta đã chuẩn bị các hình ảnh, chúng ta có thể bắt đầu đào tạo NN của mình. Như chúng ta đã làm trong các phần trước, chúng ta có thể sử dụng phương thức train trên hàm mất mát để bắt đầu quá trình đào tạo. Sau đây là mã cho điều này -
from cntk import Function
from cntk.losses import cross_entropy_with_softmax
from cntk.metrics import classification_error
from cntk.learners import sgd
@Function
def criterion_factory(output, targets):
loss = cross_entropy_with_softmax(output, targets)
metric = classification_error(output, targets)
return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, lr=0.2)
Với sự trợ giúp của mã trước đó, chúng tôi đã thiết lập mất và học cho NN. Đoạn mã sau sẽ đào tạo và xác thực NN−
from cntk.logging import ProgressPrinter
from cntk.train import TestConfig
progress_writer = ProgressPrinter(0)
test_config = TestConfig(test_datasource)
input_map = {
features: train_datasource.streams.features,
labels: train_datasource.streams.labels
}
loss.train(train_datasource,
max_epochs=10,
minibatch_size=64,
epoch_size=60000,
parameter_learners=[learner],
model_inputs_to_streams=input_map,
callbacks=[progress_writer, test_config])
Hoàn thành ví dụ triển khai
from cntk.layers import Convolution2D, Sequential, Dense, MaxPooling
from cntk.ops import log_softmax, relu
from cntk.initializer import glorot_uniform
from cntk import input_variable, default_options
features = input_variable((3,28,28))
labels = input_variable(10)
with default_options(initialization=glorot_uniform, activation=relu):
model = Sequential([
Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=8, pad=True),
MaxPooling(filter_shape=(2,2), strides=(2,2)),
Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=16, pad=True),
MaxPooling(filter_shape=(3,3), strides=(3,3)),
Dense(10, activation=log_softmax)
])
z = model(features)
import os
from cntk.io import MinibatchSource, StreamDef, StreamDefs, ImageDeserializer, INFINITELY_REPEAT
import cntk.io.transforms as xforms
def create_datasource(folder, train=True, max_sweeps=INFINITELY_REPEAT):
mapping_file = os.path.join(folder, 'mapping.bin')
image_transforms = []
if train:
image_transforms += [
xforms.crop(crop_type='randomside', side_ratio=0.8),
xforms.scale(width=28, height=28, channels=3, interpolations='linear')
]
stream_definitions = StreamDefs(
features=StreamDef(field='image', transforms=image_transforms),
labels=StreamDef(field='label', shape=10)
)
deserializer = ImageDeserializer(mapping_file, stream_definitions)
return MinibatchSource(deserializer, max_sweeps=max_sweeps)
train_datasource = create_datasource('mnist_train')
test_datasource = create_datasource('mnist_test', max_sweeps=1, train=False)
from cntk import Function
from cntk.losses import cross_entropy_with_softmax
from cntk.metrics import classification_error
from cntk.learners import sgd
@Function
def criterion_factory(output, targets):
loss = cross_entropy_with_softmax(output, targets)
metric = classification_error(output, targets)
return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, lr=0.2)
from cntk.logging import ProgressPrinter
from cntk.train import TestConfig
progress_writer = ProgressPrinter(0)
test_config = TestConfig(test_datasource)
input_map = {
features: train_datasource.streams.features,
labels: train_datasource.streams.labels
}
loss.train(train_datasource,
max_epochs=10,
minibatch_size=64,
epoch_size=60000,
parameter_learners=[learner],
model_inputs_to_streams=input_map,
callbacks=[progress_writer, test_config])
Đầu ra
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.2
142 142 0.922 0.922 64
1.35e+06 1.51e+07 0.896 0.883 192
[………]
Biến đổi hình ảnh
Như chúng ta đã thấy, rất khó để đào tạo NN được sử dụng để nhận dạng hình ảnh và chúng cũng cần rất nhiều dữ liệu để đào tạo. Một vấn đề nữa là họ có xu hướng trang bị quá nhiều hình ảnh được sử dụng trong quá trình đào tạo. Chúng ta hãy xem với một ví dụ, khi chúng ta có ảnh chụp khuôn mặt ở tư thế thẳng đứng, người mẫu của chúng ta sẽ gặp khó khăn khi nhận ra khuôn mặt được xoay theo hướng khác.
Để khắc phục vấn đề này, chúng ta có thể sử dụng chức năng nâng cao hình ảnh và CNTK hỗ trợ các phép biến đổi cụ thể khi tạo nguồn minibatch cho hình ảnh. Chúng ta có thể sử dụng một số phép biến đổi như sau:
Chúng tôi có thể cắt ngẫu nhiên hình ảnh được sử dụng để đào tạo chỉ với một vài dòng mã.
Chúng ta cũng có thể sử dụng thang đo và màu sắc.
Hãy xem với sự trợ giúp của mã Python sau, chúng ta có thể thay đổi danh sách các phép biến đổi như thế nào bằng cách bao gồm một phép chuyển đổi cắt xén trong hàm được sử dụng để tạo nguồn minibatch trước đó.
import os
from cntk.io import MinibatchSource, StreamDef, StreamDefs, ImageDeserializer, INFINITELY_REPEAT
import cntk.io.transforms as xforms
def create_datasource(folder, train=True, max_sweeps=INFINITELY_REPEAT):
mapping_file = os.path.join(folder, 'mapping.bin')
image_transforms = []
if train:
image_transforms += [
xforms.crop(crop_type='randomside', side_ratio=0.8),
xforms.scale(width=28, height=28, channels=3, interpolations='linear')
]
stream_definitions = StreamDefs(
features=StreamDef(field='image', transforms=image_transforms),
labels=StreamDef(field='label', shape=10)
)
deserializer = ImageDeserializer(mapping_file, stream_definitions)
return MinibatchSource(deserializer, max_sweeps=max_sweeps)
Với sự trợ giúp của đoạn mã trên, chúng ta có thể nâng cao chức năng bao gồm một tập hợp các phép biến đổi hình ảnh, do đó, khi chúng ta đào tạo, chúng ta có thể cắt ảnh một cách ngẫu nhiên, để chúng ta có được nhiều biến thể hơn của hình ảnh.
CNTK - Mạng thần kinh tái phát
Bây giờ, chúng ta hãy hiểu cách xây dựng Mạng thần kinh tái diễn (RNN) trong CNTK.
Giới thiệu
Chúng tôi đã học cách phân loại hình ảnh bằng mạng nơ-ron và đó là một trong những công việc mang tính biểu tượng trong học sâu. Tuy nhiên, một lĩnh vực khác mà mạng nơ-ron vượt trội và có nhiều nghiên cứu đang diễn ra là Mạng thần kinh tái tạo (RNN). Ở đây, chúng ta sẽ biết RNN là gì và nó có thể được sử dụng như thế nào trong các tình huống mà chúng ta cần xử lý dữ liệu chuỗi thời gian.
Mạng thần kinh tái phát là gì?
Mạng nơ-ron lặp lại (RNN) có thể được định nghĩa là một giống NN đặc biệt có khả năng suy luận theo thời gian. RNN chủ yếu được sử dụng trong các tình huống, nơi chúng ta cần xử lý các giá trị thay đổi theo thời gian, tức là dữ liệu chuỗi thời gian. Để hiểu nó một cách tốt hơn, chúng ta hãy có một so sánh nhỏ giữa mạng nơ-ron thông thường và mạng nơ-ron tuần hoàn -
Như chúng ta biết rằng, trong một mạng nơ-ron thông thường, chúng ta chỉ có thể cung cấp một đầu vào. Điều này giới hạn nó chỉ dẫn đến một dự đoán. Để cung cấp cho bạn một ví dụ, chúng tôi có thể thực hiện công việc dịch văn bản bằng cách sử dụng mạng nơ-ron thông thường.
Mặt khác, trong mạng nơ-ron tuần hoàn, chúng ta có thể cung cấp một chuỗi các mẫu dẫn đến một dự đoán duy nhất. Nói cách khác, sử dụng RNN, chúng ta có thể dự đoán một chuỗi đầu ra dựa trên một chuỗi đầu vào. Ví dụ, đã có khá nhiều thử nghiệm thành công với RNN trong các tác vụ dịch thuật.
Sử dụng mạng thần kinh tái phát
RNN có thể được sử dụng theo một số cách. Một số trong số chúng như sau:
Dự đoán một đầu ra duy nhất
Trước khi đi sâu vào các bước, rằng cách RNN có thể dự đoán một đầu ra duy nhất dựa trên một chuỗi, hãy xem RNN cơ bản trông như thế nào−
Như chúng ta có thể thấy trong sơ đồ trên, RNN chứa một kết nối lặp lại đến đầu vào và bất cứ khi nào, chúng tôi cung cấp một chuỗi giá trị, nó sẽ xử lý từng phần tử trong chuỗi như các bước thời gian.
Hơn nữa, do kết nối lặp lại, RNN có thể kết hợp đầu ra được tạo với đầu vào cho phần tử tiếp theo trong chuỗi. Bằng cách này, RNN sẽ xây dựng một bộ nhớ trên toàn bộ chuỗi có thể được sử dụng để đưa ra dự đoán.
Để đưa ra dự đoán với RNN, chúng ta có thể thực hiện các bước sau:
Đầu tiên, để tạo một trạng thái ẩn ban đầu, chúng ta cần nạp phần tử đầu tiên của chuỗi đầu vào.
Sau đó, để tạo ra một trạng thái ẩn được cập nhật, chúng ta cần lấy trạng thái ẩn ban đầu và kết hợp nó với phần tử thứ hai trong chuỗi đầu vào.
Cuối cùng, để tạo ra trạng thái ẩn cuối cùng và để dự đoán đầu ra cho RNN, chúng ta cần lấy phần tử cuối cùng trong chuỗi đầu vào.
Bằng cách này, với sự trợ giúp của kết nối lặp lại này, chúng ta có thể dạy RNN nhận ra các mẫu xảy ra theo thời gian.
Dự đoán một chuỗi
Mô hình cơ bản, được thảo luận ở trên, của RNN cũng có thể được mở rộng cho các trường hợp sử dụng khác. Ví dụ, chúng ta có thể sử dụng nó để dự đoán một chuỗi giá trị dựa trên một đầu vào duy nhất. Trong trường hợp này, để đưa ra dự đoán với RNN, chúng ta có thể thực hiện các bước sau:
Đầu tiên, để tạo một trạng thái ẩn ban đầu và dự đoán phần tử đầu tiên trong chuỗi đầu ra, chúng ta cần đưa một mẫu đầu vào vào mạng nơ-ron.
Sau đó, để tạo ra một trạng thái ẩn được cập nhật và phần tử thứ hai trong chuỗi đầu ra, chúng ta cần kết hợp trạng thái ẩn ban đầu với cùng một mẫu.
Cuối cùng, để cập nhật trạng thái ẩn thêm một lần nữa và dự đoán phần tử cuối cùng trong chuỗi đầu ra, chúng tôi nạp mẫu vào một lần khác.
Dự đoán trình tự
Như chúng ta đã thấy cách dự đoán một giá trị dựa trên một chuỗi và cách dự đoán một chuỗi dựa trên một giá trị duy nhất. Bây giờ chúng ta hãy xem làm thế nào chúng ta có thể dự đoán trình tự cho các chuỗi. Trong trường hợp này, để đưa ra dự đoán với RNN, chúng ta có thể thực hiện các bước sau:
Đầu tiên, để tạo một trạng thái ẩn ban đầu và dự đoán phần tử đầu tiên trong chuỗi đầu ra, chúng ta cần lấy phần tử đầu tiên trong chuỗi đầu vào.
Sau đó, để cập nhật trạng thái ẩn và dự đoán phần tử thứ hai trong chuỗi đầu ra, chúng ta cần lấy trạng thái ẩn ban đầu.
Cuối cùng, để dự đoán phần tử cuối cùng trong chuỗi đầu ra, chúng ta cần lấy trạng thái ẩn được cập nhật và phần tử cuối cùng trong chuỗi đầu vào.
Hoạt động của RNN
Để hiểu hoạt động của mạng nơ-ron tuần hoàn (RNN), trước tiên chúng ta cần hiểu cách thức hoạt động của các lớp tuần hoàn trong mạng. Vì vậy, trước tiên chúng ta hãy thảo luận về cách e có thể dự đoán đầu ra với một lớp định kỳ tiêu chuẩn.
Dự đoán đầu ra với lớp RNN tiêu chuẩn
Như chúng ta đã thảo luận trước đó rằng một lớp cơ bản trong RNN khá khác với một lớp thông thường trong mạng nơ-ron. Trong phần trước, chúng ta cũng đã trình bày trong sơ đồ kiến trúc cơ bản của RNN. Để cập nhật trạng thái ẩn cho chuỗi bước lần đầu tiên, chúng ta có thể sử dụng công thức sau:
Trong phương trình trên, ta tính trạng thái ẩn mới bằng cách tính tích số chấm giữa ẩn trạng thái ban đầu và tập hợp các trọng số.
Bây giờ cho bước tiếp theo, trạng thái ẩn cho bước thời gian hiện tại được sử dụng làm trạng thái ẩn ban đầu cho bước thời gian tiếp theo trong chuỗi. Đó là lý do tại sao, để cập nhật trạng thái ẩn cho bước lần thứ hai, chúng ta có thể lặp lại các phép tính đã thực hiện trong bước lần đầu tiên như sau:
Tiếp theo, chúng ta có thể lặp lại quá trình cập nhật trạng thái ẩn cho bước thứ ba và bước cuối cùng trong trình tự như dưới đây:
Và khi chúng tôi đã xử lý tất cả các bước trên theo trình tự, chúng tôi có thể tính toán đầu ra như sau:
Đối với công thức trên, chúng ta đã sử dụng bộ trọng số thứ ba và trạng thái ẩn từ bước thời gian cuối cùng.
Đơn vị định kỳ nâng cao
Vấn đề chính với lớp lặp lại cơ bản là vấn đề độ dốc biến mất và do đó, nó không tốt trong việc học các mối tương quan dài hạn. Nói cách đơn giản, lớp lặp lại cơ bản không xử lý tốt các chuỗi dài. Đó là lý do tại sao một số loại lớp lặp lại khác phù hợp hơn nhiều để làm việc với các chuỗi dài hơn như sau:
Bộ nhớ dài hạn (LSTM)
Mạng bộ nhớ ngắn hạn (LSTM) được giới thiệu bởi Hochreiter & Schmidhuber. Nó giải quyết vấn đề nhận được một lớp lặp lại cơ bản để ghi nhớ mọi thứ trong một thời gian dài. Kiến trúc của LSTM được đưa ra ở trên trong sơ đồ. Như chúng ta có thể thấy, nó có các tế bào thần kinh đầu vào, các tế bào bộ nhớ và các tế bào thần kinh đầu ra. Để chống lại vấn đề độ dốc biến mất, các mạng bộ nhớ ngắn hạn sử dụng một ô nhớ rõ ràng (lưu trữ các giá trị trước đó) và các cổng sau:
Forget gate- Như tên của nó, nó báo cho ô nhớ quên các giá trị trước đó. Ô nhớ lưu trữ các giá trị cho đến khi cổng tức là 'cổng quên' yêu cầu nó quên chúng.
Input gate- Như tên của nó, nó thêm những thứ mới vào ô.
Output gate- Như tên của nó, cổng xuất quyết định thời điểm truyền các vectơ từ ô sang trạng thái ẩn tiếp theo.
Đơn vị định kỳ được xác định (GRU)
Gradient recurrent units(GRUs) là một biến thể nhỏ của mạng LSTMs. Nó có một cổng ít hơn và có dây hơi khác so với LSTM. Kiến trúc của nó được thể hiện trong sơ đồ trên. Nó có các tế bào thần kinh đầu vào, các tế bào bộ nhớ được kiểm soát và các tế bào thần kinh đầu ra. Mạng Gated Recurrent Units có hai cổng sau:
Update gate- Nó quyết định hai điều sau
Số lượng thông tin nên được giữ từ trạng thái cuối cùng?
Lượng thông tin nào nên được đưa vào từ lớp trước?
Reset gate- Chức năng của cổng thiết lập lại giống như chức năng của cổng quên của mạng LSTMs. Sự khác biệt duy nhất là nó nằm hơi khác một chút.
Ngược lại với mạng bộ nhớ dài hạn, mạng bộ nhớ định kỳ nhanh hơn và dễ chạy hơn một chút.
Tạo cấu trúc RNN
Trước khi chúng ta có thể bắt đầu, đưa ra dự đoán về đầu ra từ bất kỳ nguồn dữ liệu nào của chúng ta, trước tiên chúng ta cần xây dựng RNN và việc xây dựng RNN hoàn toàn giống như chúng ta đã xây dựng mạng nơ ron thông thường trong phần trước. Sau đây là mã để tạo một
from cntk.losses import squared_error
from cntk.io import CTFDeserializer, MinibatchSource, INFINITELY_REPEAT, StreamDefs, StreamDef
from cntk.learners import adam
from cntk.logging import ProgressPrinter
from cntk.train import TestConfig
BATCH_SIZE = 14 * 10
EPOCH_SIZE = 12434
EPOCHS = 10
Xếp chồng nhiều lớp
Chúng ta cũng có thể xếp chồng nhiều lớp lặp lại trong CNTK. Ví dụ, chúng ta có thể sử dụng sự kết hợp sau của các lớp−
from cntk import sequence, default_options, input_variable
from cntk.layers import Recurrence, LSTM, Dropout, Dense, Sequential, Fold
features = sequence.input_variable(1)
with default_options(initial_state = 0.1):
model = Sequential([
Fold(LSTM(15)),
Dense(1)
])(features)
target = input_variable(1, dynamic_axes=model.dynamic_axes)
Như chúng ta thấy trong đoạn mã trên, chúng ta có hai cách sau để có thể lập mô hình RNN trong CNTK:
Đầu tiên, nếu chúng ta chỉ muốn đầu ra cuối cùng của một lớp lặp lại, chúng ta có thể sử dụng Fold kết hợp với một lớp lặp lại, chẳng hạn như GRU, LSTM hoặc thậm chí RNNStep.
Thứ hai, như một cách thay thế, chúng tôi cũng có thể sử dụng Recurrence khối.
Huấn luyện RNN với dữ liệu chuỗi thời gian
Sau khi xây dựng mô hình, hãy xem cách chúng ta có thể đào tạo RNN trong CNTK -
from cntk import Function
@Function
def criterion_factory(z, t):
loss = squared_error(z, t)
metric = squared_error(z, t)
return loss, metric
loss = criterion_factory(model, target)
learner = adam(model.parameters, lr=0.005, momentum=0.9)
Bây giờ để tải dữ liệu vào quá trình đào tạo, chúng ta phải giải mã chuỗi từ một tập hợp các tệp CTF. Mã sau cócreate_datasource , là một chức năng tiện ích hữu ích để tạo cả nguồn dữ liệu đào tạo và kiểm tra.
target_stream = StreamDef(field='target', shape=1, is_sparse=False)
features_stream = StreamDef(field='features', shape=1, is_sparse=False)
deserializer = CTFDeserializer(filename, StreamDefs(features=features_stream, target=target_stream))
datasource = MinibatchSource(deserializer, randomize=True, max_sweeps=sweeps)
return datasource
train_datasource = create_datasource('Training data filename.ctf')#we need to provide the location of training file we created from our dataset.
test_datasource = create_datasource('Test filename.ctf', sweeps=1) #we need to provide the location of testing file we created from our dataset.
Bây giờ, khi chúng ta đã thiết lập các nguồn dữ liệu, mô hình và hàm mất mát, chúng ta có thể bắt đầu quá trình đào tạo. Nó hoàn toàn tương tự như chúng ta đã làm trong các phần trước với mạng nơ-ron cơ bản.
progress_writer = ProgressPrinter(0)
test_config = TestConfig(test_datasource)
input_map = {
features: train_datasource.streams.features,
target: train_datasource.streams.target
}
history = loss.train(
train_datasource,
epoch_size=EPOCH_SIZE,
parameter_learners=[learner],
model_inputs_to_streams=input_map,
callbacks=[progress_writer, test_config],
minibatch_size=BATCH_SIZE,
max_epochs=EPOCHS
)
Chúng ta sẽ nhận được kết quả tương tự như sau:
Đầu ra−
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.005
0.4 0.4 0.4 0.4 19
0.4 0.4 0.4 0.4 59
0.452 0.495 0.452 0.495 129
[…]
Xác thực mô hình
Trên thực tế, việc tạo lại bằng RNN khá giống với việc tạo dự đoán với bất kỳ mô hình CNK nào khác. Sự khác biệt duy nhất là, chúng tôi cần cung cấp các trình tự hơn là các mẫu đơn lẻ.
Bây giờ, khi RNN của chúng tôi cuối cùng đã được đào tạo xong, chúng tôi có thể xác nhận mô hình bằng cách kiểm tra nó bằng cách sử dụng một số chuỗi mẫu như sau:
import pickle
with open('test_samples.pkl', 'rb') as test_file:
test_samples = pickle.load(test_file)
model(test_samples) * NORMALIZE
Đầu ra−
array([[ 8081.7905],
[16597.693 ],
[13335.17 ],
...,
[11275.804 ],
[15621.697 ],
[16875.555 ]], dtype=float32)