2016-07-16 47 views
0

我正在建立一個使用Keras(Theano後端)的基於chacter的rnn模型。有一點要注意的是我不想使用預先構建的丟失函數。相反,我想計算一些數據點的損失。這是我的意思。Theano的切片三維張量

Vectoried訓練集和其標籤看起來像這樣: X_train = np.array([[0,1,2,3,4]]) y_train = np.array([[1,2,3, 4,5]])

但我用y替換了y_train中的第一個k元素,出於某種原因。因此,舉例來說,新y_train是

y_train = np.array([[0,0,3,4,5]])

爲什麼前兩個元素設置爲0的原因是我不在計算丟失時不想包含它們。換句話說,我想計算X_train [2:]和y_train [2:]之間的損失。

這是我的嘗試。

import numpy as np 
np.random.seed(0) # for reproducibility 

from keras.preprocessing import sequence 
from keras.utils import np_utils 
from keras.models import Sequential 
from keras.layers import Dense, Dropout, Activation, Embedding 
from keras.layers import LSTM 
from keras.layers.wrappers import TimeDistributed 

X_train = np.array([[0,1,2,3,4]]) 
y_train = np.array([[0,0,3,4,5]]) 

y_3d = np.zeros((y_train.shape[0], y_train.shape[1], 6)) 
for i in range(y_train.shape[0]): 
    for j in range(y_train.shape[1]): 
     y_3d[i, j, y_train[i,j]] = 1 

model = Sequential() 
model.add(Embedding(6, 5, input_length=5, dropout=0.2)) 
model.add(LSTM(5, input_shape=(5, 12), return_sequences=True) ) 

model.add(TimeDistributed(Dense(6))) #output classes =6 
model.add(Activation('softmax')) 

from keras import backend as K 
import theano.tensor as T 
def custom_objective(y_true,y_pred): 
    # Find the last index of minimum value in y_true, axis=-1 
    # For example, y_train = np.array([[0,0,3,4,5]]) in my example, and 
    # I'd like to calculate the loss only between X_train[3:] and  y_train[3:] because the values 
    # in y_train[:3] (i.e.0) are dummies. The following is pseudo code if y_true is 1-d numpy array, which is not true. 
    def rindex(y_true): 
     for i in range(len(y_true), -1, -1): 
      if y_true(i) == 0: 
       return i 
    starting_point = rindex(y_true) 
    return K.categorical_crossentropy(y_pred[starting_point:], y_true[starting_point:]) 


model.compile(loss=custom_objective, 
       optimizer='adam', 
       metrics=['accuracy']) 

model.fit(X_train, y_t, batch_size=batch_size, nb_epoch=1) 
+0

你能解釋一下你的問題嗎? – malioboro

+0

函數「custom_objective」不起作用。 – user1610952

回答

0

Appart從小錯誤(如第35行錯誤的錯誤和最後一行錯誤的變量名稱)中,您的代碼有兩個問題。

首先,您定義的模型將返回每個時間步的類的概率分佈矩陣(由於softmax激活)。 但在custom_objective中,您將輸出視爲向量。您已經正確地將y_train轉換爲上面的矩陣。

所以,你必須先得到實際的預測,最簡單的情況是具有最高概率分配類,即:

y_pred = y_pred.argmax(axis=2) 
y_true = y_true.argmax(axis=2) # this reconstructs y_train resp. a subset thereof 

的第二個問題是,你喜歡真正變量處理這些(numpy數組)。 然而,y_truey_pred是符號張量。你得到明確的錯誤陳述所導致的問題之一:

TypeError: object of type 'TensorVariable' has no len() 

TensorVariable■找不長,因爲它插入實際值之前簡直是不知道!這也使得迭代的方式不可能實現。 順便說一句,在你迭代真正載體的情況下,你可能會想這樣做向後迭代這樣的:range(len(y_true)-1, -1, -1)不去出界,甚至for val in y_true[::-1]

達到你想要什麼,你需要把相應的如變量一樣,並使用爲張量提供的方法。

這個計算的中心是找到最小值的argmin函數。默認情況下,這將返回此最小值的第一個匹配項。 由於您想查找最小值的最後一次出現,我們需要將其應用於反轉張量並將其計算回origianl向量的索引。

starting_point = y_true.shape[0] - y_true[::-1].argmin() - 1 

可能,有可能,因爲它看起來像你想實現像屏蔽是一個更簡單的解決您的問題。 您可能需要查看嵌入圖層的mask_zero=True標誌。不過,這將在輸入端工作。