Con*_*son 7 python machine-learning keras tensorflow
我正在尝试制作一个简单的 CNN 分类器模型。对于我的训练图像 (BATCH_SIZEx227x227x1) 和标签 (BATCH_SIZEx7) 数据集,我使用的是通过ImageDataGenerator. 我使用的损失函数是 tf.nn.sparse_categorical_crossentropy。当模型试图训练时,问题就出现了;模型(这里的批量大小为 1,用于我的简化实验)输出形状为 [1, 7],标签为形状 [7]。
我几乎可以肯定我知道原因,但我不确定如何解决它。我的假设是 sparse_categorical_crossentropy 正在压缩我的标签的维度(例如,当 BATCH_SIZE 为 2 时,输入的真实标签形状从 [2, 7] 压缩到 [14]),使我无法修复标签形状,而我所有修复 logits 形状的尝试都没有结果。
我最初尝试使用np.expand_dims. 但是无论我如何扩展维度,损失函数总是会使标签变平。
之后,我尝试tf.keras.layers.Flatten()在模型末尾添加 a以摆脱无关的第一维,但没有效果;我仍然遇到相同的确切错误。之后,尝试使用tf.keras.layers.Reshape((-1,))挤压所有尺寸。但是,这导致了不同的错误:
在 sparse_categorical_crossentropy logits = array_ops.reshape(output, [-1, int(output_shape[-1])]) TypeError: int返回非 int (type NoneType)
问题:如何将 logits 的形状压缩为与 sparse_categorical_crossentropy 返回的标签形状相同?
### BUILD SHAPE OF THE MODEL ###
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, (3,3), padding='same', activation=tf.nn.relu,
input_shape=(227,227,1)),
tf.keras.layers.MaxPooling2D((2,2), strides=2),
tf.keras.layers.Conv2D(64, (3,3), padding='same', activation=tf.nn.relu),
tf.keras.layers.MaxPooling2D((2,2), strides=2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation=tf.nn.relu),
tf.keras.layers.Dense(7, activation=tf.nn.softmax), # final layer with node for each classification
#tf.keras.layers.Reshape((-1,))
])
# specify loss and SGD functions
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
### TRAIN THE MODEL ###
#specify training metadata
BATCH_SIZE = 1
print("about to train")
# train the model on the training data
num_epochs = 1
model.fit_generator(generator.flow(train_images, train_labels, batch_size=BATCH_SIZE), epochs=num_epochs)
Run Code Online (Sandbox Code Playgroud)
--- 完整的错误跟踪 ---
Traceback (most recent call last):
File "classifier_model.py", line 115, in <module>
model.fit_generator(generator.flow(train_images, train_labels, batch_size=BATCH_SIZE), epochs=num_epochs)
File "/Users/grammiegramco/Desktop/projects/HiRISE/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1426, in fit_generator
initial_epoch=initial_epoch)
File "/Users/grammiegramco/Desktop/projects/HiRISE/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_generator.py", line 191, in model_iteration
batch_outs = batch_function(*batch_data)
File "/Users/grammiegramco/Desktop/projects/HiRISE/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1191, in train_on_batch
outputs = self._fit_function(ins) # pylint: disable=not-callable
File "/Users/grammiegramco/Desktop/projects/HiRISE/lib/python3.6/site-packages/tensorflow/python/keras/backend.py", line 3076, in __call__
run_metadata=self.run_metadata)
File "/Users/grammiegramco/Desktop/projects/HiRISE/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1439, in __call__
run_metadata_ptr)
File "/Users/grammiegramco/Desktop/projects/HiRISE/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 528, in __exit__
c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: logits and labels must have the same first dimension, got logits shape [1,7] and labels shape [7]
[[{{node loss/dense_1_loss/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits}}]]
Run Code Online (Sandbox Code Playgroud)
Mat*_*gro 11
不,你的原因全错了。您正在提供单热编码标签,但sparse_categorical_crossentropy需要整数标签,因为它是单热编码本身(因此,稀疏)。
一个简单的解决方案是将 loss 更改为categorical_crossentropy,而不是稀疏版本。还要注意y_true形状 (7,) 是不正确的,它应该是 (1, 7)。