CNTK - ชุดข้อมูลหน่วยความจำไม่เพียงพอ
ในบทนี้จะอธิบายวิธีการวัดประสิทธิภาพของชุดข้อมูลที่ไม่อยู่ในหน่วยความจำ
ในส่วนก่อนหน้านี้เราได้พูดถึงวิธีการต่างๆในการตรวจสอบประสิทธิภาพของ NN ของเรา แต่วิธีการที่เราได้กล่าวถึงนั้นเป็นวิธีที่เกี่ยวข้องกับชุดข้อมูลที่พอดีกับหน่วยความจำ
ที่นี่คำถามเกิดจากอะไรเกี่ยวกับชุดข้อมูลหน่วยความจำที่ไม่อยู่ในหน่วยความจำเนื่องจากในสถานการณ์การผลิตเราต้องการข้อมูลจำนวนมากเพื่อฝึกอบรม NN. ในส่วนนี้เราจะพูดถึงวิธีการวัดประสิทธิภาพเมื่อทำงานกับแหล่งที่มาของมินิแบทช์และลูปมินิแบทช์ด้วยตนเอง
แหล่งที่มาของมินิแบทช์
ในขณะที่ทำงานกับชุดข้อมูลที่ไม่อยู่ในหน่วยความจำเช่นแหล่งข้อมูลมินิแบทช์เราต้องการการตั้งค่าสำหรับการสูญเสียและเมตริกที่แตกต่างกันเล็กน้อยกว่าการตั้งค่าที่เราใช้ขณะทำงานกับชุดข้อมูลขนาดเล็กเช่นชุดข้อมูลในหน่วยความจำ ขั้นแรกเราจะดูวิธีการตั้งค่าวิธีป้อนข้อมูลไปยังผู้ฝึกสอนของโมเดล NN
ต่อไปนี้เป็นขั้นตอนการติดตั้ง
Step 1 - อันดับแรกจาก cntk.โมดูล io นำเข้าส่วนประกอบสำหรับการสร้างแหล่งมินิแบทช์ดังต่อไปนี้ −
from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer,
INFINITY_REPEAT
Step 2 - จากนั้นสร้างฟังก์ชันใหม่ชื่อ say create_datasource. ฟังก์ชันนี้จะมีสองพารามิเตอร์คือชื่อไฟล์และขีด จำกัด โดยมีค่าเริ่มต้นเป็นINFINITELY_REPEAT.
def create_datasource(filename, limit =INFINITELY_REPEAT)
Step 3 - ตอนนี้ภายในฟังก์ชั่นโดยใช้ StreamDefคลาสสร้างนิยามสตรีมสำหรับเลเบลที่อ่านจากฟิลด์เลเบลที่มีคุณสมบัติสามอย่าง เราต้องตั้งค่าด้วยis_sparse ถึง False ดังต่อไปนี้
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
Step 4 - จากนั้นสร้างเพื่ออ่านคุณสมบัติที่ยื่นจากไฟล์อินพุตสร้างอินสแตนซ์อื่นของ StreamDef ดังต่อไปนี้.
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
Step 5 - ตอนนี้เริ่มต้น CTFDeserializerคลาสอินสแตนซ์ ระบุชื่อไฟล์และสตรีมที่เราต้องการเพื่อยกเลิกการกำหนดค่าตามลำดับดังนี้ -
deserializer = CTFDeserializer(filename, StreamDefs(labels=
label_stream, features=features_stream)
Step 6 - ต่อไปเราต้องสร้างอินสแตนซ์ของ minisourceBatch โดยใช้ deserializer ดังนี้ -
Minibatch_source = MinibatchSource(deserializer, randomize=True, max_sweeps=limit)
return minibatch_source
Step 7- ในที่สุดเราจำเป็นต้องจัดหาแหล่งฝึกอบรมและทดสอบซึ่งเราได้สร้างไว้ในส่วนก่อนหน้านี้ด้วย เราใช้ชุดข้อมูลดอกไอริส
training_source = create_datasource(‘Iris_train.ctf’)
test_source = create_datasource(‘Iris_test.ctf’, limit=1)
เมื่อคุณสร้าง MinibatchSourceเช่นเราต้องฝึกมัน เราสามารถใช้ตรรกะการฝึกแบบเดียวกับที่ใช้เมื่อเราทำงานกับชุดข้อมูลในหน่วยความจำขนาดเล็ก ที่นี่เราจะใช้MinibatchSource เช่นเป็นอินพุตสำหรับเมธอดรถไฟในฟังก์ชันการสูญเสียดังนี้ -
ต่อไปนี้เป็นขั้นตอนการติดตั้ง
Step 1 - ในการบันทึกผลลัพธ์ของเซสชันการฝึกอบรมขั้นแรกให้นำเข้าไฟล์ ProgressPrinter จาก cntk.logging โมดูลดังนี้ -
from cntk.logging import ProgressPrinter
Step 2 - ถัดไปในการตั้งค่าเซสชันการฝึกอบรมให้นำเข้าไฟล์ trainer และ training_session จาก cntk.train โมดูลดังนี้
from cntk.train import Trainer, training_session
Step 3 - ตอนนี้เราต้องกำหนดชุดค่าคงที่เช่น minibatch_size, samples_per_epoch และ num_epochs ดังต่อไปนี้
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
max_samples = samples_per_epoch * num_epochs
Step 4 - ถัดไปเพื่อที่จะทราบวิธีการอ่านข้อมูลระหว่างการฝึกอบรมใน CNTK เราจำเป็นต้องกำหนดการแมประหว่างตัวแปรอินพุตสำหรับเครือข่ายและสตรีมในแหล่งมินิแบทช์
input_map = {
features: training_source.streams.features,
labels: training_source.streams.labels
}
Step 5 - ถัดจากบันทึกผลลัพธ์ของกระบวนการฝึกอบรมให้เริ่มต้นไฟล์ progress_printer ตัวแปรด้วยไฟล์ ProgressPrinterตัวอย่าง. นอกจากนี้ให้เริ่มต้นไฟล์trainer และระบุรุ่นดังต่อไปนี้
progress_writer = ProgressPrinter(0)
trainer: training_source.streams.labels
Step 6 - ในที่สุดเพื่อเริ่มกระบวนการฝึกอบรมเราจำเป็นต้องเรียกใช้ไฟล์ training_session ฟังก์ชันดังต่อไปนี้ -
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()
เมื่อเราฝึกโมเดลแล้วเราสามารถเพิ่มการตรวจสอบความถูกต้องให้กับการตั้งค่านี้ได้โดยใช้ไฟล์ TestConfig วัตถุและกำหนดให้กับไฟล์ test_config อาร์กิวเมนต์คำหลักของ train_session ฟังก์ชัน
ต่อไปนี้เป็นขั้นตอนการติดตั้ง
Step 1 - ขั้นแรกเราต้องนำเข้าไฟล์ TestConfig คลาสจากโมดูล cntk.train ดังต่อไปนี้
from cntk.train import TestConfig
Step 2 - ตอนนี้เราต้องสร้างอินสแตนซ์ใหม่ของไฟล์ TestConfig กับ test_source เป็นอินพุต
Test_config = TestConfig(test_source)
ตัวอย่างที่สมบูรณ์
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)
เอาต์พุต
-------------------------------------------------------------------
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;
ห่วงมินิแบทช์ด้วยตนเอง
ดังที่เราเห็นข้างต้นการวัดประสิทธิภาพของแบบจำลอง NN ของเราในระหว่างและหลังการฝึกอบรมทำได้ง่ายโดยใช้เมตริกเมื่อฝึกอบรมกับ API ปกติใน CNTK แต่ในอีกด้านหนึ่งสิ่งต่างๆจะไม่ง่ายอย่างนั้นในขณะที่ทำงานกับมินิแบทช์แบบแมนนวล
ที่นี่เรากำลังใช้โมเดลที่ให้ไว้ด้านล่างโดยมี 4 อินพุตและ 3 เอาต์พุตจากชุดข้อมูล Iris Flower ซึ่งสร้างขึ้นในส่วนก่อนหน้านี้ด้วย
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)
จากนั้นการสูญเสียสำหรับแบบจำลองจะถูกกำหนดเป็นการรวมกันของฟังก์ชันการสูญเสียเอนโทรปีและเมตริกการวัดค่า F ตามที่ใช้ในส่วนก่อนหน้า เราจะใช้ไฟล์criterion_factory ยูทิลิตี้เพื่อสร้างสิ่งนี้เป็นวัตถุฟังก์ชัน CNTK ดังที่แสดงด้านล่าง
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
}
ตอนนี้เมื่อเราได้กำหนดฟังก์ชันการสูญเสียแล้วเราจะดูว่าเราจะใช้มันในเทรนเนอร์ได้อย่างไรเพื่อตั้งค่าเซสชั่นการฝึกด้วยตนเอง
ต่อไปนี้เป็นขั้นตอนการติดตั้ง -
Step 1 - ขั้นแรกเราต้องนำเข้าแพ็คเกจที่จำเป็นเช่น numpy และ pandas เพื่อโหลดและประมวลผลข้อมูลล่วงหน้า
import pandas as pd
import numpy as np
Step 2 - ถัดไปในการบันทึกข้อมูลระหว่างการฝึกอบรมให้นำเข้าไฟล์ ProgressPrinter class ดังนี้
from cntk.logging import ProgressPrinter
Step 3 - จากนั้นเราต้องนำเข้าโมดูลเทรนเนอร์จากโมดูล cntk.train ดังนี้ -
from cntk.train import Trainer
Step 4 - จากนั้นสร้างอินสแตนซ์ใหม่ของ ProgressPrinter ดังต่อไปนี้ -
progress_writer = ProgressPrinter(0)
Step 5 - ตอนนี้เราจำเป็นต้องเริ่มต้นผู้ฝึกสอนด้วยพารามิเตอร์การสูญเสียผู้เรียนและ progress_writer ดังต่อไปนี้ -
trainer = Trainer(z, loss, learner, progress_writer)
Step 6− ต่อไปเพื่อฝึกโมเดลเราจะสร้างลูปที่จะวนซ้ำในชุดข้อมูล 30 ครั้ง นี่จะเป็นห่วงการฝึกด้านนอก
for _ in range(0,30):
Step 7- ตอนนี้เราต้องโหลดข้อมูลจากดิสก์โดยใช้แพนด้า จากนั้นเพื่อโหลดชุดข้อมูลในmini-batches, ตั้งค่า chunksize อาร์กิวเมนต์คำหลักถึง 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 - ตอนนี้ให้สร้างการฝึกอบรมภายในสำหรับการวนซ้ำเพื่อวนซ้ำในแต่ละไฟล์ mini-batches.
for df_batch in input_data:
Step 9 - ตอนนี้อยู่ในลูปนี้อ่านสี่คอลัมน์แรกโดยใช้ iloc ดัชนีเป็นไฟล์ features เพื่อฝึกจากและแปลงเป็น float32 -
feature_values = df_batch.iloc[:,:4].values
feature_values = feature_values.astype(np.float32)
Step 10 - ตอนนี้อ่านคอลัมน์สุดท้ายเป็นป้ายกำกับที่จะฝึกดังนี้ -
label_values = df_batch.iloc[:,-1]
Step 11 - ต่อไปเราจะใช้เวกเตอร์แบบ one-hot เพื่อแปลงสตริงป้ายกำกับเป็นการนำเสนอตัวเลขดังนี้ -
label_values = label_values.map(lambda x: label_mapping[x])
Step 12- หลังจากนั้นนำเสนอตัวเลขของป้ายกำกับ จากนั้นแปลงเป็นอาร์เรย์ numpy ดังนั้นจึงง่ายต่อการทำงานกับพวกเขาดังนี้ -
label_values = label_values.values
Step 13 - ตอนนี้เราจำเป็นต้องสร้างอาร์เรย์จำนวนใหม่ที่มีจำนวนแถวเท่ากับค่าป้ายกำกับที่เราแปลง
encoded_labels = np.zeros((label_values.shape[0], 3))
Step 14 - ตอนนี้ในการสร้างป้ายที่เข้ารหัสแบบร้อนเดียวให้เลือกคอลัมน์ตามค่าป้ายตัวเลข
encoded_labels[np.arange(label_values.shape[0]), label_values] = 1.
Step 15 - ในที่สุดเราต้องเรียกใช้ไฟล์ train_minibatch วิธีการบนเทรนเนอร์และจัดเตรียมคุณสมบัติและป้ายกำกับสำหรับมินิแบทช์
trainer.train_minibatch({features: feature_values, labels: encoded_labels})
ตัวอย่างที่สมบูรณ์
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})
เอาต์พุต
-------------------------------------------------------------------
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
[………]
ในผลลัพธ์ข้างต้นเราได้รับทั้งผลลัพธ์สำหรับการสูญเสียและเมตริกระหว่างการฝึกอบรม เป็นเพราะเรารวมเมตริกและการสูญเสียไว้ในอ็อบเจ็กต์ฟังก์ชันและใช้เครื่องพิมพ์ความคืบหน้าในการกำหนดค่าเทรนเนอร์
ในการประเมินประสิทธิภาพของโมเดลเราจำเป็นต้องปฏิบัติงานเช่นเดียวกับการฝึกโมเดล แต่คราวนี้เราต้องใช้ Evaluatorอินสแตนซ์เพื่อทดสอบโมเดล แสดงในโค้ด Python ต่อไปนี้ −
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()
ตอนนี้เราจะได้ผลลัพธ์ดังนี้ like
เอาต์พุต
Finished Evaluation [1]: Minibatch[1-11]:metric = 74.62*143;