<jupyter_start><jupyter_text>IA Notebook 2 - <NAME>Aquí veremos cómo "romper" una red neuronal, usando como ejemplo práctico la IA "Inception V3", la cual es capaz de hacer reconocimiento de imágenes, pudiendo decir alto grado de probabilidad que hay en dicha imágen.**Nota: Se hizo uso de la versión 1.14.0 de Tensorflow, tener en cuenta antes de ejecutar. También revisar algunas rutas hacia algunos archivos, ya que después de las pruebas realizadas, se hizo una reorganización y se cambió de ruta pero el código no se ha ejecutado, por lo que no es del todo seguro que funcione.**<jupyter_code>import tensorflow as tf
import keras

import matplotlib.pyplot as plt
import numpy as np

#Los errores mostrados son por lo que se está haciendo uso de una anterior versión de Tensorflow, no afecta al desarrollo de la actividad.
from keras.applications.inception_v3 import InceptionV3, decode_predictions #Aquí importamos el modelo y una función que nos servirá más adelante.
from keras import backend as k
iv3=InceptionV3()
#Con esto podemos ver un recuentro de todas las capas del modelo
print("Resumen:")
#print(iv3.summary())
from keras.preprocessing import image

#Con esto podemos cargar una imagen usando Keras:
#ximg=image.load_img("./Recursos/Robot_Kuka.jpg")

#Pero para que el modelo lo pueda interpretar, convertimos la imagen a una matriz de números:
x=image.img_to_array(image.load_img("./Recursos/IA Notebook #2/Robot_Kuka.jpg"))

#Con esto podemos ver la forma de la matriz que representa a la imagen:
print(x.shape)<jupyter_output>(2440, 1832, 3)<jupyter_text>--- AnalizandoEl resultado es:(2440, 1832, 3)Dónde el primero número representa el alto de la foto, el segundo el ancho y el tercero la profundidad de bit en número de canales, para este caso, los canales son RGB y es por eso que sale 3Pero hay que aclarar que es una matriz y por lo tanto, cada pixel está representado como elemento de dicha matriz.--- Continuando...El modelo InceptionV3 requiere que la matriz cumpla cierto requisitos determinados, como por ejemplo:- La imagen tiene que ser de una proporción de 299x299 pixeles- El rango en que varía el elemento de la matriz tiene que ser entre -1 y 1- Es necesario una dimension adicional que represente la cantidad de imagenes que se le van a dar como entrada al modelo_El rango representa la intensidad de cada pixel en la imagen._<jupyter_code>#Por lo indicado anteriormente, se reescribirá la variable ximg:
x=image.img_to_array(image.load_img("./Recursos/IA Notebook #2/Robot_Kuka.jpg",target_size=(299, 299)))

print("La forma de la nueva matriz es: ",x.shape)

#Ahora cambiamos el rango de intensidad de cada pixel:
x=((x/255)-0.5)*2 #Con esto lo convertimos todo a rango de -1 a 1

#Le asignamos la dimensión adicional que representa la cantidad de imagenes:
x=x.reshape([1, x.shape[0], x.shape[1], x.shape[2]])
print("Forma de la nueva matriz ya lista para el modelo: ",x.shape)
#Momento de la verdad, ahora vamos a ingresar nuestra matriz al modelo:
y=iv3.predict(x)
#Debido a la cantidad de clases que tiene el modelo
#y que el modelo mismo le asigna una probabilidad a cada clase
#es que se espera una matriz de una tamaño de mil:

print("Tamaño o forma del resultado: ",y.shape)
#print("------------------------------\n El resultado como tal es:\n",y)
decode_predictions(y)<jupyter_output><empty_output><jupyter_text>Inicio de la Mini Sección de Practica<jupyter_code>#Repitiendo el proceso pero más rápido y evaluando dos fotos por separado:

#Ingresamos y converimos imagen a matriz:
x2=image.img_to_array(image.load_img("./Recursos/IA Notebook #2/Robot_Kuka_hacked.png"))
#Ya no se hizo el redimensionamiento porque la imagen ya está con las dimensiones adecuadas.

#Ahora cambiamos el rango de intensidad de cada pixel:
x2=((x2/255)-0.5)*2 #Con esto lo convertimos todo a rango de -1 a 1

#Le asignamos la dimensión adicional que representa la cantidad de imagenes:
x2=x2.reshape([1, x2.shape[0], x2.shape[1], x2.shape[2]])
print("Forma de la nueva matriz ya lista para el modelo: ",x2.shape)

y2=iv3.predict(x2)
decode_predictions(y2)
x3=image.img_to_array(image.load_img("./Recursos/IA Notebook #2/persona4.jpg",target_size=(299, 299)))

x3=((x3/255)-0.5)*2

x3=x3.reshape([1, x3.shape[0], x3.shape[1], x3.shape[2]])
print("Forma de la nueva matriz ya lista para el modelo: ",x3.shape)

y3=iv3.predict(x3)
decode_predictions(y3)<jupyter_output>Forma de la nueva matriz ya lista para el modelo:  (1, 299, 299, 3)<jupyter_text>Fin de la Mini Sección de PracticaY continuando...  Ataque AdversarioLo que ahora haremos primero será seleccionar la entrada de la primera capa y la salidad de la última capa de nuestro modelo InceptioV3.Luego definimos la clase objetivo (target_class) a la que queremos llegar, modificando nuestra imagen inicial almacenada en "x", de esta manera estaremos engañando al modelo, haciendole pensar que la imagen es de la clase que hemos definido.También definimos una función de coste (loss), teniendo en cuenta que la última capa de nuestra red (o modelo) es la que nos da las probabilidades de que sea una clase u otra.Aún no encuentro el significado sobre lo que se está haciendo con la función de coste, según dotCSV es una "función" pero en términos informáticos como enfocamos los valores dados en los corchetes?_"Con esto le estamos diciendo, es que nuestra función de coste que queremos maximizar es el resultado, la probabilidad de la clase 951, es decir, de todo el vector de probabilidades que nos proporciona, queremos que esa sea la clase maximizada."_Luego se crea la variable "grad" de gradiente, para almacenar el tensor cuyos valores nos dirán en que proporción tienen que variar los pixeles de nuestra imagen para que poco a poco la función de coste se vaya optimizando.La función "k.gradients" lo que hace es justamente aplicar ese método o algoritmo del "descenso del gradiente", con lo cual, nos dará como resultado una matriz y por razones no del todo claras, solo usaremos el primer elemento de dicha matriz.Ahora será necesario crear la función que se encargará de hacer este proceso del gradiente de manera iterativa (en bucle) y para ello se hace uso de la función Keras, y lo que se le suministra a está tipo de funciones es, por un lado, los valores que le vamos a dar de entrada y por otro lado, cuales son los resultados que esperamos como salida, y automáticamente crea todo el grafo necesario para realizar esa función.Por último, hacemos tres "sencillos" pasos, el primero es hacer una copia de nuestra variable x, y la segunda es crear una variable de coste la cual nos dirá si ya hemos llegado o no a nuestro objetivo, y la tercera es crear el bucle while dónde nuestra condición será la variable de coste, y este bucle ejecutará sin parar la función de optimizaciónd el gradiente, además de que se lo ira sumando a nuestra variable para ir modificando la copia de nuestra imagen.<jupyter_code>in_layer=iv3.layers[0].input
out_layer=iv3.layers[-1].output

#Las salida son tensores:
#print(in_layer)
#print(out_layer)

#Clase objetivo
target_class=951 #La clase limón está referenciada por este número.

#Función de coste:
loss=out_layer[0, target_class] #Aún no encuentro como funciona esto, si son parámetros o la forma de acceder a una matriz.

#Gradiente o descenso del gradiente
grad=k.gradients(loss, in_layer)[0]

#Gradiente optimizado u optimizo gradiente
optimize_gradient=k.function([in_layer, k.learning_phase()], [grad, loss])
#Para el caso de Keras, es necesario decirle en la parte de entrada la acción que estás queriendo realizar, si vas a entrenar o vas a testear.
#Y en nuestro caso es la de entrenar, por eso usamos "k.learning_phase()"

#Copia de la variable x en la variable adv, es solo para poder salvaguardar la original.
adv=np.copy(x)

#--------------------------------------------------------------------------------------
#Esto sección es para definir los valores límite de cuanto puede modificar y no, nuestros valores para llegar al resultado de imagen adversaria.
perturbacion=0.01

max_pert = x+0.01
min_pert = x-0.01
#--------------------------------------------------------------------------------------

#Variable de coste
cost=0.0

#Bucle iterativo
while cost<0.95:
    #Ya que nuestra función Keras, le hemos dicho antes que nos devuelva dos salidas, [grad, loss], es que tenemos:
    gr, cost = optimize_gradient([adv, 0])
    
    #Aquí le sumamos a nuestra imagen, las variaciones que tiene que sufrir.
    adv += gr
    
    #--------------------------------------------------------------------------------------
    #Ahora, con los valroes limites establecidos, hacemos:
    adv = np.clip(adv, min_pert, max_pert)
    adv = np.clip(adv, -1, 1) #Esto es para asegurarnos de que siempre esté dentro de los valores que pueda procesar el modelo.
    #--------------------------------------------------------------------------------------
    
    #Vamos viendo como se comporta nuestra función de coste y si va aumentando:
    print("Costo objetivo o target cost: ", cost)

#Guaramos una copia del resultado, el cual es un tensor.
hacked = np.copy(adv)
adv = ((adv/2)+0.5)*255
plt.imshow(adv[0].astype(np.uint8)) #Aquí convertimos los números de la matriz en valores enteros.
plt.show()
#Esto es solo para mantener el resultado anterior:
#plt.imshow(adv[0].astype(np.uint8)) #Aquí convertimos los números de la matriz en valores enteros.
#plt.show()
from PIL import Image

img_generada=Image.fromarray(adv[0].astype(np.uint8))

img_generada.save("./Recursos/IA Notebook #2/Robot_Kuka_hacked.png")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10675859187297608, 'fraction_numerical': 0.01754935756816045, 'mean_word_length': 3.9401444788441693, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '161271', 'license': 'MIT', 'n_tokens_mistral': 3224, 'n_tokens_neox': 3127, 'n_words': 1303, 'path': 'IA Notebook #2 - Ataques adversarios.ipynb', 'repo_name': 'Emgicraft/IA_Notebooks_ML', 'size': '9586'}