Hoy inauguramos la serie anual de Playtime a escala mundial con eventos consecutivos en Berlín y San Francisco. 2017 es un año increíble para los programadores en Google Play. Durante el mes próximo, nos enteraremos de cómo les está yendo a muchos programadores de apps y juegos de distintas ciudades de todo el mundo. Es un año excelente para los programadores en Google Play, y ahora hay más de 8,000 millones de instalaciones nuevas por mes en todo el mundo.

Hoy inauguramos la serie anual de Playtime a escala mundial con eventos consecutivos en Berlín y San Francisco. 2017 es un año increíble para los programadores en Google Play. Durante el mes próximo, nos enteraremos de cómo les está yendo a muchos programadores de apps y juegos de distintas ciudades de todo el mundo. Es un año excelente para los programadores en Google Play, y ahora hay más de 8,000 millones de instalaciones nuevas por mes en todo el mundo.


Para ayudarte a seguir aprovechando esta oportunidad, anunciamos innovaciones en Google Play y nuevas características en Play Console. Síguenos en Medium, donde los presentadores publicarán sus estrategias, prácticas recomendadas y ejemplos para ayudarte a alcanzar tus objetivos de negocio. A medida que crece Google Play, deseamos ayudar a los usuarios a comprender nuestro negocio. Por eso, publicamos también el informe State of Play 2017, que se actualizará anualmente y te ayudará a mantenerte informado sobre el progreso de Play y la ayuda que ofrecemos a los programadores para que alcancen el éxito.


Google Play les da vida a todos tus dispositivos, ya sean teléfonos y tablets, dispositivos Wear, TV, Daydream o Chromebook, como el nuevo dispositivo Google Pixelbook. Ahora es más fácil que los usuarios descubran contenido excelente y vuelvan a participar en Play Store.



Google Cloud Platform (GCP) es un espacio ideal para ejecutar tus cargas de trabajo .NET y mejoró aún más con la última versión de Cloud Tools para la extensión de Visual Studio, Cloud Tools para Powershell y nuestro tiempo de ejecución de ASP.NET Core para App Engine Flexible.


Google Cloud Platform (GCP) es un espacio ideal para ejecutar tus cargas de trabajo .NET y mejoró aún más con la última versión de Cloud Tools para la extensión de Visual Studio, Cloud Tools para Powershell y nuestro tiempo de ejecución de ASP.NET Core para App Engine Flexible.

Cloud Tools para Visual Studio 


Integramos los visores de extensiones para Stackdriver Logging y Stackdriver Error Reporting a Visual Studio para ayudarte a diagnosticar problemas y controlar tu código. También mejoramos Cloud Explorer con una integración más profunda de Google Cloud Storage y Google Cloud Pub/Sub, a fin de que puedas administrar tus recursos sin abandonar Visual Studio.
Integración de Stackdriver 

A veces, incluso el mejor código experimenta desperfectos en la producción. Para ayudarte a realizar un diagnóstico de lo que sucede, integramos Stackdriver Logging y Stackdriver Error Reporting a Visual Studio, para que puedas encontrar la fuente del problema mientras esté abierta tu solución de Visual Studio.

Independientemente de que tu app esté basada en ASP.NET 4.x o ASP.NET Core, si usas Stackdriver Logging para registrar tu app .NET, ahora puedes explorar las entradas de registro que esta generó directamente en Visual Studio:
También puedes realizar consultas de los registros que se originen de una versión y un servicio determinados en Google App Engine (como se muestra en la imagen anterior) o explorar las entradas de registro que provengan de una VM determinada de Compute Engine.

Lo que es aún mejor, si usas nuestro paquete NuGet de Google.Cloud.Logging.V2 para enviar las entradas de registro, la extensión puede hacer coincidir las entradas de registro con las líneas de código fuente en las que se originaron. La extensión intenta obtener la versión exacta del código fuente de git, lo cual te permite ver exactamente el origen de la entrada de registro. Consulta la documentación del visor de registros de Stackdriver para obtener más detalles sobre cómo usar esta característica.

¿Qué sucede cuando tu app falla? En este punto, entra en escena Stackdriver Error Reporting. Si tu aplicación usa Stackdriver Error Reporting para enviar informes de errores a Stackdriver, ahora puedes explorar estos informes directamente desde Visual Studio:

Puedes ver los errores más frecuentes y el seguimiento de pila completo del error, e incluso ir directamente a la línea de código fuente en la que se originó el error. Para obtener información más detallada, consulta la sección del visor de errores de Stackdriver.

Mejoras de Cloud Explorer 

Comprendemos tu deseo de permanecer en Visual Studio cuando trabajas con tus apps, porque la entrada y la salida de Visual Studio es un cambio grande de contexto. Para ello, seguimos mejorando nuestra propia Cloud Explorer para que puedas administrar los recursos más importantes directamente desde Visual Studio. En la última versión, agregamos una integración más profunda con Cloud Storage y un nodo nuevo para administrar tus recursos de Cloud Pub/Sub.

Veamos lo que puedes hacer ahora con la integración de Cloud Storage. Siempre pudiste ver directamente en Cloud Explorer los depósitos que existían en el proyecto actual. Ahora, también puedes abrir los depósitos y consultar los archivos almacenados dentro de ellos, y tratar a los depósitos como discos duros.
Con la integración nueva, puedes copiar archivos dentro y fuera de los depósitos, cambiar sus nombres y crear directorios nuevos;  en resumen, puedes administrar los contenidos de tus depósitos de Cloud Storage directamente desde Visual Studio. Consulta la documentación para obtener información completa sobre lo que puedes hacer ahora con tus depósitos de Cloud Storage.

A continuación, se encuentra el recurso nuevo de Google Cloud Pub/Sub que agregamos a Cloud Explorer:
El nodo nuevo de Cloud Pub/Sub te permite administrar tus temas y suscripciones de Pub/Sub, y también enviar mensajes nuevos a temas existentes para pruebas, todo dentro de Visual Studio. Consulta la documentación para obtener información completa sobre lo que puedes hacer con este nodo nuevo.

Nuevos cmdlets de Powershell 


Visual Studio es un entorno realmente bueno para la mayor parte del trabajo de desarrollo, pero a veces la solución correcta es usar Powershell para automatizar tus recursos de GCP. Con este fin, hemos agregado cmdlets nuevos para administrar aún más recursos. Agregamos cmdlets para interactuar con BigQuery, lo cual te permite ejecutar consultas, crear tablas y hacer otras tareas. También agregamos cmdlets para administrar clústeres y nodos de Google Container Engine.

Kubernetes, y su variante administrada por GCP de Google Container Engine, se está convirtiendo en uno de los métodos más populares para administrar las cargas de trabajo en la nube. Es por ello que agregamos un conjunto de cmdlets para administrar los clústeres de tu Container Engine desde Powershell. Por ejemplo, usa los siguientes comandos para crear un clúster nuevo.
# Creates a Container Engine Node Config with image type CONTAINER_VM
# and 20 GB disk size for each node.
$nodeConfig = New-GkeNodeConfig -DiskSizeGb 20 `
                                -ImageType CONTAINER_VM

# Creates a cluster named "my-cluster" in the default zone of the
# default project using config $nodeConfig and network "my-network".
Add-GkeCluster -NodeConfig $nodeConfig `
               -ClusterName "my-cluster" `
               -Network "my-network"

Para obtener más información sobre lo que puedes hacer con los cmdlets de Container Engine, consulta la documentación

También existe BigQuery, una gran solución de almacenamiento de datos que se usa para guardar miles de millones de filas y realiza consultas para extraer estadísticas de todos esos datos. Aquí también hay nuevos cmdlets para administrar BigQuery directamente desde Powershell. Por ejemplo, aquí se muestra la manera de crear una tabla nueva de BigQuery:
# Creates a schema object to be used in multiple tables.
$schema = New-BqSchema "Page" "STRING" | New-BqSchema "Referrer" "STRING" |
    New-BqSchema "Timestamp" "DATETIME" | Set-BqSchema

# Creates a new table with the Schema object from above.
$table = $dataset | New-BqTable "logs2014" -Schema $schema
Para obtener más información sobre lo que puedes hacer con los cmdlets de BigQuery, consulta la documentación.

Queremos recibir sus comentarios 


Deseamos trabajar en las funciones que más te importan mientras continuamos mejorando las cargas de trabajo de .NET y Windows en GCP. ¡Continúa enviándonos tus comentarios! Puedes abrir asuntos relacionados con Cloud Tools para Visual Studio y Cloud Tools para Powershell en sus repositorios de Github.

Publicado por el equipo de TensorFlow
En TensorFlow 1.3 se introducen dos funciones importantes que te recomendamos probar:
  • Conjuntos de datos: una forma completamente nueva de crear procesos de entrada (es decir, lectura de datos para tu programa).
 Publicado por el equipo de TensorFlow
En TensorFlow 1.3 se introducen dos funciones importantes que te recomendamos probar:
  • Conjuntos de datos: una forma completamente nueva de crear procesos de entrada (es decir, lectura de datos para tu programa).
  • Estimadores: un método de alto nivel para crear modelos de TensorFlow. Los estimadores incluyen modelos preconfigurados para tareas comunes de aprendizaje automático, pero también puedes usarlos para crear tus propios modelos personalizados.

A continuación, te mostramos cómo se adecuan a la arquitectura de TensorFlow. Juntos ofrecen una forma sencilla de crear modelos de TensorFlow y enviarles datos:

Nuestro modelo de ejemplo


Para explorar estas funciones, compilaremos un modelo y te mostraremos fragmentos de código importantes. El código completo está disponible aquí y se incluyen instrucciones para obtener los archivos de capacitación y prueba. Ten en cuenta que el código se escribió para demostrar la funcionalidad de los conjuntos de datos y los estimadores, pero no se optimizó para brindar el máximo rendimiento.

El modelo entrenado categoriza las flores de iris en función de cuatro características botánicas (longitud del sépalo, ancho del sépalo, longitud del pétalo y ancho del pétalo). Por lo tanto, durante la inferencia, puedes proporcionar valores para esas cuatro características y el modelo predecirá que la flor corresponde a una de las tres hermosas variedades siguientes:
De izquierda a derecha: Iris setosa (por Radomil, CC BY-SA 3.0), iris versicolor (por Dlanglois, CC BY-SA 3.0) e iris virginica(por Frank Mayfield, CC BY-SA 2.0).

Prepararemos un clasificador de red neuronal profunda con la estructura que se indica a continuación. Todos los valores de entrada y salida serán float32, y la suma de los valores de salida será igual a 1 (ya que se predice la probabilidad para cada tipo de iris individual):

Por ejemplo, un resultado de salida podría ser 0,05 para iris setosa, 0,9 para iris versicolor y 0,05 para iris virginica, lo cual indica un 90% de probabilidad de que se trate de una iris versicolor.

¡Muy bien! Ahora que definimos el modelo, veamos cómo podemos usar conjuntos de datos y estimadores para prepararlo y realizar predicciones.

Introducción a los conjuntos de datos


Los conjuntos de datos son una nueva manera de crear procesos de entrada para modelos de TensorFlow. Esta API ofrece un rendimiento muy superior al que se obtiene usando feed_dict o los procesos basados en cola, y es más limpia y fácil de usar. Si bien la Datasets API todavía reside en tf.contrib.data en la versión 1.3, prevemos que pase a ser central en la versión 1.4, por lo que este es el mejor momento para probarla.

A grandes rasgos, Datasets API está compuesta por las siguientes clases:

Donde:
  • Dataset: clase básica que contiene los métodos para crear y transformar conjuntos de datos. También te permite inicializar un conjunto de datos a partir de datos en la memoria, o de un generador Python.
  • TextLineDataset: lee líneas de archivos de texto.
  • TFRecordDataset: lee registros de archivos TFRecord.
  • FixedLengthRecordDataset: lee registros de tamaño fijo de archivos binarios.
  • Iterator: proporciona una forma de acceder a un elemento del conjunto de datos a la vez.

Nuestro conjunto de datos


Para comenzar, observemos el conjunto de datos que emplearemos en nuestro modelo. Leeremos datos de un archivo CSV, donde cada fila contendrá cinco valores (los cuatro valores de entrada y la etiqueta):

La etiqueta será la siguiente:
  • 0 para iris setosa;
  • 1 para versicolor;
  • 2 para virginica.

Representación de nuestro conjunto de datos


Para describir nuestro conjunto de datos, primero crearemos una lista de nuestras funciones:
feature_names = [
    'SepalLength',
    'SepalWidth',
    'PetalLength',
    'PetalWidth']

Cuando preparemos nuestro modelo, necesitaremos una función que lea el archivo de entrada y muestre los datos de la función y la etiqueta. La Estimators API exige la creación una función con el siguiente formato:
def input_fn():
    ...<code>...
    return ({ 'SepalLength':[values], ..<etc>.., 'PetalWidth':[values] },
            [IrisFlowerType])

El valor que se muestra debe ser una tupla de dos elementos organizada de la siguiente manera:
  • El primero debe ser un elemento dict en el que cada función de entrada sea una clave y luego una lista de valores para el lote de preparación.
  • El segundo elemento es una lista de etiquetas para el lote de preparación.

Debido a que mostraremos un lote de funciones de entrada y etiquetas de preparación, todas las listas de la instrucción return tendrán la misma extensión. En términos técnicos, siempre que mencionamos una “lista” en realidad nos referimos a un tensor TensorFlow 1-d.

Para permitir la reutilización simple de input_fn, le agregaremos algunos argumentos. Esto nos permite compilar funciones de entrada con diferentes configuraciones. Los argumentos son bastante simples:
  • file_path: indica el archivo de datos que se leerá.
  • perform_shuffle: indica si se debe aleatorizar el orden de los registros.
  • repeat_count: indica la cantidad de veces que se deben iterar los registros del conjunto de datos. Si se especifica 1, por ejemplo, cada registro se leerá una vez. Si se especifica None, la iteración continuará sin detenerse.

Aquí te mostramos la manera de implementar esta función usando la Dataset API. Integraremos esto en una “función de entrada” que resulte adecuada cuando agreguemos datos a nuestro modelo de estimador, más adelante:
def my_input_fn(file_path, perform_shuffle=False, repeat_count=1):
   def decode_csv(line):
       parsed_line = tf.decode_csv(line, [[0.], [0.], [0.], [0.], [0]])
       label = parsed_line[-1:] # Last element is the label
       del parsed_line[-1] # Delete last element
       features = parsed_line # Everything (but last element) are the features
       d = dict(zip(feature_names, features)), label
       return d

   dataset = (tf.contrib.data.TextLineDataset(file_path) # Read text file
       .skip(1) # Skip header row
       .map(decode_csv)) # Transform each elem by applying decode_csv fn
   if perform_shuffle:
       # Randomizes input using a window of 256 elements (read into memory)
       dataset = dataset.shuffle(buffer_size=256)
   dataset = dataset.repeat(repeat_count) # Repeats dataset this # times
   dataset = dataset.batch(32)  # Batch size to use
   iterator = dataset.make_one_shot_iterator()
   batch_features, batch_labels = iterator.get_next()
   return batch_features, batch_labels

Ten en cuenta lo siguiente:
  • TextLineDataset: La Dataset API realizará por ti un enorme trabajo de administración de memoria cuando uses sus conjuntos de datos basados en archivos. Por ejemplo, puedes leer archivos del conjunto de datos mucho más grandes que la memoria o leer varios archivos especificando una lista como argumento.
  • shuffle: lee registros buffer_size y luego cambia (aleatoriza) el orden de estos.
  • map: llama a la función decode_csv con cada elemento del conjunto de datos como argumento (debido a que usaremos TextLineDataset, cada elemento será una línea de texto CSV). Luego, aplicaremos decode_csv a cada una de las líneas.
  • decode_csv: divide cada línea en campos y proporciona valores predeterminados si es necesario. Luego muestra un dict con las claves y los valores de campo. La función de mapa actualiza cada elemento (línea) del conjunto de datos con el dict.

Esta fue una introducción a los conjuntos de datos. Solo por diversión, ahora podemos usar esta función para imprimir el primer lote:
next_batch = my_input_fn(FILE, True) # Will return 32 random elements

# Now let's try it out, retrieving and printing one batch of data.
# Although this code looks strange, you don't need to understand
# the details.
with tf.Session() as sess:
    first_batch = sess.run(next_batch)
print(first_batch)

# Output
({'SepalLength': array([ 5.4000001, ...<repeat to 32 elems>], dtype=float32),
  'PetalWidth': array([ 0.40000001, ...<repeat to 32 elems>], dtype=float32),
  ...
 },
 [array([[2], ...<repeat to 32 elems>], dtype=int32) # Labels
)

Eso es todo lo que necesitamos de la Dataset API para implementar nuestro modelo. No obstante, los conjuntos de datos ofrecen muchas más capacidades. Observa la sección final de esta publicación, donde hemos recopilado más recursos.

Introducción a los estimadores


La Estimators API es una API de alto nivel que reduce notablemente el código estándar que antes necesitabas escribir cuando preparabas un modelo de TensorFlow. Los estimadores también son muy flexibles y te permiten anular el comportamiento predeterminado si tu modelo tiene requisitos específicos.

Existen dos formas de compilar tu modelo usando la Estimators API:
  • Estimadores preconfigurados: son estimadores predefinidos, creados para generar un tipo de modelo específico. En esta entrada de blog, usaremos el estimador preconfigurado DNNClassifier.
  • Estimator (clase básica): te permite controlar por completo el método de creación de tu modelo usando una función model_fn. En otra entrada del blog trataremos la manera de hacer esto.

A continuación, te mostramos el diagrama de clases para los estimadores:

Prevemos agregar más estimadores preconfigurados en futuras versiones.

Como puedes ver, todos los estimadores usan input_fn, que proporciona datos de entrada al estimador. En nuestro caso, reutilizaremos la función my_input_fn que definimos para este fin.

El siguiente código crea una instancia del estimador que predice el tipo de flor iris:
# Create the feature_columns, which specifies the input to our model.
# All our input features are numeric, so use numeric_column for each one.
feature_columns = [tf.feature_column.numeric_column(k) for k in feature_names]

# Create a deep neural network regression classifier.
# Use the DNNClassifier pre-made estimator
classifier = tf.estimator.DNNClassifier(
   feature_columns=feature_columns, # The input features to our model
   hidden_units=[10, 10], # Two layers, each with 10 neurons
   n_classes=3,
   model_dir=PATH) # Path to where checkpoints etc are stored

Ahora tenemos un estimador que podemos empezar a preparar.

Preparación del modelo


La preparación se realiza usando una sola línea de código de TensorFlow:
# Train our model, use the previously function my_input_fn
# Input to training is a file with training example
# Stop training after 8 iterations of train data (epochs)
classifier.train(
   input_fn=lambda: my_input_fn(FILE_TRAIN, True, 8))

Aguarda... ¿Qué es “lambda: my_input_fn(FILE_TRAIN, True, 8)”? Es el espacio en el que vinculamos conjuntos de datos con estimadores. Los estimadores necesitan datos para la preparación, evaluación y predicción, y usan input_fn para obtener los datos. Los estimadores requieren una función input_fn sin argumentos, por lo que crearemos una función sin argumentos usando lambda, que llama a nuestra función input_fn con los argumentos deseados: file_path, shuffle setting, y repeat_count. En nuestro caso, usamos nuestra función my_input_fn, y le pasamos lo siguiente:
  • FILE_TRAIN, que es el archivo de datos de preparación.
  • True, que indica al estimador cambiar el orden de los datos.
  • 8, que indica al estimador reproducir y repetir el conjunto de datos 8 veces.

Evaluación del modelo preparado


Ya tenemos un modelo preparado. ¿Cómo podemos evaluar su funcionamiento? Por suerte, todos los estimadores tienen un método evaluate:
# Evaluate our model using the examples contained in FILE_TEST
# Return value will contain evaluation_metrics such as: loss & average_loss
evaluate_result = estimator.evaluate(
   input_fn=lambda: my_input_fn(FILE_TEST, False, 4)
print("Evaluation results")
for key in evaluate_result:
   print("   {}, was: {}".format(key, evaluate_result[key]))

En nuestro caso, alcanzamos una precisión que ronda el 93%. Por supuesto, existen varias formas de mejorar esa precisión. Una consiste simplemente en ejecutar el programa de forma repetida. Debido a que el estado del modelo es persistente (en model_dir=PATH más arriba), este mejorará a medida que lo prepares con más iteraciones, hasta estabilizarse. Otra forma consiste en ajustar la cantidad de capas ocultas o de nodos de cada capa oculta. Haz experimentos con esto libremente, pero ten en cuenta que al realizar un cambio debes eliminar el directorio especificado en model_dir=PATH, ya que modificarás la estructura de DNNClassifier.

Realización de predicciones con el modelo preparado


¡Eso es todo! Ya tenemos un modelo preparado, y si los resultados de la evaluación son satisfactorios, podemos usarla para predecir una flor de iris en función de algunos datos. Tanto en la preparación como en la evaluación, realizamos predicciones usando una llamada a una función individual:
# Predict the type of some Iris flowers.
# Let's predict the examples in FILE_TEST, repeat only once.
predict_results = classifier.predict(
    input_fn=lambda: my_input_fn(FILE_TEST, False, 1))
print("Predictions on test file")
for prediction in predict_results:
   # Will print the predicted class, i.e: 0, 1, or 2 if the prediction
   # is Iris Sentosa, Vericolor, Virginica, respectively.
   print prediction["class_ids"][0] 

Realización de predicciones sobre datos de la memoria


En el código anterior se especificó FILE_TEST para realizar predicciones sobre datos guardados en un archivo, pero ¿cómo podríamos realizar predicciones en función de datos que residen en otras fuentes, como la memoria? Como podrás suponer, para esto no es necesario modificar nuestra llamada a predict. En lugar de ello, configuraremos la Dataset API para usar una estructura de memoria como se muestra a continuación:
# Let create a memory dataset for prediction.
# We've taken the first 3 examples in FILE_TEST.
prediction_input = [[5.9, 3.0, 4.2, 1.5],  # -> 1, Iris Versicolor
                    [6.9, 3.1, 5.4, 2.1],  # -> 2, Iris Virginica
                    [5.1, 3.3, 1.7, 0.5]]  # -> 0, Iris Sentosa
def new_input_fn():
   def decode(x):
       x = tf.split(x, 4) # Need to split into our 4 features
       # When predicting, we don't need (or have) any labels
       return dict(zip(feature_names, x)) # Then build a dict from them

   # The from_tensor_slices function will use a memory structure as input
   dataset = tf.contrib.data.Dataset.from_tensor_slices(prediction_input)
   dataset = dataset.map(decode)
   iterator = dataset.make_one_shot_iterator()
   next_feature_batch = iterator.get_next()
   return next_feature_batch, None # In prediction, we have no labels

# Predict all our prediction_input
predict_results = classifier.predict(input_fn=new_input_fn)

# Print results
print("Predictions on memory data")
for idx, prediction in enumerate(predict_results):
   type = prediction["class_ids"][0] # Get the predicted class (index)
   if type == 0:
       print("I think: {}, is Iris Sentosa".format(prediction_input[idx]))
   elif type == 1:
       print("I think: {}, is Iris Versicolor".format(prediction_input[idx]))
   else:
       print("I think: {}, is Iris Virginica".format(prediction_input[idx])

Dataset.from_tensor_slides() se designa para conjuntos de datos pequeños que entran en la memoria. Cuando usas TextLineDataset, como lo hicimos para el entrenamiento y la evaluación, puedes tener archivos arbitrariamente grandes siempre que tu memoria pueda administrar el búfer de orden aleatorio y los tamaños de los lotes.

Hay más


Usar un estimador preconfigurado como DNNClassifier aporta mucho valor. Además de ser fáciles de usar, los estimadores preconfigurados proporcionan métricas de evaluación integradas y crean resúmenes que puedes ver en TensorBoard. Para ver este informe, inicia TensorBoard desde tu línea de comandos de la siguiente manera:
# Replace PATH with the actual path passed as model_dir argument when the
# DNNRegressor estimator was created.
tensorboard --logdir=PATH 

En los siguientes diagramas se muestran algunos de los datos que proporcionará TensorBoard:

Resumen


En esta entrada de blog, exploramos conjuntos de datos y estimadores. Son API importantes para definir el flujo de datos de entrada y crear modelos, por lo que vale la pena dedicar tiempo a aprenderlas.

Para obtener más información, asegúrate de observar lo siguiente:

Esto no termina aquí. En poco tiempo, publicaremos más entradas de blog en las que describiremos cómo funcionan esas API. ¡Permanece atento!

Hasta entonces, ¡feliz codificación con TensorFlow!

Publicado por Sarah Clark, administradora del programa, capacitación de desarrolladores web
Si te dedicas al desarrollo web, la oferta abunda en el mercado y probablemente te convenga distinguirte de los demás desarrolladores. ¿Te gustaría mostrar que tienes las capacidades necesarias para crear aplicaciones web receptivas y flexibles?
 Publicado por Sarah Clark, administradora del programa, capacitación de desarrolladores web
Si te dedicas al desarrollo web, la oferta abunda en el mercado y probablemente te convenga distinguirte de los demás desarrolladores. ¿Te gustaría mostrar que tienes las capacidades necesarias para crear aplicaciones web receptivas y flexibles?
El equipo de certificaciones Google Developers tiene el agrado de anunciar la certificación Mobile Web Specialist. Con esta certificación nueva, basada en un análisis exhaustivo del mercado, se destaca a los desarrolladores que tienen habilidades con más demanda, como los desarrolladores de contenido web móvil. (No te preocupes, las habilidades demostradas en este examen se pueden aplicar a equipos de escritorio y a todos los navegadores).
Usa nuestra Guía de estudio para especialistas en Web móvil como referencia en la preparación. Cuando estés listo para la evaluación, deberás escribir código y el examen será cronometrado y se basará en el desempeño. El costo para intentar acceder a la certificación es de USD 99 USD (6500 INR si resides en la India) e incluye hasta tres intentos de examen.
Mira este video corto para ver un panorama rápido del proceso de certificación Mobile Web Specialist:
Al obtener la certificación Mobile Web Specialist se te otorga una insignia digital que puedes mostrar en tu currículum y en perfiles de redes sociales. Como miembro de la comunidad de ex alumnos con certificación Mobile Web Specialist, también tendrás acceso a beneficios del programa centrados en aumentar tu visibilidad como un desarrollador certificado.
La certificación Mobile Web Specialist se suma a la certificación Associate Android Developer de la familia de certificaciones basadas en el desempeño de Google.
Visita g.co/dev/mobile-web-cert para comenzar y obtener tu certificación Mobile Web Specialist de Google.