【问题标题】:Can't change activations in existing Keras model无法更改现有 Keras 模型中的激活
【发布时间】:2017-08-19 05:38:05
【问题描述】:

我有一个带有relu 激活的普通 VGG16 模型,即

def VGG_16(weights_path=None):
    model = Sequential()
    model.add(ZeroPadding2D((1, 1),input_shape=(3, 224, 224)))
    model.add(Convolution2D(64, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(64, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
[...]
    model.add(Flatten())
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1000, activation='softmax'))

    if weights_path:
        model.load_weights(weights_path)

    return model

我正在使用现有权重对其进行实例化,现在想将所有 relu 激活更改为 softmax(我知道这没什么用)

model = VGG_16('vgg16_weights.h5')
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)

softmax_act = keras.activations.softmax
for (n, layer) in enumerate(model.layers):
    if 'activation' in layer.get_config() and layer.get_config()['activation'] == 'relu':
        print('replacing #{}: {}, {}'.format(n, layer, layer.activation))
        layer.activation = softmax_act
        print('-> {}'.format(layer.activation))

model.compile(optimizer=sgd, loss='categorical_crossentropy')

注意:model.compile 在更改之后被称为,所以我猜模型应该仍然可以修改。

但是,即使调试打印正确地说

replacing #1: <keras.layers.convolutional.Convolution2D object at 0x7f7d7c497f50>, <function relu at 0x7f7dbe699a28>
-> <function softmax at 0x7f7d7c4972d0>
[...]

实际结果与具有relu 激活的模型相同。
为什么 Keras 不使用更改后的激活函数?

【问题讨论】:

    标签: python keras keras-layer


    【解决方案1】:

    您可能想要使用 apply_modifications

    idx_of_layer_to_change = -1
    model.layers[idx_of_layer_to_change].activation = activations.softmax
    model = utils.apply_modifications(model)
    

    【讨论】:

    【解决方案2】:

    因为仅在 keras 层中设置激活并不会真正改变图形,我们需要保存修改后的模型并将其加载回来:

    from keras import activations
    from keras.models import load_model
    
    model.layers[-1].activation = activations.example
    model.save(some_path)
    model = load_model(some_path)
    

    【讨论】:

      【解决方案3】:

      utils.apply_modifications() 函数对我不起作用。它给了我一个警告

      警告:tensorflow:在保存文件中找不到训练配置: 模型编译。手动编译。

      然后我重新编译了模型然后它工作了。为了说明,我将所有激活更改为 sigmoid。看下面的例子

      from tensorflow.keras.activations import relu,sigmoid,elu
      from tensorflow.keras.applications.vgg16 import VGG16
      base_model = VGG16(weights='imagenet', include_top=False,pooling='avg',input_shape= 
          (100, 100, 3))
      # before if you check 
      base_model.get_config() # you will see all activation are relu 
      for layer in base_model.layers:
          if (hasattr(layer,'activation'))==True:
               layer.activation = sigmoid
      # without compiling you should not see any changes
      # when calling base_model.get_config()
      # when compiling
      base_model.compile(loss="categorical_crossentropy") #it forced me to put the loss
      # now you will see the changes when calling
      base_model.get_config()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-24
        • 2021-05-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多