CNTK - การถดถอยเครือข่ายประสาท

บทนี้จะช่วยให้คุณเข้าใจการถดถอยของโครงข่ายประสาทที่เกี่ยวข้องกับ CNTK

บทนำ

อย่างที่เราทราบกันดีว่าในการทำนายค่าตัวเลขจากตัวแปรทำนายหนึ่งตัวหรือมากกว่านั้นเราใช้การถดถอย ลองมาดูตัวอย่างการทำนายค่ากลางของบ้านในหนึ่งใน 100 เมือง ในการทำเช่นนั้นเรามีข้อมูลที่ประกอบด้วย -

  • สถิติอาชญากรรมของแต่ละเมือง

  • อายุของบ้านในแต่ละเมือง

  • การวัดระยะทางจากแต่ละเมืองไปยังสถานที่สำคัญ

  • อัตราส่วนนักเรียนต่อครูในแต่ละเมือง

  • สถิติประชากรทางเชื้อชาติของแต่ละเมือง

  • มูลค่าบ้านเฉลี่ยในแต่ละเมือง

จากตัวแปรตัวทำนายทั้งห้านี้เราต้องการทำนายมูลค่าบ้านเฉลี่ย และสำหรับสิ่งนี้เราสามารถสร้างแบบจำลองการถดถอยเชิงเส้นตามเส้นของ

Y = a0+a1(crime)+a2(house-age)+(a3)(distance)+(a4)(ratio)+(a5)(racial)

ในสมการข้างต้น -

Y คือค่ากลางที่คาดการณ์ไว้

a0 คือค่าคงที่และ

a1 ถึง a5 ทั้งหมดเป็นค่าคงที่ที่เกี่ยวข้องกับตัวทำนายทั้งห้าที่เรากล่าวถึงข้างต้น

นอกจากนี้เรายังมีวิธีอื่นในการใช้เครือข่ายประสาทเทียม มันจะสร้างแบบจำลองการทำนายที่แม่นยำยิ่งขึ้น

ที่นี่เราจะสร้างแบบจำลองการถดถอยของเครือข่ายประสาทโดยใช้ CNTK

กำลังโหลดชุดข้อมูล

ในการใช้การถดถอยของเครือข่ายประสาทโดยใช้ CNTK เราจะใช้ชุดข้อมูลค่าบ้านของพื้นที่บอสตัน สามารถดาวน์โหลดชุดข้อมูลได้จาก UCI Machine Learning Repository ซึ่งมีอยู่ที่https://archive.ics.uci.edu/ml/machine-learning-databases/housing/. ชุดข้อมูลนี้มีทั้งหมด 14 ตัวแปรและ 506 อินสแตนซ์

แต่สำหรับโปรแกรมการติดตั้งของเราเราจะใช้ตัวแปร 6 ตัวจาก 14 ตัวและ 100 อินสแตนซ์ จาก 6, 5 เป็นตัวทำนายและอีกหนึ่งค่าเป็นตัวทำนาย จาก 100 อินสแตนซ์เราจะใช้ 80 สำหรับการฝึกอบรมและ 20 สำหรับการทดสอบ มูลค่าที่เราต้องการทำนายคือราคาบ้านเฉลี่ยในเมือง มาดูตัวทำนายห้าตัวที่เราจะใช้ -

  • Crime per capita in the town - เราคาดว่าค่าที่น้อยกว่าจะเชื่อมโยงกับตัวทำนายนี้

  • Proportion of owner - ยูนิตที่ถูกครอบครองซึ่งสร้างขึ้นก่อนปี 1940 - เราคาดว่าค่าที่น้อยกว่าจะเชื่อมโยงกับตัวทำนายนี้เนื่องจากค่าที่มากกว่าหมายถึงบ้านที่มีอายุ

  • 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.

การเตรียมไฟล์การฝึกอบรมและการทดสอบ

อย่างที่เคยทำมาก่อนอื่นเราต้องแปลงข้อมูลดิบเป็นรูปแบบ CNTK เราจะใช้ข้อมูล 80 รายการแรกเพื่อจุดประสงค์ในการฝึกอบรมดังนั้นรูปแบบ CNTK ที่คั่นด้วยแท็บจึงเป็นดังนี้ -

|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 รายการถัดไปซึ่งแปลงเป็นรูปแบบ CNTK จะใช้เพื่อการทดสอบ

การสร้างแบบจำลองการถดถอย

ขั้นแรกเราต้องประมวลผลไฟล์ข้อมูลในรูปแบบ CNTK และสำหรับสิ่งนั้นเราจะใช้ฟังก์ชันตัวช่วยที่ชื่อ create_reader ดังต่อไปนี้ -

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

ต่อไปเราต้องสร้างฟังก์ชันตัวช่วยที่ยอมรับ CNTK mini-batch object และคำนวณเมตริกความแม่นยำที่กำหนดเอง

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)

ตอนนี้เราต้องตั้งค่าอาร์กิวเมนต์สถาปัตยกรรมสำหรับ NN ของเราและระบุตำแหน่งของไฟล์ข้อมูลด้วย สามารถทำได้ด้วยความช่วยเหลือของรหัส python ต่อไปนี้ -

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)

ตอนนี้ด้วยความช่วยเหลือของบรรทัดรหัสต่อไปนี้โปรแกรมของเราจะสร้าง NN ที่ไม่ได้รับการฝึกฝน -

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)

ตอนนี้เมื่อเราสร้างโมเดลที่ไม่ได้รับการฝึกฝนมาแล้วเราจำเป็นต้องตั้งค่าวัตถุอัลกอริทึมของผู้เรียน เราจะใช้ผู้เรียน SGD และsquared_error ฟังก์ชันการสูญเสีย -

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 }

ตอนนี้ถึงเวลาฝึกโมเดล NN ของเรา -

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)

หลังจากประเมินความแม่นยำของแบบจำลอง NN ที่ได้รับการฝึกฝนแล้วเราจะใช้มันเพื่อทำการคาดคะเนข้อมูลที่มองไม่เห็น -

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])

แบบจำลองการถดถอยที่สมบูรณ์

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()

เอาต์พุต

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)

บันทึกโมเดลที่ได้รับการฝึกฝน

ชุดข้อมูลค่าบ้านบอสตันนี้มีข้อมูลเพียง 506 รายการ (ซึ่งเราฟ้องเพียง 100 รายการ) ดังนั้นจะใช้เวลาเพียงไม่กี่วินาทีในการฝึกแบบจำลองตัวปรับแรงดัน NN แต่การฝึกชุดข้อมูลขนาดใหญ่ที่มีรายการข้อมูลนับแสนรายการอาจใช้เวลาหลายชั่วโมงหรือหลายวัน

เราสามารถบันทึกโมเดลของเราเพื่อที่เราจะได้ไม่ต้องเก็บมันไว้ตั้งแต่ต้น ด้วยความช่วยเหลือในการทำตามรหัส Python เราสามารถบันทึก NN ที่ได้รับการฝึกฝนของเรา -

nn_regressor = “.\\neuralregressor.model” #provide the name of the file
model.save(nn_regressor, format=C.ModelFormat.CNTKv2)

ต่อไปนี้เป็นอาร์กิวเมนต์ของฟังก์ชัน save () ที่ใช้ด้านบน -

  • ชื่อไฟล์เป็นอาร์กิวเมนต์แรกของ save()ฟังก์ชัน นอกจากนี้ยังสามารถเขียนพร้อมกับเส้นทางของไฟล์

  • พารามิเตอร์อื่นคือไฟล์ format พารามิเตอร์ซึ่งมีค่าเริ่มต้น C.ModelFormat.CNTKv2.

กำลังโหลดแบบจำลองที่ผ่านการฝึกอบรม

เมื่อคุณบันทึกโมเดลที่ฝึกแล้วการโหลดโมเดลนั้นทำได้ง่ายมาก เราต้องใช้ฟังก์ชัน load () เท่านั้น ลองตรวจสอบสิ่งนี้ในตัวอย่างต่อไปนี้ -

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])

ข้อดีของโมเดลที่บันทึกไว้คือเมื่อคุณโหลดโมเดลที่บันทึกไว้แล้วจะสามารถใช้งานได้เหมือนกับว่าโมเดลนั้นเพิ่งได้รับการฝึกฝนมา