当前位置: 首页 > 知识库问答 >
问题:

用Keras迁移学习。最后的层激活应该是什么?

颜欣怡
2023-03-14

我在这里参考 Keras 文档:https://keras.io/guides/transfer_learning/ 演示了一个典型的迁移学习工作流程

首先,用预先训练的权重实例化一个基础模型。

base_model = keras.applications.Xception(
    weights='imagenet',  # Load weights pre-trained on ImageNet.
    input_shape=(150, 150, 3),
    include_top=False)  # Do not include the ImageNet classifier at the top.

然后,冻结基本模型。

base_model.trainable = False

在顶部创建一个新模型。

inputs = keras.Input(shape=(150, 150, 3))
# We make sure that the base_model is running in inference mode here,
# by passing `training=False`. This is important for fine-tuning, as you will
# learn in a few paragraphs.
x = base_model(inputs, training=False)
# Convert features of shape `base_model.output_shape[1:]` to vectors
x = keras.layers.GlobalAveragePooling2D()(x)
# A Dense classifier with a single unit (binary classification)
outputs = keras.layers.Dense(1)(x)
model = keras.Model(inputs, outputs)

根据新数据训练模型。

model.compile(optimizer=keras.optimizers.Adam(),
              loss=keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=[keras.metrics.BinaryAccuracy()])
model.fit(new_dataset, epochs=20, callbacks=..., validation_data=...)

我的问题是,为什么这个示例没有在密集层中应用sigmoid或softmax激活?

# A Dense classifier with a single unit (binary classification)
outputs = keras.layers.Dense(1)(x)

这里的这个密集层默认有线性激活,这不是让模型输出一个回归值吗?

共有2个答案

何骞尧
2023-03-14

该模型将输出一个数值,然后将其与二进制值(1或0)进行比较。该差值将产生一个损耗,然后通过反向传播将其减小,从而将模型输出驱动到所需值。然而,我认为最好的做法是对图层使用S形激活。在另一个级别上,由于梯度爆炸,它们总是警告您在初始训练时冻结基础模型的权重。我已经使用转移学习运行了至少500个模型,将基础模型保留为可训练模型。事实上,一般来说,我训练N个时期的整个模型比我训练模型的结果要好,如果我首先训练模型的基础模型不可训练M个时期,然后微调K个时期的模型,其中K M=N。换句话说,对于相同的时期数,我训练整个模型比训练相同时期数的两步html" target="_blank">过程的结果要好。但是,在验证和测试精度方面,差异通常很小。此外,他们还表示,如果将基础模型从不可训练更改为可训练,则必须重新编译模型。根据下面的代码,我认为这不是真的

from keras.utils.layer_utils import count_params
model_name='EfficientNetB1'
base_model=tf.keras.applications.EfficientNetB1(include_top=False, weights="imagenet",input_shape=img_shape, pooling='max') 
base_model.trainable=False
x=base_model.output
x = Dense(256, activation='relu')(x)       
output=Dense(10, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)
model.compile(Adamax(lr=.001), loss='categorical_crossentropy', metrics=['accuracy']) 
trcount = count_params(model.trainable_weights)
non_trcount = count_params(model.non_trainable_weights)
print ('trainable parameters: ',trcount, '  non-trainable parameters: ',non_trcount)

如果运行此命令,打印输出将是

trainable parameters:  330506   non-trainable parameters:  6575239

现在在下面的代码中,我使基本模型可训练

base_model.trainable=True
trcount = count_params(model.trainable_weights)
non_trcount = count_params(model.non_trainable_weights)
print ('trainable parameters: ',trcount, '  non-trainable parameters: ',non_trcount)

结果的打印输出是

trainable parameters:  6843690   non-trainable parameters:  62055

所以在我看来,你不需要重新编译模型

蔡晨
2023-03-14

请注意,sigmoid 和 softmax 只是挤压函数,即它们压缩 [-inf, inf] 到 [0, 1] 之间的值。因此,当我们想要将线性层的输出解释为概率时,我们使用 sigmoid/softmax 层。

现在来谈谈为什么不使用sigmoid/softmax层的问题,这是因为使用了损失函数。

keras.losses.BinaryCrossentropy(from_logits=True)

如果检查文档

    < li>from_logits=True,预期的< code>y_pred在[-inf,inf]中 < li>from_logits=False,预期的< code>y_pred在[0,1]中

因此,如果损失函数中的 from_logits=False,则必须使用 sigmoid/softmax。

 类似资料:
  • 我在玩Keras,我在想线性激活层和无激活层之间的区别是什么?它不是有同样的行为吗?如果是这样,那么线性激活的意义是什么呢? 我指的是这两段代码之间的区别: 和

  • 本文向大家介绍迁移学习相关面试题,主要包含被问及迁移学习时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 迁移学习就是把之前训练好的模型直接拿来用,可以充分利用之前数据信息,而且能够避免自己实验数据量较小等问题。简单来讲就是给模型做初始化,初始化的数据来自于训练好的模型。

  • 迁移学习(Transfer learning)顾名思义就是就是把已学训练好的模型参数迁移到新的模型来帮助新模型训练数据集。 经典论文: Progressive Neural Networks

  • 使用Keras设置神经网络时,您可以使用模型或。我的理解是前者易于设置和管理,并且作为层的线性堆栈运行,并且功能方法对于更复杂的架构很有用,特别是那些涉及共享内部层输出的架构。我个人喜欢使用功能API来实现多功能性,但是,我对LeakyReLU等高级激活层有困难。当使用标准激活时,在顺序模型中可以写: 类似地,在函数API中,可以将上述内容编写为: 然而,当使用LeakyReLU和PReLU之类的

  • 译者:片刻 作者: Sasank Chilamkurthy 在本教程中,您将学习如何使用迁移学习来训练您的网络。您可以在 cs231n 笔记 上阅读更多关于迁移学习的信息 引用这些笔记: 在实践中,很少有人从头开始训练整个卷积网络(随机初始化),因为拥有足够大小的数据集是相对罕见的。相反,通常在非常大的数据集(例如 ImageNet,其包含具有1000个类别的120万个图像)上预先训练 ConvN

  • LeakyReLU层 PReLU层 为一个与xshape相同的可学习的参数向量。 ELU层 f(x) = alpha * (exp(x) - 1.) for x < 0,f(x) = x for x>=0 ThresholdedReLU层 激活函数的作用: 1,激活函数是用来加入非线性因素,解决模型所不能解决的问题。 2,激活函数可以用来组合训练数据的特征,特征的充分组合。 下面我分别对激活函数的