关于神经网络,微调是什么?

时间:2019-06-20 07:08:04

标签: neural-network finetunning

我正在阅读一些基于神经网络的研究论文,其中遇到了预训练的CNN网络上的“微调”一词。它实际上是做什么的?

2 个答案:

答案 0 :(得分:1)

微调通常被称为更复杂的NN训练的最后一步,当您仅稍微修改预训练的网络时,通常是为了提高特定域上的性能或在不同任务中重用良好的输入表示。

通常在转移学习中提到它。例如,对于图像识别,可能意味着您采用了经过训练可以识别ImageNet中的1k类的网络。您将使用经过预先训练的网络,并仅“微调”特定于任务的最后一层(较小且可能更简单的数据集)。

答案 1 :(得分:1)

预先培训:

首先,我们必须了解预训练的模型。预训练模型是已经有人在数据集上训练权重的模型。例如VGG16在图像网上接受培训。现在我们要对imagenet图像进行分类。可以说,如果我们使用预训练的VGG16,我们可以轻松对它们进行分类。由于VGG16已经过训练,可以对图像网络对象进行分类,因此我们无需再次对其进行训练。

微调:

现在,我想用VGG16(classes-1000)对Cifar-10(classes-10)进行分类,并且我想使用预先训练的模型进行这项工作。现在,我有一个在Image-net上训练的模型,该模型具有1000个类。因此,现在我将用softmax激活来更改具有10个神经元的最后一层,因为现在我要对10个类别(而不是1000)进行分类。现在,我将微调(根据需要更改)我的模型。我将在模型的最后添加一个包含10个神经元的密集层。现在,我可以使用VGG16(针对图像网络进行了预训练)。根据我们的需要更改预训练模型的过程称为微调。

转移学习:

现在整个概念都使用预训练模型,并通过微调模型将其用于对我们的数据集进行分类,称为转移学习

转移学习示例(使用预先训练的模型并对其进行微调以在数据集上使用)

在这里,我要使用在图像网上经过预训练的密集网络并微调我的模型,因为我想使用VGG16网络模型对数据集中的图像进行分类。和我的数据集有5个类别,所以我要添加具有5个神经元的最后一个致密层

model=Sequential()

dense_model=keras.applications.densenet.DenseNet121(include_top=False, weights='imagenet', input_tensor=None, input_shape=(224,224,3), pooling=None, classes=1000)
dense_model.trainable = False
dense_model.summary()
# Add the vgg convolutional base model

model.add(dense_model)

# Add new layers
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(128, activation='relu'))

model.add(keras.layers.Dense(5, activation='softmax'))
model.summary()

预先训练的模型链接: https://www.kaggle.com/sohaibanwaar1203/pretrained-densenet

现在,如果我想更改预训练模型的超参数该怎么办。如果我使用VGG16(在我的数据集上),我想检查哪个(优化器,损失函数,层数,神经元数)在我的数据集上是否运作良好。因此,我将优化称为超参数优化的参数

超参数优化: 如果您对神经网络有所了解,您将知道我们为神经网络提供了随机数。例如,密集层数,密集单元数,激活次数,退出百分比。我们不知道具有3层的神经网络在我们的数据上将表现良好,还是具有6层的神经网络在我们的数据上将表现出色。我们进行实验以获得模型的最佳数量。现在,可以在其中找到最适合您的模型的实验称为微调。现在我们有一些技术可以优化我们的模型,例如 网格搜索,随机搜索。我正在共享笔记本,您将可以通过该笔记本在代码的帮助下优化模型参数。

 import math
from keras.wrappers.scikit_learn import KerasRegressor
import keras
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import RandomizedSearchCV, KFold
from sklearn.metrics import make_scorer
from keras.models import Sequential,Model
from keras.layers import Dense,Dropout,Activation,BatchNormalization
from keras import losses
from keras import optimizers
from keras.callbacks import EarlyStopping
from keras import regularizers

def Randomized_Model(lr=0.0001,dropout=0.5,optimizer='Adam',loss='mean_squared_error',
                    activation="relu",clipnorm=0.1,
                    decay=1e-2,momentum=0.5,l1=0.01,l2=0.001,
                    ):




    #Setting Numbers of units in Every dense layer according to the number of dense layers
    no_of_units_in_dense_layer=[]
    #backwards loop


    #setting up loss fucntions
    loss=losses.mean_squared_error
    if(loss=='mean_squared_error'):
        loss=losses.mean_squared_error
    if(loss=="poisson"):
        loss=keras.losses.poisson
    if(loss=="mean_absolute_error"):
        loss=keras.losses.mean_absolute_percentage_error
    if(loss=="mean_squared_logarithmic_error"):
        loss=keras.losses.mean_squared_logarithmic_error
    if(loss=="binary_crossentropy"):
        loss=keras.losses.binary_crossentropy
    if(loss=="hinge"):
        loss=keras.losses.hinge

    #setting up Optimizers
    opt=keras.optimizers.Adam(lr=lr, decay=decay, beta_1=0.9, beta_2=0.999)
    if optimizer=="Adam":
        opt=keras.optimizers.Adam(lr=lr, decay=decay, beta_1=0.9, beta_2=0.999)
    if optimizer=="Adagrad":
        opt=keras.optimizers.Adagrad(lr=lr, epsilon=None, decay=decay)
    if optimizer=="sgd":
        opt=keras.optimizers.SGD(lr=lr, momentum=momentum, decay=decay, nesterov=False)
    if optimizer=="RMSprop":
        opt=keras.optimizers.RMSprop(lr=lr, rho=0.9, epsilon=None, decay=0.0)
    if optimizer=="Adamax":
        opt=keras.optimizers.Adamax(lr=lr, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0)


    #model sequential
    model=Sequential()

    model.add(Dense(units=64,input_dim=30,activation=activation))
    model.add(Dense(units=32,activation=activation))
    model.add(Dense(units=8,activation=activation))
    model.add(Dense(units=1))
    model.compile(loss=loss ,optimizer=opt)



    return model
params = {'lr': (0.0001, 0.01,0.0009,0.001,0.002 ),
     'epochs': [50,100,25],
     'dropout': (0, 0.2,0.4, 0.8),
     'optimizer': ['Adam','Adagrad','sgd','RMSprop','Adamax'],
     'loss': ["mean_squared_error","hinge","mean_absolute_error","mean_squared_logarithmic_error","poisson"],
     'activation' :["relu","selu","linear","sigmoid"],
     'clipnorm':(0.0,0.5,1),
     'decay':(1e-6,1e-4,1e-8),
     'momentum':(0.9,0.5,0.2),
     'l1': (0.01,0.001,0.0001),
     'l2': (0.01,0.001,0.0001),

     }
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import RandomizedSearchCV, KFold
from sklearn.metrics import make_scorer
# model class to use in the scikit random search CV 

model =  KerasRegressor(build_fn=Randomized_Model, epochs=30, batch_size=3, verbose=1)
RandomizedSearchfit = RandomizedSearchCV(estimator=model, cv=KFold(3), param_distributions=params, verbose=1,  n_iter=10, n_jobs=1)
#having some problem in this line
RandomizedSearch_result = RandomizedSearchfit.fit(X, Y )

现在将X和Y赋予该模型,它将在param_dict variable中找到您选择的最佳参数。您还可以在此笔记本中检查CNN的微调(Click Here)。在此笔记本中,我正在使用Talos库微调我的模型。

这是另一本笔记本,我正在其中使用SKLearn(随机和网格搜索)来微调我的模型(Click Here