标签:mod nta width 图形 连接 bubuko NPU text sum
VGG16内置于Keras,可以通过keras.applications模块中导入。
--------------------------------------------------------将VGG16 卷积实例化:-------------------------------------------------------------------------------------------------------------------------------------
1 from keras.applications import VGG16 2 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层来扩展已有模型,并在输入数据上端到端地运行整个模型。这样你可以使用数据增强,因为每个输入图像进入模型时都会经过卷积基。但这种方法的计算代价比第一种要高很多。 |
#方法一:不使用数据增强的快速特征提取 import os import numpy as np from keras.preprocessing.image import ImageDataGenerator 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 def extract_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 = 0 for inputs_batch,labels_batch in generator: 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 return features,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 import models from keras import layers from keras import optimizers 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 import models from keras import layers 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 import ImageDataGenerator from kera import optimizers 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万个参数,所以在你的小型数据集上训练这么多参数是有风险的。
标签:mod nta width 图形 连接 bubuko NPU text sum
原文地址:https://www.cnblogs.com/nxf-rabbit75/p/9960277.html