Inception V1(或GoogLeNet)是ILSRVRC 2014上的最新体系结构。它在ImageNet分类数据集中创纪录地实现了最低错误率,但在某些方面仍然可以改进以提高准确性并降低模型的复杂度。
Inception V1体系结构的问题
Inception V1往往使用5*5的卷积,这会导致输入尺寸大幅度减少,这导致神经网络的某些精度下降。如果输入维度急剧减小,神经网络很容易受到信息丢失的影响。
Inception V2中的体系结构更改
在Inception V2体系结构中,5×5卷积被两个3×3卷积代替,这减少了计算时间,提高了计算速度,因为5×5卷积比3×3卷积的计算量多2.78。 因此,使用两个3×3而不是5×5可以提高体系结构的性能。
该架构还将nXn分解转换为1xn和nx1分解。 如上述,可以将3×3卷积转换为1×3,然后再进行3×1卷积,与3×3相比,这在计算复杂度方面简单了33%。
为了解决主要的瓶颈问题,扩展模块的功能库,而不是对结构加深。 这样可以防止由于加深而造成的信息丢失。
Inception V3中的体系结构更改
Inception V3与Inception V2相似,包含Inception V2的所有功能,并具有以下变化:
- 使用RMSprop优化器。
- 辅助分类器的全连接层的批处理规范化。
- 使用7×7分解卷积
- 标签平滑正则化:这是一种通过估计训练期间标签丢失的情况来正则化分类器的方法。 它防止分类器过分自信地预测分类,标签平滑的添加使错误率提高了0.2%。
结构
以下是Inception V2的逐层详细信息:
上面的架构的图像输入大小为(299,299,3)。 注意,以上架构图中的图5、6、7是本文中的图1、2、3。
实现方式
在本节中,我们将研究Inception V3的实现。 我们使用Keras应用程序API加载模块,将Cats vs Dogs数据集用于此实现。
代码:导入所需的模块。
import os
import zipfile
import tensorflow as tf
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import layers
from tensorflow.keras import Model
from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.optimizers import RMSprop
代码:创建目录以准备数据集
local_zip = '/dataset/cats_and_dogs_filtered.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('/tmp')
zip_ref.close()
base_dataset_dir = '/tmp/cats_and_dogs_filtered'
train_dir = os.path.join(base_dataset_dir, 'train')
validation_dir = os.path.join(base_dataset_dir, 'validation')
# Directory with our training cat pictures
train_cats = os.path.join(train_dir, 'cats')
# Directory with our training dog pictures
train_dogs = os.path.join(train_dir, 'dogs')
# Directory with our validation cat pictures
validation_cats = os.path.join(validation_dir, 'cats')
# Directory with our validation dog pictures
validation_dogs = os.path.join(validation_dir, 'dogs')
代码:将数据集存储在上面创建的目录中,并绘制一些示例图像。
# Set up matplotlib fig, and size it to fit 4x4 pics
import matplotlib.image as mpimg
nrows = 4
ncols = 4
fig = plt.gcf()
fig.set_size_inches(ncols*4, nrows*4)
pic_index = 100
train_cat_files = os.listdir( train_cats )
train_dog_files = os.listdir( train_dogs )
next_cat_img = [os.path.join(train_cats, fname)
for fname in train_cat_files[ pic_index-8:pic_index]
]
next_dog_img = [os.path.join(train_dogs, fname)
for fname in train_dog_files[ pic_index-8:pic_index]
]
for i, img_path in enumerate(next_cat_img+next_dog_img):
# Set up subplot; subplot indices start at 1
sp = plt.subplot(nrows, ncols, i + 1)
sp.axis('Off') # Don't show axes (or gridlines)
img = mpimg.imread(img_path)
plt.imshow(img)
plt.show()
代码:数据扩充以增加数据集中的数据样本。
train_datagen = ImageDataGenerator(rescale = 1./255.,
rotation_range = 50,
width_shift_range = 0.2,
height_shift_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
test_datagen = ImageDataGenerator( rescale = 1.0/255. )
train_generator = train_datagen.flow_from_directory(train_dir,
batch_size = 20,
class_mode = 'binary',
target_size = (150, 150))
validation_generator = test_datagen.flow_from_directory( validation_dir,
batch_size = 20,
class_mode = 'binary',
target_size = (150, 150))
代码:使用我们上面导入的Inception API定义基本模型,并使用回调函数来训练模型。
base_model = InceptionV3(input_shape = (150, 150, 3),
include_top = False,
weights = 'imagenet')
for layer in base_model.layers:
layer.trainable = False
#stop training is model accuracy reached 99%
class myCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs={}):
if(logs.get('acc')>0.99):
self.model.stop_training = True
在这一步中训练模型,但是在训练之前,我们需要更改最后一层,使它只能预测一个输出并使用优化器进行训练。 在这里,我们使用RMSprop的学习率为0.0001,并且在最后一个全连接层之后添加一个dropout为0.2。 之后,我们训练模型最多100次。
代码:
# code
x = layers.Flatten()(base_model.output)
x = layers.Dense(1024, activation='relu')(x)
x = layers.Dropout(0.2)(x)
x = layers.Dense (1, activation='sigmoid')(x)
model = Model( base_model.input, x)
model.compile(optimizer = RMSprop(lr=0.0001),loss = 'binary_crossentropy',metrics = ['acc'])
callbacks = myCallback()
history = model.fit_generator(
train_generator,
validation_data = validation_generator,
steps_per_epoch = 100,
epochs = 100,
validation_steps = 50,
verbose = 2,
callbacks=[callbacks])
代码:绘制训练和验证的准确性以及训练和验证的损失。
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'r', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.figure()
plt.plot(epochs, loss, 'r', label='Training Loss')
plt.plot(epochs, val_loss, 'b', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()
结果
表现最佳的Inception V3架构在最新技术ILSVRC 2012分类挑战中,单种作物的top-5误差仅为5.6%,top-1误差为21.2%。 在ILSVRC 2012分类基准中,在多种作物(144种作物)上报告的前5位和前1位错误率分别为4.2%和18.77%。
Inception V3体系结构的整体报告表明,ILSVRC 2012验证集的前五位错误率为3.46%(ILSVRC 2012测试集为3.58%)。
参考https://www.geeksforgeeks.org/inception-v2-and-v3-inception-network-versions/?ref=lbp