简体   繁体   English

TensorFlow 模型的准确率为零

[英]TensorFlow model has zero accuracy

I am currently training a model using the Cars196 dataset from Stanford.我目前正在使用斯坦福的Cars196数据集训练模型。 However, with the dataset correctly imported and recognized by TensorFlow, my accuracy is still 0. I used a similar approach to train the model on other datasets and it works.但是,在 TensorFlow 正确导入和识别数据集的情况下,我的准确率仍然为 0。我使用类似的方法在其他数据集上训练模型并且它有效。 Did I do anything wrong?我做错什么了吗?

Here is my code这是我的代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import csv
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Flatten,Dense

car_dir = './src/'
test_dir = './src/cars_test/'
train_dir = './src/cars_train/'
train_labels_file = './src/labels-train.csv'
test_labels_file = './src/labels-test.csv'

IMG_SIZE = (150,150)
def read_labels(label_file:str):

    pathAndClass = list()
    
    with open(label_file) as csv_file:
        reader = csv.reader(csv_file)
        next(reader) # skip first row
        for row in reader:
            pathAndClass.append([row[5].lower(), row[4]])
        
        return pd.DataFrame(pathAndClass,columns=['path', 'class'])

pathAndClass = read_labels(train_labels_file)
n_classes = np.size(np.unique(pathAndClass['class']))
pathAndClass['path'] = pathAndClass['path'].astype(str)
pathAndClass['class'] = pathAndClass['class'].astype(str)
data_gen = ImageDataGenerator(rescale = 1.0/255.0, validation_split=0.25)
BATCH_SIZE = 32
index_list = []
for i in range(0, n_classes):
    index_list.append(str(i))
train_flow = data_gen.flow_from_dataframe(
    dataframe=pathAndClass,
    x_col='path',
    y_col='class',
    directory=train_dir,
    subset="training",
    seed=42,
    target_size=IMG_SIZE,
    batch_size=BATCH_SIZE, 
    shuffle=True, 
    classes=index_list,
    class_mode='categorical')

valid_flow = data_gen.flow_from_dataframe(
    dataframe=pathAndClass,
    x_col='path',
    y_col='class',
    directory=train_dir,
    subset="validation",
    seed=42,
    target_size=IMG_SIZE,
    batch_size=BATCH_SIZE, 
    shuffle=True, 
    classes=index_list,
    class_mode='categorical')
model_nn = Sequential()
model_nn.add(Flatten(input_shape=(150,150, 3)))
model_nn.add(Dense(300, activation="relu"))
model_nn.add(Dense(n_classes, activation="softmax"))
model_nn.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model_nn.summary())
training = model_nn.fit(
        train_flow,
        steps_per_epoch=train_flow.n//train_flow.batch_size,
        epochs=10,
        validation_data=valid_flow,
        validation_steps=valid_flow.n//valid_flow.batch_size)
print(model_nn.evaluate(train_flow))
plt.plot(training.history['accuracy'])
plt.plot(training.history['val_accuracy'])
plt.plot(training.history['loss'])
plt.plot(training.history['val_loss'])
plt.title('Model accuracy/loss')
plt.ylabel('accuracy/loss')
plt.xlabel('epoch')
plt.legend(['accuracy', 'val_accuracy', 'loss', 'val_loss'])
plt.show()

The output I got我得到的输出

Found 6078 validated image filenames belonging to 196 classes.
Found 2026 validated image filenames belonging to 196 classes.
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten_1 (Flatten)          (None, 67500)             0         
_________________________________________________________________
dense_2 (Dense)              (None, 300)               20250300  
_________________________________________________________________
dense_3 (Dense)              (None, 196)               58996     
=================================================================
Total params: 20,309,296
Trainable params: 20,309,296
Non-trainable params: 0
_________________________________________________________________
None

Epoch 1/10
189/189 [==============================] - 68s 361ms/step - loss: 9.6809 - accuracy: 0.0036 - val_loss: 5.2785 - val_accuracy: 0.0030
Epoch 2/10
189/189 [==============================] - 58s 307ms/step - loss: 5.2770 - accuracy: 0.0055 - val_loss: 5.2785 - val_accuracy: 0.0089
Epoch 3/10
189/189 [==============================] - 58s 307ms/step - loss: 5.2743 - accuracy: 0.0083 - val_loss: 5.2793 - val_accuracy: 0.0104
Epoch 4/10
189/189 [==============================] - 58s 306ms/step - loss: 5.2728 - accuracy: 0.0089 - val_loss: 5.2800 - val_accuracy: 0.0089
Epoch 5/10
189/189 [==============================] - 58s 307ms/step - loss: 5.2710 - accuracy: 0.0084 - val_loss: 5.2806 - val_accuracy: 0.0089
Epoch 6/10
189/189 [==============================] - 57s 305ms/step - loss: 5.2698 - accuracy: 0.0086 - val_loss: 5.2815 - val_accuracy: 0.0089
Epoch 7/10
189/189 [==============================] - 58s 307ms/step - loss: 5.2695 - accuracy: 0.0083 - val_loss: 5.2822 - val_accuracy: 0.0089
Epoch 8/10
189/189 [==============================] - 58s 310ms/step - loss: 5.2681 - accuracy: 0.0086 - val_loss: 5.2834 - val_accuracy: 0.0089
Epoch 9/10
189/189 [==============================] - 58s 306ms/step - loss: 5.2679 - accuracy: 0.0083 - val_loss: 5.2840 - val_accuracy: 0.0089
Epoch 10/10
189/189 [==============================] - 58s 308ms/step - loss: 5.2669 - accuracy: 0.0083 - val_loss: 5.2848 - val_accuracy: 0.0089
   1578/Unknown - 339s 215ms/step - loss: 5.2657 - accuracy: 0.0085

Update 1更新 1

I have increased the training sample by decreasing the batch size to 8 .我通过将批量大小减小到8来增加训练样本。 I tried to train the model again.我试图再次训练模型。 However, the accuracy is still nearly 0.但是,准确率仍然接近 0。

Epoch 1/10
759/759 [==============================] - 112s 147ms/step - loss: 7.6876 - accuracy: 0.0051 - val_loss: 5.2779 - val_accuracy: 0.0089
Epoch 2/10
759/759 [==============================] - 112s 148ms/step - loss: 5.2728 - accuracy: 0.0086 - val_loss: 5.2792 - val_accuracy: 0.0089
Epoch 3/10
759/759 [==============================] - 112s 148ms/step - loss: 5.2695 - accuracy: 0.0087 - val_loss: 5.2808 - val_accuracy: 0.0089
Epoch 4/10
759/759 [==============================] - 109s 143ms/step - loss: 5.2671 - accuracy: 0.0087 - val_loss: 5.2828 - val_accuracy: 0.0089
Epoch 5/10
759/759 [==============================] - 111s 146ms/step - loss: 5.2661 - accuracy: 0.0086 - val_loss: 5.2844 - val_accuracy: 0.0089
Epoch 6/10
759/759 [==============================] - 114s 151ms/step - loss: 5.2648 - accuracy: 0.0089 - val_loss: 5.2862 - val_accuracy: 0.0089
Epoch 7/10
759/759 [==============================] - 118s 156ms/step - loss: 5.2646 - accuracy: 0.0086 - val_loss: 5.2881 - val_accuracy: 0.0089
Epoch 8/10
759/759 [==============================] - 117s 155ms/step - loss: 5.2639 - accuracy: 0.0087 - val_loss: 5.2891 - val_accuracy: 0.0089
Epoch 9/10
759/759 [==============================] - 115s 151ms/step - loss: 5.2635 - accuracy: 0.0087 - val_loss: 5.2903 - val_accuracy: 0.0089
Epoch 10/10
759/759 [==============================] - 112s 147ms/step - loss: 5.2634 - accuracy: 0.0086 - val_loss: 5.2915 - val_accuracy: 0.0089
   2390/Unknown - 141s 59ms/step - loss: 5.2611 - accuracy: 0.0088

Indeed the last dataset I used had less classes but more samples.事实上,我使用的最后一个数据集的类别更少,但样本更多。 Maybe there is another model that fits my dataset, any suggestions?也许还有另一个适合我的数据集的模型,有什么建议吗?

For computer vision problems, you want to look at Convolutional Neural Networks.对于计算机视觉问题,你想看看卷积神经网络。 If you're unfamiliar with them, they learn to identify features in images.如果您不熟悉它们,它们会学习识别图像中的特征。 Examples could be edges and textures in early layers, and then wheels, windows, doors, etc in later layers.示例可能是早期层中的边缘和纹理,然后是后期层中的轮子、窗户、门等。

For this problem, I would suggest using an existing, pretrained network such as MobileNet V2 or InceptionNetV3 as a backbone, and then building your own classifier on top.对于这个问题,我建议使用现有的预训练网络(例如 MobileNet V2 或 InceptionNetV3)作为主干,然后在上面构建自己的分类器。 This tutorial on the Tensorflow website will get you started https://www.tensorflow.org/tutorials/images/transfer_learning#create_the_base_model_from_the_pre-trained_convnets Tensorflow 网站上的本教程将帮助您入门https://www.tensorflow.org/tutorials/images/transfer_learning#create_the_base_model_from_the_pre-trained_convnets

Here's an excerpt from this tutorial:以下是本教程的摘录:

base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                               include_top=False,
                                               weights='imagenet')

Then adding your model code from above, you could try:然后从上面添加您的模型代码,您可以尝试:

model = tf.keras.Sequential([
  base_model,
  Flatten(input_shape=(150,150, 3)),  
  Dense(300, activation="relu")),  
  Dense(n_classes, activation='softmax')
])

model_nn.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

This is the model I've used on similar datasets and got reasonable accuracy with it:这是我在类似数据集上使用的模型,并获得了合理的准确性:

base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                               include_top=False,
                                               weights='imagenet')
model = tf.keras.Sequential([
  base_model,
  GlobalAveragePooling2D(),,  
  Dense(n_classes, activation='softmax')
])

In you current model, you are not trying to extract any features from the images.在您当前的模型中,您不会尝试从图像中提取任何特征。 A single hidden layer with 300 neurons is nowhere near enough to be able to learn the features in images and give meaningful results.具有 300 个神经元的单个隐藏层远不足以学习图像中的特征并给出有意义的结果。

You also need to check your input image size.您还需要检查输入图像的大小。 MobileNet V2 works well with 224x224 colour images. MobileNet V2 适用于 224x224 彩色图像。

As per other comments, you will need to use the full dataset, you are not going to get any meaningful results with a few hundred images.根据其他评论,您将需要使用完整的数据集,数百张图像不会获得任何有意义的结果。

I would suggest that the ~6000 Training Samples for almost 200 classes is simply way to little for the model to work well.我建议近 200 个课程的约 6000 个训练样本对于模型运行良好来说是微不足道的。
The model did ~2000 wheight updates (200 in each epoch), which is way to few for it to learn to distinguish between ~200 classifications.该模型进行了约 2000 次重量更新(每个 epoch 200 次),这对于它学习区分约 200 个分类的方法来说很少。

Maybe you had less classes and more training data in the other training sets?也许您在其他训练集中有更少的课程和更多的训练数据?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM