1

MobileNet 이미지 분류자를 재교육 (finetune 읽기)하려고합니다.Tensorflow : 동일한 이미지에 대해 다른 정품 인증 값

텐서 흐름 here (tutorial에서)에 의해 주어진 재교육 스크립트는 새로 추가 된 완전히 연결된 레이어의 가중치 만 업데이트합니다. 이 스크립트를 수정하여 사전 훈련 된 모델의 모든 레이어의 가중치를 업데이트했습니다. 0.25의 깊이 배율과 128의 입력 크기를 가진 MobileNet 아키텍처를 사용하고 있습니다.

그러나 재교육 중에 나는 특정 이미지를 다른 이미지와 함께 배치의 추론을위한 입력으로 제공하면 이상한 것을 깨닫지 만 활성화 일부 레이어 뒤의 값은 이미지가 단독으로 전달 된 값과 다릅니다. 또한 다른 배치의 동일한 이미지에 대한 활성화 값이 다릅니다. 예 - 두 배치의 경우 - batch_1 : [img1, img2, img3]; batch_2 : [img1, img4, img5]. img1의 활성화는 두 배치와 다릅니다. 몇 가지 다음

layerXactivations_batch=sess.run(layerX, {input_image_tensor: np.asarray([np.squeeze(id), np.squeeze(id), np.squeeze(id)])}) 

: 위의 코드는 마지막 줄에 다음과 같이 변경 한 번 그대로 한 번 실행

for tf.Session(graph=tf.get_default_graph()) as sess: 
    image_path = '/tmp/images/10dsf00003.jpg' 
    id_ = gfile.FastGFile(image_path, 'rb').read() 

    #The line below loads the jpeg using tf.decode_jpeg and does some preprocessing 
    id = sess.run(decoded_image_tensor, {jpeg_data_tensor: id_}) 

    input_image_tensor = graph.get_tensor_by_name('input') 

    layerXname='MobilenetV1/MobilenetV1/Conv2d_1_depthwise/Relu:0' #Name of the layer whose activations to inspect. 
    layerX = graph.get_tensor_by_name(layerXname) 
    layerXactivations=sess.run(layerX, {input_image_tensor: id}) 

- 여기

내가 추론에 사용하는 코드입니다 그래프의 노드 : 이제

[u'input', u'MobilenetV1/Conv2d_0/weights', u'MobilenetV1/Conv2d_0/weights/read', u'MobilenetV1/MobilenetV1/Conv2d_0/convolution', u'MobilenetV1/Conv2d_0/BatchNorm/beta', u'MobilenetV1/Conv2d_0/BatchNorm/beta/read', u'MobilenetV1/Conv2d_0/BatchNorm/gamma', u'MobilenetV1/Conv2d_0/BatchNorm/gamma/read', u'MobilenetV1/Conv2d_0/BatchNorm/moving_mean', u'MobilenetV1/Conv2d_0/BatchNorm/moving_mean/read', u'MobilenetV1/Conv2d_0/BatchNorm/moving_variance', u'MobilenetV1/Conv2d_0/BatchNorm/moving_variance/read', u'MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/add/y', u'MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/add', u'MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/Rsqrt', u'MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/mul', u'MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/mul_1', u'MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/mul_2', u'MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/sub', u'MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/add_1', u'MobilenetV1/MobilenetV1/Conv2d_0/Relu6', u'MobilenetV1/Conv2d_1_depthwise/depthwise_weights', u'MobilenetV1/Conv2d_1_depthwise/depthwise_weights/read', ... ...] 

layerXname = 'MobilenetV1/MobilenetV1/Conv2d_0/convolution'정품 인증은 위의 두 경우 모두 동일합니다. (즉, layerxactivations 및 layerxactivations_batch [0]이 동일 함). 그러나이 계층 이후에는 모든 계층이 다른 활성화 값을 갖습니다. 'MobilenetV1/MobilenetV1/Conv2d_0/convolution'계층 이후의 batchNorm 작업은 배치 입력 및 단일 이미지에 대해 다르게 동작합니다. 아니면 다른 문제로 인한 문제입니까?

도움/의견을 보내 주시면 감사하겠습니다.

답변

0

mobilenet을 빌드 할 때 is_training이라는 매개 변수가 있습니다. false로 설정하지 않으면 드롭 아웃 레이어와 일괄 정규화 레이어가 다른 반복에서 다른 결과를 제공합니다. 일괄 정규화는 값을 거의 변경하지 않지만 일부 입력 값이 떨어지면 드롭 아웃이 많이 변경됩니다.

는 mobilnet의 서명을 살펴보십시오 :이 배치 정상화로 인해

def mobilenet_v1(inputs, 
       num_classes=1000, 
       dropout_keep_prob=0.999, 
       is_training=True, 
       min_depth=8, 
       depth_multiplier=1.0, 
       conv_defs=None, 
       prediction_fn=tf.contrib.layers.softmax, 
       spatial_squeeze=True, 
       reuse=None, 
       scope='MobilenetV1'): 
    """Mobilenet v1 model for classification. 

    Args: 
    inputs: a tensor of shape [batch_size, height, width, channels]. 
    num_classes: number of predicted classes. 
    dropout_keep_prob: the percentage of activation values that are retained. 
    is_training: whether is training or not. 
    min_depth: Minimum depth value (number of channels) for all convolution ops. 
     Enforced when depth_multiplier < 1, and not an active constraint when 
     depth_multiplier >= 1. 
    depth_multiplier: Float multiplier for the depth (number of channels) 
     for all convolution ops. The value must be greater than zero. Typical 
     usage will be to set this value in (0, 1) to reduce the number of 
     parameters or computation cost of the model. 
    conv_defs: A list of ConvDef namedtuples specifying the net architecture. 
    prediction_fn: a function to get predictions out of logits. 
    spatial_squeeze: if True, logits is of shape is [B, C], if false logits is 
     of shape [B, 1, 1, C], where B is batch_size and C is number of classes. 
    reuse: whether or not the network and its variables should be reused. To be 
     able to reuse 'scope' must be given. 
    scope: Optional variable_scope. 

    Returns: 
    logits: the pre-softmax activations, a tensor of size 
     [batch_size, num_classes] 
    end_points: a dictionary from components of the network to the corresponding 
     activation. 

    Raises: 
    ValueError: Input rank is invalid. 
    """ 
+0

감사합니다. @jorgemf! 내 질문에 의심되는 바와 같이 문제는 batchNorm에서 발생했으며'is_training'을'false'로 설정 한 것입니다. 그러나 이것이 올바른 방법은 아닙니다. 이상적으로 그래프는 훈련 중에'is_training'을'True'로로드하고, 추론 중에 False로'is_training'을로드해야합니다. 하지만 여기서부터 나는 batchnorm을 직접 작성하지 않았으며, 그래프는 MobileNet 코드에서로드되었습니다. 나는 아직 어떻게 해야할지 알아낼 수 없다.여기에서 참조하실 수 있습니다 - https://stackoverflow.com/questions/39353503/tensorflow-tf-slim-model-with-is-training-true-and-false 또는 https://ruishu.io/2016/12/27/batchnorm/ – Krist

+0

@Krist가 도움이된다면 응답을 유효한 것으로 표시하는 것을 잊지 마십시오. – jorgemf

-1

.

어째서 유추를 실행하고 있습니까? 검사 점 파일에서로드 중인지 또는 고정 Protobuf 모델을 사용하고 있습니까? 고정 된 모델을 사용하면 다양한 형식의 입력에 대해 유사한 결과를 기대할 수 있습니다.

this을 확인하십시오. 다른 응용 프로그램과 비슷한 문제가 제기됩니다.

+0

나는 그가 그래프를 고정시키지 않았거나 링크 된 이슈가 고정 그래프에 의한 것이라고 생각하지 않습니다. – jorgemf

+0

나는 Batch Normalization 때문이라고 말했다. 그래프를 고정하면 이동 평균/평균이 변경되고 예측 가능한 결과가 나타납니다. –

+1

이제는 batch_norm 또는 드롭 아웃 레이어 일 수 있습니다. 둘 다 is_training 매개 변수를 사용합니다 – jorgemf