Keras Functional 中的高级激活层 API
Advanced Activation layers in Keras Functional API
使用 Keras 设置神经网络时,您可以使用 Sequential
模型或 Functional API
。我的理解是前者易于设置和管理,并且作为层的线性堆栈运行,而功能方法对于更复杂的架构很有用,特别是那些涉及共享内部层输出的架构。我个人喜欢使用函数 API 来实现多功能性,但是,我在使用 LeakyReLU 等高级激活层时遇到了困难。使用标准激活时,在顺序模型中可以这样写:
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
与函数 API 类似,可以将上面的代码写为:
inpt = Input(shape = (100,))
dense_1 = Dense(32, activation ='relu')(inpt)
out = Dense(10, activation ='softmax')(dense_2)
model = Model(inpt,out)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
但是,当使用 LeakyReLU 和 PReLU 等高级激活时,在该顺序模型中,我们将它们写为单独的层。例如:
model = Sequential()
model.add(Dense(32, input_dim=100))
model.add(LeakyReLU(alpha=0.1))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
现在,我假设有人在功能性 API 方法中做等效的事情:
inpt = Input(shape = (100,))
dense_1 = Dense(32)(inpt)
LR = LeakyReLU(alpha=0.1)(dense_1)
out = Dense(10, activation ='softmax')(LR)
model = Model(inpt,out)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
我的问题是:
- 函数式方法中的语法是否正确?
- 为什么 Keras 需要一个新层来实现这些高级激活函数,而不是让我们只替换
'relu'
?
- 为激活函数创建一个新层,而不是将其分配给现有的层定义(就像我们写
'relu'
的第一个示例中那样)有什么根本不同吗,我知道你可以始终将您的激活函数(包括标准激活函数)编写为新层,尽管已经阅读过应该避免这种情况?
不对,你忘了把LeakyReLU连接到dense层:
LR = LeakyReLU(alpha=0.1)(dense_1)
通常高级激活具有可调或可学习的参数,并且这些必须存储在某个地方,将它们作为层更有意义,因为您可以访问和保存这些参数。
- 只有在有优势时才这样做,例如可调参数。
使用 Keras 设置神经网络时,您可以使用 Sequential
模型或 Functional API
。我的理解是前者易于设置和管理,并且作为层的线性堆栈运行,而功能方法对于更复杂的架构很有用,特别是那些涉及共享内部层输出的架构。我个人喜欢使用函数 API 来实现多功能性,但是,我在使用 LeakyReLU 等高级激活层时遇到了困难。使用标准激活时,在顺序模型中可以这样写:
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
与函数 API 类似,可以将上面的代码写为:
inpt = Input(shape = (100,))
dense_1 = Dense(32, activation ='relu')(inpt)
out = Dense(10, activation ='softmax')(dense_2)
model = Model(inpt,out)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
但是,当使用 LeakyReLU 和 PReLU 等高级激活时,在该顺序模型中,我们将它们写为单独的层。例如:
model = Sequential()
model.add(Dense(32, input_dim=100))
model.add(LeakyReLU(alpha=0.1))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
现在,我假设有人在功能性 API 方法中做等效的事情:
inpt = Input(shape = (100,))
dense_1 = Dense(32)(inpt)
LR = LeakyReLU(alpha=0.1)(dense_1)
out = Dense(10, activation ='softmax')(LR)
model = Model(inpt,out)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
我的问题是:
- 函数式方法中的语法是否正确?
- 为什么 Keras 需要一个新层来实现这些高级激活函数,而不是让我们只替换
'relu'
? - 为激活函数创建一个新层,而不是将其分配给现有的层定义(就像我们写
'relu'
的第一个示例中那样)有什么根本不同吗,我知道你可以始终将您的激活函数(包括标准激活函数)编写为新层,尽管已经阅读过应该避免这种情况?
不对,你忘了把LeakyReLU连接到dense层:
LR = LeakyReLU(alpha=0.1)(dense_1)
通常高级激活具有可调或可学习的参数,并且这些必须存储在某个地方,将它们作为层更有意义,因为您可以访问和保存这些参数。
- 只有在有优势时才这样做,例如可调参数。