Tensorflow学习笔记:批量读取 CIFAR10数据集

批量读取 CIFAR10 数据集

本文重点介绍通过拆分原始数据集来加载和训练神经网络模型。 当整个数据集对于本地 RAM 来说太大并且必须在使用“model.fit”训练模型之前拆分

背景 Background

我们通常这样加载 CIFAR10 图像数据集

import tensorflow as tf
from tensorflow.keras import datasets, layers, models

(train_data, train_labels), (test_data, test_labels) = datasets.cifar10.load_data()

load_data() 函数会自动下载数据集并将其存储在 ~/.keras/datasets/cifar-10-batches-py/ 中,这就是您可以在文件夹中找到的内容。 查看 load_data() 的源代码,它会加载所有批次并让我们将数据很好地返回到 train_data, train_labels), (test_data, test_labels),但是如果您想一一阅读它们怎么办? 你会怎么做,这就是我们今天要探讨的。
Tensorflow学习笔记:批量读取 CIFAR10数据集_第1张图片

Pickle

我们用python的pickle模块来加载数据。首先定义这个函数

def load_pickle(filename):
    """ load correct version of pickle """
    version = platform.python_version_tuple()
    if version[0] == '2':
        return pickle.load(filename)
    elif version[0] == '3': 
        return pickle.load(filename, encoding='latin1')
    raise ValueError("invalid python version: {}".format(version))

def load_data_partition(filename) -> None:
    """ load single batch of cifar """
    with open(filename, 'rb') as f:
        datadict = load_pickle(filename=f)
        data = datadict['data'] 
        labels = datadict['labels']
        batch_labels = datadict['batch_label']
        filenames = datadict['filenames']
        data = data.reshape(data.shape[0], 3, IMG_SIZE, IMG_SIZE) # reshape into (n, 3, 32, 32)
        data = data.transpose(0, 2, 3, 1) # reshape into (n, 32, 32, 3)
        data = data.astype('float32') 
        data = data / 255 # normalize
        labels = np.array(labels) # convert to numpy array
        return data, labels, batch_labels, filenames

load_pickle安python版本返回准确的pickle.load。然后load_partion能读取~/.keras/datasets/cifar-10-batches-py/里的batch文件,返回正确形状的tensor。如果直接用data的话,图片会有错误。

模型 Model

然后我们定义我们的神经网络模型。先定义一个比较简单的卷积神经网络。

def model_1():
    model = models.Sequential()
    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(MaxPooling2D((2, 2)))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(Flatten())
    model.add(Dense(64, activation='relu'))
    model.add(Dense(10))
    return model 

训练和评估 Training and Evaluation

现在我们来定义主逻辑流程。 确保将 root 更改为正确的文件路径。

root = "~/.keras/datasets/cifar-10-batches-py/"
ef main():
    model = model_1()
    model.compile(optimizer='adam', loss=SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'])
    model.summary()

    for i in range(5):
        print('training data_batch_{}'.format(i+1))
        train_images, train_labels, batch_labels, filenames = load_data_partition(os.path.join(root, 'data_batch_{}'.format(i+1)))
        
        # split into train and validation
        val_images, val_labels = train_images[:2500], train_labels[:2500]
        train_images, train_labels = train_images[2500:], train_labels[2500:]
        model.fit(train_images, train_labels, validation_data=(val_images, val_labels), epochs=10)
    # test our model at the end    
    print("testing")
    test_images, test_labels, batch_labels, file_names = load_data_partition(os.path.join(root, 'test_batch'))
    print(model.evaluate(test_images, test_labels))

结论 Conclusion

在这里我们看到如何使用pickle批量读取像CIFAR10这样的数据集,并不断调用model.fit来训练我们的神经网络模型。 在这种情况下,CIFAR10 图像集(每批)非常小,形状为 (10000, 32, 32 3)。 所有 5 个批次组合的形状都是 (50000, 32, 32, 3),但是如果图像更大怎么办? 例如,AlexNet 图像分类 CNN 模型需要具有维度 (277, 277, 3) 的图像。 如果我们将所有 50,000 张图像加载到内存中并将其大小调整为 277x277,除非您有大量 RAM,否则您的程序很可能会崩溃。 因此,有时我们可能需要批量加载和训练(这与 model.fit 中的批处理参数不同!)否则我们将耗尽内存。

下一次,让我们学习如何预处理图像(调整图像大小和数据增强)、如何保存图像以及如何定义 AlexNet 模型。下次再见!

你可能感兴趣的:(人工智能,Tensorflow,分类算法,机器学习,卷积神经网络)