우리는 우리가 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]))
수 당신이 세부 사항이 조금 ? 이러한 입력 중 일괄 처리가 수행됩니까? NN은 일반적으로 많은 데이터 "샘플"과 함께 사용됩니다. 일반적으로 각 샘플에는 자체 m, i 및 j가 있습니다. 예를 들어 10000 개의 샘플을 가지고 있다면 10000, 10000, 10000을 가질 것입니다. 네 사건에 사실인가? 그렇지 않은 경우, 어떤 것이 일괄 적으로 제공되는지, 그리고 실제로 어떤 것이 고유 한 가치인지를 알려주십시오. –
대니얼, 고마워. 내 디자인에서는 0D, 0D 입력 (스칼라 i, j)이 데이터에서 나오지만 2D 입력 (행렬 m)은 다른 레이어의 출력입니다 (다른 레이어의 출력으로 올 때 설계도 고려합니다). 0D, 0D 입력을 적절한 가중치의 사전 계산 된 2D 입력으로 바꿀 수는 있지만 곱셈을 사용하는 것이 좋습니다. 그런 접근 방식은 추한 것 같습니다. 2. 아마도 덜 효율적입니다. 3. i, j가 출력 일 때 확장 할 수 없습니다. 다른 레이어. 귀하의 질문에 대답, 네 모든 데이터가 일괄로 올 수 있습니다. – user23809
나는 정말 이런 걸 찾고 있었고, 너는 나에게 갈 길을 찾도록 영감을 주었다. 고맙습니다! –