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])
ข้อดีของโมเดลที่บันทึกไว้คือเมื่อคุณโหลดโมเดลที่บันทึกไว้แล้วจะสามารถใช้งานได้เหมือนกับว่าโมเดลนั้นเพิ่งได้รับการฝึกฝนมา