Slice 3-d tensor of Theano



我正在使用Keras(Theano后端)构建一个基于chacter的rnn模型。需要注意的一件事是,我不想使用预构建的损失函数。相反,我想计算某些数据点的损失。这就是我的意思。

矢量训练集及其标签如下所示:X_train = np.array([[0,1,2,3,4]])y_train = np.array([[1,2,3,4,5]])

但是出于某种原因,我用 0 替换了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)

从小错误(例如第 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函数。默认情况下,这将返回此最小值的第一次出现。由于你想找到这个最小值的最后一次出现,我们需要将其应用于反向张量,并将其计算回原始向量的索引。

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

可能有一个更简单的解决方案来解决您的问题,因为看起来您正在尝试实现诸如屏蔽之类的东西。您可能需要查看嵌入层的mask_zero=True标志。不过,这将适用于输入端。

相关内容

  • 没有找到相关文章

最新更新