2016-06-21 4 views
0

Tensorflow에는 활성화 기능으로 tanh을 사용하는 2 계층 비 길쌈 네트워크가 있습니다. 나는 무게로 나눈 절단 정규 분포로 초기화되어야 함을 이해 sqrt(nInputs) 예 :Supressing 가중치가 Tensorflow 신경 네트워크 성능을 향상시키는 이유는 무엇입니까?

weightsLayer1 = tf.Variable(tf.div(tf.truncated_normal([nInputUnits, nUnitsHiddenLayer1),math.sqrt(nInputUnits)))) 

가 NN과 Tensorflow에서 더듬 거리는 초보자의 비트가, 내가 실수 만 더 읽을 수 있도록 2 명 선으로이 구현 것 :

weightsLayer1 = tf.Variable(tf.truncated_normal([nInputUnits, nUnitsHiddenLayer1]) 
weightsLayer1 = tf.div(weightsLayer1, math.sqrt(nInputUnits)) 

는 지금이 잘못된 것을 알고 그리고 그 두 번째 라인은 무게가 각 학습 단계에서 다시 계산됩니다. 그러나 필자의 생각에 "잘못된"구현은 열차 및 테스트/평가 데이터 세트에서 일관되게 더 나은 성능을 제공합니다. 나는 최적화 과정에서 큰 혼란을 가져올 것으로 예상되는 옵티 마이저에 의해 선택된 값 이외의 다른 값으로 가중치를 다시 계산 (억제)하기 때문에 잘못된 2 행 구현이 열차 사고가되어야한다고 생각했지만 실제로 개선되었다. . 누구든지 이에 대한 설명이 있습니까? Tensorflow adam optimizer를 사용하고 있습니다.

업데이트 2016.6.22 - 위의 두 번째 코드 블록을 업데이트했습니다.

+0

우선, 두 줄 구현에서,''sqrt (nInputUnits)'로 나누기를 두 번하고,''nInputUnits''로 효과적으로 나눕니다. 그게 의도적 인거야? 둘째 : 나는 당신의 질문을 정확하게 이해하지 못합니까? ''weightsLayer1'' 변수가 훈련 단계를 실행할 때마다 다시 초기화되는 것을 염려하십니까? 그렇다면 사실이 아닙니다. 나는 이것에 대해 자세히 설명 할 수는 있지만, 그것이 실제로 묻고있는 것인지 확실하지는 않습니다. – lballes

+0

나의 실수는 위의 두 줄의 경우에 잘못 입력 한 것입니다. 위의 내용을 수정했습니다. 나는 'sqrt (nInputUnits)'로 한 번만 나눕니다. 2 줄의 경우,'weightsLayer1'은'tf.Variable' 줄에서 한번만 초기화된다는 것을 알고 있습니다. 내 질문 : a) 두 번째 라인 (weightsLayer1 = tf.div (weightsLayer1, math.sqrt (nInputUnits)))이 런타임에 실행되는 것이 사실입니까? b) 그렇다면 옵티마이 저가 계산 한 'weightsLayer1'의 값을 수정하여 최적화 과정을 방해합니까?c) 그렇다면 최적화 프로그램에서 계산 한 'weightsLayer1'값보다 어떻게 더 좋을까요? –

+0

좋아, 이제 알았어. 아래 내 대답을 참조하십시오. – lballes

답변

4

. 그러나 그것은 각 단계에서 가중치 변수의 값이 sqrt(nInputUnits)에 의해 축소된다는 것을 의미하지는 않습니다. 이 행은 변수에 저장된 값에 영향을주는 적절한 작동이 아닙니다. 그것은 새로운 텐서를 계산하고, 변수의 값을 sqrt(nInputUnits)으로 나눈 값을 가지고 있습니다. 그리고 그 텐서는 여러분의 계산 그래프의 나머지 부분으로갑니다. 이것은 옵티 마이저를 방해하지 않습니다. 가중치의 다소 임의적 인 스케일링만으로 유효한 계산 그래프를 정의하고 있습니다. 옵티마이 저는 계속이 변수에 대한 그래디언트를 계산할 수 있으며 (해당 나누기 연산을 통해 역 전파됩니다) 해당 업데이트 작업을 생성합니다.

정의하려는 모델 측면에서 두 버전은 완전히 동일합니다. 원래 모델의 weightsLayer1 값 집합 (division을 작성하지 않은 경우)은 sqrt(nInputUnits)으로 단순하게 스케일링 할 수 있으며 두 번째 모델과 동일한 결과를 얻을 수 있습니다. 두 모델은 꼭 같은 모델 클래스를 나타냅니다.

왜 다른 사람보다 효과가 뛰어난가요? 너의 추측은 나의 것만 큼 좋다. 모든 변수에 대해 동일한 부서를 수행 한 경우 학습 속도를 효과적으로 sqrt(nInputUnits)으로 나눈 것입니다. 이 작은 학습 속도는 당면한 문제에 유익했습니다.

편집 : 변수에 동일한 이름을 지정하고 새롭게 생성 된 텐서가 혼란을 야기한다고 생각합니다. 당신이

A = tf.Variable(1.0) 
A = tf.mul(A, 2.0) 
# Do something with A 

을 수행 할 때 다음 두 번째 라인은 새로운 텐서를 생성한다 (상기 논의 된 바와 같이) 당신은 이름을 다시 바인딩 (그리고 그것은 단지 이름)이 새로운 텐서에 A. 정의 된 그래프의 경우, 이름은 절대적으로 부적합합니다.

A = tf.Variable(1.0) 
print A 
B = A 
A = tf.mul(A, 2.0) 
print A 
print B 

출력은 당신 print A 그것을 알려줍니다 처음

<tensorflow.python.ops.variables.Variable object at 0x7ff025c02bd0> 
Tensor("Mul:0", shape=(), dtype=float32) 
<tensorflow.python.ops.variables.Variable object at 0x7ff025c02bd0> 

입니다 : 다음 코드를 실행하면

A = tf.Variable(1.0) 
B = tf.mul(A, 2.0) 
# Do something with B 

어쩌면이 분명해진다 : 다음 코드는 같은 그래프를 정의 당신 A은 변수 객체입니다. A = tf.mul(A, 2.0)을 실행하고 A을 다시 인쇄하면 A이라는 이름이 이제 tf.Tensor 개체에 바인딩되었음을 알 수 있습니다. 그러나 변수는 여전히 존재하며, B 뒤에있는 개체를 보면 알 수 있습니다.

+0

감사합니다. 따라서'A = tf.Variable (1.0)'과'A = tf.mul (A, 2.0)'을하면 두 번째 줄은 A를 수정하지 않고 A라고도하는 또 다른 텐서를 만들고 Tensorflow는 A가 계산 그래프의 다른 곳에서 사용될 때 첫 번째가 아닌 두 번째 A? 나는 이것이 변수 A의 값을 수정하는 것과 기능적으로 동일하다고 생각한다. –

+0

업데이트 된 답변보기 – lballes

1

이것은 코드의 한 줄은 무엇입니다

t = tf.truncated_normal([ nInputUnits, nUnitsHiddenLayer1 ]) 

가 절단 정규 분포의 표준 편차 1.0로 초기화 형상 [nInputUnits, nUnitsHiddenLayer1]와 Tensor를 생성한다.

t1 = tf.div(t, math.sqrt(nInputUnits)) 

divide 모든 math.sqrt와 t의 값 (nInputUnits) 코드의

당신의 두 줄 정확히 같은 일을 (1.0 표준 STDDEV 값이다). 첫 번째 줄과 두 번째 줄에서 모든 값은 math.sqrt (nInputUnits)로 나뉩니다. 명세서에 관해서는

:

지금이 잘못된 것을 알고 2 선 가중치는 각 학습 단계에서 다시 계산되도록있다.

EDIT 내 실수 실제로 그들이이 모든 execuction에서 (nInputUnits) math.sqrt으로 나누어, 오른쪽,하지만 다시 초기화됩니다

! 여기

weightsLayer1 = tf.truncated_normal([ nInputUnits, nUnitsHiddenLayer1 ]) 
weightsLayer1 = tf.Variable(tf.div(weightsLayer1, math.sqrt(nInputUnits))) 

두 번째 라인은 모든 단계에서 미리 형성된다 :

weightsLayer1 = tf.Variable(tf.truncated_normal([ nInputUnits, nUnitsHiddenLayer1 ]) 
weightsLayer1 = tf.div(weightsLayer1, math.sqrt(nInputUnits)) 

왜 두 번째 수행을 중요한 점은 tf.variable()

여기에 넣어 두 라인이 한 번만 초기화되는 곳이다 더 나은 결과를 얻을 수 있을까요? 그것은 나에게 어떤 종류의 정규화처럼 보이지만, 좀 더 지식이 많은 사람은 그것을 검증해야합니다.

ps. 이 같은 더 읽기 쓸 수 있습니다 : 당신은 weightsLayer1 = tf.div(weightsLayer1, math.sqrt(nInputUnits)) 각 단계에서 실행되는 것을 옳다

weightsLayer1 = tf.Variable(tf.truncated_normal([ nInputUnits, nUnitsHiddenLayer1 ] , stddev = 1./math.sqrt(nInputUnits)) 
+0

내 이해는 예 : 'Y = tf.Variable (2.0)'은 그래프의 각 실행 단계에서'Y = tf.div (Y, X)'가 실행되는 동안 한 번만 실행되는 초기화입니다. 그 맞습니까? 그래서 그렇다면 나는 일을 한 번 초기화하지만 두 번째 줄이 각 단계에서 실행되고 옵티마이 저가 계산 한 것 이외의 다른 값으로 가중치 값을 변경하는 것처럼 보일 것입니다. –

관련 문제