1. Construction of a simple layer
from __future__ import absolute_import, division, print_function
import tensorflow as tf
tf.keras.backend.clear_session()
tensorflow.keras import as hard
import tensorflow.keras.layers as layers
# Is the network layer defines: network weight setting and outputted to the calculation input
class MyLayer(layers.Layer):
def __init__(self, input_dim=32, unit=32):
super(MyLayer, self).__init__()
w_init = tf.random_normal_initializer()
self.weight = tf.Variable(initial_value=w_init(
shape=(input_dim, unit), dtype=tf.float32), trainable=True)
b_init = tf.zeros_initializer()
self.bias = tf.Variable(initial_value=b_init(
shape=(unit,), dtype=tf.float32), trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.weight) + self.bias
x = tf.ones((3,5))
my_layer = MyLayer(5, 4)
out = my_layer(x)
print(out)
tf.Tensor(
[[0.06709253 0.06818779 0.09926171 0.0179923 ]
[0.06709253 0.06818779 0.09926171 0.0179923 ]
[0.06709253 0.06818779 0.09926171 0.0179923 ]], shape=(3, 4), dtype=float32)
Construction of the network layer as above, the layer weights w automatic tracking and B, we can of course also be constructed directly by the method add_weight weight weight
class MyLayer(layers.Layer):
def __init__(self, input_dim=32, unit=32):
super(MyLayer, self).__init__()
self.weight = self.add_weight(shape=(input_dim, unit),
initializer=keras.initializers.RandomNormal(),
trainable=True)
self.bias = self.add_weight(shape=(unit,),
initializer=keras.initializers.Zeros(),
trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.weight) + self.bias
x = tf.ones((3,5))
my_layer = MyLayer(5, 4)
out = my_layer(x)
print(out)
tf.Tensor(
[[-0.10401802 -0.05459599 -0.08195674 0.13151655]
[-0.10401802 -0.05459599 -0.08195674 0.13151655]
[-0.10401802 -0.05459599 -0.08195674 0.13151655]], shape=(3, 4), dtype=float32)
You can not set the weight training
class AddLayer(layers.Layer):
def __init__(self, input_dim=32):
super(AddLayer, self).__init__()
self.sum = self.add_weight(shape=(input_dim,),
initializer=keras.initializers.Zeros(),
trainable=False)
def call(self, inputs):
self.sum.assign_add(tf.reduce_sum(inputs, axis=0))
return self.sum
x = tf.ones((3,3))
my_layer = AddLayer(3)
out = my_layer(x)
print(out.numpy())
out = my_layer(x)
print(out.numpy())
print('weight:', my_layer.weights)
print('non-trainable weight:', my_layer.non_trainable_weights)
print('trainable weight:', my_layer.trainable_weights)
[3. 3. 3.]
[6. 6. 6.]
weight: []
non-trainable weight: []
trainable weight: []
When defining the network does not know that the network can override the dimension build () function, the network constructed with the shape obtained
class MyLayer(layers.Layer):
def __init__(self, unit=32):
super(MyLayer, self).__init__()
self.unit = unit
def build(self, input_shape):
self.weight = self.add_weight(shape=(input_shape[-1], self.unit),
initializer=keras.initializers.RandomNormal(),
trainable=True)
self.bias = self.add_weight(shape=(self.unit,),
initializer=keras.initializers.Zeros(),
trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.weight) + self.bias
my_layer = MyLayer(3)
x = tf.ones((3,5))
out = my_layer(x)
print(out)
my_layer = MyLayer(3)
x = tf.ones((2,2))
out = my_layer(x)
print(out)
tf.Tensor(
[[ 0.00949192 -0.02009935 -0.11726624]
[ 0.00949192 -0.02009935 -0.11726624]
[ 0.00949192 -0.02009935 -0.11726624]], shape=(3, 3), dtype=float32)
tf.Tensor(
[[-0.00516411 -0.04891593 -0.0181773 ]
[-0.00516411 -0.04891593 -0.0181773 ]], shape=(2, 3), dtype=float32)
2. Construction of a recursive sub-layer network layer
class MyBlock(layers.Layer):
def __init__(self):
super(MyBlock, self).__init__()
self.layer1 = MyLayer(32)
self.layer2 = MyLayer(16)
self.layer3 = MyLayer(2)
def call(self, inputs):
h1 = self.layer1(inputs)
H1 = tf.nn.relu (H1)
h2 = self.layer2(h1)
h2 = tf.nn.relu (h2)
return self.layer3(h2)
my_block = MyBlock()
print('trainable weights:', len(my_block.trainable_weights))
y = my_block(tf.ones(shape=(3, 64)))
# Build networks in build () inside, so only the implementation of the network
print('trainable weights:', len(my_block.trainable_weights))
trainable weights: 0
trainable weights: 6
Loss may be collected by a method of constructing the network layer
class LossLayer(layers.Layer):
def __init__(self, rate=1e-2):
Super (LossLayer, self) .__ init __ ()
self.rate = rate
def call(self, inputs):
self.add_loss(self.rate * tf.reduce_sum(inputs))
return inputs
class OutLayer(layers.Layer):
def __init__(self):
super(OutLayer, self).__init__()
self.loss_fun=LossLayer(1e-2)
def call(self, inputs):
return self.loss_fun(inputs)
my_layer = OutLayer()
print (len (my_layer.losses)) # call yet
y = my_layer(tf.zeros(1,1))
After the print (len (my_layer.losses)) # perform call
y = my_layer(tf.zeros(1,1))
Will be reset to 0 before the print (len (my_layer.losses)) # call
0
1
1
If the intermediate layer is called the network keras inside regularization loss will be joined
class OuterLayer(layers.Layer):
def __init__(self):
super(OuterLayer, self).__init__()
self.dense = layers.Dense(32, kernel_regularizer=tf.keras.regularizers.l2(1e-3))
def call(self, inputs):
return self.dense(inputs)
my_layer = OuterLayer()
y = my_layer(tf.zeros((1,1)))
print(my_layer.losses)
print(my_layer.weights)
[]
[
array([[-0.11054656, 0.34735924, -0.22560999, 0.38415992, 0.13070339,
0.15960163, 0.20130599, 0.40365922, -0.09471637, -0.02402192,
0.16438413, 0.2716753 , 0.0594548 , -0.06913272, -0.40491152,
0.00894281, 0.3199494 , 0.0228827 , -0.18515846, 0.32210535,
0.41672045, 0.1942389 , -0.4254937 , 0.07178113, 0.00740242,
0.23780417, -0.24449413, -0.15526545, -0.2200018 , -0.2426699 ,
-0.17750363, -0.16994882]], dtype=float32)>,
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
dtype=float32)>]
3. Other Network Layer Configuration
The network layer may make its own serialized
class Linear(layers.Layer):
def __init__(self, units=32, **kwargs):
super(Linear, self).__init__(**kwargs)
self.units = units
def build(self, input_shape):
self.w = self.add_weight(shape=(input_shape[-1], self.units),
initializer='random_normal',
trainable=True)
self.b = self.add_weight(shape=(self.units,),
initializer='random_normal',
trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.w) + self.b
def get_config(self):
config = super(Linear, self).get_config()
config.update({'units':self.units})
return config
layer = Linear(125)
config = layer.get_config()
print(config)
new_layer = Linear.from_config(config)
{'name': 'linear_1', 'trainable': True, 'dtype': None, 'units': 125}
Configure network training can be performed only when
class MyDropout(layers.Layer):
def __init__(self, rate, **kwargs):
super(MyDropout, self).__init__(**kwargs)
self.rate = rate
def call(self, inputs, training=None):
return tf.cond(training,
lambda: tf.nn.dropout(inputs, rate=self.rate),
lambda: inputs)
4. Build your own model
Generally, we use the Layer class to define an internal calculation block and class used to define the external shape Model - i.e., an object to be trained.
Model class and Layer difference:
It discloses a built-in training, assessment and prediction of cycle (model.fit (), model.evaluate (), model.predict ()).
It is disclosed by the inner layer model.layers property list.
It discloses the preservation and serialization API.
Following by constructing a variation from the encoder (VAE), describes how to build their own network.
# Sampling Network Wuxi crowd Hospital Which is better http://www.wxbhnkyy120.com/
class Sampling(layers.Layer):
def call(self, inputs):
z_mean, z_log_var = inputs
batch = tf.shape(z_mean)[0]
dim = tf.shape(z_mean)[1]
epsilon = tf.keras.backend.random_normal(shape=(batch, dim))
return z_mean + tf.exp(0.5*z_log_var) * epsilon
# Encoder
class Encoder(layers.Layer):
def __init__(self, latent_dim=32,
intermediate_dim=64, name='encoder', **kwargs):
super(Encoder, self).__init__(name=name, **kwargs)
self.dense_proj = layers.Dense(intermediate_dim, activation='relu')
self.dense_mean = layers.Dense(latent_dim)
self.dense_log_var = layers.Dense(latent_dim)
self.sampling = Sampling()
def call(self, inputs):
h1 = self.dense_proj(inputs)
z_mean = self.dense_mean(h1)
z_log_var self.dense_log_var = (h1)
z = self.sampling((z_mean, z_log_var))
return z_mean, z_log_var, z
# decoder
class Decoder(layers.Layer):
def __init__(self, original_dim,
intermediate_dim=64, name='decoder', **kwargs):
super(Decoder, self).__init__(name=name, **kwargs)
self.dense_proj = layers.Dense(intermediate_dim, activation='relu')
self.dense_output = layers.Dense(original_dim, activation='sigmoid')
def call(self, inputs):
h1 = self.dense_proj(inputs)
return self.dense_output(h1)
# Variation from the encoder
class VAE(tf.keras.Model):
def __init__(self, original_dim, latent_dim=32,
intermediate_dim=64, name='encoder', **kwargs):
super(VAE, self).__init__(name=name, **kwargs)
self.original_dim = original_dim
self.encoder = Encoder(latent_dim=latent_dim,
intermediate_dim=intermediate_dim)
self.decoder = Decoder(original_dim=original_dim,
intermediate_dim=intermediate_dim)
def call(self, inputs):
z_mean, z_log_var, z = self.encoder(inputs)
reconstructed = self.decoder(z)
kl_loss = -0.5*tf.reduce_sum(
z_log_var-tf.square(z_mean)-tf.exp(z_log_var)+1)
self.add_loss(kl_loss)
return reconstructed
(x_train, _), _ = tf.keras.datasets.mnist.load_data()
x_train = x_train.reshape(60000, 784).astype('float32') / 255
Alas = OH (784,32,64)
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
vae.compile(optimizer, loss=tf.keras.losses.MeanSquaredError())
vae.fit(x_train, x_train, epochs=3, batch_size=64)
Epoch 1/3
60000/60000 [==============================] - 3s 44us/sample - loss: 0.7352
Epoch 2/3
60000/60000 [==============================] - 2s 33us/sample - loss: 0.0691
Epoch 3/3
60000/60000 [==============================] - 2s 33us/sample - loss: 0.0679
Write your own training methods
train_dataset = tf.data.Dataset.from_tensor_slices(x_train)
train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64)
original_dim = 784
Alas = OH (original_dim, 64, 32)
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)
mse_loss_fn = tf.keras.losses.MeanSquaredError()
loss_metric = tf.keras.metrics.Mean()
# Iterate over epochs.
for epoch in range(3):
print('Start of epoch %d' % (epoch,))
# Iterate over the batches of the dataset.
for step, x_batch_train in enumerate(train_dataset):
with tf.GradientTape() as tape:
reconstructed = vae(x_batch_train)
# Compute reconstruction loss
loss = mse_loss_fn(x_batch_train, reconstructed)
loss += sum(vae.losses) # Add KLD regularization loss
grads = tape.gradient(loss, vae.trainable_variables)
optimizer.apply_gradients(zip(grads, vae.trainable_variables))
loss_metric(loss)
if step % 100 == 0:
print('step %s: mean loss = %s' % (step, loss_metric.result()))
Start of epoch 0
step 0: mean loss = tf.Tensor(213.26726, shape=(), dtype=float32)
step 100: mean loss = tf.Tensor(6.5270114, shape=(), dtype=float32)
...
step 900: mean loss = tf.Tensor(0.3061987, shape=(), dtype=float32)