Conteúdo Visão Geral
- Crianças Leia mais
- O passo da construção
- Modelos de Keras
- Salvar os modelos
- Verificação de modelos de Keras
Observe que até este ponto, não há menção de Keras. Você pode construir sua própria API de alto nível em cima detf.Module
E as pessoas têm.
Nesta seção, você examinará como o Keras usatf.Module
Um guia de usuário completo para os modelos Keras pode ser encontrado noGuia do Keras.
As camadas e modelos Keras têm muito mais recursos extras, incluindo:
- Perdas opcionais
- Suporte às métricas
- Suporte embutido para um argumento de treinamento opcional para diferenciar entre o uso de treinamento e de inferência
- Salvar e restaurar objetos Python em vez de apenas funções de caixa preta
- Métodos get_config e from_config que permitem armazenar com precisão configurações para permitir a clonagem de modelos em Python
Esses recursos permitem modelos muito mais complexos através da subclassificação, como um modelo GAN personalizado ou um modelo Variational AutoEncoder (VAE).Guia completoPara customização de camadas e modelos.
Os modelos Keras também vêm com funcionalidade extra que os torna fáceis de treinar, avaliar, carregar, salvar e até mesmo treinar em várias máquinas.
Crianças Leia mais
tf.keras.layers.Layer
é a classe de base de todas as camadas de Keras, e herda detf.Module
.
Você pode converter um módulo em uma camada Keras simplesmente trocando o padrão e, em seguida, alterando__call__
Doiscall
:
class MyDense(tf.keras.layers.Layer):
# Adding **kwargs to support base Keras layer arguments
def __init__(self, in_features, out_features, **kwargs):
super().__init__(**kwargs)
# This will soon move to the build step; see below
self.w = tf.Variable(
tf.random.normal([in_features, out_features]), name='w')
self.b = tf.Variable(tf.zeros([out_features]), name='b')
def call(self, x):
y = tf.matmul(x, self.w) + self.b
return tf.nn.relu(y)
simple_layer = MyDense(name="simple", in_features=3, out_features=3)
As lâmpadas têm suas próprias__call__
que faz alguma contabilidade descrita na próxima seção e depois chamacall()
Você não deve notar nenhuma mudança na funcionalidade.
simple_layer([[2.0, 2.0, 2.0]])
<tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[1.1688161, 0. , 0. ]], dtype=float32)>
Obuild
Passeio
Como observado, é conveniente em muitos casos esperar para criar variáveis até que você esteja certo da forma de entrada.
As camadas de Keras vêm com um passo extra de ciclo de vida que lhe permite mais flexibilidade na forma como você define suas camadas.build
função .
build
é chamado exatamente uma vez, e é chamado com a forma da entrada. Geralmente é usado para criar variáveis (pesos).
Você pode reescreverMyDense
A camada acima para ser flexível ao tamanho de suas entradas:
class FlexibleDense(tf.keras.layers.Layer):
# Note the added `**kwargs`, as Keras supports many arguments
def __init__(self, out_features, **kwargs):
super().__init__(**kwargs)
self.out_features = out_features
def build(self, input_shape): # Create the state of the layer (weights)
self.w = tf.Variable(
tf.random.normal([input_shape[-1], self.out_features]), name='w')
self.b = tf.Variable(tf.zeros([self.out_features]), name='b')
def call(self, inputs): # Defines the computation from inputs to outputs
return tf.matmul(inputs, self.w) + self.b
# Create the instance of the layer
flexible_dense = FlexibleDense(out_features=3)
Neste momento, o modelo não foi construído, portanto, não há variáveis:
flexible_dense.variables
[]
Chamando a função aloca variáveis de tamanho apropriado:
# Call it, with predictably random results
print("Model results:", flexible_dense(tf.constant([[2.0, 2.0, 2.0], [3.0, 3.0, 3.0]])))
Model results: tf.Tensor(
[[-2.531786 -5.5550847 -0.4248762]
[-3.7976792 -8.332626 -0.6373143]], shape=(2, 3), dtype=float32)
flexible_dense.variables
[<tf.Variable 'flexible_dense/w:0' shape=(3, 3) dtype=float32, numpy=
array([[-0.77719826, -1.9281565 , 0.82326293],
[ 0.85628736, -0.31845194, 0.10916236],
[-1.3449821 , -0.5309338 , -1.1448634 ]], dtype=float32)>,
<tf.Variable 'flexible_dense/b:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>]
Desdebuild
Se for chamado apenas uma vez, as entradas serão rejeitadas se a forma de entrada não for compatível com as variáveis da camada:
try:
print("Model results:", flexible_dense(tf.constant([[2.0, 2.0, 2.0, 2.0]])))
except tf.errors.InvalidArgumentError as e:
print("Failed:", e)
Failed: Exception encountered when calling layer 'flexible_dense' (type FlexibleDense).
{ {function_node __wrapped__MatMul_device_/job:localhost/replica:0/task:0/device:CPU:0} } Matrix size-incompatible: In[0]: [1,4], In[1]: [3,3] [Op:MatMul] name:
Call arguments received by layer 'flexible_dense' (type FlexibleDense):
• inputs=tf.Tensor(shape=(1, 4), dtype=float32)
Modelos de Keras
Você pode definir seu modelo como camadas de Keras aninhadas.
No entanto, a Keras também fornece uma classe de modelo totalmente funcional chamadatf.keras.Model
Ela é herdada detf.keras.layers.Layer
Os modelos Keras vêm com funcionalidade extra que os torna fáceis de treinar, avaliar, carregar, salvar e até mesmo treinar em várias máquinas.
Você pode definir oSequentialModule
de cima com código quase idêntico, novamente convertendo__call__
Doiscall()
Mudança de pais:
@keras.saving.register_keras_serializable()
class MySequentialModel(tf.keras.Model):
def __init__(self, name=None, **kwargs):
super().__init__(**kwargs)
self.dense_1 = FlexibleDense(out_features=3)
self.dense_2 = FlexibleDense(out_features=2)
def call(self, x):
x = self.dense_1(x)
return self.dense_2(x)
# You have made a Keras model!
my_sequential_model = MySequentialModel(name="the_model")
# Call it on a tensor, with random results
print("Model results:", my_sequential_model(tf.constant([[2.0, 2.0, 2.0]])))
Model results: tf.Tensor([[ 0.26034355 16.431221 ]], shape=(1, 2), dtype=float32)
Todos os mesmos recursos estão disponíveis, incluindo variáveis de rastreamento e submódulos.
Nota: Um tf.Module bruto aninhado dentro de uma camada ou modelo Keras não receberá suas variáveis coletadas para treinamento ou poupança.
Nota: Um tf.Module bruto aninhado dentro de uma camada ou modelo Keras não receberá suas variáveis coletadas para treinamento ou poupança.
my_sequential_model.variables
[<tf.Variable 'my_sequential_model/flexible_dense_1/w:0' shape=(3, 3) dtype=float32, numpy=
array([[ 1.4749854 , 0.16090827, 2.2669017 ],
[ 1.6850946 , 1.1545411 , 0.1707306 ],
[ 0.8753734 , -0.13549292, 0.08751986]], dtype=float32)>,
<tf.Variable 'my_sequential_model/flexible_dense_1/b:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>,
<tf.Variable 'my_sequential_model/flexible_dense_2/w:0' shape=(3, 2) dtype=float32, numpy=
array([[-0.8022977 , 1.9773549 ],
[-0.76657015, -0.8485579 ],
[ 1.6919082 , 0.49000967]], dtype=float32)>,
<tf.Variable 'my_sequential_model/flexible_dense_2/b:0' shape=(2,) dtype=float32, numpy=array([0., 0.], dtype=float32)>]
my_sequential_model.submodules
(<__main__.FlexibleDense at 0x7f790c7e0e80>,
<__main__.FlexibleDense at 0x7f790c7e6940>)
Sobrevivênciatf.keras.Model
é uma abordagem muito Pythonic para construir modelos TensorFlow. Se você estiver migrando modelos de outros frameworks, isso pode ser muito simples.
Se você estiver construindo modelos que são assembleias simples de camadas e entradas existentes, você pode economizar tempo e espaço usando oFuncionamento de Fogo, que vem com recursos adicionais em torno de reconstrução de modelo e arquitetura.
Aqui está o mesmo modelo com a API funcional:
inputs = tf.keras.Input(shape=[3,])
x = FlexibleDense(3)(inputs)
x = FlexibleDense(2)(x)
my_functional_model = tf.keras.Model(inputs=inputs, outputs=x)
my_functional_model.summary()
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 3)] 0
flexible_dense_3 (Flexible (None, 3) 12
Dense)
flexible_dense_4 (Flexible (None, 2) 8
Dense)
=================================================================
Total params: 20 (80.00 Byte)
Trainable params: 20 (80.00 Byte)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________
my_functional_model(tf.constant([[2.0, 2.0, 2.0]]))
<tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[3.4276495, 2.937252 ]], dtype=float32)>
A principal diferença aqui é que a forma de entrada é especificada na frente como parte do processo de construção funcional.input_shape
argumento neste caso não precisa ser especificado completamente; você pode deixar algumas dimensões comoNone
.
Observação: Você não precisa especificar input_shape ou um InputLayer em um modelo subclassificado; esses argumentos e camadas serão ignorados.
Note:Você não precisa especificarinput_shape
Ou umInputLayer
em um modelo subclassificado; esses argumentos e camadas serão ignorados.
Salvar os modelos
Os modelos Keras têm seu próprio formato especializado de armazenamento de arquivos zip, marcado pelo.keras
Extensão: Ao ligartf.keras.Model.save
Adicione a.keras
extensão para o nome do arquivo. Por exemplo:
my_sequential_model.save("exname_of_file.keras")
Da mesma forma, eles podem ser carregados de volta em:
reconstructed_model = tf.keras.models.load_model("exname_of_file.keras")
Arquivo do Zip -.keras
arquivos – também salve os estados métricos, de perda e de otimização.
Este modelo reconstruído pode ser usado e produzirá o mesmo resultado quando chamado nos mesmos dados:
reconstructed_model(tf.constant([[2.0, 2.0, 2.0]]))
<tf.Tensor: shape=(1, 2), dtype=float32, numpy=array([[ 0.26034355, 16.431221 ]], dtype=float32)>
Verificação de modelos de Keras
Os modelos de Keras também podem ser checados, e isso parecerá o mesmo quetf.Module
.
Há mais para saber sobre salvar e serializar modelos Keras, incluindo fornecer métodos de configuração para camadas personalizadas para suporte de recursos.Guia para poupança e serialização.
O que é o próximo
Se você quiser saber mais detalhes sobre Keras, você pode seguir os guias Keras existentesaqui.
Outro exemplo de uma API de alto nível construída emtf.module
é Sonnet do DeepMind, que é coberto emSeu site.
Originalmente publicado no site TensorFlow, este artigo aparece aqui sob um novo título e é licenciado sob CC BY 4.0.
Originalmente publicado na