<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Ugni Blog]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://ugni.io/</link><image><url>https://ugni.io/favicon.png</url><title>Ugni Blog</title><link>https://ugni.io/</link></image><generator>Ghost 2.9</generator><lastBuildDate>Fri, 18 Jun 2021 01:31:40 GMT</lastBuildDate><atom:link href="https://ugni.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Google deep dream - Tutorial práctico]]></title><description><![CDATA[DeepDream es un experimento que visualiza los patrones aprendidos por una red neuronal. Al igual que cuando un niño mira nubes e intenta interpretar formas aleatorias, DeepDream sobreinterpreta y mejora los patrones que ve en una imagen. Lo hace enviando una imagen a través de la red, luego calculando el gradiente de la imagen con respecto a las activaciones de una capa en particular. Por último, la imagen se modifica para aumentar estas activaciones, mejorando los patrones vistos por la red y ]]></description><link>https://ugni.io/google-deep-dream-tutorial-practico/</link><guid isPermaLink="false">Ghost__Post__60cac6595b53e8360c631575</guid><dc:creator><![CDATA[Jose Miguel Chacon]]></dc:creator><pubDate>Thu, 17 Jun 2021 22:28:37 GMT</pubDate><media:content url="http://localhost:2368/content/images/2021/06/spaghetti-dog-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://localhost:2368/content/images/2021/06/spaghetti-dog-1.jpg" alt="Google deep dream - Tutorial práctico"/><p>DeepDream es un experimento que visualiza los patrones aprendidos por una red neuronal. Al igual que cuando un niño mira nubes e intenta interpretar formas aleatorias, DeepDream sobreinterpreta y mejora los patrones que ve en una imagen.</p><p>Lo hace enviando una imagen a través de la red, luego calculando el gradiente de la imagen con respecto a las activaciones de una capa en particular. Por último, la imagen se modifica para aumentar estas activaciones, mejorando los patrones vistos por la red y dando como resultado una imagen de ensueño. Este proceso se denominó "Inceptionism" (una referencia a <a href="https://arxiv.org/pdf/1409.4842.pdf">InceptionNet</a> y la <a href="https://en.wikipedia.org/wiki/Inception">película</a> Inception).</p><h2 id="%C2%BFc%C3%B3mo-funciona-el-algoritmo-del-sue%C3%B1o-profundo">¿Cómo funciona el algoritmo del sueño profundo?</h2><p>Cuando suministramos una imagen a una RNA entrenada, las neuronas se disparan y generan activaciones, el algoritmo sencillamente hace que algunas neuronas se disparen más. Es posible seleccionar qué neuronas en que capa estamos interesados en activar, y repetir este proceso hasta que la imagen de entrada contiene las características que una capa específica estaba buscando.</p><h3 id="pasos-del-algoritmo">Pasos del algoritmo</h3><p> Envíamos nuestra imagen a través de una red neuronal pre entrenada.</p><p> Se selecciona una capa a elección (las primeras capturan bordes, las capas más profundas detectan formas más completas)</p><p> Se calculan las activaciones (salidas) que salen de las capas de interés</p><p> Se calcula el gradiente de las activaciones con respecto a la imagen de entrada (ascenso del gradiente)</p><p> Se modifica la imagen para aumentar las activaciones y mejorar los patrones vistos por la red</p><p> Se repite el proceso</p><p>En el ejemplo desarrollado en el cuaderno, tendremos las siguientes secciones: carga y preprocesado de datos, definición del modelo preentrenado, definición de las capas que queremos activar, definición de la función que calcula el error y la función que lo maximiza, contrario al objetivo que tenemos comúnmente al entrenar una RN.</p><p>Cargamos el modelo base preentrenado</p><pre><code class="language-python">base_model = tf.keras.applications.InceptionV3(include_top = False, weights = 'imagenet')</code></pre><p>Obtenemos y procesamos nuestra entrada</p><pre><code class="language-python"># get and process the data img_1 = Image.open("/content/drive/MyDrive/COLAB NOTEBOOKS/eiffel.jpg") img_2 = Image.open("/content/drive/MyDrive/COLAB NOTEBOOKS/mars.jpg") image = Image.blend(img_1, img_2, 0.5) image.save("/content/drive/MyDrive/COLAB NOTEBOOKS/img_0.jpg") sample_image = tf.keras.preprocessing.image.load_img("/content/drive/MyDrive/COLAB NOTEBOOKS/img_0.jpg") sample_image = tf.keras.preprocessing.image.img_to_array(sample_image) sample_image = sample_image/255.0 sample_image = tf.expand_dims(sample_image, axis = 0)</code></pre><p>Elegimos las capas de la RN preentrenada y creamos nuestro modelo</p><pre><code class="language-python">layer_names = ['mixed3', 'mixed5', 'mixed7'] layers = [base_model.get_layer(name).output for name in layer_names] deepdream_model = tf.keras.Model(inputs = base_model.input, outputs = layers) activations = deepdream_model(sample_image)</code></pre><p>El siguiente bloque calcula la pérdida</p><pre><code class="language-python">def calculate_loss(image, model): img_batch = tf.expand_dims(image, axis=0) layer_activations = model(img_batch) print('Activation values (layer output) \n', layer_activations) losses = [] for act in layer_activations: loss = tf.math.reduce_mean(act) losses.append(loss) print('Losses (from multiple activations layers) = ', losses) print('Losses shape', np.shape(losses)) print('Sum of all losses', tf.reduce_sum(losses)) return tf.reduce_sum(losses) # gets the sum loss = calculate_loss(tf.Variable(sample_image), deepdream_model) </code></pre><p>Calculamos el gradiente ascendente:</p><pre><code class="language-python"># ascend gradient @tf.function def deepdream(model, image, step_size): with tf.GradientTape() as tape: tape.watch(image) loss = calculate_loss(image, model) gradients = tape.gradient(loss, image) print('Gradients =\n', gradients) print('Gradients shape =\n', np.shape(gradients)) gradients = tf.math.reduce_std(gradients) # excite the layers # we can do it adding directly the gradients (because they have the same shape) image = image + gradients * step_size image = tf.clip_by_value(image, -1, 1) return loss, image</code></pre><p>Corremos el modelo:</p><pre><code class="language-python">def run_deepdream(model, image, steps = 100, step_size = 0.01): image = tf.keras.applications.inception_v3.preprocess_input(image) deprocess = lambda image : tf.cast((255*(image+1.0)/2), tf.uint8) for step in range(steps): loss, image = deepdream(model, image, step_size) if step % 100 == 0: plt.figure(figsize=(12,12)) plt.imshow(deprocess(image)) plt.show() print("Step {}, loss {}".format(step, loss)) #clear_output(wait=True) plt.figure(figsize=(12,12)) plt.imshow(deprocess(image)) plt.show() return deprocess(image) </code></pre><p>Puede encontrar el código relacionado <a href="https://colab.research.google.com/drive/1sHUB72xtv9Bplmtpm24cQPhsH_RrllPd?usp=sharing">acá.</a></p>]]></content:encoded></item><item><title><![CDATA[When should I use multilayer printed circuits?]]></title><description><![CDATA[The main reason for using four or more layer printed circuits is to have card-size copper planes connected to the reference voltage and supply (0V, GND, Vcc, etc.), which will serve as a shield for everything. ]]></description><link>https://ugni.io/when-should-i-use-multilayer-printed-circuits/</link><guid isPermaLink="false">Ghost__Post__60cac40e5b53e8360c631562</guid><dc:creator><![CDATA[Jose Miguel Chacon]]></dc:creator><pubDate>Thu, 17 Jun 2021 03:42:24 GMT</pubDate><media:content url="http://localhost:2368/content/images/2021/06/pexels-tim-douglas-6211054.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://localhost:2368/content/images/2021/06/pexels-tim-douglas-6211054.jpg" alt="When should I use multilayer printed circuits?"/><p>Multilayer printed circuits are an essential source of resources in today's electronic development. The main reason for using four or more layer printed circuits is to have card-size copper planes connected to the reference voltage and supply (0V, GND, Vcc, etc.), which will serve as a shield for everything. Our circuit not only against parasitic noises generated by external agents but will also help us to ensure that our design is not a generator of electromagnetic radiation (EMI).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://localhost:2368/content/images/2021/06/multi.png" class="kg-image" alt="When should I use multilayer printed circuits?" loading="lazy" width="1220" height="390" srcset="http://localhost:2368/content/images/size/w600/2021/06/multi.png 600w, http://localhost:2368/content/images/size/w1000/2021/06/multi.png 1000w, http://localhost:2368/content/images/2021/06/multi.png 1220w" sizes="(min-width: 720px) 720px"><figcaption><em>4-layer PCB designed and assembled by UGNI</em></figcaption></img></figure><p>In addition to obtaining power and ground connections directly from the component power terminals, the designer will have the real possibility to design conductive tracks suitable for circuits that are sensitive to noise, minimizing the size of the connections, the area of the loops. , and shared impedances which fully facilitate this objective in today's environment where external signal fields abound such as cell towers, Wi-Fi networks, electronic equipment that does not meet Electromagnetic Compatibility (EMC) standards.</p><p>The current technological advance of the electronics industry requires products that work at increasingly higher frequencies and that, in addition to being immune to noise, must concentrate the greatest functionality in the minimum possible space.</p><p>Due to continuous technological advancement, circuit developers must consider the problem generated by the working speed of processors and data buse. as well as the performance of serial transmissions that currently extend to the Giga Hertz range. Therefore, designs that require any of these characteristics must necessarily be implemented in multilayer circuits where there are resources to reduce electromagnetic emission and pollution (EMI).</p><p>You can see a video <a href="https://drive.google.com/file/d/1ltn4akhSEo26BL-33VL7ZiGUrwIIIyrW/view?usp=sharing">here</a></p>]]></content:encoded></item><item><title><![CDATA[Crear una red neuronal básica usando TensorFlow, Keras y SKLearn]]></title><description><![CDATA[En esta ocasión, vamos a programar a una red neuronal usando librerías de diferenciación automática, las cuales extraen muchos conceptos y nos permiten diseñar RN más complejas sin tener que calcular distintas derivadas cada vez que modifiquemos nuestra arquitectura. Para esto existen librerías de diferenciación automática cómo Tensorflow y Pythorch y a continuación implementaremos la misma red neuronal anterior, solucionando el problema de la clasificación binaria per a un nivel más alto. En]]></description><link>https://ugni.io/crear-una-red-neuronal-basica-usando-tensorflow-keras/</link><guid isPermaLink="false">Ghost__Post__60c13fe0e428a350d0d2dfdd</guid><dc:creator><![CDATA[Jose Miguel Chacon]]></dc:creator><pubDate>Wed, 09 Jun 2021 22:25:56 GMT</pubDate><media:content url="http://localhost:2368/content/images/2021/06/tensorflowkeras.png" medium="image"/><content:encoded><![CDATA[<img src="http://localhost:2368/content/images/2021/06/tensorflowkeras.png" alt="Crear una red neuronal básica usando TensorFlow, Keras y SKLearn"/><p>En esta ocasión, vamos a programar a una red neuronal usando librerías de diferenciación automática, las cuales extraen muchos conceptos y nos permiten diseñar RN más complejas sin tener que calcular distintas derivadas cada vez que modifiquemos nuestra arquitectura.</p><p>Para esto existen librerías de diferenciación automática cómo <em>Tensorflow </em>y <em>Pythorch </em>y a continuación implementaremos la misma red neuronal anterior, solucionando el problema de la clasificación binaria per a un nivel más alto.</p><p>En estas librerías podemos representar el flujo de nuestros datos como grafos. Veamos el código de la RN usando <em>tensorflow 1.x</em>:</p><pre><code class="language-python">%tensorflow_version 1.x import tensorflow as tf from matplotlib import animation from IPython.core.display import display, HTML # Definimos los puntos de entrada de la red, para la matriz X e Y. iX = tf.placeholder('float', shape=[None, X.shape[1]]) iY = tf.placeholder('float', shape=[None]) lr = 0.01 # learning rate nn = [2, 16, 8, 1] # número de neuronas por capa. # Capa 1 W1 = tf.Variable(tf.random_normal([nn[0], nn[1]]), name='Weights_1') b1 = tf.Variable(tf.random_normal([nn[1]]), name='bias_1') l1 = tf.nn.relu(tf.add(tf.matmul(iX, W1), b1)) # Capa 2 W2 = tf.Variable(tf.random_normal([nn[1], nn[2]]), name='Weights_2') b2 = tf.Variable(tf.random_normal([nn[2]]), name='bias_2') l2 = tf.nn.relu(tf.add(tf.matmul(l1, W2), b2)) # Capa 3 W3 = tf.Variable(tf.random_normal([nn[2], nn[3]]), name='Weights_3') b3 = tf.Variable(tf.random_normal([nn[3]]), name='bias_3') # Vector de predicciones de Y. pY = tf.nn.sigmoid(tf.add(tf.matmul(l2, W3), b3))[:, 0] </code></pre><pre><code class="language-python"># Evaluación de las predicciones. loss = tf.losses.mean_squared_error(pY, iY) # Definimos al optimizador de la red, para que minimice el error. optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.05).minimize(loss) n_steps = 1000 # Número de ciclos de entrenamiento. iPY = [] # Aquí guardaremos la evolución de las predicción, para la animación. with tf.Session() as sess: # Inicializamos todos los parámetros de la red, las matrices W y b. sess.run(tf.global_variables_initializer()) # Iteramos n pasos de entrenamiento. for step in range(n_steps): # Evaluamos al optimizador, a la función de coste y al tensor de salida pY. # La evaluación del optimizer producirá el entrenamiento de la red. _, _loss, _pY = sess.run([optimizer, loss, pY], feed_dict={ iX : X, iY : Y }) # Cada 25 iteraciones, imprimimos métricas. if step % 25 == 0: # Cálculo del accuracy. acc = np.mean(np.round(_pY) == Y) # Impresión de métricas. print('Step', step, '/', n_steps, '- Loss = ', _loss, '- Acc =', acc) # Obtenemos predicciones para cada punto de nuestro mapa de predicción _pX. _pY = sess.run(pY, feed_dict={ iX : _pX }).reshape((res, res)) # Y lo guardamos para visualizar la animación. iPY.append(_pY) # ----- CÓDIGO ANIMACIÓN ----- # ims = [] fig = plt.figure(figsize=(10, 10)) print("--- Generando animación ---") for fr in range(len(iPY)): im = plt.pcolormesh(_x0, _x1, iPY[fr], cmap="coolwarm", animated=True) # Visualización de la nube de datos. plt.scatter(X[Y == 0,0], X[Y == 0,1], c="skyblue") plt.scatter(X[Y == 1,0], X[Y == 1,1], c="salmon") # plt.title("Resultado Clasificación") plt.tick_params(labelbottom=False, labelleft=False) ims.append([im]) ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000) HTML(ani.to_html5_video())</code></pre>]]></content:encoded></item><item><title><![CDATA[Construir una red neuronal básica desde 0 en python]]></title><description><![CDATA[Existen muchas librerías y formas de modelar, entrenar y utilizar una red neuronal en la actualidad. A continuación veremos una forma sencilla pero clara de cómo programar una RN básica utilizando python. import numpy as np import scipy as sc import matplotlib.pyplot as plt from sklearn.datasets import make_circles Importamos las librerías: numpy para el procesamiento numérico, scipy que extiende funcionalidades de numpy, matplotlib para realizar gráficas y sklearn que contiene herramientas ]]></description><link>https://ugni.io/construir-una-red-neuronal-desde-0-en-python/</link><guid isPermaLink="false">Ghost__Post__60beaa1ba3e78401e041be78</guid><dc:creator><![CDATA[Jose Miguel Chacon]]></dc:creator><pubDate>Mon, 07 Jun 2021 23:30:50 GMT</pubDate><media:content url="http://localhost:2368/content/images/2021/06/pexels-susanne-jutzeler-6309217.jpg" medium="image"/><content:encoded><![CDATA[<img src="http://localhost:2368/content/images/2021/06/pexels-susanne-jutzeler-6309217.jpg" alt="Construir una red neuronal básica desde 0 en python"/><p>Existen muchas librerías y formas de modelar, entrenar y utilizar una red neuronal en la actualidad. A continuación veremos una forma sencilla pero clara de cómo programar una RN básica utilizando python.</p><pre><code class="language-python">import numpy as np import scipy as sc import matplotlib.pyplot as plt from sklearn.datasets import make_circles</code></pre><p>Importamos las librerías: <em>numpy </em>para el procesamiento numérico, <em>scipy </em>que extiende funcionalidades de numpy, <em>matplotlib </em>para realizar gráficas y <em>sklearn </em>que contiene herramientas de deep learning.</p><p>Crearemos un dataset de ejemplo usando la función <em>make_circles, </em>que nos generará dos conjuntos de puntos de la siguiente forma:</p><pre><code class="language-python"># create dataset # number of registers n = 500 # number of characteristics of our dataset (for each register) p = 2 X, Y = make_circles(n_samples=n, factor=0.5, noise=0.05) plt.scatter(X[Y==0, 0], X[Y==0, 1], c="skyblue") plt.scatter(X[Y==1, 0], X[Y==1, 1], c="salmon") plt.axis("equal") plt.show()</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://localhost:2368/content/images/2021/06/descarga.png" class="kg-image" alt="Construir una red neuronal básica desde 0 en python" loading="lazy" width="380" height="248"><figcaption>dataset para entrenar nuestra RN</figcaption></img></figure><p>A continuación, diseñamos el esqueleto de nuestra red neuronal. Para esto, necesitamos ver a cada capa de esta como un módulo, sabiendo que cada una puede llevar una función de activación y características similares. En el constructor de la clase <em>neural_layer </em>definimos lo siguiente:</p><pre><code class="language-python"># class of network layer class neural_layer(): def __init__(self, n_connections, n_neurons, a_function): self.a_function = a_function normalization = lambda x : x * 2 - 1 # for bias self.b = normalization(np.random.rand(1, n_neurons)) # for weights self.W = normalization(np.random.rand(n_connections, n_neurons))</code></pre><p>Los parámetros <em>b</em> y <em>W</em> corresponden al vector de bias y a la matriz de pesos, que inicializaremos con valores aleatorios normalizados en cero. Así mismo, al definir un objeto de la clase <em>neural_layer </em>le enviaremos los parámetros correspondientes al número de conexiones, de neuronas y la función de activación correspondiente a cada capa, en ese orden.</p><h3 id="funciones-de-activaci%C3%B3n">Funciones de activación</h3><p>Definiremos las funciones de activación que va a usar nuestra RN, así como sus derivadas que más adelante usaremos para hacer <em>Back Propagation</em>.</p><pre><code class="language-python"># activation functions sigm = (lambda x : 1 / (1 + np.e ** (-x)), lambda x: x * (1 - x)) relu = lambda x: np.maximum(0, x) _x = np.linspace(-5, 5, 100) # 100 values from -5 to 5 plt.plot(_x, sigm[0](_x), color='green', linestyle='dashed')</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://localhost:2368/content/images/2021/06/descarga--1-.png" class="kg-image" alt="Construir una red neuronal básica desde 0 en python" loading="lazy" width="372" height="248"><figcaption>Función sigmoide</figcaption></img></figure><p>Utilizaremos una función para crear la RN, de la siguiente forma:</p><pre><code class="language-python">def create_nn(topology, a_function): nn = []; for l, layer in enumerate(topology[:-1]): nn.append(neural_layer(topology[l], topology[l+1], a_function)) return nn;</code></pre><p>La función <em>create_nn </em>crea un arreglo vacío y toma un arreglo llamado <em>topology</em>, que es la sucesión de capas y la función de activación, que puede ser <em>sigmode </em>o <em>ReLu </em>en nuestro caso, o la que sea necesaria. La función devolverá la matriz nn que contiene la cantidad de neuronas por cada capa y su función de activación.</p><p>Lo siguiente será definir nuestra topología y función para calcular el error (o función de coste)</p><pre><code class="language-python">topology = [p, 4, 8, 1] neural_network = create_nn(topology, sigm) l2_cost = (lambda Yp, Yr: np.mean((Yp - Yr )**2), lambda Yp, Yr: (Yp - Yr))</code></pre><p>Con esto listo, lo siguiente será entrenar a nuestra RN, calculando los tres ítems primordiales: El <em>forward pass</em>, <em>backpropagation</em> y el algoritmo del <em>descenso del gradiente </em>(veremos cada uno en detalle a continuación):</p><pre><code class="language-python">def train(neural_network, X, Y, l2_cost, lr = 0.5, train = True): out = [(None, X)] # forward pass: we pass our ponderate sum trough all our layers for l, layer in enumerate(neural_network): z = out[-1][1] @ neural_network[l].W + neural_network[l].b a = neural_network[l].a_function[0](z) out.append((z, a)) # we can print our error now # print("error", l2_cost[0](out[-1][1], Y)) if train: # backward pass deltas = [] for l in reversed(range(0, len(neural_network))): z = out[l+1][0] a = out[l+1][1] if l == len(neural_network)-1: # for the last layer deltas.insert(0, l2_cost[1](a, Y) * neural_network[l].a_function[1](a)) else: # for other layers deltas.insert(0, deltas[0] @ W_temporal.T * neural_network[l].a_function[1](a)) W_temporal = neural_network[l].W # gradient descent neural_network[l].b = neural_network[l].b - np.mean(deltas[0], axis=0, keepdims=True) * lr neural_network[l].W = neural_network[l].W - out[l][1].T @ deltas[0] * lr return out[-1][1]; train(neural_network, X, Y, l2_cost, 0.5)</code></pre><p>El primer paso, es recorrer cada una de nuestras capas hacia adelante y calcular el valor a la salida, recordando que nuestros valores iniciales de W y bias son aleatorios. A esto le llamamos forward pass o <em>"paso hacía adelante",</em> y es útil también para realizar predicciones sin necesidad de entrenar a nuestra red (por esto el parámetro <em>Train </em>puede ser falso).</p><p>Al final de este paso obtenemos el cálculo del error, que es totalmente aleatorio, como sus entradas. Para el siguiente paso, llamado backward pass o <em>"retropropagación" </em>necesitamos calcular las derivadas parciales desde la última capa hasta la inicial. Este cálculo difiere en la última capa y en el resto de ella, cómo se ve en el script, y en el caso de la última capa se calcula como la derivada de la función de coste, multiplicada por la derivada de la función de activación. Para las siguientes capas necesitamos la derivada de la capa anterior por los pesos W de la capa actual multiplicada nuevamente por la derivada de la función de activación.</p><p>Para el paso del descenso del gradiente iremos modificando nuestros parámetros W y bias en el mismo ciclo del cálculo del backward pass. Para esto guardamos una variable temporal con nuestro valor actual de W.</p><p>Por último, comprobaremos la capacidad para clasificar de nuestro proyecto, iterando 2500 veces y jugando con el learning rate arbitrariamente:</p><pre><code class="language-python">import time from IPython.display import clear_output neural_network = create_nn(topology, sigm) loss = [] for i in range(2500): pY = train(neural_network, X, Y, l2_cost, lr=0.01) if i % 25 == 0: loss.append(l2_cost[0](pY, Y)) res = 50 _x0 = np.linspace(-1.5, 1.5, res) _x1 = np.linspace(-1.5, 1.5, res) _Y = np.zeros((res, res)) for i0, x0 in enumerate (_x0): for i1, x1 in enumerate(_x1): _Y[i0, i1] = train(neural_network, np.array([[x0, x1]]), Y, l2_cost, train = False)[0][0] plt.pcolormesh(_x0, _x1, _Y, cmap="coolwarm") plt.axis("equal") plt.scatter(X[Y[:,0] == 0, 0], X[Y[:,0] == 0, 1], c="skyblue") plt.scatter(X[Y[:,0] == 1, 0], X[Y[:,0] == 1, 1], c="salmon") clear_output(wait=True) plt.show() plt.plot(range(len(loss)), loss) plt.show() time.sleep(0.5) </code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://localhost:2368/content/images/2021/06/image-2.png" class="kg-image" alt="Construir una red neuronal básica desde 0 en python" loading="lazy" width="387" height="499"><figcaption>Clasificación de nuestra RN y evolución de la pérdida</figcaption></img></figure><p/><p>Puede encontrar un enlace al cuaderno de collab con todo el código <a href="https://colab.research.google.com/drive/1kV9pvcbHvRChoNL2Er72vtxp-GG6VZ6C?usp=sharing">aquí</a></p>]]></content:encoded></item><item><title><![CDATA[Actualizar aplicaciones Flutter en iOS y Android]]></title><description><![CDATA[ Para actualizar nuestras aplicaciones desarrolladas usando el framework Flutter debemos realizar distintos pasos, dependiendo del sistema operativo que vamos a utilizar, por esto, vamos a dividir los pasos para cada uno. Lo primero que haremos será correr algunos comandos para actualizar el ícono de la aplicación, en este caso utilizando el paquete flutter launcher icons [https://pub.dev/packages/flutter_launcher_icons] y actualizando la versión de nuestra aplicación en el pubspec.yaml: versi]]></description><link>https://ugni.io/untitled-2/</link><guid isPermaLink="false">Ghost__Post__60bd3e3bd440441daca42f78</guid><dc:creator><![CDATA[Jose Miguel Chacon]]></dc:creator><pubDate>Sun, 06 Jun 2021 21:30:55 GMT</pubDate><content:encoded><![CDATA[<h1/><p>Para actualizar nuestras aplicaciones desarrolladas usando el framework Flutter debemos realizar distintos pasos, dependiendo del sistema operativo que vamos a utilizar, por esto, vamos a dividir los pasos para cada uno.</p><p>Lo primero que haremos será correr algunos comandos para actualizar el ícono de la aplicación, en este caso utilizando el paquete <a href="https://pub.dev/packages/flutter_launcher_icons">flutter launcher icons</a> y actualizando la versión de nuestra aplicación en el pubspec.yaml:</p><pre><code class="language-bash">version: 1.0.1+**5** ... flutter_icons: android: "launcher_icon" ios: true image_path: "assets/icons/icon.jpg" </code></pre><pre><code class="language-bash">flutter pub get flutter pub run flutter_launcher_icons:main </code></pre><h3 id="apple-store"><strong><strong>Apple Store</strong></strong></h3><p>En la carpeta del proyecto, generamos el proyecto para iOS usando los siguientes comandos:</p><pre><code class="language-bash">flutter clean flutter build ios --no-tree-shake-icons </code></pre><p>A continuación, abrimos el proyecto usando XCode, esperamos a que el IDE esté listo y vamos a la opción "Producto > Archivar". Cuando se complete la operación veremos dos opciones: Distribuir y validar, primero validamos nuestra aplicación y su configuración y si no existen problemas, procederemos a hacer click en distribuir.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.ugni.io/content/images/2021/03/Screen-Shot-2021-03-21-at-10.33.06-PM.png" class="kg-image" alt="XCode" loading="lazy"><figcaption>Ventana de XCode</figcaption></img></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://blog.ugni.io/content/images/2021/03/Screen-Shot-2021-03-21-at-10.43.46-PM.png" class="kg-image" alt="" loading="lazy"><figcaption>Resultado de la validación de la aplicación y su configuración</figcaption></img></figure><p>Una vez realizados estos pasos, iremos a la consola de App Store Connect en la <a href="https://appstoreconnect.apple.com/">web</a> y veremos nuestro último build:</p><figure class="kg-card kg-image-card"><img src="http://blog.ugni.io/content/images/2021/03/tempsnip.png" class="kg-image" alt="" loading="lazy"/></figure><p>Lo seleccionamos y enviamos nuestra aplicación para la revisión del equipo de Apple, cuando esté aceptada veremos la versión más reciente de nuestra aplicación en la tienda (El mensaje que veremos será "waiting for review").</p><figure class="kg-card kg-image-card"><img src="http://blog.ugni.io/content/images/2021/03/Screen-Shot-2021-03-23-at-8.16.54-AM.png" class="kg-image" alt="" loading="lazy"/></figure><hr><h3 id="play-store"><strong><strong>Play Store</strong></strong></h3><p>La publicación en la tienda de Google es similar al proceso anterior. Para esto, debemos ir a la carpeta principal de nuestro proyecto y crear el bundle para producción, suponiendo que tenemos la configuración para la firma lista en nuestro build.gradle:</p><pre><code class="language-bash">flutter clean flutter build appbundle --no-tree-shake-icons </code></pre><p>Posterior a esto, ubicamos el archivo AAB generado por el comando anterior.</p><p>Luego, en la web de <a href="https://play.google.com/">Play Store Publish</a>, vamos a la consola de nuestra aplicación y luego a la sección "Producción > Crear versión", donde podremos subir el bundle recién generado y firmado:</p><figure class="kg-card kg-image-card"><img src="http://blog.ugni.io/content/images/2021/03/image-3.png" class="kg-image" alt="" loading="lazy"/></figure><p>Este es uno de los procedimientos más sencillos posibles, aunque sigue siendo muy manual. Posteriormente publicaremos pasos más avanzados con el fin de implementar despliegues continuos para nuestras aplicaciones desarrolladas usando este framework.</p></hr>]]></content:encoded></item><item><title><![CDATA[Desarrollo de videojuegos 2D con Flutter y Flame]]></title><description><![CDATA[Flame es una librería que permite simplificar el desarrollo de videojuegos para móviles usando el SDK de google. A continuación veremos los conceptos principales para el desarrollo de videojuegos y luego haremos un ejemplo práctico de cómo hacerlo realidad usando estas herramientas. Introducción al desarrollo de videojuegos El game loop Es la esencia del juego. Un set de instrucciones que el computador ejecuta una y otra vez. Los juegos normalmente tienen una métrica llamada FPS (Frames por se]]></description><link>https://ugni.io/untitled/</link><guid isPermaLink="false">Ghost__Post__60bd3a74d440441daca42f6d</guid><dc:creator><![CDATA[Jose Miguel Chacon]]></dc:creator><pubDate>Sun, 06 Jun 2021 21:14:01 GMT</pubDate><content:encoded><![CDATA[<p>Flame es una librería que permite simplificar el desarrollo de videojuegos para móviles usando el SDK de google. A continuación veremos los conceptos principales para el desarrollo de videojuegos y luego haremos un ejemplo práctico de cómo hacerlo realidad usando estas herramientas.</p><h2 id="introducci%C3%B3n-al-desarrollo-de-videojuegos"><strong><strong>Introducción al desarrollo de videojuegos</strong></strong></h2><h3 id="el-game-loop"><strong><strong><em><em>El game loop</em></em></strong></strong></h3><p>Es la esencia del juego. Un set de instrucciones que el computador ejecuta una y otra vez.</p><p>Los juegos normalmente tienen una métrica llamada FPS (Frames por segundo). Esto quiere decir que si un juego está corriendo a 60 fps, el computador está ejecutando un<em><em> game loop</em></em> 60 veces por segundo. 1 frame = 1 ejecución del<em><em> game loop</em></em>.</p><p>Un game loop básico está hecho de dos métodos: <strong><strong>update </strong></strong>y <strong><strong>render</strong></strong>.</p><p>El método <strong><strong>update </strong></strong>se encarga de los movimientos de los objetos (como enemigos, obstáculos) y otras cosas que necesitan actualizarse. Por ejemplo, calcular si el enemigo es golpeado por una bala o calcular si este enemigo toca el personaje principal.</p><p>El método <strong><strong>render </strong></strong>dibuja todos los objetos en la pantalla. Esto es un proceso separado y por tanto, todo debe estar sincronizado.</p><figure class="kg-card kg-image-card"><img src="http://blog.ugni.io/content/images/2021/03/image-4.png" class="kg-image" alt="" loading="lazy"/></figure><h3 id="%C2%BFporqu%C3%A9-es-necesario-sincronizar"><strong><strong>¿Porqué es necesario sincronizar?</strong></strong></h3><p>Imagine que necesita actualizar la posición de su personaje principal, está sano y por tanto así lo renderiza.</p><p>Pero, una bala está a unos píxeles de tocarlo. La bala se actualiza y entonces afecta a su personaje, ahora él está muerto y por tanto no es necesario dibujar la bala. Para este momento usted debería está dibujando el primer frame de la animación de su personaje muriendo. En el siguiente ciclo, ya no es necesario actualizar el personaje debido a que está muerto. En lugar de eso se dibuja el primer frame de la animación del personaje muriendo (en vez del segundo frame).</p><p>Esto puede darle al juego la sensación de que está entrecortado. Imagine jugar un juego de ataque donde al disparar a un enemigo, no cae, le dispara otra vez pero antes de que la bala lo impacte muere. Esta sensación no deseada puede no ser visible, especialmente cuando se está corriendo a 60 fps, pero si esto pasa muy seguido, el juego puede sentirse de baja calidad.</p><p>Necesitamos tener todo calculado, de tal forma que cuando los estados de los objetos están calculados y finalizados, la ventana será dibujada.</p><h2 id="flame-y-flutter"><strong><strong>Flame y Flutter</strong></strong></h2><p>Flame brinda el código que maneja el manejo de estos métodos, por tanto sólo tenemos que preocuparnos por escribir el proceso de actualización y renderización reales.</p><p>Para comenzar, transformaremos nuestra pantalla principal mostrando en modo horizontal y full screen:</p><pre><code class="language-dart">import 'package:flame/util.dart'; import 'package:flutter/services.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); Util flameUtil = Util(); flameUtil.fullScreen(); flameUtil.setOrientation(DeviceOrientation.portraitUp); } </code></pre><p>Ahora, haremos uso de la clase Game de la librería mediante una subclase llamada MyAwesomeGame que la extienda:</p><pre><code class="language-dart">import 'dart:ui'; import 'package:flame/game.dart'; class MyAwesomeGame extends Game { void render(Canvas canvas) { // TODO: implement render } void update(double t) { // TODO: implement update } } </code></pre><blockquote>Traducido y adaptado de este <a href="https://jap.alekhin.io/create-mobile-game-flutter-flame-beginner-tutorial">post</a></blockquote>]]></content:encoded></item></channel></rss>