2017-10-01 4 views
0

저는 Keras (및 NN)에 익숙하지 않습니다. 제 질문은 간단 할 수도 있습니다. 그럼에도 불구하고 Keras에 다음 레이어를 구현하는 방법을 알아낼 수는 없습니다.케라 소프트 멀티플렉서 레이어

2D, 0D, 0D (행렬, 스칼라, 스칼라)의 입력이 있어야합니다.

계층은 두 번째 및 세 번째 인수로 정의 된 위치에서 첫 번째 인수의 요소를 반환해야합니다. 따라서 입력이 (m, i, j)이면 m [i, j]를 반환해야합니다. pair (i, j)가 요소들 사이에 닿는 경우 (예 : i = 2.5 및 j = 3.7) 요소는 (i, j)로 정의 된 점을 중심으로 선형 근사값을 반환해야합니다.

이 함수는 m, i 및 j의 요소에 대해 차이가 있지만 (적어도 Keras에서는 충분히 차별 가능함) NN 계층을 정의하는 것이 좋습니다.

+0

수 당신이 세부 사항이 조금 ? 이러한 입력 중 일괄 처리가 수행됩니까? NN은 일반적으로 많은 데이터 "샘플"과 함께 사용됩니다. 일반적으로 각 샘플에는 자체 m, i 및 j가 있습니다. 예를 들어 10000 개의 샘플을 가지고 있다면 10000, 10000, 10000을 가질 것입니다. 네 사건에 사실인가? 그렇지 않은 경우, 어떤 것이 일괄 적으로 제공되는지, 그리고 실제로 어떤 것이 고유 한 가치인지를 알려주십시오. –

+0

대니얼, 고마워. 내 디자인에서는 0D, 0D 입력 (스칼라 i, j)이 데이터에서 나오지만 2D 입력 (행렬 m)은 다른 레이어의 출력입니다 (다른 레이어의 출력으로 올 때 설계도 고려합니다). 0D, 0D 입력을 적절한 가중치의 사전 계산 된 2D 입력으로 바꿀 수는 있지만 곱셈을 사용하는 것이 좋습니다. 그런 접근 방식은 추한 것 같습니다. 2. 아마도 덜 효율적입니다. 3. i, j가 출력 일 때 확장 할 수 없습니다. 다른 레이어. 귀하의 질문에 대답, 네 모든 데이터가 일괄로 올 수 있습니다. – user23809

+0

나는 정말 이런 걸 찾고 있었고, 너는 나에게 갈 길을 찾도록 영감을 주었다. 고맙습니다! –

답변

0

우리는 우리가 Lambda 계층에 전달거야, 다음과 같은 기능을 시도 할 수 있습니다 :

from keras.layers import * 
import keras.backend as K 
from keras.models import Model 

import tensorflow as tf 

def getValue(x): 

    #x is a group with 3 tensors here. m, i and j 
    m = x[0] 
    i = x[1] 
    j = x[2] 

    #let's take the i and j as integers around the actual point: 
    #as well as the distances between them and the float indices 
    lowI, distI = getLowIndexAndDistance(i) 
    lowJ, distJ = getLowIndexAndDistance(j) 

    #higher indices 
    highI = lowI + 1 
    highJ = lowJ + 1 
     #in the special case when these high values are exatly equal to the 
     #unrounded ones, the distance below will be 0 and this index will be discarded 

    #special case when i or j is exactly the maximum index 
    mShape = K.shape(m) 
    highI = highI - K.cast(K.equal(highI,mShape[1]),'int32') 
    highJ = highJ - K.cast(K.equal(highJ,mShape[2]),'int32') 


    #interpolations 
    valILeft = getInterpolated(getValueFromM(m,lowI,lowJ), 
           getValueFromM(m,highI,lowJ), 
           distI) 
    valIRight = getInterpolated(getValueFromM(m,lowI,highJ), 
           getValueFromM(m,highI,highJ), 
           distI) 

    return getInterpolated(valILeft,valIRight,distJ) 


#function to get the index rounded down 
    #unfortunately I couldn't find K.floor() or a similar function 
def getLowIndexAndDistance(i): 

    #getting the closest round number 
    roundI = K.round(i) 

    #comparisons to check wheter the rounded index is greater than i 
    isGreater = K.cast(K.greater(roundI,i),K.floatx()) 
     #1 if true, 0 if false 

    #if greater, let's take one number below: 
    lowI = roundI - isGreater 

    #returns the integer lowI and the distance between i and lowI 
    return K.cast(lowI,'int32'), i - lowI 




#function to get interpolated values 
def getInterpolated(val1, val2, distanceFromLowI): 

    valRange = val2 - val1 
    #span = 1 

    return val1 + (valRange * distanceFromLowI) 


def getEntireIndexMatrix(i,j): 

    batchIndex = K.ones_like(i) 
    batchIndex = K.cumsum(batchIndex) - 1 #equivalent to range(batch) 

    #warning, i and j must be (?,1), if they're reduced, the results will be weird. 
    return K.stack([batchIndex,i,j],axis=-1) 

     #this is a matrix of indices from which to get values in m 
     #the first element in the last axis is the batch index 
     #the second element is I 
     #the third is J 


def getValueFromM(m, i, j): 

    indexMatrix = getEntireIndexMatrix(i,j) 

    #tensorflow is an easy solution kere. Keras doesn't have this available, 
    #but there may be a workaround using K.gather 3 times, one for each dimension 
    return tf.gather_nd(m, indexMatrix) 

시험이 아주 기본적인 모델 :

m = Input((5,5)) 
i = Input((1,)) 
j = Input((1,)) 

out = Lambda(getValue, output_shape=(1,))([m,i,j]) 

model = Model([m,i,j],out) 

mVals = np.asarray(range(75)).reshape((3,5,5)) 
#iVals = np.asarray([[4],[2.3],[4]]) #for special cases 
#jVals = np.asarray([[4],[4],[1.7]]) #for special cases 
iVals = np.random.uniform(0,4,(3,1)) #for all cases 
jVals = np.random.uniform(0,4,(3,1)) #for all cases 

print(mVals) 
print(iVals) 
print(jVals) 

print(model.predict([mVals,iVals,jVals])) 
+0

다소 복잡한 해결책이지만 어쩌면 불가피합니다. Keras 백엔드 기능을 배운 후에 마침내 얻었습니다. 고마워. – user23809

+0

다음 방정식은 코드를 약간 단순화 할 수 있습니다. floor (x) = -round (0.5-x) – user23809