CNTK-인 메모리 및 대용량 데이터 세트
이 장에서는 CNTK에서 인 메모리 및 대규모 데이터 세트로 작업하는 방법에 대해 알아 봅니다.
작은 메모리 데이터 세트로 훈련
CNTK 트레이너에 데이터를 공급하는 것에 대해 이야기 할 때 여러 가지 방법이있을 수 있지만 데이터 세트의 크기와 데이터 형식에 따라 달라집니다. 데이터 세트는 작은 인 메모리 또는 큰 데이터 세트 일 수 있습니다.
이 섹션에서는 메모리 내 데이터 세트로 작업 할 것입니다. 이를 위해 다음 두 프레임 워크를 사용합니다.
- Numpy
- Pandas
Numpy 배열 사용
여기서는 CNTK에서 무작위로 생성 된 numpy 기반 데이터 세트로 작업합니다. 이 예에서는 이진 분류 문제에 대한 데이터를 시뮬레이션 할 것입니다. 4 개의 특징이있는 일련의 관찰이 있고 딥 러닝 모델을 사용하여 두 개의 가능한 레이블을 예측하려고한다고 가정합니다.
구현 예
이를 위해 먼저 라벨의 원-핫 벡터 표현을 포함하는 라벨 세트를 생성해야합니다. 다음 단계의 도움으로 수행 할 수 있습니다.
Step 1 − 가져 오기 numpy 다음과 같이 패키지-
import numpy as np
num_samples = 20000
Step 2 − 다음으로 다음을 사용하여 레이블 매핑을 생성합니다. np.eye 다음과 같이 기능-
label_mapping = np.eye(2)
Step 3 − 이제 np.random.choice 함수에서 다음과 같이 20000 개의 랜덤 샘플을 수집합니다.
y = label_mapping[np.random.choice(2,num_samples)].astype(np.float32)
Step 4 − 이제 np.random.random 함수를 사용하여 다음과 같이 임의의 부동 소수점 값 배열을 생성합니다.
x = np.random.random(size=(num_samples, 4)).astype(np.float32)
일단 임의의 부동 소수점 값의 배열을 생성하면 CNTK에서 예상하는 형식과 일치 할 수 있도록 32 비트 부동 소수점 숫자로 변환해야합니다. 이 작업을 수행하려면 아래 단계를 따르십시오.
Step 5 − 다음과 같이 cntk.layers 모듈에서 Dense 및 Sequential 레이어 함수를 가져옵니다.
from cntk.layers import Dense, Sequential
Step 6− 이제 네트워크의 계층에 대한 활성화 함수를 가져와야합니다. 수입하자sigmoid 활성화 함수로-
from cntk import input_variable, default_options
from cntk.ops import sigmoid
Step 7− 이제 네트워크를 훈련시키기 위해 손실 함수를 가져와야합니다. 수입하자binary_cross_entropy 손실 함수로-
from cntk.losses import binary_cross_entropy
Step 8− 다음으로 네트워크에 대한 기본 옵션을 정의해야합니다. 여기에서 우리는sigmoid기본 설정으로 활성화 기능. 또한 다음과 같이 Sequential layer 함수를 사용하여 모델을 생성합니다.
with default_options(activation=sigmoid):
model = Sequential([Dense(6),Dense(2)])
Step 9 − 다음으로 초기화 input_variable 4 개의 입력 기능이 네트워크에 대한 입력으로 제공됩니다.
features = input_variable(4)
Step 10 − 이제이를 완료하기 위해 특성 변수를 NN에 연결해야합니다.
z = model(features)
이제 다음 단계의 도움으로 NN이 생겼습니다. 메모리 내 데이터 세트를 사용하여 훈련 해 보겠습니다.
Step 11 −이 NN을 훈련하려면 먼저 다음에서 학습자를 가져와야합니다. cntk.learners기준 치수. 수입합니다sgd 다음과 같이 학습자-
from cntk.learners import sgd
Step 12 − 그 수입과 함께 ProgressPrinter ...에서 cntk.logging 모듈도 마찬가지입니다.
from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)
Step 13 − 다음으로 다음과 같이 라벨에 대한 새 입력 변수를 정의합니다.
labels = input_variable(2)
Step 14 − NN 모델을 학습하기 위해 다음으로 손실을 정의해야합니다. binary_cross_entropy함수. 또한 모델 z 및 레이블 변수를 제공하십시오.
loss = binary_cross_entropy(z, labels)
Step 15 − 다음으로, 초기화 sgd 다음과 같이 학습자-
learner = sgd(z.parameters, lr=0.1)
Step 16− 마지막으로 손실 함수에 대해 train 메서드를 호출합니다. 또한 입력 데이터와 함께 제공하십시오.sgd 학습자와 progress_printer.−
training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=[progress_writer])
완전한 구현 예
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])
산출
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 examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.52 1.52 0 0 32
1.51 1.51 0 0 96
1.48 1.46 0 0 224
1.45 1.42 0 0 480
1.42 1.4 0 0 992
1.41 1.39 0 0 2016
1.4 1.39 0 0 4064
1.39 1.39 0 0 8160
1.39 1.39 0 0 16352
Pandas DataFrames 사용
Numpy 배열은 포함 할 수있는 것과 데이터를 저장하는 가장 기본적인 방법 중 하나가 매우 제한적입니다. 예를 들어, 단일 n 차원 배열에는 단일 데이터 유형의 데이터가 포함될 수 있습니다. 그러나 반면에 많은 실제 사례의 경우 단일 데이터 세트에서 둘 이상의 데이터 유형을 처리 할 수있는 라이브러리가 필요합니다.
Pandas라는 Python 라이브러리 중 하나를 사용하면 이러한 종류의 데이터 세트를 더 쉽게 사용할 수 있습니다. DataFrame (DF)의 개념을 소개하고 DF로 다양한 형식으로 저장된 디스크에서 데이터 세트를로드 할 수 있습니다. 예를 들어 CSV, JSON, Excel 등으로 저장된 DF를 읽을 수 있습니다.
Python Pandas 라이브러리에 대한 자세한 내용은 https://www.tutorialspoint.com/python_pandas/index.htm.
구현 예
이 예에서는 네 가지 속성을 기반으로 세 가지 가능한 붓꽃 종을 분류하는 예를 사용합니다. 이전 섹션에서도이 딥 러닝 모델을 만들었습니다. 모델은 다음과 같습니다-
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)
위의 모델은 우리가 예측할 수있는 클래스의 수와 일치하는 3 개의 뉴런이있는 하나의 은닉 계층과 출력 계층을 포함합니다.
다음으로 train 방법 및 loss네트워크를 훈련시키는 기능. 이를 위해 먼저 홍채 데이터 세트를로드하고 전처리하여 NN의 예상 레이아웃 및 데이터 형식과 일치하도록해야합니다. 다음 단계의 도움으로 수행 할 수 있습니다.
Step 1 − 가져 오기 numpy 과 Pandas 다음과 같이 패키지-
import numpy as np
import pandas as pd
Step 2 − 다음으로 read_csv 데이터 세트를 메모리에로드하는 함수-
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’,
‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
Step 3 − 이제 데이터 셋의 레이블을 해당 숫자 표현으로 매핑 할 사전을 만들어야합니다.
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
Step 4 − 이제 iloc 인덱서 DataFrame, 다음과 같이 처음 네 개의 열을 선택하십시오-
x = df_source.iloc[:, :4].values
Step 5− 다음으로 데이터 세트의 레이블로 종 열을 선택해야합니다. 다음과 같이 할 수 있습니다-
y = df_source[‘species’].values
Step 6 − 이제 데이터 셋의 레이블을 매핑해야합니다. label_mapping. 또한one_hot 인코딩하여 원-핫 인코딩 배열로 변환합니다.
y = np.array([one_hot(label_mapping[v], 3) for v in y])
Step 7 − 다음으로, CNTK로 기능과 매핑 된 레이블을 사용하려면 둘 다 부동 소수점으로 변환해야합니다.
x= x.astype(np.float32)
y= y.astype(np.float32)
아시다시피 레이블은 데이터 세트에 문자열로 저장되며 CNTK는 이러한 문자열과 함께 작동하지 않습니다. 그것이 라벨을 나타내는 원-핫 인코딩 된 벡터가 필요한 이유입니다. 이를 위해 다음과 같은 함수를 정의 할 수 있습니다.one_hot 다음과 같이-
def one_hot(index, length):
result = np.zeros(length)
result[index] = index
return result
이제 우리는 올바른 형식의 numpy 배열을 가지고 있으며 다음 단계를 통해 모델을 훈련하는 데 사용할 수 있습니다.
Step 8− 먼저 네트워크를 훈련시키기 위해 손실 함수를 가져와야합니다. 수입하자binary_cross_entropy_with_softmax 손실 함수로-
from cntk.losses import binary_cross_entropy_with_softmax
Step 9 −이 NN을 훈련하려면 다음에서 학습자를 가져와야합니다. cntk.learners기준 치수. 수입합니다sgd 다음과 같이 학습자-
from cntk.learners import sgd
Step 10 − 그 수입과 함께 ProgressPrinter ...에서 cntk.logging 모듈도 마찬가지입니다.
from cntk.logging import ProgressPrinter
progress_writer = ProgressPrinter(0)
Step 11 − 다음으로 다음과 같이 라벨에 대한 새 입력 변수를 정의합니다.
labels = input_variable(3)
Step 12 − NN 모델을 학습하기 위해 다음으로 손실을 정의해야합니다. binary_cross_entropy_with_softmax함수. 또한 모델 z 및 레이블 변수를 제공하십시오.
loss = binary_cross_entropy_with_softmax (z, labels)
Step 13 − 다음으로, 초기화 sgd 다음과 같이 학습자-
learner = sgd(z.parameters, 0.1)
Step 14− 마지막으로 손실 함수에 대해 train 메서드를 호출합니다. 또한 입력 데이터와 함께 제공하십시오.sgd 학습자와 progress_printer.
training_summary=loss.train((x,y),parameter_learners=[learner],callbacks=
[progress_writer],minibatch_size=16,max_epochs=5)
완전한 구현 예
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)
산출
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 examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.1 1.1 0 0 16
0.835 0.704 0 0 32
1.993 1.11 0 0 48
1.14 1.14 0 0 112
[………]
대규모 데이터 세트로 훈련
이전 섹션에서는 Numpy 및 pandas를 사용하여 작은 메모리 내 데이터 세트로 작업했지만 모든 데이터 세트가 그렇게 작은 것은 아닙니다. 특히 이미지, 비디오, 사운드 샘플을 포함하는 데이터 세트가 큽니다.MinibatchSourceCNTK에서 제공하는 청크 단위로 데이터를로드 할 수있는 구성 요소입니다. 일부 기능MinibatchSource 구성 요소는 다음과 같습니다-
MinibatchSource 데이터 소스에서 읽은 샘플을 자동으로 무작위 화하여 NN이 과적 합되는 것을 방지 할 수 있습니다.
데이터를 보강하는 데 사용할 수있는 기본 제공 변환 파이프 라인이 있습니다.
학습 프로세스와는 별도로 백그라운드 스레드에 데이터를로드합니다.
다음 섹션에서는 메모리 부족 데이터와 함께 미니 배치 소스를 사용하여 대규모 데이터 세트로 작업하는 방법을 살펴 보겠습니다. 우리는 또한 그것을 NN 훈련을 위해 어떻게 사용할 수 있는지 탐구 할 것입니다.
MinibatchSource 인스턴스 생성
이전 섹션에서는 붓꽃 예제를 사용하고 Pandas DataFrames를 사용하여 작은 메모리 내 데이터 세트로 작업했습니다. 여기서는 pandas DF의 데이터를 사용하는 코드를MinibatchSource. 먼저 다음의 인스턴스를 생성해야합니다.MinibatchSource 다음 단계의 도움으로-
구현 예
Step 1 − 먼저 cntk.io 모듈은 다음과 같이 minibatchsource에 대한 구성 요소를 가져옵니다-
from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer,
INFINITY_REPEAT
Step 2 − 이제 StreamDef 클래스, 레이블에 대한 스트림 정의를 생성합니다.
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
Step 3 − 다음으로, 입력 파일에서 입력 된 기능을 읽기 위해 생성하고, 다른 인스턴스를 생성합니다. StreamDef 다음과 같이.
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
Step 4 − 이제 우리는 iris.ctf 파일을 입력하고 초기화하십시오. deserializer 다음과 같이-
deserializer = CTFDeserializer(‘iris.ctf’, StreamDefs(labels=
label_stream, features=features_stream)
Step 5 − 마지막으로 다음의 인스턴스를 생성해야합니다. minisourceBatch 사용하여 deserializer 다음과 같이-
Minibatch_source = MinibatchSource(deserializer, randomize=True)
MinibatchSource 인스턴스 만들기-전체 구현 예제
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)
MCTF 파일 생성
위에서 본 것처럼 'iris.ctf'파일에서 데이터를 가져옵니다. CNTK Text Format (CTF)이라는 파일 형식이 있습니다. 데이터를 가져 오려면 CTF 파일을 생성해야합니다.MinibatchSource위에서 만든 인스턴스입니다. CTF 파일을 만드는 방법을 살펴 보겠습니다.
구현 예
Step 1 − 먼저 다음과 같이 pandas 및 numpy 패키지를 가져와야합니다.
import pandas as pd
import numpy as np
Step 2− 다음으로 데이터 파일, 즉 iris.csv를 메모리에로드해야합니다. 그런 다음df_source 변하기 쉬운.
df_source = pd.read_csv(‘iris.csv’, names = [‘sepal_length’, ‘sepal_width’, ‘petal_length’, ‘petal_width’, ‘species’], index_col=False)
Step 3 − 이제 iloc인덱서를 기능으로 사용하려면 처음 4 개 열의 내용을 가져옵니다. 또한 다음과 같이 종 열의 데이터를 사용하십시오.
features = df_source.iloc[: , :4].values
labels = df_source[‘species’].values
Step 4− 다음으로 라벨 이름과 숫자 표현 간의 매핑을 생성해야합니다. 생성하여 수행 할 수 있습니다.label_mapping 다음과 같이-
label_mapping = {‘Iris-Setosa’ : 0, ‘Iris-Versicolor’ : 1, ‘Iris-Virginica’ : 2}
Step 5 − 이제 다음과 같이 라벨을 원-핫 인코딩 된 벡터 세트로 변환합니다.
labels = [one_hot(label_mapping[v], 3) for v in labels]
이제 이전에했던 것처럼 다음과 같은 유틸리티 함수를 만듭니다. one_hot레이블을 인코딩합니다. 다음과 같이 할 수 있습니다-
def one_hot(index, length):
result = np.zeros(length)
result[index] = 1
return result
데이터를로드하고 전처리 했으므로 이제 디스크에 CTF 파일 형식으로 저장할 때입니다. 다음 파이썬 코드의 도움으로 할 수 있습니다.
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))
MCTF 파일 만들기-전체 구현 예제
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))
데이터 공급
일단 만들면 MinibatchSource,예를 들어, 우리는 그것을 훈련시켜야합니다. 작은 인 메모리 데이터 세트로 작업 할 때 사용한 것과 동일한 학습 로직을 사용할 수 있습니다. 여기서 우리는MinibatchSource 다음과 같이 손실 함수에 대한 기차 방법의 입력으로 인스턴스-
구현 예
Step 1 − 훈련 세션의 출력을 기록하려면 먼저 ProgressPrinter를 cntk.logging 다음과 같이 모듈-
from cntk.logging import ProgressPrinter
Step 2 − 다음으로 교육 세션을 설정하려면 trainer 과 training_session ...에서 cntk.train 다음과 같이 모듈-
from cntk.train import Trainer,
Step 3 − 이제 다음과 같은 상수 세트를 정의해야합니다. minibatch_size, samples_per_epoch 과 num_epochs 다음과 같이-
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
Step 4 − 다음으로, 훈련 중에 데이터를 읽는 방법을 CNTK에 알기 위해 네트워크의 입력 변수와 미니 배치 소스의 스트림 간의 매핑을 정의해야합니다.
input_map = {
features: minibatch.source.streams.features,
labels: minibatch.source.streams.features
}
Step 5 − 다음으로 훈련 과정의 출력을 기록하기 위해 progress_printer 새로운 변수 ProgressPrinter 다음과 같이 인스턴스-
progress_writer = ProgressPrinter(0)
Step 6 − 마지막으로 손실에 대해 다음과 같이 train 메서드를 호출해야합니다.
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)
데이터 공급-전체 구현 예
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)
산출
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.21 1.21 0 0 32
1.15 0.12 0 0 96
[………]