Как решить проблему, заключающуюся в том, что объект `TypeError: 'Tensor' не поддерживает назначение элементов` в Keras - PullRequest
2 голосов
/ 21 марта 2019
from keras import backend as K
from keras.optimizers import Adam
from keras.models import Model
from keras.layers.core import Dense, Activation, Flatten
from keras.layers import Input,Concatenate
from keras.layers.normalization import BatchNormalization
from keras.layers import LSTM
class MyLoss(object):
    def __init__(self, classes, filter_outlier= True ):
        self.filter_outlier = filter_outlier
        self.classes = classes

    def getMyLoss(self, y_true, y_pred):
        # number of classes
        c = self.classes
        T = np.empty((c, c))
        # predict probability on the fresh sample
        eta_corr =self.output

        # Get Matrix T
        for i in np.arange(c):
            if not self.filter_outlier:
                idx_best = np.argmax(eta_corr[:, i])
            else:
                eta_thresh = np.percentile(eta_corr[:, i], 97,
                                           interpolation='higher')
                robust_eta = eta_corr[:, i]
                robust_eta[robust_eta >= eta_thresh] = 0.0
                idx_best = np.argmax(robust_eta)
            for j in np.arange(c):
                T[i, j] = eta_corr[idx_best, j]

        T_inv = K.constant(np.linalg.inv(T))
        y_pred /= K.sum(y_pred, axis=-1, keepdims=True)
        y_pred = K.clip(y_pred, K.epsilon(), 1.0 - K.epsilon())
        return -K.sum(K.dot(y_true, T_inv) * K.log(y_pred), axis=-1)


class MyModel(object):
    '''
    BiLstm 网络
    '''
    def __init__(self, config):
        self.max_len = config["max_len"]
        self.hidden_size = config["hidden_size"]
        self.vocab_size = config["vocab_size"]
        self.embedding_size = config["embedding_size"]
        self.n_class = config["n_class"]
        self.learning_rate = config["learning_rate"]

    def build_model(self,):
        print("building model")
        input = Input(shape = (self.max_len, self.embedding_size))
        rnn_outputs, forward_h, forward_c, backward_h, backward_c = \
        Bidirectional(LSTM(self.hidden_size, return_sequences = True, 
                           return_state = True))(input)

        h_total = Concatenate()([forward_h, backward_h])

        # Fully connected layer(dense layer)
        output = Dense(self.n_class, kernel_initializer = 'he_normal')(h_total)

        # Add softmax
        output = Activation('softmax')(output)

        model = Model(inputs = input, outputs = output)        
        # My own Loss Function
        loss_fn = MyLoss(classes = self.n_class)
        self.loss = loss_fn.getLoss
        model.compile(loss = self.loss, optimizer = Adam(
            lr = self.learning_rate))

Ошибка:

---> 37                 robust_eta[robust_eta >= eta_thresh] = 0.0
TypeError: 'Tensor' object does not support item assignment

Теперь я не знаю, как преобразовать numpy dtype в тензор при присваивании значений.

1 Ответ

1 голос
/ 21 марта 2019

Это выражение недопустимо для тензоров:

robust_eta[robust_eta >= eta_thresh] = 0.0

Во-первых, этот причудливый синтаксис индексации не поддерживается для тензоров. Во-вторых, тензорные объекты доступны только для чтения. Если вы хотите читать и писать, вы должны использовать tf.Variable.

Но в этом случае практичнее создать еще один Тензор. Эквивалент TensorFlow этого кода будет:

robust_eta = tf.where(tf.greater(robust_eta, eta_thresh), tf.zeros_like(robust_eta), robust_eta)

Тем не менее, это не поможет вам в написании функции рабочих потерь, как в следующей строке:

np.argmax(robust_eta)

Не сможет ожидать ndarray. У вас есть смесь кода Numpy и TensorFlow. Вам нужно придерживаться либо Tensors, либо NumPy-массивов. Я думаю, что самым простым способом было бы получить значение eta_corr в виде массива NumPy в начале:

eta_corr = K.eval(self.output)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...