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 các 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 chúng ta đã thảo luận, là những phương pháp xử lý các tập dữ liệu phù hợp với bộ nhớ.

Ở đây, câu hỏi đặt ra đối với bộ dữ liệu ngoài bộ nhớ là gì, bởi vì trong kịch bản sản xuất, chúng ta 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à nguồn minibatch, chúng tôi cần thiết lập hơi khác biệt về tổn thất, cũng như chỉ số, 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 mô hình NN.

Sau đây là các bước thực hiện−

Step 1 - Đầu tiên, từ cntk.io mô-đun 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 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ụ, 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 trainertraining_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_epochnum_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 đào tạo CNTK, 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: 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, ở mặt 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ư numpypandas để 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 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 huấn luyện 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;