Keras TypeError:预期为float32,而<tf.Tensor ..>的类型为'Tensor'

时间:2020-06-07 11:32:23

标签: python numpy keras deep-learning

我有一个Keras模型,给我错误

TypeError: Expected float32, got <tf.Tensor 'recommender_dnn_25/strided_slice_5:0' shape=(None, 1) dtype=float32> of type 'Tensor' instead.

对于我的keras模型,我正在发送类型为numpy.ndarray的训练/验证数据。这来自movielens数据集,值分别为movie_iduser_idzip_codeagegender。下面的示例行:

x_train[0]
array(['195', '241', 415, 3, 1], dtype=object)

前两个输入连同模型训练过程一起被训练为嵌入。在合并所有五个功能之前,最后三个(邮政编码,年龄,性别)经过以下转换。

  1. 转换为浮动
  2. 重塑为(None,1)
  3. 使用zip_code = K.constant(zip_code)转换为张量,如果没有此步骤,我将看到错误ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type int)

现在,当我运行此模型时-我收到错误TypeError: Expected float32, got <tf.Tensor 'recommender_dnn_25/strided_slice_5:0' shape=(None, 1) dtype=float32> of type 'Tensor' instead.

错误zip_code = K.constant(zip_code)甚至在进入连接阶段之前就发生了。

以下型号代码:

x_train.shape
(90000, 5)

EMBEDDING_SIZE = 50
NUM_USERS =movielens['user_id'].nunique()
NUM_MOVIES = movielens['movie_id'].nunique()

class RecommenderDNN(keras.Model):
    def __init__(self, num_users, num_movies, embedding_size, **kwargs):
        super(RecommenderDNN, self).__init__(**kwargs)
        self.num_users = num_users
        self.num_movies = num_movies
        self.embedding_size = embedding_size
        self.user_embedding = layers.Embedding(
            num_users,
            embedding_size,
            embeddings_initializer="he_normal",
            embeddings_regularizer=keras.regularizers.l2(1e-6),
        )
        self.movie_embedding = layers.Embedding(
            num_movies,
            embedding_size,
            embeddings_initializer="he_normal",
            embeddings_regularizer=keras.regularizers.l2(1e-6),
        )


    def call(self, inputs):
        user_vector = self.user_embedding(inputs[:, 0])

        movie_vector = self.movie_embedding(inputs[:, 1])

        zip_code = float(inputs[:, 2])
        age = float(inputs[:, 3])
        gender = float(inputs[:,4])

        zip_code = zip_code[: ,None]
        age = age[: ,None]
        gender = gender[: ,None]

        zip_code = K.constant(zip_code)
        age = K.constant(age)
        gender = K.constant(gender)


        print(user_vector.shape)
        print(movie_vector.shape)
        print(zip_code.shape)
        print(age.shape)
        print(gender.shape)


        concat = layers.concatenate([user_vector, movie_vector, zip_code, age, gender], axis=1)
        concat_dropout = layers.Dropout(0.2)(concat)
        # rest of the layers ...
        result = layers.Dense(1, activation='softmax',name='Activation')(dense_4)
        return result


model = RecommenderDNN(NUM_USERS, NUM_MOVIES, EMBEDDING_SIZE)
model.compile(
    loss=keras.losses.BinaryCrossentropy(), optimizer=keras.optimizers.Adam(lr=0.001)
)

请提出建议。

1 个答案:

答案 0 :(得分:0)

我正在做的事情有一些根本性的问题。我正在将嵌入层与分类输入连接在一起。嵌入层输出3D张量(尽管打印出.shape仅显示2D,但不确定原因)。尽管没有其他任何层,但将其与输入类别组合而不通过类别却没有任何意义。因此,我flattened嵌入层的输出将输入分类并通过Dense层进行分类,然后再将它们串联。

为简单起见,假设我们有2个功能-user_idage。我们希望通过训练过程为user_id生成嵌入。 age是在LabelEncoding之后作为模型输入传递的分类变量。

以下解决问题的代码:

row_count = train.shape[0]
EMBEDDING_SIZE = 50
NUM_USERS = movielens['user_id'].nunique()

user_input = keras.Input(shape=(1,), name='user')
age_input = keras.Input(shape=(1,), name='age')
user_emb = layers.Embedding(output_dim=EMBEDDING_SIZE, input_dim=NUM_USERS+1, input_length=row_count, name='user_emb')(user_input)
user_vec = layers.Flatten(name='FlattenUser')(user_emb)
dense_1 = layers.Dense(20, activation='relu')(age_input)
concat = layers.concatenate([user_vec, dense_1], axis=1)
dense = layers.Dense(10,name='FullyConnected')(concat)
outputs = layers.Dense(10, activation="softmax") (dense)
adam = keras.optimizers.Adam(lr=0.005)
model = keras.Model([user_input, age_input], outputs)
model.compile(optimizer=adam,loss= 'mean_absolute_error')