ffnn = Sequential([ Flatten(input_shape=X_train.shape[1:]), Dense(512, activation='relu'), Dropout(0.2), Dense(512, activation='relu'), Dropout(0.2), Dense(10, activation='softmax')])
ffnn_history = ffnn.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.2, callbacks=[checkpointer, early_stopping], verbose=1, shuffle=True)
ffnn_accuracy = ffnn.evaluate(X_test, y_test, verbose=0)[1]
我理解这个网络以及softmax函数的运作方式。我的问题是,输出层有10个节点。输出应该是一个长度为10的向量(该向量的总和为1)。在训练和评估过程中,它是如何与标签y匹配的,其中y是一个整数(难道不应该先将输出向量转换为相应的整数吗)?
TensorFlow是否会自动将长度为10的输出向量解释为相应的整数,还是有什么其他方法?
回答:
在你的情况下,标签是由损失函数 sparse_categorical_crossentropy()
进行one-hot编码的:
>>> y_true = [1, 2]>>> y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]>>> tf.keras.losses.sparse_categorical_crossentropy(y_true, y_pred).numpy()array([0.05129344, 2.3025851 ], dtype=float32)
输出 softmax(x)
可以被解释为一个概率分布(Σ softmax(x) = 1.0
)。例如,argmax(softmax(x)) = id_maxprob
将返回概率最大的类的索引。
因此,你的神经网络的目标向量将是10维的,每个整数 [0, 1, .., 8, 9]
对应softmax输出层的一个节点。
话虽如此,你要预测的目标向量将是one-hot编码的:
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0] # == 0[0, 1, 0, 0, 0, 0, 0, 0, 0, 0] # == 1..[0, 0, 0, 0, 0, 0, 0, 0, 0, 1] # == 9
换句话说:如果你有一批 images
并将其输入到你的网络中,输出将是 (n, num_classes)
(这里 num_classes
是10),并且是你自己来对输出进行最终解释,例如通过使用 np.argmax
来获得你的最终预测。
predictions = model(images)predicted_ids = np.argmax(predictions, axis=1)# 打印每个索引 == 预测的整数print(predicted_ids)
另外,请注意以下示例:
>>> tf.one_hot([1, 2, 9], depth=10)<tf.Tensor: shape=(3, 10), dtype=float32, numpy=array([[0., 1., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]], dtype=float32)>