1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/Python_Ai_Road-eat_tensorflow2_in_30_days

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
4-5,AutoGraph和tf.Module.md 13 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 03.12.2024 15:14 374a95e

4-5,AutoGraph и tf.Module

Есть три способа построения вычислительного графа: статический вычислительный граф, динамический вычислительный граф и Autograph.

В TensorFlow 2.0 в основном используются динамические вычислительные графы и Autograph.

Динамические вычислительные графы легко отлаживать, они имеют высокую эффективность кодирования, но низкую производительность выполнения.

Статические вычислительные графы имеют высокую производительность выполнения, но их сложно отлаживать.

Механизм Autograph может преобразовывать динамические графы в статические вычислительные графы, сочетая преимущества производительности выполнения и эффективности кодирования.

Конечно, код, который может быть преобразован механизмом Autograph, не является неограниченным, необходимо следовать некоторым правилам кодирования, иначе преобразование может завершиться неудачно или привести к неожиданным результатам.

Ранее мы рассказывали о правилах кодирования Autograph и принципе преобразования Autograph в статическую диаграмму.

В этой статье мы расскажем об использовании tf.Module для лучшего создания Autograph.

I, Обзор Autograph и tf.Module

Ранее, при объяснении правил кодирования Autograph, упоминалось, что при создании Autograph следует избегать определения tf.Variable внутри функции, оформленной @tf.function.

Но если определить tf.Variable вне функции, то функция будет зависеть от внешних переменных, что не идеально с точки зрения инкапсуляции.

Простая идея заключается в определении класса и создании соответствующих tf.Variables в методе инициализации класса. А логику функции поместить в другие методы.

После всех этих операций мы почувствуем, что всё стало естественным и понятным.

К счастью, TensorFlow предоставляет базовый класс tf.Module. Создавая подклассы этого класса, мы можем не только получить вышеупомянутые преимущества, но и удобно управлять переменными, а также ссылающимися на них другими модулями. И что самое важное, мы можем использовать tf.saved_model для сохранения модели и обеспечения кроссплатформенного развёртывания.

Фактически, tf.keras.models.Model и tf.keras.layers.Layer являются подклассами tf.Module, предоставляя удобные функции управления переменными и ссылающимися на них дочерними модулями.

Таким образом, используя инкапсуляцию, предоставленную tf.Module в сочетании с богатым низкоуровневым API TensorFlow, мы фактически можем разрабатывать любые модели машинного обучения (а не только модели нейронных сетей) на основе TensorFlow и обеспечивать их кроссплатформенное развёртывание.

II, Применение инкапсуляции tf.Module к Autograph

Определим простую функцию.

import tensorflow as tf 
x = tf.Variable(1.0,dtype=tf.float32)

# В tf.function используем input_signature для определения типа подписи входного тензора: shape и dtype
@tf.function(input_signature=[tf.TensorSpec(shape = [], dtype = tf.float32)])    
def add_print(a):
    x.assign_add(a)
    tf.print(x)
    return(x)
add_print(tf.constant(3.0))
# add_print(tf.constant(3)) # Ошибка, если входные параметры не соответствуют типу тензорной подписи
4

Теперь используем наследование tf.Module для инкапсуляции этого.

class DemoModule(tf.Module):
    def __init__(self,init_value = tf.constant(0.0),name=None):
        super(DemoModule, self).__init__(name=name)
        with self.name_scope:  # Эквивалентно with tf.name_scope("demo_module")
            self.x = tf.Variable(init_value,dtype = tf.float32,trainable=True)

     
    @tf.function(input_signature=[tf.TensorSpec(shape = [], dtype = tf.float32)])  
    def addprint(self,a):
        with self.name_scope:
            self.x.assign_add(a)
            tf.print(self.x)
            return(self.x)
# Выполнение
demo = DemoModule(init_value = tf.constant(1.0))
result = demo.addprint(tf.constant(5.0))
6
# Просмотр всех переменных и обучаемых переменных модуля
print(demo.variables)
print(demo.trainable_variables)
(<tf.Variable 'demo_module/Variable:0' shape=() dtype=float32, numpy=6.0>,)
(<tf.Variable 'demo_module/Variable:0' shape=() dtype=float32, numpy=6.0>,)
# Просмотр всех подмодулей
demo.submodules
# Использование tf.saved_model для сохранения модели и указание метода, необходимого для кроссплатформенного развертывания
tf.saved_model.save(demo,"./data/demo/1",signatures = {"serving_default":demo.addprint})
# Загрузка модели
demo2 = tf.saved_model.load("./data/demo/1")
demo2.addprint(tf.constant(5.0))
11
# Просмотр информации о файле модели, выходные данные, выделенные красным цветом, могут быть полезны при развертывании модели и кроссплатформенном использовании
!saved_model_cli show --dir ./data/demo/1 --all

![](./data/Просмотр информации о файле модели.jpg)

Просматриваем вычислительную диаграмму в tensorboard, модули будут добавлены с именем модуля demo_module для удобства представления структуры вычислительной диаграммы.

import datetime

# Создание журнала
stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
logdir = './data/demomodule/%s' % stamp
writer = tf.summary.create_file_writer(logdir)

# Запуск autograph отслеживания
tf.summary.trace_on(graph=True, profiler=True) 

# Выполнение autograph
demo = DemoModule(init_value = tf.constant(0.0))
result = demo.addprint(tf.constant(5.0))

# Запись информации о вычислительной диаграмме в журнал
with writer.as_default():
    tf.summary.trace_export(
        name="demomodule",
        step=0,
        profiler_outdir=logdir)
    
# Запуск магии tensorboard в jupyter
%reload_ext tensorboard
from tensorboard import notebook
notebook.list() 
notebook.start("--logdir ./data/demomodule/")

![](./data/Вычислительная диаграмма demomodule.jpg)

Помимо наследования tf.Module для реализации инкапсуляции, мы также можем инкапсулировать через добавление атрибутов к tf.Module.

mymodule = tf.Module()
mymodule.x = tf.Variable(0.0)

@tf.function(input_signature=[tf.TensorSpec(shape = [], dtype = tf.float32)])  
def addprint(a):
    mymodule.x.assign_add(a)
    tf.print(mymodule.x)
    return (mymodule.x)

mymodule.addprint = addprint
mymodule.addprint(tf.constant(1.0)).numpy()
1.0
print(mymodule.variables)
(<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>,)
``` ```
# 使用tf.saved_model 保存模型
tf.saved_model.save(mymodule,"./data/mymodule",
    signatures = {"serving_default":mymodule.addprint})

# 加载模型
mymodule2 = tf.saved_model.load("./data/mymodule")
mymodule2.addprint(tf.constant(5.0))
INFO:tensorflow:Assets written to: ./data/mymodule/assets
5

三,tf.Module和tf.keras.Model,tf.keras.layers.Layer

tf.keras中的模型和层都是继承tf.Module实现的,也具有变量管理和子模块管理功能。

import tensorflow as tf
from tensorflow.keras import models,layers,losses,metrics
print(issubclass(tf.keras.Model,tf.Module))
print(issubclass(tf.keras.layers.Layer,tf.Module))
print(issubclass(tf.keras.Model,tf.keras.layers.Layer))
True
True
True
tf.keras.backend.clear_session() 

model = models.Sequential()

model.add(layers.Dense(4,input_shape = (10,)))
model.add(layers.Dense(2))
model.add(layers.Dense(1))
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 4)                 44        
_________________________________________________________________
dense_1 (Dense)              (None, 2)                 10        
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 3         
=================================================================
Total params: 57
Trainable params: 57
Non-trainable params: 0
_________________________________________________________________
model.variables
[<tf.Variable 'dense/kernel:0' shape=(10, 4) dtype=float32, numpy=
 array([[-0.06741005,  0.45534766,  0.5190817 , -0.01806331],
        [-0.14258742, -0.49711505,  0.26030976,  0.18607801],
        [-0.62806034,  0.5327399 ,  0.42206633,  0.29201728],
        [-0.16602087, -0.18901917,  0.55159235, -0.01091868],
        [ 0.04533798,  0.326845  , -0.582667  ,  0.19431782],
        [ 0.6494713 , -0.16174704,  0.4062966 ,  0.48760796],
        [ 0.58400524, -0.6280886 , -0.11265379, -0.6438277 ],
        [ 0.26642334,  0.49275804,  0.20793378, -0.43889117],
        [ 0.4092741 ,  0.09871006, -0.2073121 ,  0.26047975],
        [ 0.43910992,  0.00199282, -0.07711256, -0.27966842]],
       dtype=float32)>,
 <tf.Variable 'dense/bias:0' shape=(4,) dtype=float32, numpy=array([0., 0., 0., 0.], dtype=float32)>,
 <tf.Variable 'dense_1/kernel:0' shape=(4, 2) dtype=float32, numpy=
 array([[ 0.5022683 , -0.0507431 ],
        [-0.61540484,  0.9369011 ],
        [-0.14412141, -0.54607415],
        [ 0.2027781 , -0.4651153 ]], dtype=float32)>,
 <tf.Variable 'dense_1/bias:0' shape=(2,) dtype=float32, numpy=array([0., 0.], dtype=float32)>,
 <tf.Variable 'dense_2/kernel:0' shape=(2, 1) dtype=float32, numpy=
 array([[-0.244825 ],
        [-1.2101456]], dtype=float32)>,
 <tf.Variable 'dense_2/bias:0' shape=(1,) dtype=float32, numpy=array([0.], dtype=float32)>]
model.layers[0].trainable = False #冻结第0层的变量,使其不可训练
model.trainable_variables
[<tf.Variable 'dense_1/kernel:0' shape=(4, 2) dtype=float32, numpy=
 array([[ 0.5022683 , -0.0507431 ],
        [-0.61540484,  0.9369011 ],
        [-0.14412141, -0.54607415],
        [ 0.2027781 , -0.4651153 ]], dtype=float32)>,
 <tf.Variable 'dense_1/bias:0' shape=(2,) dtype=float32, numpy=array([0., 0.], dtype=float32)>,
 <tf.Variable 'dense_2/kernel:0' shape=(2, 1) dtype=float32, numpy=
 array([[-0.244825 ],
        [-1.2101456]], dtype=float32)>,
 <tf.Variable 'dense_2/bias:0' shape=(1,) dtype=float32, numpy=array([0.], dtype=float32)>]
model.submodules
(<tensorflow.python.keras.engine.input_layer.InputLayer at 0x144d8c080>,
 <tensorflow.python.keras.layers.core.Dense at 0x144daada0>,
 <tensorflow.python.keras.layers.core.Dense at 0x144d8c5c0>,
 <tensorflow.python.keras.layers.core.Dense at 0x144d7aa20>)
model.layers
[<tensorflow.python.keras.layers.core.Dense at 0x144daada0>,

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/Python_Ai_Road-eat_tensorflow2_in_30_days.git
git@api.gitlife.ru:oschina-mirror/Python_Ai_Road-eat_tensorflow2_in_30_days.git
oschina-mirror
Python_Ai_Road-eat_tensorflow2_in_30_days
Python_Ai_Road-eat_tensorflow2_in_30_days
master