2017-11-27 3 views
0

다음 코드가 그램 레이어를 두 번 실행하는 이유는 무엇입니까?Keras Lambda 레이어가 한 번만 호출 되더라도 두 번 실행됩니다.

import numpy as np 
from keras.applications import vgg19 
from keras import backend as K 
from keras.layers import Input, Lambda 
import tensorflow as tf 
from keras.models import Model 

def gram_layer(y): 
    print('Using Gram Layer') 
    # assert K.ndim(y) == 4 
    print(y.shape, 'y.shape') 
    # a = y.get_shape()[1].value 
    # b = y.get_shape()[2].value 
    # c = y.get_shape()[3].value 
    # print(a, b, c) 
    # x = K.squeeze(y, axis=0) 

    # features = K.batch_flatten(K.permute_dimensions(x, (2, 0, 1))) 
    # features_nomean = features - K.mean(features, axis=0, keepdims=True) 
    # gram = K.dot(features_nomean, K.transpose(features_nomean))/(a * b * c) 
    print('exiting Gram') 
    # return x 
    return y 


In = K.placeholder((1, 256, 256, 3)) 
model = vgg19.VGG19(input_tensor = In, weights='imagenet', include_top=False) 

for layer in model.layers: 
    if layer.name == 'block1_conv1': 
     print(layer.name) 
     print(layer.output.shape) 
     outputs = (Lambda(gram_layer))(layer.output) 

디버그 정보 :

block1_conv1 
(1, 256, 256, 64) 
Using Gram Layer 
(1, 256, 256, 64) y.shape 
exiting Gram 
Using Gram Layer 
(?, ?, ?, 64) y.shape 
exiting Gram 

디버그 정보는이 레이어를 두 번 실행하고 두 번째에 실패하지만 이상하게도이 한 번만라고 의미 "그램 레이어를 사용하여"이 포함되어 있습니다.

어떤 아이디어가 잘못 되었나요?

PS : 나는 문제가 루프 부분에 자리 잡고 실현

outputs = (Lambda(gram_layer))(layer.output) 

디버그 정보가

block1_conv1 
(1, 256, 256, 64) 
Using Gram Layer 
(1, 256, 256, 3) y.shape 
exiting Gram 
Using Gram Layer 
(?, ?, ?, 3) y.shape 
exiting Gram 
로가는
outputs = (Lambda(gram_layer))(In) 

로 교체 마지막 줄 경우

마지막 5 줄을

그것은 여전히 ​​두 번 실행되지만 형상 추론이 정확
Using Gram Layer 
(1, 256, 256, 3) y.shape 
exiting Gram 
Using Gram Layer 
(1, 256, 256, 3) y.shape 
exiting Gram 

outputs = (Lambda(gram_layer))(In) 

다음 디버그 정보가 간다. 이거 버그 야? 아니면 GitHub에서보고해야합니까?

답변

0

함수가 두 번 호출되는 이유를 잘 모르는 경우가 있지만 흔히 볼 수 있습니다. 컴파일하는 동안 먼저 호출됩니다.

"없음"값으로 재 형성되는 문제가있는 것 같습니다. 그것은 지원되지 않습니다.

"-1"대신 "없음"으로 바꿀 수 있지만 "-1"만 바꿀 수 있습니다.

제안 1 : x = K.squeeze(y,axis=0)

경고 :

귀하의 모든 모양 변경 코드는 교체 할 수 있습니다

그러나이 keras에서 매우 이례적인 일이다. axis=0 크기는 배치 크기입니다. 이 코드는 batch_size = 1으로 만 실행됩니다. (당신의 코드와 제 제안 중 하나).

제안 2 :

당신은 왜 모양 변경 한 후, batch_flatten을 사용하려고하는 경우? batch_flatten() 전에 수행하는 모든 모양은 실제로 마지막 두 차원 만 평평하게하고 (256,768) 텐서가없는 한 무의미합니다.

제안 3 : 당신이 a의 실제 값, b, c에 대한 계산을 원하는 경우에, 당신이 그들의 텐서 값 대신 자신의 설정 값을 얻을 필요가

:

shp = K.shape(y) 
a = shp[1] #maybe you need shp[1:2], depending on whether you get an error in the division line  
b = shp[2] 
c = shp[3] 

제안 4 :

자리 표시자를 사용하는 것은 이상합니다. 그것을하는 keras 방법이 아니다.

당신은 단순히 모델을 생성하고 원하는 그것을 모양을 말해야한다 :

inputTensor = Input(batch_shape=(1,256,256,64) 
output = model(inputTensor) 
model = Model(inputTensor, output) 
: 당신은 하나의 배치 크기를 적용 할 경우

model = vgg19.VGG19(input_shape = (256,256,64), weights='imagenet', include_top=False) 

는, 당신은 입력 텐서를 만들 수 있습니다

+0

답장을 보내 주셔서 감사합니다. 이제 대부분의 줄을 지우고 gram_layer 함수는 단순히 입력 y를 반환하지만 문제는 여전히 존재합니다. 내 코드는 "없음"값으로 계속할 수 없습니다. – DDz

+0

새 코드와 새 오류를 게시 할 수 있습니까? –

+0

물론입니다. 원본 게시물을 편집 할 준비가되었습니다. 일부 줄은 주석으로 표시되고 디버그 정보는 약간 다릅니다. – DDz