[PYTHON] [TensorFlow 2.x (tf.keras)] Correction de la graine aléatoire pour améliorer la reproductibilité

Je vais vous montrer comment réparer la graine aléatoire avec Tensorflow 2.x ( tf.keras).

Environnement d'exécution

Le code utilisé pour le test se trouve ici (https://github.com/tokusumi/tf-keras-random-seed).

Contexte

Dans le développement de l'apprentissage automatique, il existe des exigences telles que «Je veux rendre l'apprentissage reproductible» et «Je veux fixer la valeur initiale du modèle pour le test». Puisque la différence de la valeur initiale du poids affecte le résultat de l'apprentissage, il semble que la fixation de la valeur initiale aidera à résoudre ces problèmes.

Des nombres aléatoires sont utilisés pour générer la valeur initiale du poids. Les nombres aléatoires sont générés sur la base de graines de nombres aléatoires. Par défaut, TensorFlow a une valeur de départ aléatoire variable. Par conséquent, un modèle avec une valeur initiale différente sera généré à chaque fois. Par conséquent, cette fois, nous visons à améliorer la reproductibilité en fixant la graine de nombre aléatoire.

Graine aléatoire fixe

En plus de TensorFlow, nous corrigeons également les bases des fonctions intégrées NumPy et Python. En résumé, les fonctions de nombres aléatoires fixes suivantes peuvent être implémentées.

import tensorflow as tf
import numpy as np
import random
import os

def set_seed(seed=200):
    tf.random.set_seed(seed)

    # optional
    # for numpy.random
    np.random.seed(seed)
    # for built-in random
    random.seed(seed)
    # for hash seed
    os.environ["PYTHONHASHSEED"] = str(seed)

Il est utilisé comme suit. Cependant, si la graine aléatoire fixe de TensorFlow est suffisante, remplacez set_seed par tf.random.set_seed.

set_seed(0)
toy_model = tf.keras.Sequential(
    tf.keras.layers.Dense(2, input_shape=(10,))
)

#Certains traitements...

#Reproduire le modèle
set_seed(0)
reproduced_toy_model = tf.keras.Sequential(
    tf.keras.layers.Dense(2, input_shape=(10,))
)

reproduced_toy_model a la même valeur initiale (de poids) que le modèle précédemment généré toy_model. En d'autres termes, il a été reproduit.

Si vous n'utilisez pas set_seed, reproductible_toy_model et toy_model auront des valeurs initiales complètement différentes, ce qui nuira à la reproductibilité.

En plus de tf.keras.Sequential, vous pouvez également utiliser l'API fonctionnelle et la sous-classe.

Voyons comment corriger un peu plus la graine aléatoire (set_seed).

À propos de tf.random.set_seed

Le comportement de tf.random.set_seed a besoin d'un peu d'attention.

Tout d'abord, après avoir utilisé tf.random.set_seed, essayez d'utiliser une fonction qui utilise des nombres aléatoires ( tf.random.uniform: échantillonner aléatoirement des valeurs d'une distribution uniforme) plusieurs fois.

tf.random.set_seed(0)
tf.random.uniform([1])  # => [0.29197514]
tf.random.uniform([1])  # => [0.5554141]  (Différentes valeurs!)
tf.random.uniform([1])  # => [0.1952138]  (Différentes valeurs!!)
tf.random.uniform([1])  # => [0.17513537](Différentes valeurs!!!)

Différentes valeurs ont été produites pour chacun. Il semble qu'il n'y ait pas de reproductibilité telle quelle. Cependant, utilisez à nouveau tf.random.set_seed comme suit.

tf.random.set_seed(0)
tf.random.uniform([1])  # => [0.29197514](A)
tf.random.uniform([1])  # => [0.5554141]  (B)

tf.random.set_seed(0)
tf.random.uniform([1])  # => [0.29197514](Reproduction d'un)
tf.random.uniform([1])  # => [0.5554141]  (Reproduction de B)

De cette façon, la sortie est reproduite à partir de l'endroit où tf.random.set_seed est appelé (même si tf.random.uniform est une fonction qui produit une valeur au hasard).

Ainsi, par exemple, si vous appelez tf.random.set_seed juste avant de créer une instance de modèle (en utilisant Sequential, Functional API ou SubClass), le modèle généré aura la même valeur initiale à chaque fois.

Supplément

TensorFlow a des couches et des fonctions qui vous permettent de passer des semences comme argument.

Cependant, je pense que spécifier explicitement l'argument d'initialisation à passer au calque ou au calque n'est pas une méthode très réaliste à mesure que le modèle se développe.

De plus, il y en a qui ne fonctionnent pas bien à moins que le tf.random.set_seed introduit cette fois ne soit utilisé ensemble.

Donc, même s'il y a peu d'endroits que vous souhaitez corriger, veuillez d'abord essayer tf.random.set_seed.

Résumé

Dans TensorFlow 2.x (tf.keras), vous pouvez utiliser tf.random.set_seed pour corriger la graine aléatoire.

En particulier, il sera possible de générer un modèle avec la même valeur de poids initiale à chaque fois, on peut donc s'attendre à une amélioration de la reproductibilité.

Ref

Recommended Posts

[TensorFlow 2.x (tf.keras)] Correction de la graine aléatoire pour améliorer la reproductibilité
Graine aléatoire corrigée dans TensorFlow et Numpy Un peu différent
Correction de la graine aléatoire avec TensorFlow
Assurer la reproductibilité avec tf.keras dans Tensorflow 2.3