Tensorflow:logits 和 labels 必须具有相同的第一维度
Tensorflow : logits and labels must have the same first dimension
我是 tensoflow 的新手,我想用我自己的数据(40x40 的图像)改编 MNIST 教程 https://www.tensorflow.org/tutorials/layers。
这是我的模型函数:
def cnn_model_fn(features, labels, mode):
# Input Layer
input_layer = tf.reshape(features, [-1, 40, 40, 1])
# Convolutional Layer #1
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=32,
kernel_size=[5, 5],
# To specify that the output tensor should have the same width and height values as the input tensor
# value can be "same" ou "valid"
padding="same",
activation=tf.nn.relu)
# Pooling Layer #1
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
# Convolutional Layer #2 and Pooling Layer #2
conv2 = tf.layers.conv2d(
inputs=pool1,
filters=64,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
# Dense Layer
pool2_flat = tf.reshape(pool2, [-1, 10 * 10 * 64])
dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
dropout = tf.layers.dropout(
inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
# Logits Layer
logits = tf.layers.dense(inputs=dropout, units=2)
predictions = {
# Generate predictions (for PREDICT and EVAL mode)
"classes": tf.argmax(input=logits, axis=1),
# Add `softmax_tensor` to the graph. It is used for PREDICT and by the
# `logging_hook`.
"probabilities": tf.nn.softmax(logits, name="softmax_tensor")
}
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
# Calculate Loss (for both TRAIN and EVAL modes)
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
# Configure the Training Op (for TRAIN mode)
if mode == tf.estimator.ModeKeys.TRAIN:
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(
loss=loss,
global_step=tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)
# Add evaluation metrics (for EVAL mode)
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(
labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(
mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
标签和 logits 之间存在形状大小错误:
InvalidArgumentError(回溯见上):logits 和 labels 必须具有相同的第一维,得到 logits shape [3,2] 和 labels shape [1]
filenames_array是16个字符串的数组
["file1.png", "file2.png", "file3.png", ...]
和labels_array是一个16位整数的数组
[0,0,1,1,0,1,0,0,0,...]
主要功能是:
# Create the Estimator
mnist_classifier = tf.estimator.Estimator(model_fn=cnn_model_fn, model_dir="/tmp/test_convnet_model")
# Train the model
cust_train_input_fn = lambda: train_input_fn_custom(
filenames_array=filenames, labels_array=labels, batch_size=1)
mnist_classifier.train(
input_fn=cust_train_input_fn,
steps=20000,
hooks=[logging_hook])
我尝试重塑 logits 但没有成功:
logits = tf.reshape(logits, [1, 2])
我需要你的帮助,谢谢
编辑
经过更多的时间搜索,在我的模型函数的第一行
input_layer = tf.reshape(features, [-1, 40, 40, 1])
表示batch_size维度将被动态计算的“-1”在这里的值为“3”。与我的错误中相同的“3”:logits 和标签必须具有相同的第一维,得到 logits 形状 [3,2] 和标签形状 [1]
如果我将值强制设置为“1”,则会出现此新错误:
reshape 的输入是一个有 4800 个值的张量,但请求的形状有 1600 个
可能是我的功能有问题?
编辑2:
完整代码在这里:https://gist.github.com/geoffreyp/cc8e97aab1bff4d39e10001118c6322e
EDIT3
我用
更新了要点
logits = tf.layers.dense(inputs=dropout, units=1)
https://gist.github.com/geoffreyp/cc8e97aab1bff4d39e10001118c6322e
但是我不完全理解你关于批处理大小的回答,这里的批处理大小怎么可以是 3 而我选择的批处理大小是 1 ?
如果我选择 batch_size = 3 我有这个错误:
logits 和 labels 必须具有相同的第一维,得到 logits shape [9,1] 和 labels shape [3]
我尝试重塑标签:
labels = tf.reshape(labels, [3, 1])
我更新了特征和标签结构:
filenames_train = [['blackcorner-data/1.png', 'blackcorner-data/2.png', 'blackcorner-data/3.png',
'blackcorner-data/4.png', 'blackcorner-data/n1.png'],
['blackcorner-data/n2.png',
'blackcorner-data/n3.png', 'blackcorner-data/n4.png',
'blackcorner-data/11.png', 'blackcorner-data/21.png'],
['blackcorner-data/31.png',
'blackcorner-data/41.png', 'blackcorner-data/n11.png', 'blackcorner-data/n21.png',
'blackcorner-data/n31.png']
]
labels = [[0, 0, 0, 0, 1], [1, 1, 1, 0, 0], [0, 0, 1, 1, 1]]
但没有成功...
您的 logits 形状看起来正确,批量大小为 3,输出层大小为 2,这就是您定义的输出层。您的标签也应该是 [3, 2] 形状。 3 批次,每批次有 2 [1,0] 或 [0,1].
另请注意,当您有一个布尔分类输出时,您不应该在 output/logits 层上有 2 个神经元。您可以只输出一个取 0 或 1 的值,您可能会看到 [1,0] 和 [0,1] 的 2 个输出是多余的,可以表示为一个简单的 [0|1] 值。此外,当您这样做时,您往往会获得更好的结果。
因此,您的 logits 最终应该是 [3,1],您的标签应该是一个包含 3 个值的数组,一个对应于您批次中的每个样本。
我遇到了类似的问题,结果是一个池化层没有正确重塑。在我的案例中,我错误地使用了 tf.reshape(pool, shape=[-1, 64 * 7 * 7])
而不是 tf.reshape(pool, shape=[-1, 64 * 14 * 14])
,这导致了关于 logits 和标签的类似错误消息。改变因素,例如tf.reshape(pool, shape=[-1, 64 * 12 * 12])
导致完全不同、误导性更小的错误消息。
或许这里也是如此。我建议通过代码检查节点的形状,以防万一。
我解决了它,从 sparse_categorical_crossentropy
更改为 categorical_crossentropy
,现在 运行 没问题。
我第一次使用 tensorflow 时就遇到了这个问题,我发现我的问题是忘记将属性 class_mode='sparse'
/ class_mode='binary'
添加到上传训练数据和验证的函数中数据:
所以尽量照顾 class_mode 选项
image_gen_val = ImageDataGenerator(rescale=1./255)
val_data_gen = image_gen_val.flow_from_directory(batch_size=batch_size,
directory=val_dir,
target_size=(IMG_SHAPE, IMG_SHAPE),
class_mode='sparse')
问题出在你的目标形状上,与正确选择合适的损失函数有关。你有 2 种可能性:
1.可能性:如果你有一维整数编码目标,你可以使用sparse_categorical_crossentropy
作为损失函数
n_class = 3
n_features = 100
n_sample = 1000
X = np.random.randint(0,10, (n_sample,n_features))
y = np.random.randint(0,n_class, n_sample)
inp = Input((n_features,))
x = Dense(128, activation='relu')(inp)
out = Dense(n_class, activation='softmax')(x)
model = Model(inp, out)
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(X, y, epochs=3)
2。可能性:如果您对目标进行单热编码以获得二维形状(n_samples、n_class),您可以使用categorical_crossentropy
n_class = 3
n_features = 100
n_sample = 1000
X = np.random.randint(0,10, (n_sample,n_features))
y = pd.get_dummies(np.random.randint(0,n_class, n_sample)).values
inp = Input((n_features,))
x = Dense(128, activation='relu')(inp)
out = Dense(n_class, activation='softmax')(x)
model = Model(inp, out)
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(X, y, epochs=3)
我遇到过类似的问题,发现我错过了 CNN 和 Dense 层之间的展平层。添加展平层为我解决了这个问题。
我是 tensoflow 的新手,我想用我自己的数据(40x40 的图像)改编 MNIST 教程 https://www.tensorflow.org/tutorials/layers。 这是我的模型函数:
def cnn_model_fn(features, labels, mode):
# Input Layer
input_layer = tf.reshape(features, [-1, 40, 40, 1])
# Convolutional Layer #1
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=32,
kernel_size=[5, 5],
# To specify that the output tensor should have the same width and height values as the input tensor
# value can be "same" ou "valid"
padding="same",
activation=tf.nn.relu)
# Pooling Layer #1
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
# Convolutional Layer #2 and Pooling Layer #2
conv2 = tf.layers.conv2d(
inputs=pool1,
filters=64,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
# Dense Layer
pool2_flat = tf.reshape(pool2, [-1, 10 * 10 * 64])
dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
dropout = tf.layers.dropout(
inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
# Logits Layer
logits = tf.layers.dense(inputs=dropout, units=2)
predictions = {
# Generate predictions (for PREDICT and EVAL mode)
"classes": tf.argmax(input=logits, axis=1),
# Add `softmax_tensor` to the graph. It is used for PREDICT and by the
# `logging_hook`.
"probabilities": tf.nn.softmax(logits, name="softmax_tensor")
}
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
# Calculate Loss (for both TRAIN and EVAL modes)
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
# Configure the Training Op (for TRAIN mode)
if mode == tf.estimator.ModeKeys.TRAIN:
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(
loss=loss,
global_step=tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)
# Add evaluation metrics (for EVAL mode)
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(
labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(
mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
标签和 logits 之间存在形状大小错误:
InvalidArgumentError(回溯见上):logits 和 labels 必须具有相同的第一维,得到 logits shape [3,2] 和 labels shape [1]
filenames_array是16个字符串的数组
["file1.png", "file2.png", "file3.png", ...]
和labels_array是一个16位整数的数组
[0,0,1,1,0,1,0,0,0,...]
主要功能是:
# Create the Estimator
mnist_classifier = tf.estimator.Estimator(model_fn=cnn_model_fn, model_dir="/tmp/test_convnet_model")
# Train the model
cust_train_input_fn = lambda: train_input_fn_custom(
filenames_array=filenames, labels_array=labels, batch_size=1)
mnist_classifier.train(
input_fn=cust_train_input_fn,
steps=20000,
hooks=[logging_hook])
我尝试重塑 logits 但没有成功:
logits = tf.reshape(logits, [1, 2])
我需要你的帮助,谢谢
编辑
经过更多的时间搜索,在我的模型函数的第一行
input_layer = tf.reshape(features, [-1, 40, 40, 1])
表示batch_size维度将被动态计算的“-1”在这里的值为“3”。与我的错误中相同的“3”:logits 和标签必须具有相同的第一维,得到 logits 形状 [3,2] 和标签形状 [1]
如果我将值强制设置为“1”,则会出现此新错误:
reshape 的输入是一个有 4800 个值的张量,但请求的形状有 1600 个
可能是我的功能有问题?
编辑2:
完整代码在这里:https://gist.github.com/geoffreyp/cc8e97aab1bff4d39e10001118c6322e
EDIT3
我用
更新了要点logits = tf.layers.dense(inputs=dropout, units=1)
https://gist.github.com/geoffreyp/cc8e97aab1bff4d39e10001118c6322e
但是我不完全理解你关于批处理大小的回答,这里的批处理大小怎么可以是 3 而我选择的批处理大小是 1 ?
如果我选择 batch_size = 3 我有这个错误: logits 和 labels 必须具有相同的第一维,得到 logits shape [9,1] 和 labels shape [3]
我尝试重塑标签:
labels = tf.reshape(labels, [3, 1])
我更新了特征和标签结构:
filenames_train = [['blackcorner-data/1.png', 'blackcorner-data/2.png', 'blackcorner-data/3.png',
'blackcorner-data/4.png', 'blackcorner-data/n1.png'],
['blackcorner-data/n2.png',
'blackcorner-data/n3.png', 'blackcorner-data/n4.png',
'blackcorner-data/11.png', 'blackcorner-data/21.png'],
['blackcorner-data/31.png',
'blackcorner-data/41.png', 'blackcorner-data/n11.png', 'blackcorner-data/n21.png',
'blackcorner-data/n31.png']
]
labels = [[0, 0, 0, 0, 1], [1, 1, 1, 0, 0], [0, 0, 1, 1, 1]]
但没有成功...
您的 logits 形状看起来正确,批量大小为 3,输出层大小为 2,这就是您定义的输出层。您的标签也应该是 [3, 2] 形状。 3 批次,每批次有 2 [1,0] 或 [0,1].
另请注意,当您有一个布尔分类输出时,您不应该在 output/logits 层上有 2 个神经元。您可以只输出一个取 0 或 1 的值,您可能会看到 [1,0] 和 [0,1] 的 2 个输出是多余的,可以表示为一个简单的 [0|1] 值。此外,当您这样做时,您往往会获得更好的结果。
因此,您的 logits 最终应该是 [3,1],您的标签应该是一个包含 3 个值的数组,一个对应于您批次中的每个样本。
我遇到了类似的问题,结果是一个池化层没有正确重塑。在我的案例中,我错误地使用了 tf.reshape(pool, shape=[-1, 64 * 7 * 7])
而不是 tf.reshape(pool, shape=[-1, 64 * 14 * 14])
,这导致了关于 logits 和标签的类似错误消息。改变因素,例如tf.reshape(pool, shape=[-1, 64 * 12 * 12])
导致完全不同、误导性更小的错误消息。
或许这里也是如此。我建议通过代码检查节点的形状,以防万一。
我解决了它,从 sparse_categorical_crossentropy
更改为 categorical_crossentropy
,现在 运行 没问题。
我第一次使用 tensorflow 时就遇到了这个问题,我发现我的问题是忘记将属性 class_mode='sparse'
/ class_mode='binary'
添加到上传训练数据和验证的函数中数据:
所以尽量照顾 class_mode 选项
image_gen_val = ImageDataGenerator(rescale=1./255)
val_data_gen = image_gen_val.flow_from_directory(batch_size=batch_size,
directory=val_dir,
target_size=(IMG_SHAPE, IMG_SHAPE),
class_mode='sparse')
问题出在你的目标形状上,与正确选择合适的损失函数有关。你有 2 种可能性:
1.可能性:如果你有一维整数编码目标,你可以使用sparse_categorical_crossentropy
作为损失函数
n_class = 3
n_features = 100
n_sample = 1000
X = np.random.randint(0,10, (n_sample,n_features))
y = np.random.randint(0,n_class, n_sample)
inp = Input((n_features,))
x = Dense(128, activation='relu')(inp)
out = Dense(n_class, activation='softmax')(x)
model = Model(inp, out)
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(X, y, epochs=3)
2。可能性:如果您对目标进行单热编码以获得二维形状(n_samples、n_class),您可以使用categorical_crossentropy
n_class = 3
n_features = 100
n_sample = 1000
X = np.random.randint(0,10, (n_sample,n_features))
y = pd.get_dummies(np.random.randint(0,n_class, n_sample)).values
inp = Input((n_features,))
x = Dense(128, activation='relu')(inp)
out = Dense(n_class, activation='softmax')(x)
model = Model(inp, out)
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(X, y, epochs=3)
我遇到过类似的问题,发现我错过了 CNN 和 Dense 层之间的展平层。添加展平层为我解决了这个问题。