Este blog es un espacio personal donde recopilo y comparto información sobre lo que enseño en clases y los proyectos en los que trabajo. Es un registro de ideas, aprendizajes y experiencias que me sirven como referencia, pero que también pueden ser útiles para otros que se enfrenten a retos similares en educación, programación o tecnología.
Pues hoy tocó preparar el entorno para ejecutar en FastApi un servicio que reciba un audio y regrese un texto.
Como es necesario procesar el audio que se graba en web y se envía al servidor, se necesitan algunas librerias para convertir entre formatos de audio
en mi caso utilicé home brew para instalar la librería ffmpeg para que funcione correctamente algunos módulos de python, el detalle es que al tener varias versiones de python tuve algunos problemas por lo que finalmente encontré una solución, que fue, instalar las versiones compiladas de las librerías que se pueden descargar aquí.
Para la prueba utilicé vue, en el cuál existe un método para iniciar y detener la grabación y finalmente el método que envía a la api.
y bueno este es parte del código de la api, como se observa ya que instalé ffmpeg y ffprobe con una versión compilada, los ejecutables los pasé al directorio /Applications para que python los pudiera encontrar.
En otras pruebas se pueden ver los resultados
ahora a probar con modelos preentrenados que se ejecuten localmente.
Una alternativa que tenemos para construir un chatbot son los mapas conceptuales, que nos ayudan a conectar conceptos y definir relaciones entre ellos. Esta práctica fue parte de la temática expuesta en la materia de Inteligencia Artificial, enfocada en la aplicación de modelos de representación del conocimiento en el desarrollo de asistentes virtuales.
Los mapas conceptuales o grafos de conocimiento permiten modelar información en forma de nodos y relaciones, facilitando la organización y el acceso a los datos. En este contexto, podemos crear un chatbot que responda preguntas basadas en la estructura de un grafo. Los conceptos utilizados son referentes a la temática de Inteligencia Artificial, aprovechando los temas propios de la materia de IA que imparto, en donde utilicé el ejemplo para explicar la relación.
El primer ejercicio consistió en construir un grafo dirigido que representa la relación entre distintos subcampos de la Inteligencia Artificial. Con la biblioteca networkx, al ejecutar el código se puede observar el grafo.
Este ejercicio ayudó a visualizar cómo los conceptos de IA están conectados y cómo se pueden representar jerárquicamente mediante grafos.
y el chat bot?
Ahora toca integrar el mapa en un chatbot que pueda responder preguntas. Para esto se implementó un sistema de preguntas y respuestas que interpreta consultas sobre conceptos en el grafo y devuelve respuestas basadas en las conexiones definidas.
def responder_pregunta(pregunta):
pregunta = pregunta.lower()
# Pregunta: ¿Qué es <concepto>?
for nodo in G.nodes:
if f"qué es {nodo.lower()}" in pregunta:
subtemas = list(G.successors(nodo))
if subtemas:
return f"{nodo} es un área de la Inteligencia Artificial que incluye conceptos como: {', '.join(subtemas)}."
else:
return f"{nodo} es un concepto en Inteligencia Artificial, pero no tiene subcategorías en este modelo."
# Pregunta: ¿Qué relación tiene <concepto1> con <concepto2>?
conceptos = [nodo for nodo in G.nodes if nodo.lower() in pregunta]
if len(conceptos) == 2:
nodo1, nodo2 = conceptos
if G.has_edge(nodo1, nodo2):
return f"{nodo1} es una subcategoría de {nodo2}."
elif G.has_edge(nodo2, nodo1):
return f"{nodo2} es una subcategoría de {nodo1}."
else:
return f"{nodo1} y {nodo2} están relacionadas con Inteligencia Artificial, pero no directamente en este grafo."
return "Lo siento, no tengo información sobre eso."
Aquí algunas de las preguntas y la salida.
qué sigue?
El reto no termina aquí. Ahora se espera que los estudiantes puedan aplicar lo aprendido en otro contexto, utilizando otro tipo de conocimientos. La idea es ver los resultados más adelante y explorar cómo se pueden extender estos modelos a otras áreas de conocimiento.
Esta guía rápida también aplica para subdominios y servicios, en esta entrada no encontrarás cómo hacer la app o servicios, simplemente cómo publicarla teniendo como prerrequisito un dominio con acceso a cpanel.
1. Preparar Archivos
Borra lo innecesario (vendor/ si usaste Composer, lo regenerarás en el servidor).
Configura .env, ajustando la base de datos y estableciendo CI_ENVIRONMENT = production. #con esto evitas que se muestren los errores y expongas información
Comprime el proyecto en un .zip, dejando public/ fuera del archivo.
2. Subir Archivos
En cPanel > Administrador de Archivos, sube el .zip a public_html (o a la carpeta del subdominio/servicio) y extráelo.
Asegúrate de que la estructura de archivos quede bien organizada.
3. Ajustar Directorios
Mueve el contenido de public/ a la raíz de public_html o la carpeta del subdominio.
Edita index.php para corregir la ruta: $pathsPath = realpath(FCPATH . '../Config/Paths.php'); #elimina los dos puntos
Revisa .htaccess y ajusta las reglas si es necesario.
4. Base de Datos
Desde cPanel > MySQL Databases, crea la base de datos.
Genera un usuario, asigna permisos completos y anota las credenciales.
Exporta la BD desde tu entorno local usando phpMyAdmin o mysqldump.
Importa la BD en phpMyAdmin del servidor.
Edita .env con los datos correctos de la BD.
5. Si tienes algún error por la versión de php
En cPanel > Seleccionar Versión de PHP, elige una compatible con la versión de tu CI4.
Activa mod_rewrite si es necesario para URLs limpias.
Prueba accediendo al dominio, subdominio o servicio y verifica que todo funcione.
La inteligencia artificial (IA) es una disciplina que permite a las computadoras aprender y tomar decisiones basadas en datos. Utilizando modelos de aprendizaje automático, es posible entrenar algoritmos para reconocer patrones y hacer predicciones. En esta breve entrada, se muestra cómo desarrollar una aplicación en Python que permita el reconocimiento de patrones, para este caso, reconocer los números del 0 – 9 utilizando una red neuronal entrenada con TensorFlow. y para la interfaz gráfica, Tkinter, en python.
Librerias
Tkinter: Para la interfaz gráfica.
NumPy: Para manejar la matriz de datos.
TensorFlow/Keras: Para cargar y utilizar un modelo de reconocimiento de patrones.
Carga del Modelo de Reconocimiento
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import to_categorical
# Ejemplos simples para 0 al 9
digits = {
0: [
[0,1,1,0],
[1,0,0,1],
[1,0,0,1],
[1,0,0,1],
[1,0,0,1],
[0,1,1,0]
],
1: [
[0,0,1,0],
[0,1,1,0],
[0,0,1,0],
[0,0,1,0],
[0,0,1,0],
[0,1,1,1]
],
2: [
[0,1,1,0],
[1,0,0,1],
[0,0,1,0],
[0,1,0,0],
[1,0,0,0],
[1,1,1,1]
],
3: [
[1,1,1,0],
[0,0,0,1],
[0,1,1,0],
[0,0,0,1],
[0,0,0,1],
[1,1,1,0]
],
4: [
[0,0,1,0],
[0,1,1,0],
[1,0,1,0],
[1,1,1,1],
[0,0,1,0],
[0,0,1,0]
],
5: [
[1,1,1,1],
[1,0,0,0],
[1,1,1,0],
[0,0,0,1],
[1,0,0,1],
[0,1,1,0]
],
6: [
[0,1,1,0],
[1,0,0,0],
[1,1,1,0],
[1,0,0,1],
[1,0,0,1],
[0,1,1,0]
],
7: [
[1,1,1,1],
[0,0,0,1],
[0,0,1,0],
[0,1,0,0],
[1,0,0,0],
[1,0,0,0]
],
8: [
[0,1,1,0],
[1,0,0,1],
[0,1,1,0],
[1,0,0,1],
[1,0,0,1],
[0,1,1,0]
],
9: [
[0,1,1,0],
[1,0,0,1],
[1,0,0,1],
[0,1,1,1],
[0,0,0,1],
[0,1,1,0]
]
}
# Preparación de los datos
X = np.array([np.array(digits[d]).flatten() for d in digits]) # Convertir a vectores de 24 elementos
y = np.array(list(digits.keys()))
# Codificación one-hot para las etiquetas
y_categorical = to_categorical(y, num_classes=10)
# Definir el modelo de red neuronal
model = Sequential([
Dense(32, activation='relu', input_shape=(24,)),
Dense(16, activation='relu'),
Dense(10, activation='softmax') # 10 clases (0 al 9)
])
# Compilar el modelo
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Entrenar el modelo
model.fit(X, y_categorical, epochs=1000, verbose=1)
# Guardar el modelo entrenado
model.save("modeloReconocimiento0-9.keras")
print("Modelo guardado exitosamente como 'modelo_numeros.keras")
El primer paso es cargar el modelo previamente entrenado. En este caso, el modelo debe haber sido guardado en un archivo modelo0-9.keras.
import tensorflow as tf
import numpy as np
import tkinter as tk
# Cargar el modelo
try:
model = tf.keras.models.load_model('modelo0-9.keras')
except:
print(" No se encontró el archivo 'modelo0-9.keras'. Asegúrate de entrenar y guardar el modelo.")
exit()
Creación de la Interfaz Gráfica con Tkinter
La interfaz se basa en un lienzo donde el usuario puede dibujar un patrón de 6×4 celdas. Cada celda puede activarse o desactivarse haciendo clic en ella.
Cada clic del usuario alterna el estado de la celda, cambiando su color de blanco a negro y viceversa.
rectangles = {}
def toggle_cell(event):
col = event.x // CELL_SIZE
row = event.y // CELL_SIZE
if 0 <= row < ROWS and 0 <= col < COLS:
matrix[row, col] = 1 if matrix[row, col] == 0 else 0
color = "black" if matrix[row, col] == 1 else "white"
canvas.itemconfig(rectangles[(row, col)], fill=color)
Creación de la Cuadrícula
for r in range(ROWS):
for c in range(COLS):
x1, y1 = c * CELL_SIZE, r * CELL_SIZE
x2, y2 = x1 + CELL_SIZE, y1 + CELL_SIZE
rect = canvas.create_rectangle(x1, y1, x2, y2, fill="white", outline="gray")
rectangles[(r, c)] = rect
canvas.bind("<Button-1>", toggle_cell)
Reconocimiento del Patrón
Al presionar el botón «Reconocer», la matriz se procesa y se pasa al modelo para obtener una predicción.
def reset_matrix():
global matrix
matrix = np.zeros((ROWS, COLS), dtype=int)
for (r, c), rect in rectangles.items():
canvas.itemconfig(rect, fill="white")
Esta aplicación es un ejemplo práctico de cómo integrar modelos de inteligencia artificial en interfaces gráficas de usuario. Puedes mejorarla entrenando modelos más precisos o ampliando la resolución de la cuadrícula para mejorar la precisión en el reconocimiento.
Hoy en día, compartir opiniones en internet es más fácil que nunca, pero también ha traído consigo un problema creciente: la difusión de publicaciones vacías, sin fundamentos sólidos y muchas veces cargadas de difamación. Lo preocupante no es solo que existan, sino la rapidez con la que se propagan y la cantidad de personas que las toman como verdad sin cuestionarlas.
El anonimato en la red ha dado pie a que muchos se sientan con la libertad de atacar sin consecuencias, escondiéndose tras perfiles sin rostro para lanzar acusaciones sin pruebas. Lo peor es que en muchos casos, estas publicaciones logran gran alcance, dañando la reputación de personas y empresas sin motivo real.
Plataformas como Facebook, Twitter y grupos en WhatsApp o Telegram han amplificado este fenómeno. En estos espacios, la información se comparte sin filtros, permitiendo que los rumores y la desinformación se propaguen a gran velocidad. Especialmente en algunos grupos de Facebook, se ha vuelto común ver cómo los usuarios difunden contenido sin verificarlo, generando una cultura de ataque sin reflexión.
Ayer, por ejemplo, me topé con un caso que ilustra esto perfectamente. En un grupo de Facebook, varias personas estaban criticando y difamando a una empresa sin aportar ninguna prueba concreta. Me dieron ganas de intervenir con argumentos y hechos verificables, pero me di cuenta de que no había espacio para el diálogo. La mayoría de los participantes solo buscaban sumarse a la indignación sin cuestionar lo que leían. Situaciones como esta son una clara muestra de la importancia de fomentar el pensamiento crítico y no dejarnos llevar por la información superficial.
¿Por qué tanta gente se suma a esta dinámica? En parte, porque es más fácil creer en algo llamativo que tomarse el tiempo de investigar la verdad. Además, compartir información que refuerza ciertas ideas genera una sensación de pertenencia, sin considerar el impacto que puede tener en la vida real.
Es fundamental desarrollar una actitud más responsable al consumir y compartir información. No basta con leer y dar por hecho lo que nos dicen; hay que cuestionar, verificar fuentes y ser conscientes del efecto que nuestras palabras pueden tener en los demás.
Han pasado varios años desde que inicié este blog bajo el nombre de «abdielicus», y con el tiempo evolucionó a «e-icus.net». Sin embargo, por diversas razones, el proyecto quedó en pausa. Hoy, con energía renovada y muchas ideas en mente, es momento de retomarlo.
En esta nueva etapa, quiero compartir contenido sobre temas que siempre me han apasionado: educación, programación y actividades diarias. Desde artículos técnicos y guías de desarrollo hasta reflexiones sobre el aprendizaje y la tecnología, este espacio será un punto de encuentro para el conocimiento y la experimentación.
Es momento de cambiar la esencia del blog, me propongo mejorar la frecuencia de publicaciones y la interacción con quienes se sumen a esta comunidad. Leeré sus opiniones, sugerencias y temas de interés para hacer de este sitio un espacio más enriquecedor para todos.