【问题标题】:How do I train a neural network with tensorflow-datasets?如何使用 tensorflow 数据集训练神经网络?
【发布时间】:2020-09-10 10:19:50
【问题描述】:

我正在尝试在 emnist 数据集上训练神经网络,但是当我尝试展平图像时,它会引发以下错误:

WARNING:tensorflow:Model 是用 shape (None, 28, 28) 作为输入 Tensor("flatten_input:0", shape=(None, 28, 28), dtype=float32) 构建的,但它是在一个形状不兼容的输入(无、1、28、28)。

我无法弄清楚似乎是什么问题,并尝试更改我的预处理,从我的 model.fit 和我的 ds.map 中删除批量大小。

这里是完整的代码:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
from tensorflow import keras
import tensorflow_datasets as tfds
import matplotlib.pyplot as plt

def preprocess(dict):
    image = dict['image']
    image = tf.transpose(image)
    label = dict['label']
    return image, label

train_data, validation_data = tfds.load('emnist/letters', split = ['train', 'test'])
train_data_gen = train_data.map(preprocess).shuffle(1000).batch(32)
validation_data_gen = validation_data.map(preprocess).batch(32)

print(train_data_gen)
model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape = (28, 28)),
    tf.keras.layers.Dense(128, activation = 'relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation = 'softmax')
])

model.compile(optimizer = 'adam',
    loss = 'sparse_categorical_crossentropy',
    metrics = ['accuracy'])

early_stopping = keras.callbacks.EarlyStopping(monitor = 'val_accuracy', patience = 10)
history = model.fit(train_data_gen, epochs = 50, batch_size = 32, validation_data = validation_data_gen, callbacks = [early_stopping], verbose = 1)
model.save('emnistmodel.h5')

【问题讨论】:

    标签: python tensorflow keras neural-network


    【解决方案1】:

    嗨 @Rattandeep 我刚刚检查了 emnist 数据集它有 47 个不同的类,在你的密集层中,你提到了 10 个。

    如果您从

    更改代码

    tf.keras.layers.Dense(10, activation = 'softmax')

    对于这个,它会起作用的

    tf.keras.layers.Dense(47, activation = 'softmax')

    谢谢

    【讨论】:

    • 我改变了,但没有效果。此外,错误是针对第一个展平层的。
    • 能否添加您所面临的错误或附上相同的屏幕截图?
    • 问题就在那里(开头)。
    【解决方案2】:

    所以这里实际上发生了一些事情,所以让我们一次解决它们。

    1. 输入形状

      因此,为了解决您的直接问题,您收到了不兼容的形状错误,因为输入的形状与预期的形状不匹配。

      tf.keras.layers.Flatten(input_shape=(28, 28)), 这一行中,我们告诉模型期望输入形状为 (28, 28),但这并不准确。我们的输入实际上具有形状 (28, 28, 1),因为我们正在拍摄具有 1 个通道 的 28x28 像素图像(而不是具有 3 个通道 r、g 和 b 的彩色图像)。所以为了解决这个直接的问题,我们只需更新模型以使用输入的形状。即tf.keras.layers.Flatten(input_shape=(28, 28, 1)),

    2. 输出节点数

      正如 Rishabh 在他的回答中所建议的那样,EMNIST dataset 有 10 多个平衡类。但是,在您的情况下,您似乎正在使用具有 26 个平衡类的 EMNIST Letters。因此,您的神经网络应该相应地具有 27 个输出节点(因为类标签从 1.. 26 开始,而我们的输出节点对应于 0.. 26)才能对给定数据进行分类。当然,给它额外的输出节点也可以让它运行,但是这些会给我们额外的权重来训练,这不是必需的,这会增加我们模型所需的训练时间。总之,你的最后一层应该是tf.keras.layers.Dense(27, activation='softmax')

    3. 预处理 TensorFlow 数据集

      阅读您的 preprocess() 函数,我相信您正在尝试将训练和验证数据集转换为(图像,标签)的元组。 TensorFlow 没有创建我们自己的函数,而是通过参数as_supervised 方便地为我们实现了这一点。

      此外,我看到您正在尝试实现一些额外的预处理,例如对数据进行批处理和洗牌。同样,TensorFlow 为我们实现了 batch_sizeshuffle_files(参见常用参数)!所以加载数据集看起来像

      train_data, validation_data = tfds.load('emnist/letters',
                                              split=['train', 'test'],
                                              shuffle_files=True,
                                              batch_size=32,
                                              as_supervised=True)
      
    4. 一些补充说明

      另外,作为建议,请考虑从 model.fit() 中排除 batch_size。在两个不同的地方定义相同的东西会导致错误和意外行为。此外,在使用 TensorFlow Datasets 时,没有必要,因为它们already generate batches

    总体而言,您更新后的程序应如下所示

    import matplotlib.pyplot as plt
    import tensorflow_datasets as tfds
    from tensorflow import keras
    import tensorflow as tf
    import os
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
    
    
    train_data, validation_data = tfds.load('emnist/letters',
                                            split=['train', 'test'],
                                            shuffle_files=True,
                                            batch_size=32,
                                            as_supervised=True)
    
    model = tf.keras.models.Sequential([
        tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
        tf.keras.layers.Dense(128, activation='relu'),
        tf.keras.layers.Dropout(0.2),
        tf.keras.layers.Dense(27, activation='softmax')
    ])
    
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    
    early_stopping = keras.callbacks.EarlyStopping(
        monitor='val_accuracy', patience=10)
    
    history = model.fit(train_data,
                        epochs=50,
                        validation_data=validation_data,
                        callbacks=[early_stopping],
                        verbose=1)
    model.save('emnistmodel.h5')
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 2016-12-23
      • 2019-05-19
      • 1970-01-01
      • 2011-04-07
      • 1970-01-01
      相关资源
      最近更新 更多