Tensorflow/Keras: 训练过程中模型准确率始终为0.5,输入大小与第一个官方教程不同

我是一个深度学习和Keras/TensorFlow的初学者。我已经按照tensorflow.org上的第一个教程进行了学习:使用时尚MNIST进行基本分类。

在这种情况下,输入数据是60000张28×28的图像,模型如下:

model = keras.Sequential([    keras.layers.Flatten(input_shape=(28, 28)),    keras.layers.Dense(128, activation=tf.nn.relu),    keras.layers.Dense(10, activation=tf.nn.softmax)])

编译方式如下:

model.compile(optimizer=tf.train.AdamOptimizer(),                 loss='sparse_categorical_crossentropy',                metrics=['accuracy'])

训练结束时,模型的准确率如下:

10000/10000 [==============================] - 0s 21us/stepTest accuracy: 0.8769

这是正常的。现在我尝试使用另一组数据复制这个模型。新输入是从kaggle下载的数据集。

数据集包含不同大小的狗和猫的图片,因此我创建了一个简单的脚本来获取图片,将它们调整为28×28像素,并转换为numpy数组。

以下是执行此操作的代码:

import tensorflow as tffrom tensorflow import kerasfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_imgfrom tensorflow.keras.models import load_modelfrom PIL import Imageimport os# Helper librariesimport numpy as np# base path datasetbase_path = './dataset/'training_path = base_path + "training_set/"test_path = base_path + "test_set/"# size rate of imagessize = 28, 28# train_images = []train_labels = []test_images = []test_labels = []classes = ['dogs', 'cats']# Scorre sulle cartelle contenute nel path e trasforma le immagini in nparraydef from_files_to_nparray(path):    images = []    labels = []    for subfolder in os.listdir(path):        if subfolder == '.DS_Store':            continue        for image_name in os.listdir(path + subfolder):            if not image_name.endswith('.jpg'):                continue            img = Image.open(path + subfolder + "/" + image_name).convert("L").resize(size) # convert to grayscale and resize            npimage = np.asarray(img)            images.append(npimage)            labels.append(classes.index(subfolder))            img.close()    # convertt to np arrays    images = np.asarray(images)    labels = np.asarray(labels)    # Normalize to [0, 1]    images = images / 255.0     return (images, labels)(train_images, train_labels) = from_files_to_nparray(training_path)(test_images, test_labels) = from_files_to_nparray(test_path)

最后,我得到的形状如下:

Train images shape   :  (8000, 128, 128)Labels images shape  :  (8000,)Test images shape    :  (2000, 128, 128)Test images shape    :  (2000,)

在训练了相同的模型(但最后的Dense层改为2个神经元)后,我得到了以下结果,应该是正常的:

Train images shape   :  (8000, 28, 28)Labels images shape  :  (8000,)Test images shape    :  (2000, 28, 28)Test images shape    :  (2000,)_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================flatten (Flatten)            (None, 784)               0         _________________________________________________________________dense (Dense)                (None, 128)               100480    _________________________________________________________________dense_1 (Dense)              (None, 2)                 258       =================================================================Total params: 100,738Trainable params: 100,738Non-trainable params: 0_________________________________________________________________NoneEpoch 1/52018-07-27 15:25:51.283117: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA8000/8000 [==============================] - 1s 66us/step - loss: 0.6924 - acc: 0.5466Epoch 2/58000/8000 [==============================] - 0s 39us/step - loss: 0.6679 - acc: 0.5822Epoch 3/58000/8000 [==============================] - 0s 41us/step - loss: 0.6593 - acc: 0.6048Epoch 4/58000/8000 [==============================] - 0s 39us/step - loss: 0.6545 - acc: 0.6134Epoch 5/58000/8000 [==============================] - 0s 39us/step - loss: 0.6559 - acc: 0.60392000/2000 [==============================] - 0s 33us/stepTest accuracy:  0.592

现在,问题是,如果我尝试将输入大小从28×28更改为例如128×128,结果如下:

Train images shape   :  (8000, 128, 128)Labels images shape  :  (8000,)Test images shape    :  (2000, 128, 128)Test images shape    :  (2000,)_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================flatten (Flatten)            (None, 16384)             0         _________________________________________________________________dense (Dense)                (None, 128)               2097280   _________________________________________________________________dense_1 (Dense)              (None, 2)                 258       =================================================================Total params: 2,097,538Trainable params: 2,097,538Non-trainable params: 0_________________________________________________________________NoneEpoch 1/52018-07-27 15:27:41.966860: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA8000/8000 [==============================] - 4s 483us/step - loss: 8.0341 - acc: 0.4993Epoch 2/58000/8000 [==============================] - 3s 362us/step - loss: 8.0590 - acc: 0.5000Epoch 3/58000/8000 [==============================] - 3s 351us/step - loss: 8.0590 - acc: 0.5000Epoch 4/58000/8000 [==============================] - 3s 342us/step - loss: 8.0590 - acc: 0.5000Epoch 5/58000/8000 [==============================] - 3s 342us/step - loss: 8.0590 - acc: 0.50002000/2000 [==============================] - 0s 217us/stepTest accuracy:  0.5

为什么会这样?即使添加新的Dense层或增加神经元数量,结果仍然相同。

输入大小与模型层之间有什么联系?谢谢!


回答:

问题在于第二个例子中你有更多的参数需要训练。在第一个例子中,你只有10万个参数。你用8千张图像来训练它们。

在第二个例子中,你有200万个参数,你试图用相同数量的图像来训练它们。这行不通,因为自由参数和样本数量之间存在关系。没有确切的公式来计算这种关系,但有一个经验法则,即可训练参数的数量应该少于样本数量。

你可以尝试训练更多的轮次,看看效果如何,但总的来说,复杂模型需要更多的数据。

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注