6.1.6 - Layer
e Model
: un approfondimento¶
La classe Layer
¶
L'astrazione fondamentale alla base di Keras è la classe Layer
, che rappresenta lo stato di un layer di una rete neurale (ovvero, i suoi pesi), oltre che i metodi che permettono di mappare l'input del layer verso l'output, questi ultimi contenuti nel metodo call
. Il seguente snippet illustra un esempio di layer Keras:
In particolare:
- gli attributi di ogni istanza del layer
Linear
saranno il tensore dei pesiw
e quello dei biasb
; - nel metodo
__init__
, alla riga 8, usiamo il metodorandom_normal_initializer()
di TensorFlow per creare un inizializzatore del tensore dei pesi \(w\) in modo che detti pesi siano estratti casualmente da una distribuzione normale; - i pesi sono inizializzati sotto forma di una
Variable
TensorFlow usando l'inizializzatore definito in precedenza, ed impostando una dimensioneinput_dim
\(\times\)units
, coninput_dim
dimensione del vettore di ingresso, edunits
numero di unità. L'attributotrainable
assicura infine che sia possibile modificare questi pesi a valle di una procedura di addestramento; - in modo simile, alla riga 12 creiamo un inizializzatore del tensore degli offset \(b\) sfruttando il metodo
zeros_initializer
, che verrà inizializzato in modo simile al tensore dei pesi \(w\); - alle righe 17-18, infine, definiamo il metodo
call
, che descrive il rapporto tra ingresso ed uscita del layer.
Aggiunga dei pesi ad un layer¶
La procedura vista in precedenza per l'aggiunta dei pesi e del bias al nostro layer può essere notevolmente semplificata mediante il metodo add_weight()
:
class Linear(tf.keras.layers.Layer):
def __init__(self, units=32, input_dim=32):
super(Linear, self).__init__()
self.w = self.add_weight(
shape=(input_dim, units), initializer="random_normal", trainable=True
)
self.b = self.add_weight(shape=(units,), initializer="zeros", trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.w) + self.b
Layer con pesi non addestrabili¶
Un layer può avere anche dei pesi non addestrabili. In tal senso, si può impostare a False
il parametro trainable
.
class ComputeSum(tf.keras.layers.Layer):
def __init__(self, input_dim):
super(ComputeSum, self).__init__()
self.total = tf.Variable(initial_value=tf.zeros((input_dim,)), trainable=False)
def call(self, inputs):
self.total.assign_add(tf.reduce_sum(inputs, axis=0))
return self.total
Omettere la dimensione dell'input¶
Keras ci permette di omettere la dimensione dell'input, creandola in maniera lazy al momento dell'istanziazione del layer nel nsotro modello. Per farlo, Keras ci mette a disposizione il metodo build()
:
class Linear(tf.keras.layers.Layer):
def __init__(self, units=32):
super(Linear, self).__init__()
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
Stack di layer¶
I layer sono componibili; ciò avviene usando un layer come attributo di un altro:
class MLP(keras.layers.Layer):
def __init__(self):
super(MLPBlock, self).__init__()
self.linear_1 = Linear(32)
self.linear_2 = Linear(32)
self.linear_3 = Linear(1)
def call(self, inputs):
x = self.linear_1(inputs)
x = tf.nn.relu(x)
x = self.linear_2(x)
x = tf.nn.relu(x)
return self.linear_3(x)
La classe Model
¶
In generale, l'uso della classe Layer
è destinato alla definizione di nuovi layer della rete neurale o, in alternativa, di stack degli stessi. La classe Model
, invece, viene usata per definire il modello complessivo della rete, che sarà quello che sarà addestrato. Per fare un esempio, in un modello che riproduce una ResNet, avremo diversi blocchi residuali derivanti dalla classe Layer
, ed un singolo Model
contenente l'intera architettura di rete.
La classe Model
usa un'interfaccia molto simile a quella di Layer
a meno di alcune differenze:
- la classe
Model
espone i metodicompile()
,fit()
,evaluate()
epredict()
per addestrare, validare ed usare in inferenza la rete; - un oggetto di classe
Model
espone la lista di layer al suo interno usando l'attributolayers
; - un oggetto di classe
Model
ha a sua disposizione le API per il caricamento ed il salvataggio del modello e dei suoi pesi.