1

바이너리 분류 문제에 대해 원하는 결과를 얻지 못했습니다. 양성, 또는 - - 악성logisitc 회귀에 대한 올바른 답을 얻는 방법?

그것은 원하는 출력을 제공하지 않습니다 : 문제는 유방암에 레이블을 이진 분류를 사용

.

x_train is of shape: (30, 381), 
y_train is of shape: (1, 381), 
x_test is of shape: (30, 188), 
y_test is of shape: (1, 188). 

그 다음 출력을 예측하는 회귀 분류를위한 클래스가있다 :

은 제 1 형상의 테스트 및 기차 데이터를 반환하는 데이터 세트를로드 할 수있는 기능이있다.

from sklearn.datasets import load_breast_cancer 
from sklearn.model_selection import train_test_split 
from sklearn.metrics import accuracy_score 
import numpy as np 

def load_dataset(): 
    cancer_data = load_breast_cancer() 
    x_train, x_test, y_train, y_test = train_test_split(cancer_data.data, cancer_data.target, test_size=0.33) 
    x_train = x_train.T 
    x_test = x_test.T 
    y_train = y_train.reshape(1, (len(y_train))) 
    y_test = y_test.reshape(1, (len(y_test))) 
    m = x_train.shape[1] 
    return x_train, x_test, y_train, y_test, m 

class Neural_Network(): 
    def __init__(self): 
     np.random.seed(1) 
     self.weights = np.random.rand(30, 1) * 0.01 
     self.bias = np.zeros(shape=(1, 1)) 

    def sigmoid(self, x): 
     return 1/(1 + np.exp(-x)) 

    def train(self, x_train, y_train, iterations, m, learning_rate=0.5): 

     for i in range(iterations): 
      z = np.dot(self.weights.T, x_train) + self.bias 
      a = self.sigmoid(z) 

      cost = (-1/m) * np.sum(y_train * np.log(a) + (1 - y_train) * np.log(1 - a)) 

      if (i % 500 == 0): 
       print("Cost after iteration %i: %f" % (i, cost)) 

      dw = (1/m) * np.dot(x_train, (a - y_train).T) 
      db = (1/m) * np.sum(a - y_train) 

      self.weights = self.weights - learning_rate * dw 
      self.bias = self.bias - learning_rate * db 

    def predict(self, inputs): 
     m = inputs.shape[1] 
     y_predicted = np.zeros((1, m)) 
     z = np.dot(self.weights.T, inputs) + self.bias 
     a = self.sigmoid(z) 
     for i in range(a.shape[1]): 
      y_predicted[0, i] = 1 if a[0, i] > 0.5 else 0 
     return y_predicted 

if __name__ == "__main__": 
    ''' 
    step-1 : Loading data set 
       x_train is of shape: (30, 381) 
       y_train is of shape: (1, 381) 
       x_test is of shape: (30, 188) 
       y_test is of shape: (1, 188) 
    ''' 

    x_train, x_test, y_train, y_test, m = load_dataset() 

    neuralNet = Neural_Network() 

    ''' 
     step-2 : Train the network 
    ''' 

    neuralNet.train(x_train, y_train,10000,m) 


    y_predicted = neuralNet.predict(x_test) 

    print("Accuracy on test data: ") 
    print(accuracy_score(y_test, y_predicted)*100) 

이 출력을 제공 프로그램 :

C:\Python36\python.exe C:/Users/LENOVO/PycharmProjects/MarkDmo001/Numpy.py 
Cost after iteration 0: 5.263853 
C:/Users/LENOVO/PycharmProjects/MarkDmo001/logisticReg.py:25: RuntimeWarning: overflow encountered in exp 
    return 1/(1 + np.exp(-x)) 
C:/Users/LENOVO/PycharmProjects/MarkDmo001/logisticReg.py:33: RuntimeWarning: divide by zero encountered in log 
    cost = (-1/m) * np.sum(y_train * np.log(a) + (1 - y_train) * np.log(1 - a)) 
C:/Users/LENOVO/PycharmProjects/MarkDmo001/logisticReg.py:33: RuntimeWarning: invalid value encountered in multiply 
    cost = (-1/m) * np.sum(y_train * np.log(a) + (1 - y_train) * np.log(1 - a)) 
Cost after iteration 500: nan 
Cost after iteration 1000: nan 
Cost after iteration 1500: nan 
Cost after iteration 2000: nan 
Cost after iteration 2500: nan 
Cost after iteration 3000: nan 
Cost after iteration 3500: nan 
Cost after iteration 4000: nan 
Cost after iteration 4500: nan 
Cost after iteration 5000: nan 
Cost after iteration 5500: nan 
Cost after iteration 6000: nan 
Cost after iteration 6500: nan 
Cost after iteration 7000: nan 
Cost after iteration 7500: nan 
Cost after iteration 8000: nan 
Cost after iteration 8500: nan 
Cost after iteration 9000: nan 
Cost after iteration 9500: nan 

Accuracy: 
0.0 

답변

2

문제는 폭발적으로 그라디언트. 입력을 [0, 1]으로 정규화해야합니다.

훈련 데이터에서 피쳐 3과 피쳐 23을 보면 3000보다 큰 값을 볼 수 있습니다.이 피치가 초기 중량으로 곱해지면 여전히 범위가 [0, 30]입니다. 따라서, 첫 번째 반복에서 z 벡터 주변 (50) 결과 최대 값 만 긍정적 번호가 포함의 a 벡터 (당신의 시그 모이 드의 출력은) 다음과 같습니다 : 첫 번째에 따라서

[0.9994797 0.99853904 0.99358676 0.99999973 0.98392862 0.99983016 0.99818802 ...] 

을 단계에서 모델은 항상 높은 확신을 가지고 1을 예측합니다. 그러나 이것이 항상 올바르지는 않으며 모델 출력이 큰 그라데이션으로 이어질 확률이 높으므로 가장 높은 값인 dw을 볼 때 알 수 있습니다. 내 경우에는,

  • dw[3]

  • dw[23] 388

571이었다 다른 값은 [0, 55]에 누워. 따라서 이러한 기능의 커다란 입력이 어떻게 폭발적인 구배로 이어지는지를 명확하게 볼 수 있습니다. 그래디언트 디센트는 이제 반대 방향으로 너무 큰 단계를 거치므로 다음 단계의 가중치는 [0, 0.01]이 아니지만 [-285, 0.002]이되어 상황이 악화됩니다. 다음 반복에서 z에는 -1 백만 정도의 값이 포함되어있어 시그 모이 드 함수에서 오버플로가 발생합니다. 그들은 대략 서로 상쇄되도록

솔루션

  1. [-0.01, 0.01][0, 1]
  2. 를 사용하여 무게에 입력을 정상화. 그렇지 않은 경우 z의 값은 보유하고있는 지형지 물의 수와 선형으로 조정됩니다.

입력 정상화에 관해서는, 당신이 사용할 수있는 sklearn의 MinMaxScaler : 당신의 x_trainx_test이 모양 (num_features, num_samples)있는 동안 sklearn는 훈련 입력이 모양 (num_samples, num_features)을 기대하기 때문에

x_train, x_test, y_train, y_test, m = load_dataset() 

scaler = MinMaxScaler() 
x_train_normalized = scaler.fit_transform(x_train.T).T 

neuralNet = Neural_Network() 

''' 
    step-2 : Train the network 
''' 

neuralNet.train(x_train_normalized, y_train,10000,m) 

# Use the same transformation on the test inputs as on the training inputs 
x_test_normalized = scaler.transform(x_test.T).T 
y_predicted = neuralNet.predict(x_test_normalized) 

.T들입니다.

+0

나는 당신이 말한대로했는데, 결과물을 얻지 못했습니다. 해결책 2를 적용하는 방법을 알려주세요. 나는 다른 무게를 시도했지만 여전히 같은 결과를 얻었습니다. –

+0

위의 코드를 복사하고 코드 줄을 60 ~ 71 줄로 간단하게 바꿉니다. 그런 다음 0.06의 손실과 97.8 %의 정확도를 얻었습니다. 덧붙여서, 정확도를 평가하기 위해서는'print (accuracy_score (y_test [0], y_predicted [0]) * 100)'을 호출해야합니다.'y_test'와'y_predicted'는 2 차원 배열입니다. –