您的代码存在多个问题 -
- 您在重塑
x_test = x_test.reshape(10000,784) 时遇到了一些错误,因为它只有 10000 张图片。
- 您在第一个密集层中使用了
sigmoid 激活,这不是一个好的做法。请改用relu。
- 您的输出 Dense 只有 1 个节点。您正在使用具有 10 个唯一类的数据集。输出必须是 Dense(10)。请理解,即使 y_train 具有
0-10 类,神经网络也无法预测具有 softmax 或 sigmoid 激活的整数值。相反,您要做的是预测 10 个类别中每个类别的概率值。
- 您在多类分类的最后一层使用了不正确的激活。使用
softmax。
- 您使用的损失函数不正确。对于多类分类,请使用
categorical_crossentropy。由于您的输出是 10 维概率分布,但您的 y_train 是每个类标签的单个值,您可以使用 sparse_categorical_crossentropy 代替,它是相同的,但处理标签编码的 y。
- 尝试使用更好的优化器以避免陷入局部最小值,例如
adam。
- 首选将 CNN 用于图像数据,因为简单的 Dense 层将无法捕获构成图像的空间特征。由于图片很小
(28,28),而且这是一个玩具示例,所以没关系。
请参阅此表以查看要使用的内容。不过,您必须确保首先知道要解决什么问题。
在您的情况下,您想要进行多类单标签分类,但您正在通过使用不正确的损失和输出层激活来进行多类多标签分类。
from tensorflow.keras.datasets import fashion_mnist
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
#Load data
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
#Normalize
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
#Reshape
x_train = x_train.reshape(60000,784)
x_train = x_train / 255.0
x_test = x_test.reshape(10000,784)
x_test = x_test / 255.0
print('Data shapes->',[i.shape for i in [x_train, y_train, x_test, y_test]])
#Contruct computation graph
model = Sequential()
model.add(Dense(100, activation="relu", input_shape=(784,)))
model.add(Dense(10, activation="softmax"))
#Compile with loss as cross_entropy and optimizer as adam
model.compile(optimizer='adam', loss="sparse_categorical_crossentropy", metrics=["accuracy"])
#Fit model
model.fit(x_train, y_train, epochs=10, batch_size=1000)
Data shapes-> [(60000, 784), (60000,), (10000, 784), (10000,)]
Epoch 1/10
60/60 [==============================] - 0s 5ms/step - loss: 0.8832 - accuracy: 0.7118
Epoch 2/10
60/60 [==============================] - 0s 6ms/step - loss: 0.5125 - accuracy: 0.8281
Epoch 3/10
60/60 [==============================] - 0s 6ms/step - loss: 0.4585 - accuracy: 0.8425
Epoch 4/10
60/60 [==============================] - 0s 6ms/step - loss: 0.4238 - accuracy: 0.8547
Epoch 5/10
60/60 [==============================] - 0s 7ms/step - loss: 0.4038 - accuracy: 0.8608
Epoch 6/10
60/60 [==============================] - 0s 6ms/step - loss: 0.3886 - accuracy: 0.8656
Epoch 7/10
60/60 [==============================] - 0s 6ms/step - loss: 0.3788 - accuracy: 0.8689
Epoch 8/10
60/60 [==============================] - 0s 6ms/step - loss: 0.3669 - accuracy: 0.8725
Epoch 9/10
60/60 [==============================] - 0s 6ms/step - loss: 0.3560 - accuracy: 0.8753
Epoch 10/10
60/60 [==============================] - 0s 6ms/step - loss: 0.3451 - accuracy: 0.8794
我还使用Convolutional layers 添加了一个代码供您参考,使用categorical_crossentropy 和functional API 而不是Sequential。请阅读 cmets 内联代码以获得更清晰的信息。这应该有助于您了解使用 Keras 时的一些良好做法。
from tensorflow.keras.datasets import fashion_mnist
from tensorflow.keras import layers, Model, utils
#Load data
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
#Normalize
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
#Reshape
x_train = x_train.reshape(60000,28,28,1)
x_train = x_train / 255.0
x_test = x_test.reshape(10000,28,28,1)
x_test = x_test / 255.0
#Set y to onehot instead of label encoded
y_train = utils.to_categorical(y_train)
y_test = utils.to_categorical(y_test)
#print([i.shape for i in [x_train, y_train, x_test, y_test]])
#Contruct computation graph
inp = layers.Input((28,28,1))
x = layers.Conv2D(32, (3,3), activation='relu', padding='same')(inp)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Conv2D(32, (3,3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Flatten()(x)
out = Dense(10, activation='softmax')(x)
#Define model
model = Model(inp, out)
#Compile with loss as cross_entropy and optimizer as adam
model.compile(optimizer='adam', loss="categorical_crossentropy", metrics=["accuracy"])
#Fit model
model.fit(x_train, y_train, epochs=10, batch_size=1000)
utils.plot_model(model, show_layer_names=False, show_shapes=True)