Keras函数式API

使用函数式API,你可以直接操作张量,也可以把层当做函数来使用,接收张量并返回张量。

# 简单的实例
import os
# **** change the warning level ****
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

from keras.models import Sequential, Model
from keras import layers
from keras import Input

# 使用Sequential模型
seq_model = Sequential()
seq_model.add(layers.Dense(32, activation='relu', input_shape=(64,)))
seq_model.add(layers.Dense(32, activation='relu'))
seq_model.add(layers.Dense(10, activation='softmax'))

# 对应的函数式API实现
input_tensor = Input(shape=(64,))
x = layers.Dense(32, activation='relu')(input_tensor)
x = layers.Dense(32, activation='softmax')(x)
output_tensor = layers.Dense(10, activation='softmax')(x)

model = Model(input_tensor, output_tensor)
model.summary()
Model: "model_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_2 (InputLayer)         (None, 64)                0         
_________________________________________________________________
dense_10 (Dense)             (None, 32)                2080      
_________________________________________________________________
dense_11 (Dense)             (None, 32)                1056      
_________________________________________________________________
dense_12 (Dense)             (None, 10)                330       
=================================================================
Total params: 3,466
Trainable params: 3,466
Non-trainable params: 0
_________________________________________________________________

Keras会在后台检索从input_tensor到output_tensor所包含的每一层,并将这些层组合成一个类图的数据结构,即一个Model。这种方法有效的原因在于,output_tensor是通过对input_tensor进行多次变换得到的。如果你试图利用不相关的输入和输出来构建一个模型,那么会得到RuntimeError

unrelated_input = Input(shape=(32,))
bad_model = model = Model(unrelated_input, output_tensor)
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-3-54197a8d0ec3> in <module>
      1 unrelated_input = Input(shape=(32,))
----> 2 bad_model = model = Model(unrelated_input, output_tensor)


/usr/lib/python3.7/site-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
     89                 warnings.warn('Update your `' + object_name + '` call to the ' +
     90                               'Keras 2 API: ' + signature, stacklevel=2)
---> 91             return func(*args, **kwargs)
     92         wrapper._original_function = func
     93         return wrapper


/usr/lib/python3.7/site-packages/keras/engine/network.py in __init__(self, *args, **kwargs)
     92                 'inputs' in kwargs and 'outputs' in kwargs):
     93             # Graph network
---> 94             self._init_graph_network(*args, **kwargs)
     95         else:
     96             # Subclassed network


/usr/lib/python3.7/site-packages/keras/engine/network.py in _init_graph_network(self, inputs, outputs, name, **kwargs)
    239         # Keep track of the network's nodes and layers.
    240         nodes, nodes_by_depth, layers, layers_by_depth = _map_graph_network(
--> 241             self.inputs, self.outputs)
    242         self._network_nodes = nodes
    243         self._nodes_by_depth = nodes_by_depth


/usr/lib/python3.7/site-packages/keras/engine/network.py in _map_graph_network(inputs, outputs)
   1509                                          'The following previous layers '
   1510                                          'were accessed without issue: ' +
-> 1511                                          str(layers_with_complete_input))
   1512                 for x in node.output_tensors:
   1513                     computable_tensors.append(x)


ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_2:0", shape=(None, 64), dtype=float32) at layer "input_2". The following previous layers were accessed without issue: []

对这种Model实例进行编译、训练或评估时,其API与Sequential模型相同

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

import numpy as np
x_train = np.random.random((1000, 64))
y_train = np.random.random((1000, 10))

model.fit(x_train, y_train, epochs=10, batch_size=128)

score = model.evaluate(x_train, y_train)
Epoch 1/10
1000/1000 [==============================] - 0s 83us/step - loss: 11.6211
Epoch 2/10
1000/1000 [==============================] - 0s 33us/step - loss: 11.6215
Epoch 3/10
1000/1000 [==============================] - 0s 32us/step - loss: 11.6216
Epoch 4/10
1000/1000 [==============================] - 0s 27us/step - loss: 11.6216
Epoch 5/10
1000/1000 [==============================] - 0s 36us/step - loss: 11.6216
Epoch 6/10
1000/1000 [==============================] - 0s 37us/step - loss: 11.6217
Epoch 7/10
1000/1000 [==============================] - 0s 37us/step - loss: 11.6217
Epoch 8/10
1000/1000 [==============================] - 0s 25us/step - loss: 11.6217
Epoch 9/10
1000/1000 [==============================] - 0s 40us/step - loss: 11.6217
Epoch 10/10
1000/1000 [==============================] - 0s 34us/step - loss: 11.6216
1000/1000 [==============================] - 0s 69us/step