【问题标题】:Tensorflow: either input labels or feature vector seem to be in wrong shapeTensorflow:输入标签或特征向量似乎形状错误
【发布时间】:2020-09-15 13:46:44
【问题描述】:

我目前正在开始使用 TensorFlow 2.0,我刚刚阅读了有关估算器类的信息。

我创建了一个简单的 XOR 生成器,它为我提供了 2D 坐标(numpy 数组)和一个标签。

数据正确标准化,一切正常,直到第 40 行,此时我收到以下错误:

ValueError: 无法用 2 个元素重塑张量以形成 [2,2] (4 元素)对于'{{节点 dnn/input_from_feature_columns/input_layer/X_1/Reshape}} = 重塑[T=DT_FLOAT, Tshape=DT_INT32](dnn/input_from_feature_columns/input_layer/X_1/ExpandDims, dnn/input_from_feature_columns/input_layer/X_1/Reshape/shape)' 与 输入形状:[2,1]、[2],输入张量计算为部分 形状:输入[1] = [2,2]。

这对我来说没有意义,因为我检查了我的输入形状,它确实是指定的 (2,) 并且标签是一个标量张量:

({'X': <tf.Tensor: shape=(2,), dtype=float64, numpy=array([ 0.2885114 , -0.77485602])>}, <tf.Tensor: shape=(), dtype=float64, numpy=0.0>)

代码如下:

import tensorflow as tf
import XorGenerator as XOR
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import StandardScaler as SC

@tf.function
def trainingData(X, y, batchSize=1):
    y = tf.cast(y, tf.uint8)
    y = tf.one_hot(y, depth=2, on_value=1, off_value=0)
    dataset = tf.data.Dataset.from_tensor_slices(({'data' : X}, y))
    #dataset.batch(batchSize)

    return dataset.repeat()

def main():
    X, y = XOR.XOR(400)     # X: float 2D-coordinates, y: class labels (-1 and 1)

    y = np.where(y == -1, np.zeros(shape=y.shape), y)   # labels from (-1 and 1) to (0 and 1)

    sc = SC(with_mean=True, with_std=True)
    X = sc.fit_transform(X)

    BATCH_SIZE = 1
    EPOCHS = 10
    N_SAMPLES = 400

    inputFeatureColumns = [tf.feature_column.numeric_column(key='data', shape=(2))]

    estimator = tf.estimator.DNNClassifier(hidden_units=[32, 16], feature_columns=inputFeatureColumns, n_classes=2, 
                                            activation_fn=tf.nn.sigmoid, optimizer='SGD')
    estimator.train(input_fn=lambda: trainingData(X, y, BATCH_SIZE), steps=EPOCHS * N_SAMPLES / BATCH_SIZE)    

if __name__ == "__main__":
    main()

异或生成器:

import numpy as np
import matplotlib.pyplot as plt

def sign(x):
    return 1 if x > 0 else -1

def XOR(nSamples):
    resX = [np.random.random(size=2) * 2 - 1 for _ in range(nSamples)]
    resY = [np.random.random(size=2) * 2 - 1 for _ in range(nSamples)]

    for x in range(nSamples):
        resY[x] = sign(resX[x][0] * resX[x][1])

    return np.array(resX), np.array(resY)

【问题讨论】:

    标签: python tensorflow machine-learning


    【解决方案1】:

    模型的输出形状为2,为n_classes=2,您的标签为1,形状为&lt;tf.Tensor: shape=(), dtype=float64, numpy=0.0&gt;。在计算损失时,您需要减去这两个向量,因为它们具有不同的形状,所以您不能这样做。您应该使用tf.one_hot将您的标签转换为一种热编码

    编辑: 试试这个:

    import tensorflow as tf
    import matplotlib.pyplot as plt
    import numpy as np
    from sklearn.preprocessing import StandardScaler as SC
    
    @tf.function
    def trainingData(X0, X1, y, batchSize=1):
        dataset = tf.data.Dataset.from_tensor_slices(({'data0' : X0, 'data1':X1}, y))
        return dataset.repeat()
    
    def main():
        X, y = np.asarray([[1.0,2.5] for i in range(200)]), np.asarray([1 for i in range(200)])
        y = np.expand_dims(np.asarray(np.where(y == -1, np.zeros(shape=y.shape), y)),1)  
        sc = SC(with_mean=True, with_std=True)
        X = sc.fit_transform(X)
        BATCH_SIZE = 1
        EPOCHS = 10
        N_SAMPLES = 400
    
        inputFeatureColumns = [tf.feature_column.numeric_column(key='data0', shape=(1,)), tf.feature_column.numeric_column(key='data1', shape=(1,))]
    
        estimator = tf.estimator.DNNClassifier(hidden_units=[32, 16], feature_columns=inputFeatureColumns, n_classes=2, 
                                                activation_fn=tf.nn.sigmoid, optimizer='SGD')
        estimator.train(input_fn=lambda: trainingData(np.expand_dims(X[:,0],1),np.expand_dims(X[:,1],1), y, BATCH_SIZE), steps=EPOCHS * N_SAMPLES / BATCH_SIZE)    
    
    if __name__ == "__main__":
        main()
    

    我无法安装XorGenerator,所以您仍然需要更改一些内容。它运行,但我不确定它是否符合您的要求。

    【讨论】:

    • 尽管你的解释看起来完全合乎逻辑,但不幸的是我仍然遇到同样的错误。
    • 嗯。你能更新你的代码吗? tensorflow.org/api_docs/python/tf/estimator/Estimator#train 表示您可以只提供Dataset 对象,无需将其包装在lambda 中。删除lambda 有帮助吗?
    • 我实际上什么也没做,只是用 depth=2 将 y 编码为 one-hot。
    • 我需要将 tensorflow.function 装饰器添加到我的 trainingData(X, y, batchSize) 函数中,但现在我得到一个不同的错误:“没有找到方向的一元变体设备复制函数:1 和变体 type_index:类 tensorflow::data::`匿名命名空间'::DatasetVariantWrapper"。我想,我应该将更改恢复为 lambda 实现。
    • 刚刚更新了代码,简化了一点。还是一样。
    猜你喜欢
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 2018-05-28
    • 2015-12-31
    • 2013-12-18
    • 2020-04-29
    相关资源
    最近更新 更多