深度学习作业-图像识别

一、AlexNet进行中文字体的识别
	1 、数据准备
	2 、构造数据生成器
	3 、输出图像
	4 、AlexNet代码实现
		1 .模型结构搭建
		2 .模型编译
		3 .模型运行与拟合
二、自搭建网络进行中文字体的识别
	1 、数据准备
	2 、构造数据生成器
	3 、自搭建模型代码实现
		1 .模型结构搭建
		2 .模型运行与拟合
		3 .对新预测集进行模型预测
			1 .使用带泄露的ReLU函数
			2 .模型中不使用dropout
结论

数据背景

本次作业任务为文本字体识别,也即给定文本图像,判断该文本属于哪一类字体,是一个图像识别问题。具体字体类别有隶书、行楷两种,故而这是一个二分类问题。

主要使用以下两种方法:①使用AlexNet网络结构进行中文字体识别;②通过自搭建网络进行字体识别。

一、AlexNet进行中文字体的识别

AlexNet一共有 8 层。分别是卷积层-池化层-卷积层-池化层-卷积层-卷积层-卷积层-池化层-输出层(三个全连接层)。关于模型的详细结构组成,将在 41.模型结构搭建 一节进行说明。

AlexNet的创新点有:

  • 使用ReLU作为CNN的激活函数;
  • 使用Dropout方法来随机丢弃一部分神经元,解决模型的过拟合问题;
  • 在CNN中使用重叠的最大值池化(步长小于卷积核);
  • 提出局部响应归一化层(Local Response Normalization,LRN), 但是后来逐渐被BN(Batch Normalization)代替;
  • 使用CUDA加速神经网络的训练,利用了GPU强大的计算能力;
  • 采用了数据增强(Data Augmentation)技术,达到增加样本量的目的。
# 加载函数包:
import tensorflow as tf
import keras

1 、数据准备

AlexNet对于数据的存储目录结构有特殊的要求,因为传统数据分析一般是把数据集一次性完整地读入内存,然后进行分析。但是在深度学习中,数据量通常较大,就需要把数据分批次、随机读入。所以把ChineseStyle当作存储数据的核心根目录,根目录下包含两个目录,分别是训练数据和测试数据。两个目录下面又分别有两个目录,分别存放着隶书字体的图片和行楷字体的图片, 目的就是让程序自动识别为一个二分类问题 。而且训练和测试目录下两个字体目录的名字必须完全相同。

%ls /mnt/ChineseStyle/
%ls /mnt/ChineseStyle/train
%ls /mnt/ChineseStyle/test

2 、构造数据生成器

数据生成器是一种特有的数据读入方法,按照特定的目录结构和要求把相应少量的、多批次的数据读入内存,做相应的数据分析。这样可以在有限的内存资源的支持下,处理非常大的数据,但是会造成效率的降低。

这里使用ImageDataGenerator函数来构造两个数据生成器,一个生成验证数据集,一个生成训练数据
集。

from keras.preprocessing.image import ImageDataGenerator
IMSIZE = 227
validation_generator = ImageDataGenerator(rescale = 1./ 255 ).flow_from_directory(
'/mnt/ChineseStyle/test', #从本地目录中读取数据,程序会自动识别该目录下的两个字体目录,
识别为二分类问题
target_size = (IMSIZE, IMSIZE), #统一原始图像的像素规格
batch_size = 200 , #定义batchsize = 200,也就是每次读取 200 张图像进入内存
class_mode = 'categorical') #因变量是一个分类变量
train_generator = ImageDataGenerator(rescale = 1./ 255 ).flow_from_directory(
'/mnt/ChineseStyle/train',
target_size = (IMSIZE, IMSIZE),
batch_size = 200 ,
class_mode = 'categorical')

3 、输出图像

在进行字体识别之前,首先对生成的图像进行预览,确认生成的图片数据是否存在问题。

from matplotlib import pyplot as plt
plt.figure()
fig, ax = plt.subplots( 2 , 5 )
fig.set_figheight( 7 )
fig.set_figwidth( 15 )
ax = ax.flatten()
X, Y = next(validation_generator) #把validation_generator数据生成器输入给next命令,每
执行一次next,就会输出一张图像。

for i in range( 10 ): ax[i].imshow(X[i, :, :, :])

深度学习图像处理评价指标是什么 图像处理深度识别_python


在上述十幅图中,图 1 、 2 、 3 、 4 、 6 为行楷,图 5 、 6 、 8 、 9 、 10 为隶书。接下来将基于上述图像进行模型训练与模型识别测试。

4 、AlexNet代码实现

# 加载函数包:
from keras.layers import Activation, Conv2D, BatchNormalization, Dense
from keras.layers import Dropout, Flatten, Input, MaxPooling2D, ZeroPadding2D
from keras import Model
1.模型结构搭建

接下来搭建AlexNet网络结构模型,将其作为图像识别模型。

IMSIZE = 227
input_layer = Input([IMSIZE, IMSIZE, 3 ])
x = input_layer
x = Conv2D( 96 , [ 11 , 11 ], strides = [ 4 , 4 ], activation = 'relu')(x) #第一层卷积核,
大小为11*
x = MaxPooling2D([ 3 , 3 ], strides = [ 2 , 2 ])(x) #第二层:最大值池化
x = Conv2D( 256 , [ 5 , 5 ], padding = 'same', activation = 'relu')(x) #第三层卷积核:
5*
x = MaxPooling2D([ 3 , 3 ], strides = [ 2 , 2 ])(x)
x = Conv2D( 384 , [ 3 , 3 ], padding = 'same', activation = 'relu')(x)
x = Conv2D( 384 , [ 3 , 3 ], padding = 'same', activation = 'relu')(x)
x = Conv2D( 256 , [ 3 , 3 ], padding = 'same', activation = 'relu')(x)
x = MaxPooling2D([ 3 , 3 ], strides = [ 2 , 2 ])(x)
x = Flatten()(x)
x = Dense( 4096 , activation = 'relu')(x)
x = Dropout(0.5)(x)
x = Dense( 4096 , activation = 'relu')(x)
x = Dropout(0.5)(x)
x = Dense( 2 , activation = 'softmax')(x)
output_layer = x

model = Model(input_layer, output_layer)
model.summary() #观察模型的结构展示

深度学习图像处理评价指标是什么 图像处理深度识别_池化_02

对上述模型结构作如下解释:

  1. 输入层。一张像素为227×227的图像,共有 3 个颜色通道。
  2. 卷积层。将输入与 96 个大小为11×11的卷积核进行valid卷积,步长为 4 ,使用ReLU函数作为激活函数。由于 (227-11)/4+1 = 55 ,卷积后的结果为像素55×55,深度为 96 。在此过程中,需要消耗 (11113+1)*96 = 34944 个参数。
  3. 池化层。池化层的大小为3×3,步长为 2 。进行valid最大值池化,根据 (55-3)/2+1 = 27 ,得到的像素矩阵大小为27×27,通道数为 96 不改变。
  4. 卷积层。将上一级输入矩阵与 256 个大小为5×5的卷积核进行same卷积,使用ReLU函数作为激活函数。因此输出像素矩阵为27×27×256。在此过程中,需要消耗 (5596+1)*256 = 614656 个参数。
  5. 池化层。池化层的大小为3×3,进行valid池化,步长设置为 2 。根据 (27-3)/2+1 = 13,输出的像素矩阵大小为13×13,通道数为 256 不改变。
  6. 卷积层。使用 384 个大小为3×3的卷积核提取图像特征,进行same卷积,使用ReLU函数作为激活函数。输出像素矩阵为13×13×384。在此过程中,需要消耗 (33256+1)*384 = 885120 个参数。
  7. 卷积层。使用 384 个大小为3×3的卷积核提取图像特征,进行same卷积,使用ReLU函数作为激活函数。输出像素矩阵为13×13×384。在此过程中,需要消耗 (33384+1)*384 = 1327488 个参数。
  8. 卷积层。使用 256 个大小为3×3的卷积核提取图像特征,进行same卷积,使用ReLU函数作为激活函数。输出像素矩阵为13×13×256。在此过程中,需要消耗 (33256+1)*256 = 884992 个参数。
  9. 池化层。池化层的大小为3×3,步长为 2 。进行valid最大值池化,根据 (13-3)/2+1 = 6 ,得到的像素矩阵大小为6×6,通道数为 256 不改变。
  10. 向量拉直。使用Flatten()函数将向量拉直,输出的变量为长度为 66256 = 9216 的数组。
  11. 全连接层。在全连接层生成 4096 个神经元,使用ReLU函数作为激活函数。在这个过程中,需要 (9216+1)*4096 = 37752832 个参数。
  12. Dropout操作。为防止过拟合,设置神经元的失活概率为0.5。
  13. 全连接层。在全连接层生成 4096 个神经元,使用ReLU函数作为激活函数。在这个过程中,需要 (4096+1)*4096 = 16781312 个参数。
  14. Dropout操作。为防止过拟合,设置神经元的失活概率为0.5。
  15. 输出层。由于本问题为二分类问题,最后使用one-hot编码下的生成结果标量,因此输出层共 2 个神经元。使用softmax函数作为激活函数。在这个过程中,需要 (4096+1)*2 = 8194 个参数。
2.模型编译
from keras.optimizers import Adam
model.compile(loss = 'categorical_crossentropy', optimizer = Adam(lr = 0.001),
metrics = ['accuracy'])

对上述参数设定进行解释:

  • 损失函数为对数似然函数,这个似然函数在TesorFlow框架下为categorical_crossentropy;
  • 优化方法为Adam算法,学习率为0.001;
  • 评价指标为预测精度(因为是分类问题)。
3.模型运行与拟合
model.fit_generator(train_generator, epochs = 20 , validation_data =
validation_generator)
# 使用 20 个epoch进行模型拟合

深度学习图像处理评价指标是什么 图像处理深度识别_深度学习图像处理评价指标是什么_03

上述结果显然有,AlexNet模型对本数据的拟合和预测效果很好。 具体体现在如下方面:

  • 在训练集上,训练到第三个Epoch时模型损失已不到0.01,准确率超过99.5%。训练至第 11 个 Epoch,损失函数已低于10^-4,准确率100%。
  • 在测试集上,第一个Epoch训练完毕时,模型已经达到很好的拟合效果——损失函数不到0.05取值,准确率近99%。至训练完第八个Epoch,损失函数取值基本稳定在 一下,准确率在99.85%附近。

二、自搭建网络进行中文字体的识别

1 、数据准备

由于在上一案例中,用于训练、测试的分别是原训练集自划分的训练集和测试集。因此,在本次改良中,对数据进行手动处理,而不使用原本的train和test,以避免原本训练集划分可能的非随机性影响。

from os import listdir
from os.path import isfile, join

l = ([],[])
for n in ['train','test']:
for t in ['lishu','xingkai']:
IMG_DIR = 'ChineseStyle/'+n+'/'+t
files = [IMG_DIR+'/'+f for f in listdir(IMG_DIR) if isfile(join(IMG_DIR,
f))]
l[ 0 ].extend(files)
l[ 1 ].extend([t]*len(files))
data = pd.DataFrame(pd.DataFrame(l).values.T,columns=['images','type'])
data.head()

深度学习图像处理评价指标是什么 图像处理深度识别_图像识别_04

2 、构造数据生成器

#创建文件夹
import os
from shutil import copyfile
os.mkdir('train/')
os.mkdir('test/')
os.mkdir('val/')
for class_ in data['type'].unique():
os.mkdir('train/'+str(class_)+'/')
os.mkdir('test/'+str(class_)+'/')
os.mkdir('val/'+str(class_)+'/')

from sklearn.model_selection import train_test_split
from shutil import copyfile, copy

X_train, X_test, y_train, y_test = train_test_split(data,
data['type'],test_size=0.4, stratify=data['type'])
X_test, X_val, y_test, y_val = train_test_split(X_test, y_test,
test_size=0.33,stratify=y_test)

for image,type_ in zip(X_train['images'], y_train):
copy2(image, 'train/'+type_)
for image,type_ in zip(X_test['images'], y_test):
copy2(image, 'test/'+type_)
for image,type_ in zip(X_val['images'], y_val):
copy2(image, 'val/'+type_)

from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator()

train = datagen.flow_from_directory('train/',batch_size = 128 ) #本次定义batchsize
= 128,也就是每次读取 128 张图像进入内存
test = datagen.flow_from_directory('test/',batch_size = 128 )
val = datagen.flow_from_directory('val/',batch_size = 128 )

深度学习图像处理评价指标是什么 图像处理深度识别_池化_05

3 、自搭建模型代码实现

1.模型结构搭建
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten,
Dense, Activation, BatchNormalization, Lambda
from tensorflow.keras.preprocessing.image import ImageDataGenerator

def build():
	model = Sequential()
	IMAGE_WIDTH = 256
	IMAGE_HEIGHT = 256 #图片原始尺寸
	IMAGE_CHANNELS = 3 #此处也可以用 1 ,此时在上一步读取时在flow_from_directory将color设置为灰度
	模式,但结果上没有区别
	model.add(Lambda(lambda x: x, input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT,
	IMAGE_CHANNELS)))
	
	#连续交替使用 3 个卷积层和池化层,中间加入BatchNormalization,每个池化层后随机dropout
	25%
	#卷积层步长均为 1 ,卷积核2*2*32/64/128,池化层采样区域为3*3,方式为最大汇聚
	model.add(Conv2D( 32 , ( 2 , 2 ), activation='relu'))
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	model.add(Dropout(0.25))
	
	model.add(Conv2D( 64 , ( 2 , 2 ), activation='relu'))
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	model.add(Dropout(0.25))
	
	model.add(Conv2D( 128 , ( 2 , 2 ), activation='relu'))
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	model.add(Dropout(0.25))
	
	#偏平化数据,加入 512 个神经元的全连接层提取特征,激活函数为relu,之后
	BatchNormalization,并dropout 50%
	model.add(Flatten())
	model.add(Dense( 512 , activation='relu'))
	model.add(BatchNormalization())
	model.add(Dropout(0.5))
	
	#输出结果,激活函数为softmax
	model.add(Dense( 2 , activation='softmax'))
	
	#定义损失函数为二分类交叉熵,优化器为Adam Optimizer
	model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc'])
	
	model.summary()
	return model
model = build()

深度学习图像处理评价指标是什么 图像处理深度识别_图像识别_06

对上述模型结构作如下解释:

  1. 输入层。一张像素为256×256的图像,共有 3 个颜色通道。
  2. 卷积层。将输入与 32 个大小为2×2的卷积核进行valid卷积,步长为 1 ,使用ReLU函数作为激活函数。由于 (2562)/1+1 = 255 ,卷积后的结果为像素255×255,深度为 32 。在此过程中,需要消耗 (22*3+1)*32 = 416 个参数。
  3. 批归一化。也即BatchNormalization()操作。在此过程中,需要消耗 4*32 = 128 个参数。
  4. 池化层。池化层的大小为3×3,进行valid池化,步长设置为 3 。根据 (256-3)/3+1 = 85 ,输出的像素矩阵大小为85×85,通道数为 32 不改变。
  5. Dropout操作。为防止过拟合,设置神经元的失活概率为0.25。
  6. 卷积层。将输入与 64 个大小为2×2的卷积核进行valid卷积,步长为 1 ,使用ReLU函数作为激活函数。由于 (85-2)/1+1 = 84 ,卷积后的结果为像素84×84,深度为 64 。在此过程中,需要消耗 (2232 + 1) * 64 = 8256 个参数。
  7. 批归一化。在此过程中,需要消耗 4*64 = 256 个参数。
  8. 池化层。池化层的大小为3×3,进行valid池化,步长设置为 3 。根据 (84-3)/3+1 = 28 ,输出的像素矩阵大小为28×28,通道数为 64 不改变。
  9. Dropout操作。为防止过拟合,设置神经元的失活概率为0.25。
  10. 卷积层。将输入与 128 个大小为2×2的卷积核进行valid卷积,步长为 1 ,使用ReLU函数作为激活函数。由于 (28-2)/1+1 = 27,卷积后的结果为像素27×27,深度为 128 。在此过程中,需要消耗 (2264 + 1) * 128 = 32896 个参数。
  11. 批归一化。在此过程中,需要消耗 4*128 = 512 个参数。
  12. 池化层。池化层的大小为3×3,进行valid池化,步长设置为 3 。根据 (27-3)/3 + 1 = 9 ,输出的像素矩阵大小为9×9,通道数为 128 不改变。
  13. Dropout操作。为防止过拟合,设置神经元的失活概率为0.25。
  14. 向量拉直。使用Flatten()函数将向量拉直,输出的变量为长度为 99128 = 10368 的数组。
  15. 全连接层。在全连接层生成 512 个神经元,使用ReLU函数作为激活函数。在这个过程中,需要 (10368+1)*512 = 5308928 个参数。
  16. 批归一化。在此过程中,需要消耗 4*512 = 2048 个参数。
  17. Dropout操作。为防止过拟合,设置神经元的失活概率为0.5。
  18. 输出层。由于本问题为二分类问题,最后使用one-hot编码下的生成结果标量,因此输出层共 2 个神经元。使用softmax函数作为激活函数。在这个过程中,需要 (512+1)*2 = 1026 个参数。

同时完成了模型编译工作:

  • 损失函数为对数似然函数,这个似然函数在TesorFlow框架下为categorical_crossentropy;
  • 优化方法为Adam算法,学习率为0.001;
  • 评价指标为预测精度(因为是分类问题)。
2.模型运行与拟合
history = model.fit_generator(train, epochs= 10 , validation_data=test)
model.save('my_model.h5')

深度学习图像处理评价指标是什么 图像处理深度识别_python_07

可见自搭建模型对本数据的拟合和预测效果也较好。

  • 在训练集上,训练第 1 个Epoch时模型损失已不到0.05,准确率已达到98.9%。训练至第 6 个 Epoch,损失函数已低于,准确率在99.8%附近并缓步增加。由于使用了dropout()操作,对 训练集的拟合效果不如AlexNet模型,但已经达到了很高的水平。
  • 在测试集上,第一个Epoch训练完毕时,模型已经达到很好的拟合效果——损失函数不到0.05取值,准确率为98.4%。至训练完第 7 个Epoch,损失函数取值基本稳定在0.02左右,准确率在99.5%以上。

并进一步考察模型预测效果,对验证集以及预测集考察分类准确度、召回率、f1分数以及预测正确的结果数。

from sklearn.metrics import classification_report
import pandas as pd
import numpy as np
def report(model,data):
	predict = model.predict_generator(data)
	y_p = np.argmax(predict, axis=- 1 )
	y_r = data[ 0 ][ 1 ]
	for i in range( 1 ,len(data)):
	y_r = np.vstack((y_r,data[i][ 1 ]))
	y_r = np.argmax(y_r, axis=- 1 )
	print(classification_report(y_p,y_r))

report(model,test)
report(model,val)

深度学习图像处理评价指标是什么 图像处理深度识别_卷积_08

同样可得出模型拟合效果极好的结论。

3.对新预测集进行模型预测

对新的预测集进行预测,考量模型的泛化能力。

test_unshuffle = datagen.flow_from_directory('test/',batch_size =
128 ,shuffle=False)
val_unshuffle = datagen.flow_from_directory('val/',batch_size =
128 ,shuffle=False)

深度学习图像处理评价指标是什么 图像处理深度识别_python_09

predict = model.predict_generator(test_unshuffle)

data = test_unshuffle
y_p = np.argmax(predict, axis=- 1 )
y_r = data[ 0 ][ 1 ]
for i in range( 1 ,len(data)):
y_r = np.vstack((y_r,data[i][ 1 ]))
y_r = np.argmax(y_r, axis=- 1 )
errors = (y_p - y_r != 0 )

接下来查看预测错误的概率差距有多大,越接近 1 说明该错误预测在模型中影响越大。且从结果上,发现对隶书结果的错误预测影响更大。

m = []
for p in predict[errors]:
m.append(p[ 0 ]-p[ 1 ])
m

深度学习图像处理评价指标是什么 图像处理深度识别_python_10

展示错误预测结果。可以发现: 模型预测错误的结果基本是较为简单的形状 。

from PIL import Image
import matplotlib.pyplot as plt
tus = np.array(test_unshuffle.filenames)
for imag in tus[errors]:
img = Image.open('test/'+imag)
fig = plt.figure()
plt.imshow(img)

深度学习图像处理评价指标是什么 图像处理深度识别_池化_11

深度学习图像处理评价指标是什么 图像处理深度识别_图像识别_12

深度学习图像处理评价指标是什么 图像处理深度识别_图像识别_13

深度学习图像处理评价指标是什么 图像处理深度识别_python_14

1.使用带泄露的ReLU函数

考虑使用带泄露的ReLU作为激活函数,当净输出小于 0 时,以alpha = 0.1输出结果。

from tensorflow import keras
def build2():
	LeakyReLU = keras.layers.LeakyReLU(alpha=0.01)
	model = Sequential()
	IMAGE_WIDTH = 256
	IMAGE_HEIGHT = 256
	IMAGE_CHANNELS = 3
	model.add(Lambda(lambda x: x, input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT,
	IMAGE_CHANNELS)))
	model.add(Conv2D( 32 , ( 2 , 2 ), activation=LeakyReLU))
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	model.add(Dropout(0.25))
	
	model.add(Conv2D( 64 , ( 2 , 2 ), activation=LeakyReLU))
	
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	model.add(Dropout(0.25))
	
	model.add(Conv2D( 128 , ( 2 , 2 ), activation=LeakyReLU))
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	model.add(Dropout(0.25))
	
	model.add(Flatten())
	model.add(Dense( 512 , activation='relu'))
	model.add(BatchNormalization())
	model.add(Dropout(0.5))
	model.add(Dense( 2 , activation='softmax'))
	
	model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc'])
	
	model.summary()
	return model
model = build2()

除激活函数变化外,相较原始搭建模型,模型不做其他变化,因此不再对模型结构进行解读。使用 5 个Epoch做训练。

history = model.fit_generator(train, epochs= 5 , validation_data=val)

深度学习图像处理评价指标是什么 图像处理深度识别_python_15


根据结果显示:,模型效果与使用ReLU函数作为激活函数的差异不大。

2.模型中不使用dropout

def build3():
	model = Sequential()
	IMAGE_WIDTH = 256
	IMAGE_HEIGHT = 256
	IMAGE_CHANNELS = 3
	model.add(Lambda(lambda x: x, input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT,
	IMAGE_CHANNELS)))
	model.add(Conv2D( 32 , ( 2 , 2 ), activation='relu'))
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	model.add(Conv2D( 64 , ( 2 , 2 ), activation='relu'))
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	
	model.add(Conv2D( 128 , ( 2 , 2 ), activation='relu'))
	model.add(BatchNormalization())
	model.add(MaxPooling2D(pool_size=( 3 , 3 )))
	
	model.add(Flatten())
	model.add(Dense( 512 , activation='relu'))
	model.add(BatchNormalization())
	model.add(Dense( 2 , activation='softmax'))
	
	model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc'])
	
	model.summary()
	return model
model = build3()

除去掉dropout操作外,相较原始搭建模型,模型不做其他变化,因此不再对模型结构进行解读。使用 5
个Epoch做训练。

history = model.fit_generator(train, epochs= 5 , validation_data=val)

根据上述结果,去掉dropout后:

  • 训练集精度大幅上升,第 4 个Epoch训练完毕后,损失函数值已低于 ,准确率达到并稳定在 100%。
  • 由于过拟合,测试集在一开始时拟合效果不佳。但训练完第三个Epoch后,准确率已近似99%,损失函数值很低。可能是数据本身结构较为接近,不容易出现过拟合。

结论

本次二分类的图像识别问题(判断图像中汉字的字体是隶书还是行楷)分别使用了AlexNet模型、自搭建模型及其衍变(将激活函数修改为带泄露的ReLU函数/去掉dropout操作两种 )一共四个模型完成。结果显示每个模型的拟合、预测效果都十分良好,在训练 3 个Epoch后,训练集、测试集的拟合准确率基本已超98.5%。少量错误预测的实例为比较简单的笔画形状,图像中所含特征信息较少。