2017-01-19 1 views
3

기계 학습 및 파이썬에 대한 배경 지식이 있지만 TensorFlow를 배우는 중입니다. 나는 tutorial on deep convolutional neural nets을 통해 이미지 분류에 사용하는 방법을 스스로 가르쳐야 할 것입니다. 그 길을 따라 가면서 나는 문제를 풀고있다.TensorFlow CNN 튜토리얼 : 로컬 레이어에 연결하기 위해 상단 레이어를 편집하는 방법은 무엇입니까?

연습 : 추론()의 모델 아키텍처는 cuda-convnet에 지정된 CIFAR-10 모델과 약간 다릅니다. 특히, Alex의 원래 모델의 최상위 레이어는 로컬로 연결되어 있으며 완전히 연결되어 있지 않습니다. 아키텍처를 편집하여 최상위 계층에 로컬로 연결된 아키텍처를 정확하게 재현 해보십시오.

연습 문제는 cifar10.py model의 inference() 함수를 참조하십시오. 두 번째 레이어부터 마지막 ​​레이어 (local4라고 함)는 shape = [384, 192]이고, 최상위 레이어는 shape = [192, NUM_CLASSES]입니다. 여기서 NUM_CLASSES = 10입니다. 나는 우리가 편집하도록 요청 코드가 상위 레이어를 정의하는 코드 어딘가에 생각 :

with tf.variable_scope('softmax_linear') as scope: 
    weights = _variable_with_weight_decay('weights', [192, NUM_CLASSES], 
             stddev=1/192.0, wd=0.0) 
    biases = _variable_on_cpu('biases', [NUM_CLASSES], 
          tf.constant_initializer(0.0)) 
    softmax_linear = tf.add(tf.matmul(local4, weights), biases,name=scope.name 
    _activation_summary(softmax_linear) 

하지만 층 사이 연결의 가능성을 결정하는 코드가 표시되지 않기 때문에 나도 몰라 모델을 완전히 연결된 상태에서 로컬로 연결된 상태로 바꿀 수있는 방법. 누군가 이것을하는 방법을 알고 있습니까?

답변

2

저는이 연습에도 착수했습니다. 솔루션을 제공하는 것보다 내 접근 방법을 올바르게 설명하려고 노력할 것입니다. 완벽하게 연결된 레이어 (https://www.tensorflow.org/get_started/mnist/beginners)의 수학을 되돌아 볼 가치가 있습니다.

그래서 완전히 접속 층 선형 대수이다

Y는 = W가 * X + B X가 N 차원의 입력 벡터가

Bn은 바이어스의 차원 벡터이고, Wnbyn 가중치 행렬이다.Y의 I 번째 원소 W 승산 요소 와이즈 X와의 I 번째 행의 합이다. 만 Y 원한다면

그래서 ... [I]X [I-1], X [I]X 접속 [난 + 1] 간단히 설정할 이격 (I-1) 번째 행 제로 W I 번째 행의 모든 ​​값, I 번째 해당 행의 (I + 1) 번째 열. 따라서 로컬로 연결된 레이어를 만들려면 W을 밴드 매트릭스 (https://en.wikipedia.org/wiki/Band_matrix)로 지정하면됩니다. 여기서 밴드의 크기는 원하는 로컬 연결의 크기와 같습니다. Tensorflow에는 행렬을 줄무늬로 설정하는 기능이 있습니다 (tf.batch_matrix_band_part(input, num_lower, num_upper, name=None)).

이것은 운동에 대한 가장 단순한 수학적 해결책 인 것처럼 보입니다.

+0

이 답변은이 문제를 해결하지 못합니다. W 행렬은 "다중 대역"이어야합니다. 예를 들어, 필터가 3x3이면 3 개의 대각선, 각각 3 개의 요소 폭이 있어야합니다. tf.matrix_band_part()는 하나의 밴드 만 허용합니다. 또한 W의 차원이 변경되므로 원본 W를 가져 와서 일부 요소를 0으로 설정할 수 없습니다. 특히 W의 행 수는 병합 된 출력 특성 맵의 길이와 같아야합니다. 저는 Xyand의 대답이 더 나은 접근법이라고 생각합니다. 이미지 패치를 추출하고 각각의 커널에 곱하기 때문에 텐서가 두 개의 추가 차원을 얻습니다 (6D가 됨). – MichaelSB

+0

충분합니다. 이것은 제가이 운동을 해결하는 방법에 대한 단서를 제공하기 위해 수학에 대한 일종의 이해를 얻으려고하는 것입니다. 연습 문제는 사람들로 하여금 스스로 생각하게하는 것이라고 생각합니다. 따라서 실제로 복사/붙여 넣기가 가능한 코드를 제공하지는 않았지만 이것이 이론적으로 어떻게 접근 할 수 있는지에 대한 기본적인 이해를 돕습니다. 공학이 아니라 신경망으로 작업 할 때 선형 대수학의 일부를 이해하면 도움이됩니다. –

+0

로컬로 연결된이 계층을 처리 한 지 꽤 오래되었습니다. 그러나 @DavidPickup에 의한 접근법은 전체 행렬에 상수 지시 행렬을 곱한 멀티 밴드 행렬을 시뮬레이트하여 실제로 작동 할 수 있습니다. W의 크기는 (w_out * h_out) X (w_in * h_in * d_in) 여야합니다. 그러나 그것은 꽤 낭비적인 것처럼 보인다. 내가 놓친 게 있니? – Xyand

2

나는 100 % 아니지만 나는 당신의 질문에 답하려고 노력할 것이다.

cuda-convnet에서 보면, TensorFlow 및 cuda-convnet 구현은 두 번째 풀링 계층 다음에 달라지기 시작합니다.

TensorFlow 구현은 완전히 연결된 두 개의 레이어와 softmax 분류기를 구현합니다.

cuda-convnet은 로컬로 연결된 두 개의 레이어 (하나의 완전 연결된 레이어와 softmax 분류기)를 구현합니다.

포함 된 코드 스 니펫은 softmax 분류자를 참조하며 실제로 두 구현간에 공유됩니다. TensorFlow를 사용하여 cuda-convnet 구현을 재현하려면 기존에 완전히 연결된 레이어를 로컬로 연결된 레이어 2 개와 완전히 연결된 레이어로 대체해야합니다.

Tensor는 SDK의 일부로 로컬로 연결된 레이어가 없기 때문에 기존 도구를 사용하여 구현해야합니다. 다음은 로컬로 연결된 첫 번째 레이어를 구현하려는 시도입니다.

with tf.variable_scope('local3') as scope: 
    shape = pool2.get_shape() 
    h = shape[1].value 
    w = shape[2].value 

    sz_local = 3 # kernel size 
    sz_patch = (sz_local**2)*shape[3].value 
    n_channels = 64 

    # Extract 3x3 tensor patches 
    patches = tf.extract_image_patches(pool2, [1,sz_local,sz_local,1], [1,1,1,1], [1,1,1,1], 'SAME') 
    weights = _variable_with_weight_decay('weights', shape=[1,h,w,sz_patch, n_channels], stddev=5e-2, wd=0.0) 
    biases = _variable_on_cpu('biases', [h,w,n_channels], tf.constant_initializer(0.1)) 

    # "Filter" each patch with its own kernel 
    mul = tf.multiply(tf.expand_dims(patches, axis=-1), weights) 
    ssum = tf.reduce_sum(mul, axis=3) 
    pre_activation = tf.add(ssum, biases) 
    local3 = tf.nn.relu(pre_activation, name=scope.name) 
+0

h 및 w 체중의 차원은 입력 특성 맵이 아니라 출력 특성 맵 높이 및 너비를 참조해야합니다. – MichaelSB

관련 문제