图像数据必须经过预处理,才能作为图像分类任务中建模的基础。
图像数据预处理的一个方面是缩放像素值,例如将值归一化到0-1范围,居中,标准化等等。
对于您的图像分类或计算机视觉建模任务,如何选择一个好的,甚至最好的像素缩放方法?
在本教程中,您将学习如何使用深度学习方法为图像分类选择像素缩放方法。
完成本教程后,您将了解:
- 一个通过实验和特定数据集上的经验结果选择像素缩放方法的过程。
- 如何实现标准像素缩放方法以准备用于建模的图像数据。
- 如何通过案例研究为标准图像分类问题选择像素缩放方法。
通过我的新书《深度学习与计算机视觉》**开启您的项目**,包括*分步教程*和所有示例的*Python源代码文件*。
让我们开始吧。

如何评估用于卷积神经网络图像分类的像素缩放方法
摄影:Andres Alvarado,保留部分权利。
教程概述
本教程分为6个部分;它们是
- 选择像素缩放方法的过程
- 选择数据集:MNIST图像分类
- 选择模型:卷积神经网络
- 选择像素缩放方法
- 运行实验
- 分析结果
选择像素缩放方法的过程
给定一个新的图像分类任务,应该使用哪些像素缩放方法?
有很多方法可以回答这个问题;例如:
- 使用研究论文中报告的用于类似问题的技术。
- 使用博客文章、课程或书籍中的启发式方法。
- 使用您最喜欢的技术。
- 使用最简单的技术。
- …
相反,我建议使用实验来发现最适合您特定数据集的方法。
这可以通过以下过程实现:
- 步骤1:选择数据集。这可以是整个训练数据集或一小部分。目的是快速完成实验并获得结果。
- 步骤2:选择模型。设计一个熟练但不必是问题最佳的模型。可能需要进行一些模型的并行原型设计。
- 步骤3:选择像素缩放方法。列出3-5个数据准备方案以评估您的问题。
- 步骤4:运行实验。以结果稳健且具有代表性的方式运行实验,理想情况下重复每个实验多次。
- 步骤5:分析结果。比较方法在学习速度和重复实验的平均性能方面。
实验方法将使用未优化的模型,并且可能使用训练数据的子集,这两者都可能给您必须做出的决策增加噪声。
因此,您正在寻找一个信号,即您的图像的一种数据准备方案明显优于其他方案;如果您的数据集不是这种情况,则应使用最简单(计算复杂性最低)的技术,例如像素归一化。
卓越像素缩放方法的清晰信号可以通过两种方式看到:
- 更快的学习。学习曲线清楚地表明,模型使用给定数据准备方案学习得更快。
- 更好的准确性。平均模型性能清楚地表明,使用给定数据准备方案的准确性更高。
现在我们有了为图像数据选择像素缩放方法的过程,让我们看一个例子。我们将使用MNIST图像分类任务,并用CNN拟合,然后评估一系列标准像素缩放方法。
想通过深度学习实现计算机视觉成果吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
步骤1. 选择数据集:MNIST图像分类
MNIST问题,简称MNIST,是一个图像分类问题,包含70,000张手写数字图像。
问题的目标是将给定的手写数字图像分类为0到9的整数。因此,它是一个多类图像分类问题。
它是评估机器学习和深度学习算法的标准数据集。最佳结果的准确率约为99.79%,或错误率约为0.21%(例如小于1%)。
该数据集作为Keras库的一部分提供,可以通过调用keras.datasets.mnist.load_data() 函数自动下载(如果需要)并加载到内存中。
该函数返回两个元组:一个用于训练输入和输出,一个用于测试输入和输出。例如:
1 2 3 |
# 加载MNIST数据集的示例 from keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() |
我们可以加载MNIST数据集并进行总结。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 |
# 加载并总结MNIST数据集 from keras.datasets import mnist # 加载数据集 (train_images, train_labels), (test_images, test_labels) = mnist.load_data() # 总结数据集形状 print('Train', train_images.shape, train_labels.shape) print('Test', (test_images.shape, test_labels.shape)) # 总结像素值 print('Train', train_images.min(), train_images.max(), train_images.mean(), train_images.std()) print('Train', test_images.min(), test_images.max(), test_images.mean(), test_images.std()) |
运行示例首先将数据集加载到内存中。然后报告训练和测试数据集的形状。
我们可以看到所有图像都是28x28像素,灰度图像只有一个通道。训练数据集有60,000张图像,测试数据集有10,000张。
我们还可以看到像素值是0到255之间的整数值,并且两个数据集的像素值的平均值和标准差相似。
1 2 3 4 |
训练 (60000, 28, 28) (60000,) 测试 ((10000, 28, 28), (10000,)) 训练 0 255 33.318421449829934 78.56748998339798 训练 0 255 33.791224489795916 79.17246322228644 |
数据集相对较小;我们将使用完整的训练和测试数据集。
现在我们熟悉了MNIST以及如何加载数据集,接下来我们回顾一些像素缩放方法。
步骤2. 选择模型:卷积神经网络
我们将使用卷积神经网络模型来评估不同的像素缩放方法。
CNN有望在此问题上表现出色,尽管本实验选择的模型不必在该问题上表现良好或最佳。相反,它必须是熟练的(优于随机),并且必须能够区分不同数据准备方案在学习速度和/或模型性能方面的影响。
因此,模型必须具有足够的容量来学习这个问题。
我们将在MNIST问题上演示基线模型。
首先,必须加载数据集,并扩展训练和测试数据集的形状以添加一个通道维度,由于我们只有一个黑白通道,因此将其设置为1。
1 2 3 4 5 6 |
# 加载数据集 (trainX, trainY), (testX, testY) = mnist.load_data() # 将数据集重塑为单通道 width, height, channels = trainX.shape[1], trainX.shape[2], 1 trainX = trainX.reshape((trainX.shape[0], width, height, channels)) testX = testX.reshape((testX.shape[0], width, height, channels)) |
接下来,我们将为此示例归一化像素值,并对目标值进行一次热编码,这是多类分类所必需的。
1 2 3 4 5 6 |
# 归一化像素值 trainX = trainX.astype('float32') / 255 testX = testX.astype('float32') / 255 # 独热编码目标值 trainY = to_categorical(trainY) testY = to_categorical(testY) |
该模型被定义为卷积层后跟最大池化层;这种组合再次重复,然后过滤图被展平,由一个全连接层解释,然后是一个输出层。
ReLU激活函数用于隐藏层,softmax激活函数用于输出层。指定了足够的过滤器图和节点以提供足够的容量来学习问题。
1 2 3 4 5 6 7 8 9 |
# 定义模型 model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(width, height, channels))) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) model.add(Dense(64, activation='relu')) model.add(Dense(10, activation='softmax')) |
使用随机梯度下降的Adam变体来寻找模型权重。使用分类交叉熵损失函数(多类分类所需),并在训练期间监控分类准确率。
1 2 |
# 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) |
模型拟合了五个训练周期,并使用了128张图像的大批量大小。
1 2 |
# 拟合模型 model.fit(trainX, trainY, epochs=5, batch_size=128) |
拟合完成后,模型在测试数据集上进行评估。
1 2 3 |
# 评估模型 _, acc = model.evaluate(testX, testY, verbose=0) print(acc) |
完整的示例列在下面,它可以在大约一分钟内在CPU上轻松运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# MNIST问题的基线CNN模型 from keras.datasets import mnist from keras.utils import to_categorical from keras.models import Sequential 从 keras.layers 导入 Conv2D 从 keras.layers 导入 MaxPooling2D from keras.layers import Dense from keras.layers import Flatten # 加载数据集 (trainX, trainY), (testX, testY) = mnist.load_data() # 将数据集重塑为单通道 width, height, channels = trainX.shape[1], trainX.shape[2], 1 trainX = trainX.reshape((trainX.shape[0], width, height, channels)) testX = testX.reshape((testX.shape[0], width, height, channels)) # 归一化像素值 trainX = trainX.astype('float32') / 255 testX = testX.astype('float32') / 255 # 独热编码目标值 trainY = to_categorical(trainY) testY = to_categorical(testY) # 定义模型 model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(width, height, channels))) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) model.add(Dense(64, activation='relu')) model.add(Dense(10, activation='softmax')) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 拟合模型 model.fit(trainX, trainY, epochs=5, batch_size=128) # 评估模型 _, acc = model.evaluate(testX, testY, verbose=0) print(acc) |
运行示例显示模型能够很好地、快速地学习问题。
注意:由于算法或评估过程的随机性质,或数值精度差异,您的结果可能会有所不同。请考虑多次运行示例并比较平均结果。
事实上,该模型在此次运行中在测试数据集上的性能为99%,即1%的错误率。这并非最先进(设计如此),但离最先进也并不遥远。
1 2 3 4 5 6 7 8 9 10 |
60000/60000 [==============================] - 13秒 220微秒/步 - 损失:0.2321 - 准确率:0.9323 第2/5个周期 60000/60000 [==============================] - 12秒 204微秒/步 - 损失:0.0628 - 准确率:0.9810 第3/5个周期 60000/60000 [==============================] - 13秒 208微秒/步 - 损失:0.0446 - 准确率:0.9861 第4/5个周期 60000/60000 [==============================] - 13秒 209微秒/步 - 损失:0.0340 - 准确率:0.9895 第5/5个周期 60000/60000 [==============================] - 12秒 208微秒/步 - 损失:0.0287 - 准确率:0.9908 0.99 |
步骤3. 选择像素缩放方法
神经网络模型通常无法在原始像素值上进行训练,例如像素值在0到255范围内。
原因在于网络使用输入的加权和,为了使网络稳定并有效训练,权重应保持较小。
相反,像素值必须在训练前进行缩放。像素值缩放大概有三种主要方法;它们是:
- 归一化:像素值缩放到0-1范围。
- 居中:从每个像素值中减去平均像素值,导致像素值分布以零均值为中心。
- 标准化:像素值缩放到标准高斯分布,均值为零,标准差为一。
传统上,使用S形激活函数,并优先使用和为0(零均值)的输入。随着ReLU和类似激活函数的广泛采用,情况可能仍然如此,也可能不再如此。
此外,在居中和标准化中,均值或均值和标准差可以按通道、图像、小批量或整个训练数据集计算。这可能会增加所选缩放方法的额外变体,可以进行评估。
归一化通常是默认方法,因为我们可以假设像素值始终在0-255范围内,这使得该过程的实现非常简单高效。
居中通常被推荐为首选方法,因为它在许多流行论文中使用,尽管均值可以按图像(全局)或按通道(局部)计算,并且可以跨图像批次或整个训练数据集计算,而且论文中描述的过程通常没有明确说明使用了哪种变体。
我们将实验上述三种方法,即归一化、居中和标准化。居中的均值以及标准化的均值和标准差将根据整个训练数据集计算。
您可以探索的其他变体包括:
- 计算每个通道的统计数据(针对彩色图像)。
- 计算每个图像的统计数据。
- 计算每个批次的统计数据。
- 在居中或标准化后进行归一化。
以下示例实现了三种选定的像素缩放方法,并展示了它们对MNIST数据集的影响。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# 在mnist数据集上演示像素缩放方法 from keras.datasets import mnist # 归一化图像 def prep_normalize(train, test): # 将整数转换为浮点数 train_norm = train.astype('float32') test_norm = test.astype('float32') # 归一化到0-1范围 train_norm = train_norm / 255.0 test_norm = test_norm / 255.0 # 返回归一化图像 return train_norm, test_norm # 居中图像 def prep_center(train, test): # 将整数转换为浮点数 train_cent = train.astype('float32') test_cent = test.astype('float32') # 计算统计数据 m = train_cent.mean() # 居中数据集 train_cent = train_cent - m test_cent = test_cent - m # 返回归一化图像 return train_cent, test_cent # 标准化图像 def prep_standardize(train, test): # 将整数转换为浮点数 train_stan = train.astype('float32') test_stan = test.astype('float32') # 计算统计数据 m = train_stan.mean() s = train_stan.std() # 居中数据集 train_stan = (train_stan - m) / s test_stan = (test_stan - m) / s # 返回归一化图像 return train_stan, test_stan # 加载数据集 (train_images, train_labels), (test_images, test_labels) = mnist.load_data() # 归一化 trainX, testX = prep_normalize(train_images, test_images) print('normalization') print('Train', trainX.min(), trainX.max(), trainX.mean(), trainX.std()) print('Test', testX.min(), testX.max(), testX.mean(), testX.std()) # 居中 trainX, testX = prep_center(train_images, test_images) print('center') print('Train', trainX.min(), trainX.max(), trainX.mean(), trainX.std()) print('Test', testX.min(), testX.max(), testX.mean(), testX.std()) # 标准化 trainX, testX = prep_standardize(train_images, test_images) print('standardize') print('Train', trainX.min(), trainX.max(), trainX.mean(), trainX.std()) print('Test', testX.min(), testX.max(), testX.mean(), testX.std()) |
运行示例首先归一化数据集,并报告训练和测试数据集的最小值、最大值、平均值和标准差。
注意:由于算法或评估过程的随机性质,或数值精度差异,您的结果可能会有所不同。请考虑多次运行示例并比较平均结果。
然后对居中和标准化数据准备方案重复此操作。结果证明缩放过程确实正确实现。
1 2 3 4 5 6 7 8 9 10 11 |
归一化 训练 0.0 1.0 0.13066062 0.30810776 测试 0.0 1.0 0.13251467 0.31048027 居中 训练 -33.318447 221.68155 -1.9512918e-05 78.567444 测试 -33.318447 221.68155 0.47278798 79.17245 标准化 训练 -0.42407447 2.8215446 -3.4560264e-07 0.9999998 测试 -0.42407447 2.8215446 0.0060174568 1.0077008 |
步骤4. 运行实验
现在我们已经定义了数据集、模型和要评估的数据准备方案,我们已准备好定义和运行实验。
每个模型在CPU上运行大约需要一分钟,因此我们不希望实验花费太长时间。我们将评估三种数据准备方案,每种方案将评估10次,这意味着在现代硬件上完成实验大约需要30分钟。
我们可以定义一个函数,在需要时重新加载数据集。
1 2 3 4 5 6 7 8 9 10 11 12 |
# 加载训练和测试数据集 def load_dataset(): # 加载数据集 (trainX, trainY), (testX, testY) = mnist.load_data() # 将数据集重塑为单通道 width, height, channels = trainX.shape[1], trainX.shape[2], 1 trainX = trainX.reshape((trainX.shape[0], width, height, channels)) testX = testX.reshape((testX.shape[0], width, height, channels)) # 独热编码目标值 trainY = to_categorical(trainY) testY = to_categorical(testY) return trainX, trainY, testX, testY |
我们还可以定义一个函数来定义和编译我们的模型,准备好解决问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 定义cnn模型 def define_model(): model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(width, height, channels))) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) model.add(Dense(64, activation='relu')) model.add(Dense(10, activation='softmax')) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) return model |
我们已经有了用于准备训练和测试数据集像素数据的函数。
最后,我们可以定义一个名为 repeated_evaluation() 的函数,该函数接受要调用以准备数据的 prepare_data 函数的名称,并将加载数据集并重复定义模型、准备数据集、拟合和评估模型。它将返回一个准确率分数列表,可用于总结所选数据准备方案下模型的性能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 重复评估带有数据准备方案的模型 def repeated_evaluation(datapre_func, n_repeats=10): # 准备数据 trainX, trainY, testX, testY = load_dataset() # 重复评估 scores = list() for i in range(n_repeats): # 定义模型 model = define_model() # 准备数据 prep_trainX, prep_testX = datapre_func(trainX, testX) # 拟合模型 model.fit(prep_trainX, trainY, epochs=5, batch_size=64, verbose=0) # 评估模型 _, acc = model.evaluate(prep_testX, testY, verbose=0) # 存储结果 scores.append(acc) print('> %d: %.3f' % (i, acc * 100.0)) return scores |
然后可以为三种数据准备方案中的每一种调用 repeated_evaluation() 函数,并报告该方案下模型性能的均值和标准差。
我们还可以创建一个箱线图来总结和比较每种方案的准确率分数分布。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
all_scores = list() # 归一化 scores = repeated_evaluation(prep_normalize) print('Normalization: %.3f (%.3f)' % (mean(scores), std(scores))) all_scores.append(scores) # 居中 scores = repeated_evaluation(prep_center) print('Centered: %.3f (%.3f)' % (mean(scores), std(scores))) all_scores.append(scores) # 标准化 scores = repeated_evaluation(prep_standardize) print('Standardized: %.3f (%.3f)' % (mean(scores), std(scores))) all_scores.append(scores) # 结果的箱线图 pyplot.boxplot(all_scores, labels=['norm', 'cent', 'stan']) pyplot.show() |
将所有这些联系起来,运行实验以比较MNIST数据集上的像素缩放方法的完整示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# MNIST上基于训练集的像素缩放方法比较 from numpy import mean from numpy import std from matplotlib import pyplot from keras.datasets import mnist from keras.utils import to_categorical from keras.models import Sequential 从 keras.layers 导入 Conv2D 从 keras.layers 导入 MaxPooling2D from keras.layers import Dense from keras.layers import Flatten # 加载训练和测试数据集 def load_dataset(): # 加载数据集 (trainX, trainY), (testX, testY) = mnist.load_data() # 将数据集重塑为单通道 width, height, channels = trainX.shape[1], trainX.shape[2], 1 trainX = trainX.reshape((trainX.shape[0], width, height, channels)) testX = testX.reshape((testX.shape[0], width, height, channels)) # 独热编码目标值 trainY = to_categorical(trainY) testY = to_categorical(testY) return trainX, trainY, testX, testY # 定义cnn模型 def define_model(): model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) model.add(Dense(64, activation='relu')) model.add(Dense(10, activation='softmax')) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) return model # 归一化图像 def prep_normalize(train, test): # 将整数转换为浮点数 train_norm = train.astype('float32') test_norm = test.astype('float32') # 归一化到0-1范围 train_norm = train_norm / 255.0 test_norm = test_norm / 255.0 # 返回归一化图像 return train_norm, test_norm # 居中图像 def prep_center(train, test): # 将整数转换为浮点数 train_cent = train.astype('float32') test_cent = test.astype('float32') # 计算统计数据 m = train_cent.mean() # 居中数据集 train_cent = train_cent - m test_cent = test_cent - m # 返回归一化图像 return train_cent, test_cent # 标准化图像 def prep_standardize(train, test): # 将整数转换为浮点数 train_stan = train.astype('float32') test_stan = test.astype('float32') # 计算统计数据 m = train_stan.mean() s = train_stan.std() # 居中数据集 train_stan = (train_stan - m) / s test_stan = (test_stan - m) / s # 返回归一化图像 return train_stan, test_stan # 重复评估带有数据准备方案的模型 def repeated_evaluation(datapre_func, n_repeats=10): # 准备数据 trainX, trainY, testX, testY = load_dataset() # 重复评估 scores = list() for i in range(n_repeats): # 定义模型 model = define_model() # 准备数据 prep_trainX, prep_testX = datapre_func(trainX, testX) # 拟合模型 model.fit(prep_trainX, trainY, epochs=5, batch_size=64, verbose=0) # 评估模型 _, acc = model.evaluate(prep_testX, testY, verbose=0) # 存储结果 scores.append(acc) print('> %d: %.3f' % (i, acc * 100.0)) return scores all_scores = list() # 归一化 scores = repeated_evaluation(prep_normalize) print('Normalization: %.3f (%.3f)' % (mean(scores), std(scores))) all_scores.append(scores) # 居中 scores = repeated_evaluation(prep_center) print('Centered: %.3f (%.3f)' % (mean(scores), std(scores))) all_scores.append(scores) # 标准化 scores = repeated_evaluation(prep_standardize) print('Standardized: %.3f (%.3f)' % (mean(scores), std(scores))) all_scores.append(scores) # 结果的箱线图 pyplot.boxplot(all_scores, labels=['norm', 'cent', 'stan']) pyplot.show() |
运行该示例可能在CPU上花费大约30分钟。
注意:由于算法或评估过程的随机性质,或数值精度差异,您的结果可能会有所不同。请考虑多次运行示例并比较平均结果。
模型每次重复评估的准确性都会报告,并且在每次运行结束时会重复报告准确性分数的均值和标准差。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
> 0: 98.930 > 1: 98.960 > 2: 98.910 > 3: 99.050 > 4: 99.040 > 5: 98.800 > 6: 98.880 > 7: 99.020 > 8: 99.100 > 9: 99.050 归一化:0.990 (0.001) > 0: 98.570 > 1: 98.530 > 2: 98.230 > 3: 98.110 > 4: 98.840 > 5: 98.720 > 6: 9.800 > 7: 98.170 > 8: 98.710 > 9: 10.320 居中:0.808 (0.354) > 0: 99.150 > 1: 98.820 > 2: 99.000 > 3: 98.850 > 4: 99.140 > 5: 99.050 > 6: 99.120 > 7: 99.100 > 8: 98.940 > 9: 99.110 标准化:0.990 (0.001) |

不同像素缩放方法下CNN在MNIST上的性能箱线图
步骤5. 分析结果
为简洁起见,我们仅在数据准备方案的比较中关注模型性能。这项研究的扩展还将考虑每种像素缩放方法下的学习率。
实验结果表明,在MNIST数据集上,使用所选模型时,像素归一化和标准化之间几乎没有区别(在所选精度下)。
根据这些结果,我将在此数据集上使用归一化而非标准化,因为结果良好,并且归一化比标准化更简单。
这些结果很有用,因为它们表明,在建模前将像素值居中的默认启发式方法对于此数据集而言并非一个好的建议。
遗憾的是,箱线图并未使准确率分数的分布比较变得容易,因为居中缩放方法的一些糟糕的异常值会压扁分布。
扩展
本节列出了一些您可能希望探索的扩展本教程的想法。
- 分批缩放。更新研究以计算每个批次的缩放统计数据,而不是整个训练数据集的统计数据,并查看这是否对缩放方法的选择产生影响。
- 学习曲线。更新研究,为每种数据缩放方法收集一些学习曲线,并比较学习速度。
- CIFAR。在CIFAR-10数据集上重复这项研究,并添加支持全局(跨所有通道缩放)和局部(按通道缩放)方法的像素缩放方法。
如果您探索了这些扩展中的任何一个,我很想知道。
请在下面的评论中发布您的发现。
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
总结
在本教程中,您学习了如何使用深度学习方法为图像分类选择像素缩放方法。
具体来说,你学到了:
- 一个通过实验和特定数据集上的经验结果选择像素缩放方法的过程。
- 如何实现标准像素缩放方法以准备用于建模的图像数据。
- 如何通过案例研究为标准图像分类问题选择像素缩放方法。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
Jason干得好!我喜欢您设置程序与不同模块(函数)的方式,例如加载数据、定义模型、图像预处理、不同预处理图像的评估以及绘制结果。结构非常清晰,您传达的信息也非常清楚!
我有一个问题。在许多情况下,您没有大量的图像数据集进行训练,甚至图像的分辨率(每张图像的像素较少)低于预期。由于这个MNIST数据集取得了辉煌的成果(优于99%),您是否尝试研究过需要训练的最小数据集图像数量(少于60,000)和较低分辨率(少于28,28)也能取得良好结果,也就是说,对结果如何依赖于不同数据集大小和图像分辨率进行敏感性分析?
我特别对不同的图像分辨率(在另一个案例研究中)感兴趣,因为这会影响CPU时间和内存,此外还存在获取高分辨率图像的困难。谢谢
好问题。
我没有进行这项分析,但由于实验速度的原因,研究中经常使用较小的数据集/尺寸的图像。
较大的数据/图像处理起来需要很长时间。
嗨,Jason,好帖子。我的代码出了问题。
当我运行
“# 总结像素值
print(‘Train’, train_images.min(), train_images.max(), train_images.mean(), train_images.std())”
控制台卡住了,您也遇到过吗?
很抱歉听到这个消息,我在这里有一些建议。
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
先生您好,我在如何使用CNN构建多类分类器来解决图像分类问题上遇到了一些困难,我需要一些帮助,我是机器学习的新手。
嗨,Rayane……以下内容可能对您有帮助
https://machinelearning.org.cn/how-to-develop-a-convolutional-neural-network-to-classify-satellite-photos-of-the-amazon-rainforest/