剪切Theano的3-d张量

时间:2016-07-16 05:01:57

标签: python theano keras

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

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

但是由于某种原因,我将y_train中的第一个k元素替换为0。所以,例如,新的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)

1 个答案:

答案 0 :(得分:0)

来自第35行中错误的paranthesis和最后一行中错误的变量名称之类的小错误,您的代码存在两个问题。

首先,您定义的模型将返回每个时间步的类的概率分布矩阵(由于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没有长度,因为在插入实际值之前根本就不知道!这也使迭代成为你实现它的方式不可能。 顺便说一句,如果你迭代真正的向量,你可能想要这样做:#{1}}向后迭代,不要越界,甚至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 标记。不过,这可以在输入端工作。