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.
Một 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 Nơ-ron 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 đào tạo -
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 thành việc đà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 trên 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
Bộ 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 đà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.