Keras通过子类(subclass)自定义神经网络模型

参考文献:Géron, Aurélien. Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems. Reilly Media, 2019.

除了使用函数API外,还可以通过子类(subclass)自定义神经网络模型。

假设要搭建如图所示的神经网格,使用函数API:

input_A = keras.layers.Input(shape=[5], name="wide_input")
input_B = keras.layers.Input(shape=[6], name="deep_input")
hidden1 = keras.layers.Dense(30, activation="relu")(input_B)
hidden2 = keras.layers.Dense(30, activation="relu")(hidden1)
concat = keras.layers.concatenate([input_A, hidden2])
output = keras.layers.Dense(1, name="main_output")(concat)
aux_output = keras.layers.Dense(1, name="aux_output")(hidden2)
model = keras.models.Model(inputs=[input_A, input_B],
                           outputs=[output, aux_output])

换成子类API,

class WideAndDeepModel(keras.models.Model):
    def __init__(self, units=30, activation="relu", **kwargs):
        super().__init__(**kwargs)
        self.hidden1 = keras.layers.Dense(units, activation=activation)
        self.hidden2 = keras.layers.Dense(units, activation=activation)
        self.main_output = keras.layers.Dense(1)
        self.aux_output = keras.layers.Dense(1)
        
    def call(self, inputs):
        input_A, input_B = inputs
        hidden1 = self.hidden1(input_B)
        hidden2 = self.hidden2(hidden1)
        concat = keras.layers.concatenate([input_A, hidden2])
        main_output = self.main_output(concat)
        aux_output = self.aux_output(hidden2)
        return main_output, aux_output

初始化模型并编译

model = WideAndDeepModel(30, activation="relu")
model.compile(loss="mse", loss_weights=[0.9, 0.1], optimizer=keras.optimizers.SGD(lr=1e-3))

和函数式API不同,使用子类搭建的神经网络,如果运行model.summary,系统会报错

ValueError: This model has not yet been built. Build the model first by calling `build()` or calling `fit()` with some data, or specify an `input_shape` argument in the first layer(s) for automatic build.

这是因为通过子类搭建的网络中不存在graph,即没有网络层之间的连接信息,因此无法使用model.summary() 。如果想要使用model.summary(),有两种方法:
第一种方法比较别扭,就是先读入数据训练一次,

history = model.fit((X_train_A, X_train_B), (y_train, y_train), epochs=2,
                    validation_data=((X_valid_A, X_valid_B), (y_valid, y_valid)))

再运行model.summary就可以输出模型信息

Model: "wide_and_deep_model_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_28 (Dense)             multiple                  210       
_________________________________________________________________
dense_29 (Dense)             multiple                  930       
_________________________________________________________________
dense_30 (Dense)             multiple                  36        
_________________________________________________________________
dense_31 (Dense)             multiple                  31        
=================================================================
Total params: 1,207
Trainable params: 1,207
Non-trainable params: 0
_________________________________________________________________

不同于通过子类API搭建的模型,使用model.summary()无法输出神经网络的详细信息,这是子类API的缺点。
第二种方法其实报错信息里提示,就是需要先运行一次模型build,输入神经网络的input shape。需要注意的是,这是一个Multi-Inputs神经网格,因此input shape是一个列表

model.build([(None, 5),(None, 6)])

之后再运行一次model.summary()就不会报错。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Keras完成利用深度学习神经网络模型进行手写体识别的Python代码: ``` # 导入必要的库 import numpy as np import keras from keras.models import Sequential from keras.layers import Dense, Flatten from keras.datasets import mnist # 加载MNIST数据集 (x_train, y_train), (x_test, y_test) = mnist.load_data() # 将图像像素值归一化到0到1之间 x_train = x_train.astype('float32') / 255 x_test = x_test.astype('float32') / 255 # 将标签使用One-Hot编码 y_train = keras.utils.to_categorical(y_train, 10) y_test = keras.utils.to_categorical(y_test, 10) # 构建神经网络模型 model = Sequential() model.add(Flatten(input_shape=(28, 28))) model.add(Dense(128, activation='relu')) model.add(Dense(10, activation='softmax')) # 编译模型 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # 训练模型 model.fit(x_train, y_train, batch_size=128, epochs=10, validation_data=(x_test, y_test)) # 评估模型 score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) ``` 在这个代码中,我们首先加载MNIST数据集,然后将图像像素值归一化到0到1之间,将标签使用One-Hot编码。接下来,我们构建了一个包含一个输入层、一个隐藏层和一个输出层的神经网络模型,使用ReLU作为激活函数。然后,我们使用Adam优化器和交叉熵损失函数编译模型。最后,我们使用训练数据训练模型,并在测试数据上进行评估。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值