0

신경망을 학습 할 때 우리는 일반적으로 연속적이며 차별화 할 수있는 실수 값 비용 함수에 의존하는 그라디언트 디센트를 사용합니다. 최종 비용 함수는 예를 들어 평균 제곱 오차를 취할 수 있습니다. 또는 다른 방법으로, 그래디언트 디센트는 최종 목표가 회귀 인 것으로 암묵적으로 가정합니다. 실수 값을 최소화합니다.비용 기능 훈련 대상 대 정확성 목표 원하는 목표

때로는 신경망에서 수행하고자하는 것은 분류입니다. 입력이 주어지면 두 개 이상의 이산 카테고리로 분류됩니다. 이 경우 사용자가 신경 쓰는 최종 목표는 분류 정확성 - 올바르게 분류 된 사례의 비율입니다.

그러나 우리 목표는 신경 네트워크가을 최적화하기 위해 노력하고있다되지 않은 것을 분류 정확성, 는하지만 우리는 분류에 신경 네트워크를 사용하는 경우. 신경망은 여전히 ​​실제 가치가있는 비용 함수를 최적화하려고합니다. 때때로 이들은 같은 방향을 가리키고 있지만 때로는 그렇지 않습니다. 특히, 나는 비용 함수를 정확하게 최소화하도록 훈련 된 신경 네트워크가 간단한 손으로 코딩 된 문턱 값 비교보다 나쁜 분류 정확도를 갖는 경우로 뛰어 들었다.

TensorFlow를 사용하여 최소한의 테스트 케이스로 마무리했습니다. 그것은 퍼셉트론 (숨겨진 레이어가없는 신경망)을 설정하고, 절대적으로 최소의 데이터 세트 (하나의 입력 변수, 하나의 바이너리 출력 변수)에서 결과의 분류 정확도를 평가 한 후 간단한 손의 분류 정확도와 비교합니다 코딩 된 임계 값 비교; 결과는 각각 60 %와 80 %입니다. 직관적으로 이것은 큰 입력 값을 가진 단일 특이 값이 이에 상응하는 큰 출력 값을 생성하기 때문에 비용 함수를 최소화하는 방법은 두 개의 더 일반적인 경우를 잘못 분류하는 과정에서 그 한 사례를 수용하기 위해 특별히 노력하는 것입니다. 퍼셉트론은 정확히 무엇을하도록 지시 받았 는가? 이것이 우리가 실제로 분류자를 원한 것과 일치하지 않는다는 것입니다. 그러나 분류 정확도는 연속 차등 함수가 아니므로 그라디언트 디센트의 대상으로 사용할 수 없습니다.

신경망을 훈련시켜 분류 정확도를 극대화 할 수있는 방법은 무엇입니까?

import numpy as np 
import tensorflow as tf 
sess = tf.InteractiveSession() 
tf.set_random_seed(1) 

# Parameters 
epochs = 10000 
learning_rate = 0.01 

# Data 
train_X = [ 
    [0], 
    [0], 
    [2], 
    [2], 
    [9], 
] 
train_Y = [ 
    0, 
    0, 
    1, 
    1, 
    0, 
] 

rows = np.shape(train_X)[0] 
cols = np.shape(train_X)[1] 

# Inputs and outputs 
X = tf.placeholder(tf.float32) 
Y = tf.placeholder(tf.float32) 

# Weights 
W = tf.Variable(tf.random_normal([cols])) 
b = tf.Variable(tf.random_normal([])) 

# Model 
pred = tf.tensordot(X, W, 1) + b 
cost = tf.reduce_sum((pred-Y)**2/rows) 
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) 
tf.global_variables_initializer().run() 

# Train 
for epoch in range(epochs): 
    # Print update at successive doublings of time 
    if epoch&(epoch-1) == 0 or epoch == epochs-1: 
     print('{} {} {} {}'.format(
      epoch, 
      cost.eval({X: train_X, Y: train_Y}), 
      W.eval(), 
      b.eval(), 
      )) 
    optimizer.run({X: train_X, Y: train_Y}) 

# Classification accuracy of perceptron 
classifications = [pred.eval({X: x}) > 0.5 for x in train_X] 
correct = sum([p == y for (p, y) in zip(classifications, train_Y)]) 
print('{}/{} = perceptron accuracy'.format(correct, rows)) 

# Classification accuracy of hand-coded threshold comparison 
classifications = [x[0] > 1.0 for x in train_X] 
correct = sum([p == y for (p, y) in zip(classifications, train_Y)]) 
print('{}/{} = threshold accuracy'.format(correct, rows)) 
+0

정확도가 낮을수록 오류가 적습니다. 그것은 유효한 진술이 아닌가? –

+0

@AlexeyR. 요점은 용어가 아니기 때문에 그라디언트 디센트는 * 실수 값 * 오류 함수를 최소화하려고하지만 사용자가 신경 쓰는 것은 잘못 분류 된 오류의 비율 *과 두 가지입니다. – rwallace

+0

[right proxy-function] (https://datascience.stackexchange.com/questions/13663/neural-networks-loss-and-accuracy-correlation)을 사용하십시오. 제곱 오류는 여기서 확실하게 실패합니다. – sascha

답변

1

나는 아직도이 잘 제기 질문, SO 혼자 적절한을 할 경우 확실하지 않다; 그럼에도 불구하고, 나는 그것을 시도하고, 아마도 당신은 적어도 내 대답의 일부 요소가 도움이 될 것입니다.

어떻게 신경망을 훈련하여 분류 정확도를 최대화 할 수 있습니까? 내가

로 시작하려면 정확성에 분류 작업을 위해 현재 사용되는 손실 함수에 더 가까운 연속 프록시 기능을 얻을 수있는 방법에 대한 부탁 해요

(깊이) 신경망은 함께 발명되지 않았다 그러나 그것은 수십 년 전으로 거슬러 올라갑니다, 그리고 그것은 사실 로지스틱 회귀 초기부터 왔습니다.광대 한

enter image description here

뒤에 아이디어는 우리가를 악용 할 수 있도록하는 연속 & 미분 기능을 마련 정확히했다 (다음은 이진 분류의 간단한 경우에 대한 방정식은 , 그리고 여전히 확장) 분류 문제에 대한 볼록 최적화의 병기.

위의 손실 함수는 까지 지금까지인데, 위에서 언급 한 원하는 수학적 제약 조건을 감안할 때 안전하다고 말할 수 있습니다.

이 문제 (즉, 정확도를보다 정확하게 계산)를 해결하고 완료해야한다고 생각합니까? 최소한 원칙적으로는 안된다. 나는 실제로 활성화 된 유일한 활성화 기능이 tanhsigmoid 인 시대를 기억하기에 충분히 오래되었다. 그때 ReLU가 와서 현장에 진정한 힘을주었습니다. 마찬가지로, 누군가는 결국 더 나은 손실 함수를 내놓을 수는 있겠지만, 논란의 여지가 있지만 연구 논문에서 그렇게 될 것입니다.

사실, 손실 함수는 매우 초등 확률 및 정보 이론 (현재의 심층 학습 분야와 확연히 대조적 인 분야, 확고한 이론적 토대로서야 함)에 대한 고려는 손실에 대한 더 나은 제안이 모퉁이 만 돌면된다.


이전에 비해 질적으로 다른 후자의 무언가를 만들고, 자주 등의 토론에 손실 손실과 정확성 사이의 관계, 다른 미묘한 지점이있다. 조금 자세히 설명해 드리겠습니다 ...

이 토론과 관련된 모든 분류 기준 (즉, 신경망, 로지스틱 회귀 등)은 확률 개입니다. 즉, 하드 클래스 멤버쉽 (0/1)을 반환하지 않지만 클래스 확률 ([0, 1]의 연속 실수)을 반환합니다. A (하드) 클래스 멤버십 클래스 확률을 변환 할 때 이진 케이스 편의상 설명을 제한

, 우리는 내재적 다음 class[i] = "1" 같은 p[i] > 0.5 경우 0.5 통상 동일한 임계를, 포함한다. 이제 우리는 임계 값의이 기본 값 선택이 작동하지 않는 많은 경우를 발견 할 수 있습니다 (무겁게 불균형 한 데이터 세트가 가장 먼저 떠오름). 다른 옵션을 선택해야합니다. 그러나 여기에서 우리가 논의 할 중요한 점은이 임계 값 선택이 정확도를 중요하게 고려하지만 손실을 최소화하는 수학적 최적화 문제에 대해서는 완전히 external이며이 둘 사이의 "절연 층"역할을한다는 것입니다. 손실은 정확성을위한 프록시 일 뿐이라는 단순한 견해를 손상시킵니다 (그렇지 않습니다).


다소 이미 폭 넓은 논의를 확대 : 우리는 아마도 완전히 떨어져 연속 & 미분 가능 함수의 수학적 최적화 (매우) 제한 제약에서 이동할 수 있습니까? 즉, 역 전파 및 그래디언트 강하를 없앨 수 있습니까?

글쎄, 우리는 실제로 적어도 강화 학습의 서브 필드에, 아직 일을 : 2017 뭔가에 new research from OpenAI진화 전략made headlines라고 해였다.추가 보너스로 여기에 주제에 대한 신선한 (2017 년 12 월) paper by Uber이며 다시 커뮤니티에 much enthusiasm을 생성합니다.


이것은 내 생각에 대한 질문입니다. 비록 내가 이미 말했듯이,이 이해가 올바르지 않더라도, 여기에 도움이되는 요소를 찾을 수 있습니다. ...

1

나는 당신이 simgoid를 통해 출력물을 전달하는 것을 잊어 버리고 있다고 생각합니다. 아래에 고정 :

import numpy as np 
import tensorflow as tf 
sess = tf.InteractiveSession() 
tf.set_random_seed(1) 

# Parameters 
epochs = 10000 
learning_rate = 0.01 

# Data 
train_X = [ 
    [0], 
    [0], 
    [2], 
    [2], 
    [9], 
] 
train_Y = [ 
    0, 
    0, 
    1, 
    1, 
    0, 
] 

rows = np.shape(train_X)[0] 
cols = np.shape(train_X)[1] 

# Inputs and outputs 
X = tf.placeholder(tf.float32) 
Y = tf.placeholder(tf.float32) 

# Weights 
W = tf.Variable(tf.random_normal([cols])) 
b = tf.Variable(tf.random_normal([])) 

# Model 
# CHANGE HERE: Remember, you need an activation function! 
pred = tf.nn.sigmoid(tf.tensordot(X, W, 1) + b) 
cost = tf.reduce_sum((pred-Y)**2/rows) 
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) 
tf.global_variables_initializer().run() 

# Train 
for epoch in range(epochs): 
    # Print update at successive doublings of time 
    if epoch&(epoch-1) == 0 or epoch == epochs-1: 
     print('{} {} {} {}'.format(
      epoch, 
      cost.eval({X: train_X, Y: train_Y}), 
      W.eval(), 
      b.eval(), 
      )) 
    optimizer.run({X: train_X, Y: train_Y}) 

# Classification accuracy of perceptron 
classifications = [pred.eval({X: x}) > 0.5 for x in train_X] 
correct = sum([p == y for (p, y) in zip(classifications, train_Y)]) 
print('{}/{} = perceptron accuracy'.format(correct, rows)) 

# Classification accuracy of hand-coded threshold comparison 
classifications = [x[0] > 1.0 for x in train_X] 
correct = sum([p == y for (p, y) in zip(classifications, train_Y)]) 
print('{}/{} = threshold accuracy'.format(correct, rows)) 

출력 :

0 0.28319069743156433 [ 0.75648874] -0.9745011329650879 
1 0.28302448987960815 [ 0.75775659] -0.9742625951766968 
2 0.28285878896713257 [ 0.75902224] -0.9740257859230042 
4 0.28252947330474854 [ 0.76154679] -0.97355717420578 
8 0.28187844157218933 [ 0.76656926] -0.9726400971412659 
16 0.28060704469680786 [ 0.77650583] -0.970885694026947 
32 0.27818527817726135 [ 0.79593837] -0.9676888585090637 
64 0.2738055884838104 [ 0.83302218] -0.9624817967414856 
128 0.26666420698165894 [ 0.90031379] -0.9562843441963196 
256 0.25691407918930054 [ 1.01172411] -0.9567816257476807 
512 0.2461051195859909 [ 1.17413962] -0.9872989654541016 
1024 0.23519910871982574 [ 1.38549554] -1.088881492614746 
2048 0.2241383194923401 [ 1.64616168] -1.298340916633606 
4096 0.21433120965957642 [ 1.95981205] -1.6126530170440674 
8192 0.2075471431016922 [ 2.31746769] -1.989408016204834 
9999 0.20618653297424316 [ 2.42539024] -2.1028473377227783 
4/5 = perceptron accuracy 
4/5 = threshold accuracy 
+0

감사합니다. Sigmoid가 도움이되는 것은 합리적으로 보입니다. 귀하의 코드를 시도해도 여전히 작동하지 않지만 귀하의 TF가 다른 난수 시퀀스를 사용하고 있기 때문에 생각합니다. 내가 시작 W/B를 시도하면 작동하지 ... – rwallace

+0

내 시작 W/B와 함께, 그것은 여전히 ​​작동하지 않습니다, 심지어 같은 코드로, 그것은 다른 종점에 도달하지만, 그것은 이상한, perceptrons는 항상 글로벌 최적으로 수렴 할 때, 그들은 로컬 최적 값을 가지지 않는다. 아직도 그 일이 벌어지고 있는지 알아 내려고 노력 중입니다. – rwallace

+0

좋아, 나는 '퍼셉트론은 항상 글로벌 최적으로 수렴한다'는 것을 기억했지만, '데이터가 선형으로 분리 가능하다면'올바른 버전의 후반을 잊었다. 그래서 글로벌 최적은 실제로 시그 모이 드와 함께 4/5를 기록합니다. – rwallace