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 − 가져 오기 numpyPandas 다음과 같이 패키지-

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 − 다음으로 교육 세션을 설정하려면 trainertraining_session ...에서 cntk.train 다음과 같이 모듈-

from cntk.train import Trainer,

Step 3 − 이제 다음과 같은 상수 세트를 정의해야합니다. minibatch_size, samples_per_epochnum_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
[………]