对于图像分类中,由于图像价值都是一样的,所以对图像进行wide&deep模型分类没有太大的意义。
由于wide&deep模型不是严格意义上的层级结构,而是由两部分组成,所以就不能用sequential,用函数式API。像使用函数一样调用层次。
下面修改模型那块代码
# 函数式API 功能API
input = keras.layers.Input(shape=x_train.shape[1:])
hidden1 = keras.layers.Dense(30, activation='relu')(input)
hidden2 = keras.layers.Dense(30, activation='relu')(hidden1)
# 复合函数: f(x) = h(g(x))
#将深层网络和wide网络拼接起来
concat = keras.layers.concatenate([input, hidden2])
output = keras.layers.Dense(1)(concat)
#下面把model固化下来
model = keras.models.Model(inputs = [input],
outputs = [output])
model.summary()
lr = 1e-4
optimizer = keras.optimizers.SGD(lr)
model.compile(loss="mean_squared_error", optimizer=optimizer)
callbacks = [keras.callbacks.EarlyStopping(
patience=5, min_delta=1e-2)]
history = model.fit(x_train_scaled, y_train,
validation_data = (x_valid_scaled, y_valid),
epochs = 10,
callbacks = callbacks)
下面用子类(subclass)API实现同样功能
同样,我只改写模型部分:
# 子类API 定义一个类,它的父类是keras.models.Model
class WideDeepModel(keras.models.Model):
def __init__(self):
#承载初始化函数
#调用父类初始化函数
super(WideDeepModel, self).__init__()
"""定义模型的层次"""
self.hidden1_layer = keras.layers.Dense(30, activation='relu')
self.hidden2_layer = keras.layers.Dense(30, activation='relu')
self.output_layer = keras.layers.Dense(1)
def call(self, input):
"""完成模型的正向计算"""
hidden1 = self.hidden1_layer(input)
hidden2 = self.hidden2_layer(hidden1)
concat = keras.layers.concatenate([input, hidden2])
output = self.output_layer(concat)
return output
# model = WideDeepModel()
model = keras.models.Sequential([
WideDeepModel(),
])
model.build(input_shape=(None, 8))
model.summary()
lr = 1e-4
optimizer = keras.optimizers.SGD(lr)
model.compile(loss="mean_squared_error", optimizer=optimizer)
callbacks = [keras.callbacks.EarlyStopping(
patience=5, min_delta=1e-2)]
history = model.fit(x_train_scaled, y_train,
validation_data = (x_valid_scaled, y_valid),
epochs = 10,
callbacks = callbacks)
我们继续修改模型。进行多输入模型分析
# 多输入,前五个给wide,后6个给deep,二者还有交集
input_wide = keras.layers.Input(shape=[5])
input_deep = keras.layers.Input(shape=[6])
hidden1 = keras.layers.Dense(30, activation='relu')(input_deep)
hidden2 = keras.layers.Dense(30, activation='relu')(hidden1)
concat = keras.layers.concatenate([input_wide, hidden2])
output = keras.layers.Dense(1)(concat)
model = keras.models.Model(inputs=[input_wide, input_deep],
outputs=[output])
x_train_scaled_wide = x_train_scaled[:, :5]
x_train_scaled_deep = x_train_scaled[:, 2:]
x_valid_scaled_wide = x_valid_scaled[:, :5]
x_valid_scaled_deep = x_valid_scaled[:, 2:]
x_test_scaled_wide = x_test_scaled[:, :5]
x_test_scaled_deep = x_test_scaled[:, 2:]
history = model.fit([x_train_scaled_wide, x_train_scaled_deep],
y_train,
validation_data = (
[x_valid_scaled_wide, x_valid_scaled_deep],
y_valid),
epochs = 100,
callbacks = callbacks)
多输出
# 多输出
input_wide = keras.layers.Input(shape=[5])
input_deep = keras.layers.Input(shape=[6])
hidden1 = keras.layers.Dense(30, activation='relu')(input_deep)
hidden2 = keras.layers.Dense(30, activation='relu')(hidden1)
concat = keras.layers.concatenate([input_wide, hidden2])
output = keras.layers.Dense(1)(concat)
output2 = keras.layers.Dense(1)(hidden2)
model = keras.models.Model(inputs=[input_wide, input_deep],
outputs=[output, output2])
history = model.fit([x_train_scaled_wide, x_train_scaled_deep],
[y_train, y_train],
validation_data = (
[x_valid_scaled_wide, x_valid_scaled_deep],
[y_valid, y_valid]),
epochs = 100,
callbacks = callbacks)
model.evaluate([x_test_scaled_wide, x_test_scaled_deep],
[y_test, y_test])