1

정규화 된 MNIST 데이터 세트를 사용하고 있습니다 (입력 기능 = 784). 내 네트워크 아키텍처는 784-256-256-10 : Sigmoid 활성화 기능을 사용하는 각각 256 개의 뉴런으로 구성된 2 개의 숨겨진 레이어와 10-neuron 출력 레이어에서 softmax 활성화. 또한 교차 엔트로피 비용 함수를 사용하고 있습니다. 탈락 : 신경 네트워크가 작동하지 않는 이유는 무엇입니까?

무게 매트릭스 초기화 : 여기에 예상대로

input_size=784 
hidden1_size=256 
hidden2_size=256 
output_size=10 
Theta1 = np.random.randn(hidden1_size, input_size) 
b1 = np.random.randn(hidden1_size) 

Theta2 = np.random.randn(hidden2_size, hidden1_size) 
b2 = np.random.randn(hidden2_size) 

Theta3 = np.random.randn(output_size, hidden2_size) 
b3 = np.random.randn(output_size) 

내 네트워크 작동 :

epochs = 2000 
learning_rate = 0.01 
for j in range(epochs): 
    # total_train is an array of length 50000 
    # Each element of total_train is a tuple of: (a) input vector of length 784 
    # and (b) the corresponding one-hot encoded label of length 10 
    # Similarly, total_test is an array of length 10000 
    shuffle(total_train) 
    train = total_train[:1000] 
    shuffle(total_test) 
    test = total_test[:1000] 
    predictions = [] 
    test_predictions = [] 
    for i in range(len(train)): 
     # Feed forward 
     x, t = train[i][0], train[i][1] 
     z1 = np.dot(Theta1, x) + b1 
     a1 = sigmoid(z1) 
     z2 = np.dot(Theta2, a1) + b2 
     a2 = sigmoid(z2) 
     z3 = np.dot(Theta3, a2) + b3 
     y = softmax(z3) 
     # Is prediction == target? 
     predictions.append(np.argmax(y) == np.argmax(t)) 

     # Negative log probability cost function 
     cost = -t * np.log(y) 

     # Backpropagation 
     delta3 = (y - t) * softmax_prime(z3) 
     dTheta3 = np.outer(delta3, a2) 
     db3 = delta3 

     delta2 = np.dot(Theta3.T, delta3) * sigmoid_prime(z2) 
     dTheta2 = np.outer(delta2, a1) 
     db2 = delta2 

     delta1 = np.dot(Theta2.T, delta2) * sigmoid_prime(z1) 
     dTheta1 = np.outer(delta1, x) 
     db1 = delta1 

     # Update weights 
     Theta1 -= learning_rate * dTheta1 
     b1 -= learning_rate * db1 
     Theta2 -= learning_rate * dTheta2 
     b2 -= learning_rate * db2 
     Theta3 -= learning_rate * dTheta3 
     b3 -= learning_rate * db3 

    if j % 10 == 0: 
     m = len(predictions) 
     performance = sum(predictions)/m 
     print('Epoch:', j, 'Train performance:', performance) 

    # Test accuracy on test data 
    for i in range(len(test)): 
     # Feed forward 
     x, t = test[i][0], test[i][1] 
     z1 = np.dot(Theta1, x) + b1 
     a1 = sigmoid(z1) 
     z2 = np.dot(Theta2, a1) + b2 
     a2 = sigmoid(z2) 
     z3 = np.dot(Theta3, a2) + b3 
     y = softmax(z3) 
     # Is prediction == target? 
     test_predictions.append(np.argmax(y) == np.argmax(t)) 

    m = len(test_predictions) 
    performance = sum(test_predictions)/m 
    print('Epoch:', j, 'Test performance:', performance) 

출력 (각 10 시대) :

Epoch: 0 Train performance: 0.121 
Epoch: 0 Test performance: 0.146 
Epoch: 10 Train performance: 0.37 
Epoch: 10 Test performance: 0.359 
Epoch: 20 Train performance: 0.41 
Epoch: 20 Test performance: 0.433 
Epoch: 30 Train performance: 0.534 
Epoch: 30 Test performance: 0.52 
Epoch: 40 Train performance: 0.607 
Epoch: 40 Test performance: 0.601 
Epoch: 50 Train performance: 0.651 
Epoch: 50 Test performance: 0.669 
Epoch: 60 Train performance: 0.71 
Epoch: 60 Test performance: 0.711 
Epoch: 70 Train performance: 0.719 
Epoch: 70 Test performance: 0.694 
Epoch: 80 Train performance: 0.75 
Epoch: 80 Test performance: 0.752 
Epoch: 90 Train performance: 0.76 
Epoch: 90 Test performance: 0.758 
Epoch: 100 Train performance: 0.766 
Epoch: 100 Test performance: 0.769 

을하지만 Dropout을 소개 할 때 정규화 계획, 내 네트워크 중단. 드롭 아웃에 대한 나의 코드 업데이트는 다음과 같습니다

dropout_prob = 0.5 

# Feed forward 
x, t = train[i][0], train[i][1] 
z1 = np.dot(Theta1, x) + b1 
a1 = sigmoid(z1) 
mask1 = np.random.random(len(z1)) 
mask1 = mask1 < dropout_prob 
a1 *= mask1 
z2 = np.dot(Theta2, a1) + b2 
a2 = sigmoid(z2) 
mask2 = np.random.random(len(z2)) 
mask2 = mask2 < dropout_prob 
a2 *= mask2 
z3 = np.dot(Theta3, a2) + b3 
y = softmax(z3) 

# Backpropagation 
delta3 = (y - t) * softmax_prime(z3) 
dTheta3 = np.outer(delta3, a2) 
db3 = delta3 * 1 

delta2 = np.dot(Theta3.T, delta3) * sigmoid_prime(z2) 
dTheta2 = np.outer(delta2, a1) 
db2 = delta2 * 1 

delta1 = np.dot(Theta2.T, delta2) * sigmoid_prime(z1) 
dTheta1 = np.outer(delta1, x) 
db1 = delta1 * 1 

성능은 약 0.1 (10 %)에서 유지됩니다.

내가 잘못 가고있는 부분에 대한 모든 의견을 보내 주시면 감사하겠습니다.

+0

50 % 드롭 아웃은 이러한 소규모 네트워크에서 너무 많이 발생합니다. –

+0

@ThomasJungblut'dropout_prob = 0.9'로 시도하고 0.005의 더 작은 학습 률을 시도했지만별로 개선되지 않았습니다. 이제 정확도는 약 20 %이지만 거의 일정합니다. 나는 비용과 대열을 구상 해 보았습니다. [this] (https://i.imgur.com/pF2cCGI.png)는 제가 본 것입니다. ('dropout_prob = 1 '로 설정하면 드롭 아웃없이 똑같이 작동하고 예상대로 정확도가 올라갑니다.) –

+0

'내 네트워크 휴식 '이란 무엇입니까? 하나의 생각; 'dropout_prob'을 포함하도록 그라디언트 디센트 업데이트를 변경 했습니까? – jonnybazookatone

답변

0

테스트 시간에 활성화이 아닌 이기 때문에 드롭 아웃 구현에 중대한 문제가 있습니다. 여기에 great CS231n tutorial에서 따옴표는 다음과 같습니다

결정적으로는 predict 기능에 우리가 더 이상 하락하지 않는 점에 유의,하지만 우리는 p 모두에 의해 숨겨진 레이어 출력의 스케일링을 수행하고 있습니다.

시험 시간에 모든 신경 세포는 모든 입력을 볼 수 있기 때문에 중요하다, 그래서 우리는 훈련 시간에 자신의 예상 출력에 동일하게 시험 시간에 신경 세포의 출력을 할 수 있습니다. 예를 들어, p=0.5의 경우, 뉴런은 테스트 시간에 출력을 반으로 줄여 이 학습 시간 (기대치) 동안의 출력과 같아야합니다.

이것을 보려면 뉴런 x의 출력 (드롭 아웃 전)을 고려하십시오. 이 누락 된 경우이 뉴런의 예상 출력은 px+(1−p)0이됩니다. 이는 뉴런의 출력이 의 확률로 1−p으로 설정되기 때문입니다. 테스트 시간에 뉴런을 항상 으로 유지하면 같은 예상 출력을 유지하기 위해 x→px을 조정해야합니다.

또한 시험 시간에이 감쇠를 수행하는 것이 가능한 모든 이진 마스크 ​​반복의 처리에 관한 될 수 있음을 나타낼 수있다 (및 모든 기하 급수적으로 많은 서브 네트워크) 및 컴퓨팅 그들의 앙상블 예측.

가장 일반적인 해결책은 그대로 시험시 포워드 패스를 떠나는 기차 시간에 스케일링을 수행하는 반전 강하을 사용하는 것이다.코드의 모양은 다음과 같습니다.

mask1 = (mask1 < dropout_prob)/dropout_prob 
... 
mask2 = (mask2 < dropout_prob)/dropout_prob 
... 
+0

I [_have_] (https://i.imgur.com/pMv0ll0.png)는 위의 주석에서 언급 한 것처럼 테스트 시간 동안 정품 인증을 조정했습니다. 내가 제안한대로 거꾸로 된 드롭 아웃을 시도했지만, 여전히 네트워크가 훈련하는 것 같지 않습니다. [Here] (https://gist.github.com/IshwarBhat/869a12b3a1f50aa78b382f178968c6ae)는 전체 코드입니다. –