vgg16卷积层的计算量_使用预训练的卷积神经网络__keras实现VGG16

本文介绍了如何在Keras中使用预训练的VGG16模型进行图像处理。首先,展示了如何加载并实例化VGG16模型,包括设置权重、是否包含顶层及输入形状。接着,通过提取特征和添加密集连接分类器,展示了两种不同的方法:一种是不使用数据增强的快速特征提取,另一种是端到端的模型训练,包括冻结和微调卷积层。
摘要由CSDN通过智能技术生成

VGG16内置于Keras,可以通过keras.applications模块中导入。

--------------------------------------------------------将VGG16 卷积实例化:-------------------------------------------------------------------------------------------------------------------------------------

1 from keras.applications importVGG162

3 conv_base = VGG16(weights = ‘imagenet‘,#指定模型初始化的权重检查点4 include_top =False,5 input_shape = (150,150,30))

weights:指定模型初始化的权重检查点、

include_top:指定模型最后是否包含密集连接分类器。默认情况下,这个密集连接分类器对应于ImageNet的100个类别。如果打算使用自己的密集连接分类器,可以不适用它,置为False。

input_shape:是输入到网络中的图像张量的形状。这个参数完全是可选的,如果不传入这个参数,那么网络能够处理任意形状的输入。

--------------------------------------------------------查看VGG详细架构:conv_base.summary()----------------------------------------------------------------------------------------------------------

最后一特征图形状为(4,4,512),我们将在这个特征上添加一个密集连接分类器,有两种方式:

在你的数据集上运行卷积基,将输出保存为numpy数组,然后用这个数据做输入,输入到独立的密集连接分类器中。这种方法速度快,计算代价低,因为对于每个输入图像只需运行一次卷积基,而卷积基是日前流程中计算代价最高的。但这种方法不允许使用数据增强。

在顶部添加Dense层来扩展已有模型,并在输入数据上端到端地运行整个模型。这样你可以使用数据增强,因为每个输入图像进入模型时都会经过卷积基。但这种方法的计算代价比第一种要高很多。

#方法一:不使用数据增强的快速特征提取

importosimportnumpy as npfrom keras.preprocessing.image importImageDataGenerator

base_dir= ‘cats_dogs_images‘train_dir= os.path.join(base_dir,‘train‘)

validation_dir= os.path.join(base_dir,‘validation‘)

test_dir= os.path.join(base_dir,‘test‘)

datagen= ImageDataGenerator(rescale = 1./255)#将所有图像乘以1/255缩放

batch_size = 20

defextract_features(directory,sample_count):

features= np.zeros(shape=(sample_count,4,4,512))

labels= np.zeros(shape=(sample_count))#通过.flow或.flow_from_directory(directory)方法实例化一个针对图像batch的生成器,这些生成器#可以被用作keras模型相关方法的输入,如fit_generator,evaluate_generator和predict_generator

generator =datagen.flow_from_directory(‘cats_dogs_images/train‘,

target_size= (150,150),

batch_size=batch_size,

class_mode= ‘binary‘)

i=0for inputs_batch,labels_batch ingenerator:

features_batch=conv_base.predict(inputs_batch)

features[i* batch_size:(i+1) * batch_size] =features_batch

labels[i* batch_size:(i+1)*batch_size] =labels_batch

i+= 1

if i * batch_size >=sample_count:break

returnfeatures,labels

train_features,train_labels= extract_features(train_dir,2000)

validation_features,validation_labels= extract_features(validataion_dir,1000)

test_features,test_labels= extract_features(test_dir,1000)#要减特征(samples,4,4,512)输入密集连接分类器中,首先必须将其形状展平为(samples,8192)

train_features= np.reshape(train_features,(2000,4*4*512))

validation_features= np.reshape(validation_features,(2000,4*4*512))

test_features= np.reshape(test_features,(2000,4*4*512))#定义并训练密集连接分类器

from keras importmodelsfrom keras importlayersfrom keras importoptimizers

model=models.Sequential()

model.add(layers.Dense(256,activation=‘relu‘,input_dim=4*4*512))

model.add(layers.Dropout(0.5))

model.add(layers.Dense(1,activation=‘sigmoid‘))

model.compile(optimizers=optimizers.RMSprop(lr=2e-5),

loss=‘binary_crossentropy‘,

metrics= [‘acc‘])

history=model.fit(train_features,train_labels,

epochs=30,batch_size=20,

validation_data= (Validation_features,validation_labels) )

#在卷积基上添加一个密集连接分类器

from keras importmodelsfrom keras importlayers

model=models.Sequential()

model.add(conv_base)

model.add(layers.Flatten())

model.add(layers.Dense(256,activation=‘relu‘))

model.add(layers.Dense(1,activation=‘sigmoid‘))

model.summary()

如上图,VGG16的卷积基有14714688个参数,非常多。在其上添加的分类器有200万个参数。

在编译和训练模型之前,一定要“冻结”卷积基。

冻结? 指一个或多个层在训练过程中保持其权重不变

如果不这么做,那么卷积基之前学到的表示将会在训练过程中被修改。因为其上添加的Dense层是随机初始化的,所以非常大的权重更新将会在网络中传播,对之前学到的表示造成很大破坏。

在keras中,冻结网络的方法是将其trainable属性设置为False

eg. conv_base.trainable = False

#使用冻结的卷积基端到端地训练模型

from keras.preprocessing.image importImageDataGeneratorfrom kera importoptimizers

train_datagen=ImageDataGenerator(

rescale= 1./255,

rotation_range= 40,

width_shift_range= 0.2,

height_shift_range= 0.2,

shear_range= 0.2,

zoom_range= 0.2,

horizontal_flip=True,

fill_mode= ‘nearest‘)

test_datagen= ImageDataGenerator(rescale=1./255)

train_generator=train_datagen.flow_from_dirctory(

train_dir,

target_size= (150,150),

batch_size= 20,

class_mode= ‘binary‘)

validation_generator=test_datagen.flow_from_dirctory(

validation,

target_size= (150,150),

batch_size= 20,

class_mode= ‘binary‘)

model.compile(optimizer=optimizers.RMSprop(lr=2e-5),

loss=‘binary_crossentropy‘,

metrics= [‘acc‘])

history=model.fit_generator(

train_generator,

steps_per_epoch= 100,

epochs= 30,

validation_data=validation_generator,

validation_steps=50)

--------------------------------------------------------微调模型--------------------------------------------------------------------------------------------------------------------------------------------------------------

另外一种广泛使用的模型复用方法是模型微调,与特征提取互为补充。

对于用于特征提取的冻结的模型基,微调是指将其顶部的几层“解冻”,并将这解冻的几层和新增加的部分联合训练。之所以叫作微调,是因为他只是略微调整了所复用模型中更加抽象的表示,

以便让这些表示与手头的问题更加相关。

冻结VGG16的卷积基是为了能够在上面训练一个随机初始化的分类器。同理,只有上面的分类器训练好了,才能微调卷积基的顶部几层。如果分类器没有训练好,那么训练期间通过网络传播的

误差信号会特别大,微调的几层之前学到的表示都会被破坏。因此,微调网络的步骤如下:

(1)在已经训练好的基网络上添加自定义网络

(2)冻结基网络

(3)训练所添加的部分

(4)解冻基网络的一些层

(5)联合训练解冻的这些层和添加的部分

#微调模型

model.compile(loss=‘binary_crossentropy‘,

optimizer= optimizers.RMSprop(lr=1e-5),

metrics= [‘acc‘])

history=model.fit_generator(

train_generator,

steps_per_epoch=100,

epochs= 100,

validation_data=validation_generator,

validation_steps= 50)

test_generator=test_datagen.flow_from_directory(

test_dir,

target_size= (150,150),

batch_size= 20,

class_mode= ‘binary‘)

test_loss,test_acc= model.evaluate_generator(test_generator,steps=50)

为什么不微调更多层?为什么不微调整个卷积基?当然可以这么做,但需要先考虑以下几点:

(1)卷积基中更靠底部的层编码的是更加通用的可复用特征,而更靠顶部的层编码的是更专业化的特征。微调这些更专业化的特征更加有用,因为它们需要在你的新问题上改变用途。

微调更靠底部的层,得到的汇报会更少

(2)训练的参数越多,过拟合的风险越大。卷积基有1500万个参数,所以在你的小型数据集上训练这么多参数是有风险的。

原文:https://www.cnblogs.com/nxf-rabbit75/p/9960277.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值