CNTK-로지스틱 회귀 모델

이 장에서는 CNTK에서 로지스틱 회귀 모델을 구성하는 방법을 다룹니다.

로지스틱 회귀 모델의 기초

가장 간단한 ML 기술 중 하나 인 로지스틱 회귀는 특히 이진 분류를위한 기술입니다. 즉, 예측할 변수의 값이 단 두 개의 범주 값 중 하나 일 수있는 상황에서 예측 모델을 생성하는 것입니다. 로지스틱 회귀 분석의 가장 간단한 예 중 하나는 사람의 나이, 목소리, 머리카락 등을 기반으로 해당 사람이 남성인지 여성인지 예측하는 것입니다.

다른 예제의 도움을 받아 수학적으로 로지스틱 회귀의 개념을 이해해 봅시다.

대출 신청의 신용 가치를 예측한다고 가정 해 보겠습니다. 0은 거부를 의미하고 1은 승인을 의미합니다.debt , incomecredit rating. 부채는 X1, 수입은 X2, 신용 등급은 X3입니다.

로지스틱 회귀에서는 다음과 같이 표현되는 가중치 값을 결정합니다. w, 모든 특성 및 단일 편향 값에 대해 b.

자,

X1 = 3.0
X2 = -2.0
X3 = 1.0

그리고 다음과 같이 가중치와 편향을 결정한다고 가정합니다.

W1 = 0.65, W2 = 1.75, W3 = 2.05 and b = 0.33

이제 클래스를 예측하기 위해 다음 공식을 적용해야합니다.

Z = (X1*W1)+(X2*W2)+(X3+W3)+b
i.e. Z = (3.0)*(0.65) + (-2.0)*(1.75) + (1.0)*(2.05) + 0.33
= 0.83

다음으로 우리는 P = 1.0/(1.0 + exp(-Z)). 여기서 exp () 함수는 오일러의 수입니다.

P = 1.0/(1.0 + exp(-0.83)
= 0.6963

P 값은 클래스가 1 일 확률로 해석 될 수 있습니다. P <0.5이면 예측은 클래스 = 0이고 그렇지 않으면 예측 (P> = 0.5)은 클래스 = 1입니다.

가중치 및 편향 값을 결정하려면 알려진 입력 예측 변수 값과 알려진 올바른 클래스 레이블 값을 갖는 훈련 데이터 세트를 얻어야합니다. 그 후 가중치와 편향 값을 찾기 위해 일반적으로 Gradient Descent라는 알고리즘을 사용할 수 있습니다.

LR 모델 구현 예

이 LR 모델의 경우 다음 데이터 세트를 사용합니다.

1.0, 2.0, 0
3.0, 4.0, 0
5.0, 2.0, 0
6.0, 3.0, 0
8.0, 1.0, 0
9.0, 2.0, 0
1.0, 4.0, 1
2.0, 5.0, 1
4.0, 6.0, 1
6.0, 5.0, 1
7.0, 3.0, 1
8.0, 5.0, 1

CNTK에서이 LR 모델 구현을 시작하려면 먼저 다음 패키지를 가져와야합니다.

import numpy as np
import cntk as C

프로그램은 다음과 같이 main () 함수로 구성됩니다.

def main():
print("Using CNTK version = " + str(C.__version__) + "\n")

이제 다음과 같이 훈련 데이터를 메모리에로드해야합니다.

data_file = ".\\dataLRmodel.txt"
print("Loading data from " + data_file + "\n")
features_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",", skiprows=0, usecols=[0,1])
labels_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",", skiprows=0, usecols=[2], ndmin=2)

이제 우리는 훈련 데이터와 호환되는 로지스틱 회귀 모델을 생성하는 훈련 프로그램을 만들 것입니다.

features_dim = 2
labels_dim = 1
X = C.ops.input_variable(features_dim, np.float32)
y = C.input_variable(labels_dim, np.float32)
W = C.parameter(shape=(features_dim, 1)) # trainable cntk.Parameter
b = C.parameter(shape=(labels_dim))
z = C.times(X, W) + b
p = 1.0 / (1.0 + C.exp(-z))
model = p

이제 다음과 같이 Lerner와 trainer를 만들어야합니다.

ce_error = C.binary_cross_entropy(model, y) # CE a bit more principled for LR
fixed_lr = 0.010
learner = C.sgd(model.parameters, fixed_lr)
trainer = C.Trainer(model, (ce_error), [learner])
max_iterations = 4000

LR 모델 훈련

일단 LR 모델을 만들었 으면 다음으로 훈련 과정을 시작할 차례입니다.

np.random.seed(4)
N = len(features_mat)
for i in range(0, max_iterations):
row = np.random.choice(N,1) # pick a random row from training items
trainer.train_minibatch({ X: features_mat[row], y: labels_mat[row] })
if i % 1000 == 0 and i > 0:
mcee = trainer.previous_minibatch_loss_average
print(str(i) + " Cross-entropy error on curr item = %0.4f " % mcee)

이제 다음 코드를 사용하여 모델 가중치와 편향을 인쇄 할 수 있습니다.

np.set_printoptions(precision=4, suppress=True)
print("Model weights: ")
print(W.value)
print("Model bias:")
print(b.value)
print("")
if __name__ == "__main__":
main()

로지스틱 회귀 모델 훈련-전체 예제

import numpy as np
import cntk as C
   def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
data_file = ".\\dataLRmodel.txt" # provide the name and the location of data file
print("Loading data from " + data_file + "\n")
features_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",", skiprows=0, usecols=[0,1])
labels_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",", skiprows=0, usecols=[2], ndmin=2)
features_dim = 2
labels_dim = 1
X = C.ops.input_variable(features_dim, np.float32)
y = C.input_variable(labels_dim, np.float32)
W = C.parameter(shape=(features_dim, 1)) # trainable cntk.Parameter
b = C.parameter(shape=(labels_dim))
z = C.times(X, W) + b
p = 1.0 / (1.0 + C.exp(-z))
model = p
ce_error = C.binary_cross_entropy(model, y) # CE a bit more principled for LR
fixed_lr = 0.010
learner = C.sgd(model.parameters, fixed_lr)
trainer = C.Trainer(model, (ce_error), [learner])
max_iterations = 4000
np.random.seed(4)
N = len(features_mat)
for i in range(0, max_iterations):
row = np.random.choice(N,1) # pick a random row from training items
trainer.train_minibatch({ X: features_mat[row], y: labels_mat[row] })
if i % 1000 == 0 and i > 0:
mcee = trainer.previous_minibatch_loss_average
print(str(i) + " Cross-entropy error on curr item = %0.4f " % mcee)
np.set_printoptions(precision=4, suppress=True)
print("Model weights: ")
print(W.value)
print("Model bias:")
print(b.value)
if __name__ == "__main__":
  main()

산출

Using CNTK version = 2.7
1000 cross entropy error on curr item = 0.1941
2000 cross entropy error on curr item = 0.1746
3000 cross entropy error on curr item = 0.0563
Model weights:
[-0.2049]
   [0.9666]]
Model bias:
[-2.2846]

훈련 된 LR 모델을 사용한 예측

LR 모델이 학습되면 다음과 같이 예측에 사용할 수 있습니다.

우선, 우리의 평가 프로그램은 numpy 패키지를 가져 와서 위에서 구현 한 훈련 프로그램과 같은 방식으로 훈련 데이터를 특성 행렬과 클래스 레이블 행렬에로드합니다.

import numpy as np
def main():
data_file = ".\\dataLRmodel.txt" # provide the name and the location of data file
features_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",",
skiprows=0, usecols=(0,1))
labels_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",",
skiprows=0, usecols=[2], ndmin=2)

다음으로, 훈련 프로그램에 의해 결정된 가중치와 편향의 값을 설정할 때입니다.

print("Setting weights and bias values \n")
weights = np.array([0.0925, 1.1722], dtype=np.float32)
bias = np.array([-4.5400], dtype=np.float32)
N = len(features_mat)
features_dim = 2

다음으로 평가 프로그램은 다음과 같이 각 훈련 항목을 살펴보면서 로지스틱 회귀 확률을 계산합니다.

print("item pred_prob pred_label act_label result")
for i in range(0, N): # each item
   x = features_mat[i]
   z = 0.0
   for j in range(0, features_dim):
   z += x[j] * weights[j]
   z += bias[0]
   pred_prob = 1.0 / (1.0 + np.exp(-z))
  pred_label = 0 if pred_prob < 0.5 else 1
   act_label = labels_mat[i]
   pred_str = ‘correct’ if np.absolute(pred_label - act_label) < 1.0e-5 \
    else ‘WRONG’
  print("%2d %0.4f %0.0f %0.0f %s" % \ (i, pred_prob, pred_label, act_label, pred_str))

이제 예측을 수행하는 방법을 보여 드리겠습니다.

x = np.array([9.5, 4.5], dtype=np.float32)
print("\nPredicting class for age, education = ")
print(x)
z = 0.0
for j in range(0, features_dim):
z += x[j] * weights[j]
z += bias[0]
p = 1.0 / (1.0 + np.exp(-z))
print("Predicted p = " + str(p))
if p < 0.5: print("Predicted class = 0")
else: print("Predicted class = 1")

완벽한 예측 평가 프로그램

import numpy as np
def main():
data_file = ".\\dataLRmodel.txt" # provide the name and the location of data file
features_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",",
skiprows=0, usecols=(0,1))
labels_mat = np.loadtxt(data_file, dtype=np.float32, delimiter=",",
skiprows=0, usecols=[2], ndmin=2)
print("Setting weights and bias values \n")
weights = np.array([0.0925, 1.1722], dtype=np.float32)
bias = np.array([-4.5400], dtype=np.float32)
N = len(features_mat)
features_dim = 2
print("item pred_prob pred_label act_label result")
for i in range(0, N): # each item
   x = features_mat[i]
   z = 0.0
   for j in range(0, features_dim):
     z += x[j] * weights[j]
   z += bias[0]
   pred_prob = 1.0 / (1.0 + np.exp(-z))
   pred_label = 0 if pred_prob < 0.5 else 1
   act_label = labels_mat[i]
   pred_str = ‘correct’ if np.absolute(pred_label - act_label) < 1.0e-5 \
     else ‘WRONG’
  print("%2d %0.4f %0.0f %0.0f %s" % \ (i, pred_prob, pred_label, act_label, pred_str))
x = np.array([9.5, 4.5], dtype=np.float32)
print("\nPredicting class for age, education = ")
print(x)
z = 0.0
for j in range(0, features_dim):
   z += x[j] * weights[j]
z += bias[0]
p = 1.0 / (1.0 + np.exp(-z))
print("Predicted p = " + str(p))
if p < 0.5: print("Predicted class = 0")
else: print("Predicted class = 1")
if __name__ == "__main__":
  main()

산출

가중치 및 편향 값 설정.

Item  pred_prob  pred_label  act_label  result
0   0.3640         0             0     correct
1   0.7254         1             0      WRONG
2   0.2019         0             0     correct
3   0.3562         0             0     correct
4   0.0493         0             0     correct
5   0.1005         0             0     correct
6   0.7892         1             1     correct
7   0.8564         1             1     correct
8   0.9654         1             1     correct
9   0.7587         1             1     correct
10  0.3040         0             1      WRONG
11  0.7129         1             1     correct
Predicting class for age, education =
[9.5 4.5]
Predicting p = 0.526487952
Predicting class = 1