簡體   English   中英

用keras,tensorflow和python編寫這個充滿異國情調的NN架構

[英]Writing this exotic NN architecture with keras, tensorflow and python

我試圖讓Keras訓練一個可以在這樣的網絡中編寫的多類分類模型:

在此輸入圖像描述 唯一可訓練的參數是那些 在此輸入圖像描述 ,其余的都給出了。 函數fi是通常數學函數的組合(例如 在此輸入圖像描述 .Sigma代表以前術語的總和,softmax是通常的功能。 (x1,x2,... xn)是火車或測試裝置的元素 分子 是已選擇的原始數據的特定子集。

該模型更深入:

具體而言,給定(x_1,x_2,...,x_n)列車或測試集中的輸入,網絡進行評估

在此輸入圖像描述

fi給出數學函數, 分子 是原始數據和系數的特定子集的行 在此輸入圖像描述 是我想訓練的參數。 當我使用keras時,我希望它為每一行添加一個偏差項。

在上述評估之后,我將應用softmax層(上面m行中的每一行都是將作為softmax函數的輸入的數字)。

最后,我想編譯模型並像往常一樣運行model.fit。

問題是我不能將表達翻譯成keras sintax。

我的嘗試:

在上面的網絡划痕之后,我首先嘗試考慮表單的每個表達式 行 作為序列模型中的lambda層,但我能夠工作的最好的是密集層與線性激活的組合(它將扮演行參數的角色: 參數 )后面是輸出矢量的Lambda層 向量 沒有所需的總和,如下:

model = Sequential()
#single row considered:
model.add(Lambda(lambda x:  f_fixedRow(x), input_shape=(nFeatures,))) 
#parameters set after lambda layer to get (a1*f(x1,y1),...,an*f(xn,yn)) and not (f(a1*x1,y1),...,f(an*xn,yn))
model.add(Dense(nFeatures, activation='linear')) 

#missing summation: sum(x)
#missing evaluation of f in all other rows

model.add(Dense(classes,activation='softmax',trainable=False)) #should get all rows
model.compile(optimizer='sgd',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

另外,我必須在lambda函數調用中定義函數 分子 參數已經修復(因為lambda函數只能將輸入層作為變量):

def f_fixedRow(x):
   #picking a particular row (as a vector) to evaluate f in (f works element-wise)
   y=tf.constant(value=x[0,:],dtype=tf.float32) 
   return f(x,y)

我設法用tensorflow編寫f函數(連續工作元素),雖然這可能是我的代碼中出現問題的原因(上面的解決方法似乎不自然)。

我還認為如果我能夠在上述嘗試中正確地寫出向量的元素和,我可以用keras Functional API以並行方式重復相同的過程,然后在softmax函數中插入每個並行模型的輸出,因為我需要。

我考慮的另一種方法是訓練參數保持其在網絡描述中看到的自然矩陣結構,也許寫一個矩陣Lambda層,但我找不到任何與這個想法相關的東西。

無論如何,我不確定在keras中使用這個模型的好方法是什么,也許我錯過了重要的一點,因為參數編寫的非標准方式或缺乏​​tensorflow的經驗。 歡迎任何建議。

對於這個答案,重要的是f是一個按元素運算的張量函數。 (沒有迭代)。 這很容易,只需檢查keras后端功能

假設:

  • x_pk集是常量,否則必須檢查此解決方案。
  • 函數f是元素(如果沒有,請顯示f以獲得更好的代碼)

您的模型需要x_pk作為張量輸入 您應該在功能API模型中執行此操作。

import keras.backend as K
from keras.layers import Input, Lambda, Activation
from keras.models import Model

#x_pk data
x_pk_numpy = select_X_pk_samples(x_train)
x_pk_tensor = K.variable(x_pk_numpy)

#number of rows in x_pk
m = len(x_pk_numpy)

#I suggest a fixed batch size for simplicity
batch = some_batch_size

首先讓我們處理將xx_pk調用f

def calculate_f(inputs): #inputs will be a list with x and x_pk
    x, x_pk = inputs

    #since f will work elementwise, let's replicate x and x_pk so they have equal shapes 
    #please explain f for better optimization

    # x from (batch, n) to (batch, m, n)
    x = K.stack([x]*m, axis=1)

    # x_pk from (m, n) to (batch, m, n)
    x_pk = K.stack([x_pk]*batch, axis=0)
        #a batch size of 1 could make this even simpler    
        #a variable batch size would make this more complicated
        #certain f functions could make this process unnecessary    

    return f(x, x_pk)

現在,與Dense圖層不同,此公式使用a_pk權重乘以元素。 所以我們需要一個自定義圖層:

class ElementwiseWeights(Layer):
    def __init__(self, **kwargs):
        super(ElementwiseWeights, self).__init__(**kwargs)

    def build(self, input_shape):
        weight_shape = (1,) + input_shape[1:] #shape (1, m, n)

        self.kernel = self.add_weight(name='kernel', 
                                  shape=weight_shape,
                                  initializer='uniform',
                                  trainable=True)

        super(ElementwiseWeights, self).build(input_shape)  

    def compute_output_shape(self,input_shape):
        return input_shape

    def call(self, inputs):
        return self.kernel * inputs

現在讓我們構建我們的功能API模型:

#x_pk model tensor input
x_pk = Input(tensor=x_pk_tensor) #shape (m, n)

#x usual input with fixed batch size
x = Input(batch_shape=(batch,n))  #shape (batch, n)

#calculate F
out = Lambda(calculate_f)([x, xp_k]) #shape (batch, m, n)

#multiply a_pk
out = ElementwiseWeights()(out) #shape (batch, m, n)

#sum n elements, keep m rows:
out = Lambda(lambda x: K.sum(x, axis=-1))(out) #shape (batch, m)

#softmax
out = Activation('softmax')(out) #shape (batch,m)

用你想要的任何東西繼續這個模型並完成它:

model = Model([x, x_pk], out)
model.compile(.....)
model.fit(x_train, y_train, ....) #perhaps you might need .fit([x_train], ytrain,...)

編輯功能f

您可以像這樣建議f

#create the n coefficients:
coefficients = np.array([c0, c1, .... , cn])
coefficients = coefficients.reshape((1,1,n))

def f(x, x_pk):

    c = K.variable(coefficients) #shape (1, 1, n)
    out = (x - x_pk) / c
    return K.exp(out)
  • 這個f將接受帶有形狀(batch, 1, n) x ,而不使用calculate_f函數中使用的stack
  • 或者可以接受x_pk的形狀(1, m, n) ,允許變量批量大小。

但我不確定是否可以將這兩種形狀結合在一起。 測試這可能很有趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM