Cualquier marco de aprendizaje profundo para tener éxito tiene que proporcionar una buena colección de redes neuronales de vanguardia, junto con sus pesos entrenados en conjuntos de datos populares y ampliamente aceptados. Muchos marcos generalmente se refieren a esta colección como Model Zoo. TensorFlow en sus versiones iniciales proporcionó este zoológico de redes a través de su marco TF-Slim. Pero la usabilidad de TF-Slim para las redes no era intuitiva y, con el tiempo, TF-Slim quedo en desuso.
TensorFlow, ahora ha creado un marco mejor conocido como TensorFlow Hub, que es muy fácil de usar y está bien organizado. Con TensorFlow Hub, podemos realizar con confianza la actividad ampliamente utilizada de Transfer Learning al importar redes grandes y populares en unas pocas líneas de código. TensorFlow Hub es muy flexible y proporciona la posibilidad de alojar nuestras redes para que otros usuarios las utilicen. Estas redes en TensorFlow Hub se denominan módulos.
Es
importante tener en cuenta que TensorFlow Hub solo proporciona un gráfico que
comprende la arquitectura de la red junto con sus pesos entrenados en ciertos
conjuntos de datos. La mayoría de los módulos dan acceso a capas internas de la
red que se pueden usar en función de diferentes casos de uso. Sin embargo,
algunos de los módulos no son ajustables. Antes de comenzar con el desarrollo,
es recomendable consultar la descripción proporcionada sobre el módulo en el
sitio web de TensorFlow Hub.
A continuación, veremos algunos aspectos y funciones importantes que se pueden utilizar para comprender más detalles sobre el módulo del TensorFlow Hub.
Si te gusta esta foto |
Prerrequisitos
Instanciación
En TensorFlow Hub se alojan varios módulos formados con diferentes redes (Inception, ResNet, ElMo, etc.) que sirven para diferentes propósitos (clasificación de imágenes, incrustaciones de texto, etc.). El usuario tiene que navegar por el catálogo de módulos y luego, una vez finalizado su propósito, necesitamos copiar la URL donde está alojada la red. Luego, podemos instanciar nuestro módulo de la siguiente forma:
import
tensorflow_hub as hub
module =
hub.Module(<<Module URL as
string>>, trainable=True)
Además del parámetro URL, el otro parámetro más notable es "trainable". Si deseamos ajustar / modificar los pesos del modelo, este parámetro debe establecerse como Verdadero.
Firma
La firma del módulo especifica para qué se utiliza el módulo. Todo el módulo viene con la firma "predeterminada" y la utiliza, si una firma no se menciona explícitamente. Para la mayoría de los módulos, cuando se utiliza la firma "predeterminada", las capas internas del modelo se abstraen del usuario. La función utilizada para enumerar todos los nombres de firma del módulo es get_signature_names ().
import
tensorflow_hub as hub
module =
hub.Module('https://tfhub.dev/google/imagenet/inception_v3/classification/1')
print(module.get_signature_names())
# ['default', 'image_classification', 'image_feature_vector']
Entradas esperadas
Cada
módulo tiene un conjunto de entradas esperadas dependiendo de la firma del
módulo que se esté utilizando. Aunque la mayoría de los módulos han documentado
el conjunto de entradas esperadas en el sitio web de TensorFlow Hub
(particularmente para la firma "predeterminada"), algunos de ellos no
lo han hecho. En este caso, es más fácil obtener la entrada esperada junto con
su tamaño y tipo de datos usando get_input_info_dict ().
module =
hub.Module('https://tfhub.dev/google/imagenet/inception_v3/classification/1')
print(module.get_input_info_dict())
# When no
signature is given, considers it as 'default'# {'images': <hub.ParsedTensorInfo
shape=(?, 299, 299, 3) dtype=float32 is_sparse=False>}
print(module.get_input_info_dict(signature='image_feature_vector')) # {'images': <hub.ParsedTensorInfo shape=(?, 299, 299, 3)
dtype=float32 is_sparse=False>}
Resultados esperados
Para construir la parte restante del gráfico después de que se construye el modelo de TensorFlow Hub, es necesario conocer el tipo de salida esperado. La función get_output_info_dict () se usa para este propósito. Hay que tener en cuenta que para la firma "predeterminada", generalmente habrá solo una salida, pero cuando utilizamos una firma no predeterminada, se expondrán varias capas del gráfico.
module =
hub.Module('https://tfhub.dev/google/imagenet/inception_v3/classification/1')
print(module.get_output_info_dict())
# When no
signature is given, considers it as 'default'
# {'default': <hub.ParsedTensorInfo shape=(?, 1001)
dtype=float32 is_sparse=False>}
print(module.get_output_info_dict(signature='image_classification'))
# {'InceptionV3/global_pool': <hub.ParsedTensorInfo shape=(?,
1, 1, 2048) dtype=float32 is_sparse=False>,
# 'InceptionV3/Logits': <hub.ParsedTensorInfo shape=(?, 1001)
dtype=float32 is_sparse=False>,
# 'InceptionV3/Conv2d_2b_3x3': <hub.ParsedTensorInfo shape=(?,
147, 147, 64) dtype=float32 is_sparse=False>
# ..... Several other exposed layers...... }
Recopilación de las capas necesarias del módulo
Después de crear una instancia del módulo, debemos extraer la capa/salida deseada del módulo y agregarla al gráfico. Estas son algunas de las formas de hacerlo:
import
tensorflow as tf
import
tensorflow_hub as hub
images =
tf.placeholder(tf.float32, (None, 299, 299, 3))
module =
hub.Module('https://tfhub.dev/google/imagenet/inception_v3/classification/1')
logits1 =
module(dict(images=images))
# implies
default signature
print(logits1)
# Tensor("module_apply_default/InceptionV3/Logits/SpatialSqueeze:0",
shape=(?, 1001), dtype=float32)
module_features =
module(dict(images=images),
signature='image_classification', as_dict=True)
# module_features stores all layers in key-value pairs
logits2 =
module_features['InceptionV3/Logits']
print(logits2)
#
Tensor("module_apply_image_classification/InceptionV3/Logits/SpatialSqueeze:0",
shape=(?, 1001), dtype=float32)
global_pool =
module_features['InceptionV3/global_pool']
print(global_pool)
# Tensor("module_apply_image_classification/InceptionV3/Logits/GlobalPool:0", shape=(?, 1, 1, 2048), dtype=float32)
Inicialización de las operaciones de TensorFlow Hub
TensorFlow Hub aloja el peso / valores de salida resultantes de todas las operaciones presentes en los módulos en formato tabular. Esto debe inicializarse usando tf.tables_initializer () junto con las inicializaciones de variables regulares. El bloque de código se ve así:
import
tensorflow as tf
with
tf.Session() as sess:
sess.run([tf.tables_initializer(), <<other initializers>>])
Bloque de esqueleto de código
Una
vez que se construye el gráfico completo que comprende su módulo, optimizadores
de algoritmos de aprendizaje, función objetivo, capas personalizadas, etc., así
es como puede verse la parte gráfica de su código.
import tensorflow as tf
import tensorflow_hub as hub
<< Create Placeholders >>
<< Create Dataset and Iterators >>
module1 = hub.Module(<< Module URL >>)
logits1 =
module1(<< input_dict >>)
module2 =
hub.Module(<< Module URL
>>)
module2_features =
module2(<< input_dict >>, signature='default', as_dict=True)
logits2 =
module2_features['default']
<<
Remaining graph, learning algorithms, objective function, etc >>
with
tf.Session() as sess:
sess.run([tf.tables_initializer(), <<
other initializers >>])
<< Remaining training pipeline >>
Estamos
haciendo uso de dos módulos. El primer módulo se construye utilizando un código
mínimo básico que utiliza implícitamente la firma y la capa predeterminadas. En
el segundo módulo, especifica explícitamente la firma y la capa
predeterminadas. De manera similar, podemos especificar la firma y las capas no
predeterminadas.
Ahora que hemos analizado cómo integrar un módulo en el gráfico, veamos varios tipos de módulos presentes en TensorFlow Hub. En cada uno de los ejemplos, se ha integrado con el conjunto de datos y la tubería Iterator y guardado con Saved_Model.
Módulos de clasificación de imágenes
Como su nombre indica, este conjunto de módulos se utilizan para la clasificación de imágenes. En esta categoría de módulos, se proporciona la arquitectura completa de la red. Esto incluye la capa densa final que se usa para la clasificación. En el ejemplo de código para esta categoría, solo vamos a ver el problema de clasificación de perros y gatos de Kaggle en 1001 clases ImageNet usando el módulo Inception V3.
import tensorflow as tf
import tensorflow_hub as hub
from Dataset import Dataset
tf.reset_default_graph()
dataset = Dataset()
module = hub.Module('https://tfhub.dev/google/imagenet/inception_v3/classification/1')
logits = module(dict(images=dataset.img_data))
softmax = tf.nn.softmax(logits)
top_predictions = tf.nn.top_k(softmax, top_k, name='top_predictions')
Si imprimimos las firmas de estos módulos, la mayoría de ellos tendrá un total de tres firmas que son "predeterminadas", "clasificación_imagen" e "imagen_feature_vector". Aunque la firma de "image_feature_vector" aparece en esta categoría de módulos, esta firma exhibirá características similares a las de la categoría de módulos de vectores de características que se explica a continuación.
Módulos de vectores de características
Esto
es muy similar al de los módulos de clasificación de imágenes, con la única
diferencia de que el módulo no incluye la capa de clasificación densa final. En
el ejemplo de código para esta categoría, voy a ajustar el módulo Resnet-50
para el problema de clasificación de atributos de animales con múltiples
etiquetas de Hackerearth.
Durante la operación de ajuste, muy a menudo, se hace necesario optimizar las capas finales del módulo además de las capas densas anexas de manera personalizada. Durante tales escenarios, tendremos que encontrar los nombres del alcance o las variables que deseamos ajustar. Se adjunta la parte relevante del código para realizar dicho procedimiento en el Módulo de vectores de características.
Module =
hub.Module('https://tfhub.dev/google/imagenet/resnet_v2_50/feature_vector/1',
trainable=True) # Trainable is True since we are going to
fine-tune the model
module_features
= module(dict(images=dataset.image_data), signature="image_feature_vector",
as_dict=True)
features =
module_features["default"]
with
tf.variable_scope('CustomLayer'):
weight = tf.get_variable('weights',
initializer=tf.truncated_normal((2048, n_class)))
bias = tf.get_variable('bias',
initializer=tf.ones((n_class)))
logits = tf.nn.xw_plus_b(features, weight,
bias)
# Find out the
names of all variables present in graph
print(tf.all_variables())
# After finding
the names of variables or scope, gather the variables you wish to fine-tune
var_list =
tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='CustomLayer')
var_list2 =
tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
scope='module/resnet_v2_50/block4')
var_list.extend(var_list2)
# Pass this set
of variables into your optimiser
optimizer =
tf.train.AdamOptimizer(learning_rate=lr).minimize(loss, var_list=var_list)
Código
de función del vector que muestra cómo ajustar las capas del módulo
Si los nodos en el gráfico del módulo no se nombran intuitivamente (escenario muy poco probable), tendremos que descubrir la arquitectura del módulo y luego asignarlos a los nodos que se están imprimiendo.
En
el ejemplo de código, Se han ajustado las variables finales de las pocas capas
que se encuentran dentro del alcance variable de "resnet_v2_50 /
block4". Al entrenar durante 10 épocas, obtendremos un puntaje de F1 de
0.95819 sin esfuerzo para este problema.
Módulos
de clasificación de video
La
clasificación de video se refiere a categorizar la naturaleza de las actividades
que ocurren en un video clip. En el ejemplo de código, se ha entrenado el
conjunto de datos 20BN-Jester que consta de 27 clases en el módulo Inception
3D. Nuevamente, con solo 3 épocas de entrenamiento, he logrado un puntaje de
91.45% de precisión. La parte relevante del código del módulo se muestra a
continuación.
import tensorflow as tf
import tensorflow_hub as hub
from Dataset
import Dataset
dataset =
Dataset()
module =
hub.Module("https://tfhub.dev/deepmind/i3d-kinetics-400/1",
trainable=True)
features =
module(dict(rgb_input=dataset.image_data))
n_class = 27
with
tf.variable_scope('CustomLayer'):
weight = tf.get_variable('weights',
initializer=tf.truncated_normal((400, n_class)))
bias = tf.get_variable('bias',
initializer=tf.ones((n_class)))
logits =
tf.nn.xw_plus_b(features, weight, bias)
Para probar la precisión del modelo, se creó una aplicación simple de clasificación de vídeo en tiempo real y aquí hay un pequeño vídeo.
Clasificación de vídeo en tiempo real construida utilizando TensorFlow Hub
Módulos de incrustación de texto
TensorFlow Hub ha suministrado varios módulos de incrustación de texto no solo en inglés sino también en varios otros idiomas como alemán, coreano, japonés, etc., muchos de ellos producen incrustaciones a nivel de oración y no a nivel de oración. nivel de palabra En el ejemplo del código, se ha trabajado en el análisis de sentimientos de Kaggle sobre la crítica de películas. Usando el módulo de incrustaciones ELMO, se entrenó una la red usando incrustaciones producidas a nivel de oración y palabra por separado. La red se compone de una sola capa de LSTM bidireccional. A nivel de la oración, después de entrenar durante 6 épocas, la precisión alcanzada fue del 65%. Adjuntando la parte relevante del código del módulo Incorporación de texto de TensorFlow Hub
module = hub.Module('https://tfhub.dev/google/elmo/2',
trainable=True)
embeddings =
module(dict(text=dataset.text_data))
embeddings =
tf.expand_dims(embeddings, axis=1)
with tf.variable_scope('Layer1'):
cell_fw1 =
tf.nn.rnn_cell.LSTMCell(num_units=128, state_is_tuple=True)
cell_bw1 =
tf.nn.rnn_cell.LSTMCell(num_units=128, state_is_tuple=True)
outputs1, states1 =
tf.nn.bidirectional_dynamic_rnn(
cell_fw=cell_fw1,
cell_bw=cell_bw1,
inputs=embeddings)
rnn_output = tf.reshape(outputs1[0], (-1, 128))
with
tf.variable_scope('Layer2'):
weight2 = tf.get_variable('weight',
initializer=tf.truncated_normal((128, n_class)))
bias2 = tf.get_variable('bias',
initializer=tf.ones(n_class))
logits = tf.nn.xw_plus_b(rnn_output, weight2, bias2)
Módulos
de aumento de imagen
El aumento de imagen es un componente esencial en el proceso de capacitación para aumentar la precisión de una red. Ninguno de los módulos de aumento de imagen tiene ninguna variable en ellos, y en consecuencia, estos módulos no son ajustables / entrenables. Con la firma de "from_decoded_images", podemos alimentar directamente las imágenes a estos módulos. A continuación se muestra un bloque de código de ejemplo junto con las imágenes aumentadas generadas.
import tensorflow as tf
import
tensorflow_hub as hub
import tensorflow.contrib.image # Needed for Image Augmentation modules
from Dataset
import Dataset
dataset = Dataset()
module =
hub.Module('https://tfhub.dev/google/image_augmentation/nas_svhn/1')
input_dict =
dict(image_size=image_size, # Output Image size
images=dataset.img_data, # Has the image in Numpy data format
augmentation=True)
aug_images = module(input_dict, signature='from_decoded_images')
La utilidad real del aumento de imagen se produce cuando agrupamos este módulo con otros módulos de clasificación de imágenes, vector de características, etc. En el problema de clasificación de atributos de animales multi-etiqueta previamente entrenado usando el módulo Feature Vector, se agregó el módulo de aumento de imagen crop_color, y con el mismo número de épocas, el puntaje F1 mejora a 0.96244. En este ejemplo de código, se utiliza la firma predeterminada, que esperará que la imagen en forma codificada sea su entrada. Ahora, a medida que el módulo de aumento de imagen redimensiona la imagen de entrada a un tamaño fijo para su posterior procesamiento por el módulo Resnet50, se ha guardado el trabajo de cambiar explícitamente el tamaño de las imágenes, lo que había hecho anteriormente.
import tensorflow as tf
import
tensorflow_hub as hub
import tensorflow.contrib.image # Needed for Image Augmentation modules
aug_module =
hub.Module('https://tfhub.dev/google/image_augmentation/crop_color/1')
aug_features =
aug_module(dict(encoded_images=dataset.encoded_img_data,
image_size=image_size,
augmentation=is_training)) # No augmentation needed for test and validation pipeline
resnet_module = hub.Module('https://tfhub.dev/google/imagenet/resnet_v2_50/feature_vector/1',
trainable=True)
img_features =
resnet_module(dict(images=aug_features))
with
tf.variable_scope('CustomLayer'):
weight = tf.get_variable('weights',
initializer=tf.truncated_normal((2048, n_class)))
bias = tf.get_variable('bias',
initializer=tf.ones((n_class)))
logits = tf.nn.xw_plus_b(img_features, weight, bias)
Módulos de detección de objetos
Los módulos de detección de objetos no son compatibles con el ajuste fino, por lo que tendremos que realizar un entrenamiento desde cero si tiene su propio conjunto de datos. El procesamiento por lotes de los datos tampoco es compatible en este momento. En el ejemplo de código, solo realizaremos inferencias en las imágenes usando FasterRCNN en el módulo Inception-ResNet V2. Se ha adjuntado la parte del módulo de código e imágenes generadas a partir del módulo a continuación.
import tensorflow as tf
import tensorflow_hub as hub
from Dataset
import Dataset
dataset = Dataset()
module =
hub.Module('https://tfhub.dev/google/faster_rcnn/openimages_v4/inception_resnet_v2/1')
detector = module(dict(images=dataset.image_data), as_dict=True)
class_entities =
detector['detection_class_entities']
boxes =
detector['detection_boxes']
scores =
detector['detection_scores']
class_labels =
detector['detection_class_labels']
class_names = detector['detection_class_names']
Módulos generadores
Estos
corresponden a Redes Adversales Generativas (GAN). Algunos de los módulos no
han expuesto su parte Discriminadora de la red. Al igual que la detección de
objetos, incluso aquí en la muestra de código, solo realizaremos inferencia.
Usando el módulo Progressive GANs que está capacitado en el conjunto de datos
CelebA, generaremos nuevas caras. Se ha adjuntado la parte del módulo de código
e imágenes generadas a partir del módulo a continuación.
import tensorflow_hub as hub
from Dataset
import Dataset
dataset = Dataset()
module =
hub.Module("https://tfhub.dev/google/progan-128/1")
images = module(dataset.latent_vector_space)
Para ver el código completo integrado con Dataset e Iterators, y guardado con Saved_Model, consultar el código en el repositorio de GitHub.
No hay comentarios:
Publicar un comentario