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 nhỏ trong bộ 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. Các tập dữ liệu có thể là tập dữ liệu nhỏ trong bộ 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 khung sau –
- Numpy
- gấu trúc
Sử dụng mảng Numpy
Ở đây, chúng tôi sẽ làm việc với 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 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 mình.
Ví dụ triển khai
Để làm được đ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 chứa biểu diễn vectơ một điểm nóng của các nhãn mà 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 –
Bước 1 − Nhập gói numpy như sau − import numpy as npnum_samples = 20000
Bước 2 − Tiếp theo, tạo ánh xạ nhãn bằng cách sử dụng hàm np.eye như sau − label_mapping = np.eye(2)
Bước 3 − Bây giờ bằng cách sử dụng hàm np.random.choice, thu thập 20000 mẫu ngẫu nhiên như sau − y = label_mapping[np.random.choice(2,num_samples)].astype(np.float32)
Bước 4 − Cuối cùng, bằng cách sử dụng hàm np.random.random, tạo ra một mảng các giá trị dấu phẩy động ngẫu nhiên như sau − x = np.random.random(size=(num_samples, 4)).astype(np.float32)
Sau khi tạo một mảng các giá trị dấu phẩy động ngẫu nhiên, chúng ta cần chuyển đổi chúng thành số dấu phẩy động 32 bit để 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 để thực hiện việc này –
Bước 5 − Nhập các hàm lớp dày đặc và tuần tự từ mô-đun cntk.layers như sau − from cntk.layers import Dense, Sequential
Bước 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. Chúng ta hãy nhập sigmoid làm hàm kích hoạt − from cntk import input_variable, default_optionsfrom cntk.ops import sigmoid
Bước 7 − Bây giờ, chúng ta cần nhập hàm loss để huấn luyện mạng. Chúng ta hãy nhập binary_cross_entropy dưới dạng hàm mất − from cntk.losses import binary_cross_entropy
Bước 8 − Tiếp theo, chúng ta cần xác định các tùy chọn mặc định cho mạng. Tại đây, chúng tôi sẽ cung cấp chức năng kích hoạt sigmoid làm cài đặt mặc định. Ngoài ra, hãy 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)])
Bước 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)
Bước 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 huấn luyện nó bằng cách sử dụng tập dữ liệu trong bộ nhớ –
Bước 11 − Để huấn luyện NN này, trước tiên chúng ta cần nhập người học từ cntk.learners mô-đun. Chúng ta sẽ nhập sgd người học như sau − from cntk.learners import sgd
Bước 12 − Cùng với đó, nhập ProgressPrinter từ cntk.logging mô-đun nữa. from cntk.logging import ProgressPrinterprogress_writer = ProgressPrinter(0)
Bước 13 − Tiếp theo, xác định biến đầu vào mới cho nhãn như sau − labels = input_variable(2)
Bước 14 − Để huấn luyện mô hình NN, tiếp theo, chúng ta cần xác định tổn thất bằng cách sử dụng binary_cross_entropy< một hàm i=3>. Ngoài ra, hãy cung cấp mô hình z và biến nhãn. loss = binary_cross_entropy(z, labels)
Bước 15 − Tiếp theo, khởi tạo trình học sgd như sau − learner = sgd(z.parameters, lr=0.1)
Bước 16 − Cuối cùng, gọi phương thức train trên hàm mất mát. Ngoài ra, hãy cung cấp cho nó dữ liệu đầu vào, người học sgd và progress_printer.− training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer])
Ví dụ triển khai hoàn chỉnh
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 examplesloss last metric last
Sử dụng DataFrames của Pandas
Mảng Numpy rất hạn chế về những gì chúng có thể chứa và 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 thuộc một kiểu dữ liệu. Nhưng mặt khác, trong nhiều trường hợp thực tế, chúng ta cần một thư viện có thể xử lý nhiều loại dữ liệu trong một tập dữ liệu. Một trong những thư viện Python có tên Pandas giúp làm việc với loại bộ 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 tôi tải các tập dữ liệu từ đĩa được lưu trữ ở nhiều đị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
Ví dụ triển khai
Trong ví dụ này, chúng ta sẽ sử dụng ví dụ về việc phân loại ba loài hoa diên vĩ có thể có dựa trên bốn đặc tính. Chúng tôi cũng đã tạo mô hình deep learning 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 có ba nơ-ron để phù hợp với số lượng lớp mà chúng ta có thể dự đoán.
Tiếp theo, chúng ta sẽ sử dụng phương pháp train và loss chức năng huấn luyện mạng. Để làm đ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ó phù hợp với bố cục và định dạng dữ liệu dự kiến cho NN. Nó có thể được thực hiện với sự trợ giúp của các bước sau −
Bước 1 − Nhập numpy và Pandas< /span> gói như sau − import numpy as npimport pandas as pd
Bước 2 − Tiếp theo, sử dụng hàm read_csv để 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)
Bước 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}
Bước 4 − Bây giờ, bằng cách sử dụng bộ chỉ mục iloc trên DataFrame, chọn bốn cột đầu tiên như sau − x = df_source.iloc[:, :4].values
Bước 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
Bước 6 − Bây giờ, chúng ta cần ánh xạ các nhãn trong tập dữ liệu, việc này có thể được thực hiện bằng cách sử dụng label_mapping< a i=3>. Ngoài ra, hãy sử dụng mã hóa one_hot để chuyển đổi chúng thành mảng mã hóa một lần. y = np.array([one_hot(label_mapping[v], 3) for v in y])
Bước 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 tôi biết, 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ơ mã hóa one-hot đại diện cho các nhãn. Đối với điều này, chúng ta có thể định nghĩa một hàm có tên one_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 để huấn luyện mô hình của mình –
Bước 8 − Đầu tiên, chúng ta cần nhập hàm loss để huấn luyện mạng. Chúng ta hãy nhập binary_cross_entropy_with_softmax dưới dạng hàm mất − from cntk.losses import binary_cross_entropy_with_softmax
Bước 9 − Để huấn luyện NN này, chúng ta cũng cần nhập người học từ cntk.learners mô-đun. Chúng ta sẽ nhập sgd người học như sau − from cntk.learners import sgd
Bước 10 − Cùng với đó, nhập ProgressPrinter từ cntk.logging mô-đun nữa. from cntk.logging import ProgressPrinterprogress_writer = ProgressPrinter(0)
Bước 11 − Tiếp theo, xác định biến đầu vào mới cho nhãn như sau − labels = input_variable(3)
Bước 12 − Để huấn luyện mô hình NN, tiếp theo, chúng ta cần xác định tổn thất bằng cách sử dụng binary_cross_entropy_with_softmax< một hàm i=3>. Đồng thời cung cấp mô hình z và biến nhãn. loss = binary_cross_entropy_with_softmax (z, labels)
Bước 13 − Tiếp theo, khởi tạo trình học sgd như sau − learner = sgd(z.parameters, 0.1)
Bước 14 − Cuối cùng, gọi phương thức train trên hàm mất mát. Ngoài ra, hãy cung cấp cho nó dữ liệu đầu vào, người học sgd và progress_printer. training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer],minibatch_size=16,max_epochs=5)
Ví dụ triển khai hoàn chỉnh
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
Đà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 cách sử dụng Numpy và pandas, nhưng không phải tất cả các tập dữ liệu đều nhỏ như vậy. Đặc biệt các tập dữ liệu chứa hình ảnh, video, mẫu âm thanh đều có dung lượng lớn. MinibatchSource là một thành phần có thể tải dữ liệu theo từng khối do CNTK cung cấp để hoạt động với các tập dữ liệu lớn như vậy. Một số tính năng của các thành phần MinibatchSource như sau −
- MinibatchSource có thể ngăn NN trang bị quá mức bằng cách tự động ngẫu nhiên hóa các mẫu được đọc từ nguồn dữ liệu.
- Nó có đường dẫn 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 ta cũng sẽ khám phá cách chúng ta có thể sử dụng nó làm nguồn cấp dữ liệu cho việc đào tạo NN.
Tạo phiên bản MinibatchSource
Trong phần trước, chúng tôi đã sử dụng ví dụ về hoa diên vĩ 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 gấu trúc bằng MinibatchSource. Trước tiên, chúng ta cần tạo một phiên bản của MinibatchSource với sự trợ giúp của các bước sau −
Ví dụ triển khai
Bước 1 − Đầu tiên, từ mô-đun cntk.io nhập các thành phần cho minibatchsource như sau − from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer, INFINITY_REPEAT
Bước 2 − Bây giờ, bằng cách sử dụng lớp StreamDef, tạo định nghĩa luồng cho nhãn. labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
Bước 3 − Tiếp theo, tạo để đọc các tính năng được cung cấp 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)
Bước 4 − Bây giờ, chúng ta cần cung cấp tệp iris.ctf làm đầu vào và khởi tạo bộ giải tuần tự như sau − deserializer = CTFDeserializer(‘iris.ctf’, StreamDefs(labels=label_stream, features=features_stream)
Bước 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 như sau −bộ giải tuần tự Minibatch_source = MinibatchSource(deserializer, randomize=True)
Tạo một phiên bản MinibatchSource – Ví dụ triển khai hoàn chỉnh
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 tin 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à Định dạng văn bản CNTK (CTF). Bắt buộc phải tạo tệp CTF để lấy dữ liệu cho phiên bản MinibatchSource mà 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
Bước 1 − Đầu tiên, chúng ta cần nhập các gói pandas và numpy như sau − import pandas as pdimport numpy as np
Bước 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ó trong biến df_source. df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
Bước 3 − Bây giờ, bằng cách sử dụng bộ chỉ mục iloc làm đối tượng địa lý, hãy 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].valueslabels = df_source[‘species’].values
Bước 4 − Tiếp theo, chúng ta cần tạo ánh xạ giữa tên nhãn và biểu diễn số của nó. Việc này có thể được thực hiện bằng cách tạo label_mapping như sau − label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
Bước 5 − Bây giờ, chuyển đổi nhãn thành một tập hợp các vectơ được mã hóa một lần 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] = 1return resultVì chúng tôi đã tải và xử lý trước dữ liệu nên đã đến lúc lưu trữ dữ liệu đó trên đĩa ở định dạng tệp CTF. Chúng ta 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 – Ví dụ triển khai hoàn chỉnh
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 phiên bản MinibatchSource,, chúng tôi cần đào tạo phiên bản đó. Chúng ta có thể sử dụng logic huấn luyện tương tự như khi làm việc với các tập dữ liệu nhỏ trong bộ nhớ. Ở đây, chúng ta sẽ sử dụng phiên bản MinibatchSource làm đầu vào cho phương thức huấn luyện về hàm mất mát như sau
Ví dụ triển khai
Bước 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 i=3> như sau − from cntk.logging import ProgressPrinter
Bước 2 − Tiếp theo, để thiết lập phiên đào tạo, hãy nhập huấn luyện viên và như sau −cntk.train từ mô-đun training_session from cntk.train import Trainer,
Bước 3 − Bây giờ, chúng ta cần xác định một số tập hợp hằng số như minibatch_size, như sau −num_epochs và samples_per_epoch minbatch_size = 16samples_per_epoch = 150num_epochs = 30
Bước 4 − Tiếp theo, để biết CNTK cách đọc dữ liệu trong quá trình đào tạo, 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 minibatch nguồn.
input_map = { features: minibatch.source.streams.features, labels: minibatch.source.streams.features}
Bước 5 − Tiếp theo, để ghi lại kết quả của quá trình đào tạo, hãy khởi tạo biến progress_printer với phiên bản ProgressPrinter mới như sau − progress_writer = ProgressPrinter(0)
Bước 6 − Cuối cùng, chúng ta cần gọi phương thức train khi mất 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 – Ví dụ triển khai hoàn chỉnh
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 :
Xem thêm : Đo hiệu suất mạng thần kinh nhân tạo – CNTK