tf.data.Dataset中的SparseTensors,错误的输入形状或不同的嵌套结构

时间:2020-06-03 19:54:36

标签: python keras tensorflow2.0

我正在尝试使用tf.SparseTensor作为Keras模型的输入。数据特征是包含零和几的形状[20 20]稀疏数组。标签是形状[2]的二进制类别。

功能
[[0 0 0 ... 1 0 0]
[0 1 0 ... 0 0 0]
...
[0 1 0 ... 0 0 0]]

和标签
[0 1]

如果我使用numpy数组作为输入(X,y),则model.fit()可以正常工作。但是,如果我尝试使用包含SparseTensor(数据集)的数据集,那么我似乎无法正确地馈送其形状正确的数据。

我收到以下错误:ValueError:这两个结构没有相同的嵌套结构。更具体地说:子结构“ type = SparseTensorSpec str = SparseTensorSpec(TensorShape([20,20]),tf.int64)”是一个序列,而子结构“ type = Tensor str = Tensor(“ conv1d_input:0”,shape =(None ,20,20),dtype = float32)“不是

也尝试创建Dataset.from_tensor_slices,但出现ValueError:尺寸20和5不兼容

任何帮助将不胜感激。

编辑1 因此,我能够通过将每个SparseTensor转换为_dense,然后使用tf.stack对其进行堆叠来完成这项工作,但是这种做法违反了使用SparseTensor的目的。 tf.stack不会将SparseTensor用作输入,仅将Tensor用作输入。也许我需要以某种方式用SparseTensor格式表示整个数据集。

import tensorflow as tf
import numpy as np
import os

os.environ["KERAS_BACKEND"] = "plaidml.keras.backend"
verbose, epochs, batch_size = 0, 10, 32
n_timesteps, n_features, n_outputs = 20, 20, 2

# not working
def create_tensor_data():
    X = []
    y = []
    for i in range(5):
        rand = np.random.randint(n_timesteps, size=(5, 2))
        v = np.ones(5, dtype=int)
        tensor = tf.SparseTensor(indices=rand, values=v, dense_shape=[n_timesteps, n_timesteps])
        tensor = tf.sparse.reorder(tensor)
        #tensor = tf.sparse.to_dense(tensor) # Edit 1 to_dense
        X.append(tensor)
        y.append(i % 2)
    y = tf.keras.utils.to_categorical(y)
    return X, y

# working input
def create_numpy_data():
    X = []
    y = []
    for i in range(5):
        rand = np.random.randint(n_timesteps, size=(5, 2))
        graph = np.zeros((n_timesteps, n_timesteps))
        for xy in rand:
            graph[xy[0], xy[1]] = 1
        X.append(graph)
        y.append(i % 2)

    X = np.asarray(X)
    y = tf.keras.utils.to_categorical(y)
    return X, y

# not working
tX, ty = create_tensor_data()
tX = tuple(tX) # edit 1 comment this
#tX = tf.stack(tX) # edit 1 use this instead
dataset = tf.data.Dataset.from_tensors((tX,ty))

# working input
X, y = create_numpy_data()

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(n_timesteps, n_features)))
model.add(tf.keras.layers.Conv1D(filters=64, kernel_size=3, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.MaxPooling1D(pool_size=2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(100, activation='relu'))
model.add(tf.keras.layers.Dense(n_outputs, activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(dataset, epochs=epochs, verbose=verbose) #model.fit(X, y ...)


predictions = model.predict(X)
print("Predictions")
print(predictions)

0 个答案:

没有答案