卷积神经网络概述和Python程序实现
- 了解卷积
- 了解神经网络
- 数据预处理
- 了解CNN
- 了解优化器
- 了解ImageDataGenerator 进行预测并计算准确性
- demo
什么是卷积?
在数学(尤其是泛函分析)中,卷积是对两个函数(f 和 g)进行的数学运算,用于创建第三个函数,该函数表示一个函数的形状如何被另一个函数改变。 (来源:维基百科)
此运算用于概率、统计、计算机视觉、自然语言处理、图像和信号处理、工程和微分方程等各个领域。该运算在数学上表示为: 卷积运算
要更直观地了解卷积运算,请参阅此链接。
什么是人工神经网络?
人工神经网络 (ANN) 或连接系统是松散模拟构成动物大脑的生物神经网络的计算机系统。这些系统通过从示例中“学习”来执行任务,通常不需要使用特定规则进行编程。 (来源:维基百科)
人工神经网络是称为人工神经元的较小处理单元的集合,类似于生物神经元。
生物神经回路
神经元之间互连构成网络模型
人工神经网络
现在开始具体实现。
导入必要的数据包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import tflearn.data_utils as du
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from keras.optimizers import RMSprop
from keras.preprocessing.image import ImageDataGenerator
from sklearn.metrics import confusion_matrix
加载数据集
train_data = pd.read_csv('../input/csvTrainImages 13440x1024.csv', header = None)
train_label = pd.read_csv('../input/csvTrainLabel 13440x1.csv', header = None)
test_data = pd.read_csv('../input/csvTestImages 3360x1024.csv', header = None)
test_label = pd.read_csv('../input/csvTestLabel 3360x1.csv', header = None)
数据集
这里使用的数据集是手稿数据集。
trainIamges.csv 有 1024 列和 13440 行。每列代表图像中的一个像素,每行代表一个单独的灰度图像。每个像素的取值范围为 0 到 255 之间。
train_data = train_data.iloc[:,:].values.astype('float32')
train_label = train_label.iloc[:,:].values.astype('int32')-1
test_data = test_data.iloc[:,:].values.astype('float32')
test_label = test_label.iloc[:,:].values.astype('int32')-1
可视化数据集
def row_calculator(number_of_images, number_of_columns):
if number_of_images % number_of_columns != 0:
return (number_of_images / number_of_columns)+1
else:
return (number_of_images / number_of_columns)
def display_image(x, img_size, number_of_images):
plt.figure(figsize = (8, 7))
if x.shape[0] > 0:
n_samples = x.shape[0]
x = x.reshape(n_samples, img_size, img_size)
number_of_rows = row_calculator(number_of_images, 4)
for i in range(number_of_images):
plt.subplot(number_of_rows, 4, i+1)
plt.imshow(x[i])
训练数据集
display_image(train_data, 32, 16)
测试数据集
display_image(test_data, 32, 16)
数据预处理
编码分类变量
什么是分类变量?
在统计学中,分类变量是可以充当限制变量之一的变量,根据某些定性属性将每个个体或其他观察单位分配给特定组或名义类别。 (来源:维基百科)
简单地说,分类变量的值代表类别或类别。
为什么需要对分类变量进行编码?
直接对代表类别的数字进行运算是没有意义的。因此,需要对其进行分类和编码。
请参阅此链接以获取分类变量的示例。
阿拉伯字母中有28个字母。因此,数据集有 28 个类别。
train_label = du.to_categorical(train_label,28)
标准化
什么是标准化?
归一化,使整个数据处于一个明确的范围内,一般选择0到1之间的归一化
在神经网络中,数据不仅要标准化,还要标量化,这样处理的目的是更快地接近误差面的全局最小值。 (来源:Stack Overflow)
train_data = train_data/255
test_data = test_data/255
train_data = train_data.reshape([-1, 32, 32, 1])
test_data = test_data.reshape([-1, 32, 32, 1])
扭曲,使数据的每个部分代表一个平面图像
train_data, mean1 = du.featurewise_zero_center(train_data)
test_data, mean2 = du.featurewise_zero_center(test_data)
使用功能将每个样本的中心归零并确定平均值。如果未指定,则估计所有样本的平均值。
创建 CNN
recognizer = Sequential()
recognizer.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', activation ='relu', input_shape = (32,32,1)))
recognizer.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', activation ='relu'))
recognizer.add(MaxPool2D(pool_size=(2,2)))
recognizer.add(Dropout(0.25))
recognizer.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', activation ='relu'))
recognizer.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', activation ='relu'))
recognizer.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))
recognizer.add(Dropout(0.25))
recognizer.add(Flatten())
recognizer.add(Dense(units = 256, input_dim = 1024, activation = 'relu'))
recognizer.add(Dense(units = 256, activation = "relu"))
recognizer.add(Dropout(0.5))
recognizer.add(Dense(28, activation = "softmax"))
什么是最大池化?
聚合是指将一组数据进行组合,数据聚合过程中必须遵循一些规则。
根据定义,最大连接选择数据集中的最大值作为其输出值。 (来源:machinelearningonline.blog)
最大聚类还可以用来降低特征的维数,同时也可以避免过拟合的现象。查看此博客以更好地了解最大池化。
什么是 Dropout?
Dropout 是一种正则化技术,可通过防止训练数据的复杂协同拟合来减少神经网络的过度拟合。这是神经网络模型中最有效的方法之一。 “损失”是指神经网络中以一定概率随机丢弃一些神经单元。 (来源:维基百科)
什么是扁平化?
展平特征图,将多维数据转换为一维特征向量,以便在下一层(密集层)中使用
什么是密集层?
密集层只是一个人工神经网络层,也称为全连接层。
CNN优化方法
什么是优化?
优化算法帮助我们最小化(或最大化)目标函数,这只是一个依赖于模型中可学习参数的数学函数。目标值 (Y) 使用模型中的一组预测变量 (X) 计算。例如,神经网络的权重(W)和偏差(b)的值称为其内部可学习参数,用于计算输出值并学习和更新这些参数以达到最佳解决方案,即最小化网络损失。这就是训练神经网络的过程。 (来源:Data Science)
optimizer = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
本文使用的优化器是 RMSprop,点击此处了解有关 RMSprop 的更多信息。
recognizer.compile(optimizer = optimizer , loss = "categorical_crossentropy", metrics=["accuracy"])
什么是 ImageDataGenerator?
当您的数据集规模相对较小时,您可以使用图像数据生成器,它用于创建具有实时增强功能的批量张量图像数据以扩展数据集。一般来说,随着数据量的增加,模型的性能会提高。以下代码用于批量加载图像:
datagen = ImageDataGenerator(
featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=10,
zoom_range = 0.1,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=False,
vertical_flip=False)
datagen.fit(train_data)
CNN 拟合训练数据
recognizer.fit_generator(datagen.flow(train_data,train_label, batch_size=100), epochs = 30, verbose = 2, steps_per_epoch=train_data.shape[0] // 100)
进行预测
predictions = recognizer.predict(test_data)
predictions = np.argmax(predictions,axis = 1)
创建混淆矩阵
什么是混淆矩阵?
混淆矩阵是一种用于总结分类算法性能的技术。如果每个类别中的观察数量不等,或者数据集中有两个以上的类别,则分类本身的准确性可能会产生误导。计算混淆矩阵可以让我们更好地了解分类模型的正确程度以及它产生的错误类型。来源:machinelearningonline.blog
cm = confusion_matrix(test_label, predictions)
计算精度
accuracy = sum(cm[i][i] for i in range(28)) / test_label.shape[0]
print("accuracy = " + str(accuracy))
本文达到了97%的准确率。有兴趣的读者可以自己尝试一下。
CNN 手写数字识别演示
点击此链接可实时观看 CNN 的实际操作。演示展示了CNN的工作流程以及各层的特征图输出。最后,CNN 被训练来识别手写数字。
以上是阿里云云栖社区组织翻译的翻译。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网

发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。