import numpy as np
import torch
from torch import nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from ipywidgets import interact, interact_manual, interactive, fixed
import ipywidgets as widgets
from IPython.display import display
def read(fileName):
""" Lee las imágenes desde first hasta last y las almacena en un arreglo 2D,
donde cada renglón corresponde a una imagen.
"""
file = open(fileName, "rb")
# Leer número mágico
## Los dos primeros bytes son cero
byte = file.read(4)
if byte[0] != 0 or byte[1] != 0:
raise Error("Encabezado corrupto: deben ser ceros" + str(byte))
## El tercero codifica el tipo de datos:
## 0x08: unsigned byte
## 0x09: signed byte
## 0x0B: short (2 bytes)
## 0x0C: int (4 bytes)
## 0x0D: float (4 bytes)
## 0x0E: double (8 bytes)
switcher = {
0x08 : np.uint8,
0x09 : np.int8,
0x0B : np.int16,
0x0C : np.int32,
0x0D : np.float32,
0x0E : np.float64,
}
dataType = switcher.get(byte[2], None)
## Número de dimensiones
numDims = byte[3]
## Tamaño de cada dimensión (cada una es un int de 4 bytes MSB first)
sizes = tuple(np.fromfile(file, dtype=np.int32, count=numDims).newbyteorder())
print("Vector de ", numDims, " dimensiones: ", sizes, " tipo ", dataType)
## Resto
a = np.fromfile(file, dtype=dataType)
data = np.reshape(a, sizes)
file.close()
return data
def printFull(array):
opt = np.get_printoptions()
np.set_printoptions(threshold=np.inf)
print(array)
np.set_printoptions(**opt)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import warnings
from IPython.core.pylabtools import figsize
def muestraImagen(vector3D, labelsVector, indice):
figsize(3, 3)
plt.title(labelsVector[indice])
# El -1 invierte el orden en y
plt.pcolormesh(vector3D[indice][::-1], cmap=cm.winter)
plt.show()
def muestraActividad(red, iEntrada):
""" Grafica los valores de activación de cada neurona
para la entrada en la columna iEntrada.
"""
if(iEntrada > red.A0.shape[1]):
raise IndexError("Ejemplar de entrenamiento inexistente " + str(iEntrada))
nRens = 4
nCols = 1
fig, axes = plt.subplots(figsize=(6,4))
norm = matplotlib.colors.Normalize(vmin=0, vmax=1)
ax_0 = plt.subplot2grid((nRens,nCols), (2,0), rowspan=2)
ax_1 = plt.subplot2grid((nRens,nCols), (1,0))
ax_2 = plt.subplot2grid((nRens,nCols), (0,0), sharey=ax_1)
a0 = red.A0[:,iEntrada]
a1 = red.A1[:,iEntrada:iEntrada+1].T
a2 = red.A2[:,iEntrada:iEntrada+1].T
# A0
ax_0.pcolormesh(a0[1:].reshape((28,28))[::-1], cmap=cm.cool, norm=norm)
ax_0.set_xlim(0, 28)
ax_0.set_ylim(0, 28)
# A1
ax_1.pcolormesh(a1, cmap=cm.cool, norm=norm)
ax_1.set_yticks(np.array([0,1]))
ax_1.set_xlim(0, 26)
ax_1.set_xticks(np.arange(26) + 0.5)
ax_1.set_xticklabels(np.arange(26), minor=False, ha='center')
# A2
ax_2.pcolormesh(a2, cmap=cm.cool, norm=norm)
ax_2.set_xticks(np.arange(10) + 0.5)
ax_2.set_xticklabels(np.arange(10), minor=False, ha='center')
# Barra de color
ax1 = fig.add_axes([1.0, 0, 0.025, 1.0]) # left, bottom, width, height
cb1 = matplotlib.colorbar.ColorbarBase(ax1, cmap=cm.cool,
norm=norm,
orientation='vertical')
with warnings.catch_warnings():
warnings.simplefilter("ignore")
plt.tight_layout()
filesDir = './'
trainingSetFile = filesDir + 'train-images-idx3-ubyte'
trainingSetLabelsFile = filesDir + 'train-labels-idx1-ubyte'
testSetFile = filesDir + 't10k-images-idx3-ubyte'
testSetLabelsFile = filesDir + 't10k-labels-idx1-ubyte'
trainData = read(fileName=trainingSetFile).astype(np.float64)
trainDataLabels = read(fileName=trainingSetLabelsFile).astype(np.float64)
testData = read(fileName=testSetFile).astype(np.float64)
testDataLabels = read(fileName=testSetLabelsFile).astype(np.float64)
@interact(index = (0, len(trainData) - 1))
def ShowImageTrain(index):
muestraImagen(trainData, trainDataLabels, index)
def makeX(data_train):
num_inputs = data_train.shape[0]
return torch.FloatTensor(data_train.reshape((num_inputs, 28 * 28)))
def makeY(labels_train):
num_inputs = labels_train.shape[0]
return torch.LongTensor(labels_train.reshape((num_inputs, 1)))
X = makeX(trainData)
print("X shape=", X.shape)
Y = makeY(trainDataLabels)
print("Y shape=", Y.shape)
## Repite lo mismo con los datos de entrenamiento
XTest = makeX(testData)
YTest = makeY(testDataLabels)
class Network(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(Network, self).__init__()
self.l1 = nn.Linear(input_size, hidden_size)
self.bn1 = nn.BatchNorm1d(hidden_size)
self.relu = nn.Sigmoid()
self.l3 = nn.Linear(hidden_size, output_size)
self.bn2 = nn.BatchNorm1d(output_size)
def forward(self, x):
x = self.l1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.l3(x)
x = self.bn2(x)
return F.softmax(x, dim=1)
net = Network(input_size=28*28, hidden_size=170, output_size=10)
print(net)
optimizer = optim.SGD(net.parameters(), lr=0.005, momentum=0.7)
loss_func = nn.CrossEntropyLoss()
epochs = 45
batch_size = 32
loss_log = []
for e in range(epochs):
for i in range(0, X.shape[0], batch_size):
x_mini = X[i:i + batch_size]
y_mini = Y[i:i + batch_size]
x_var = Variable(x_mini)
y_var = Variable(y_mini)
optimizer.zero_grad()
net_out = net(x_var)
loss = loss_func(net_out, y_var[:, 0])
loss.backward()
optimizer.step()
if i % 100 == 0:
loss_log.append(loss.data.item())
print('Epoch: {} - Loss: {:.6f}'.format(e, loss.data.item()))
def print_proba(ps):
labels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
plt.bar(labels, ps, align='center', alpha=0.5)
plt.xticks(labels)
plt.ylabel('Que tan seguro')
plt.title('Estimation')
plt.show()
@interact(index = (0, len(testData) - 1))
def ShowImagePrediction(index):
muestraImagen(testData, testDataLabels, index)
data = XTest[index:index+1]
estimation = net.eval()(data)[0].tolist()
print_proba(estimation)
matrix_confusion = np.zeros((10, 10), dtype=int)
correct = 0
total = XTest.shape[0]
for index in range(0, total):
data = XTest[index:index+1]
expected = YTest[index].item()
estimation = net.eval()(data)[0].tolist()
result = np.argmax(estimation)
matrix_confusion[expected][result] += 1
if int(expected) == int(result):
correct += 1
print(matrix_confusion)
import seaborn as sns
sns.set()
ax = sns.heatmap(matrix_confusion)
print(f"accuracy = {correct / total}")
matrix_confusion = np.zeros((10, 10), dtype=float)
correct = 0
total = XTest.shape[0]
for index in range(0, total):
data = XTest[index:index+1]
expected = YTest[index].item()
estimation = net(data)[0].tolist()
result = np.argmax(estimation)
matrix_confusion[expected] += estimation
if int(expected) == int(result):
correct += 1
print(matrix_confusion.astype(int))
import seaborn as sns
sns.set()
ax = sns.heatmap(matrix_confusion)
print(f"accuracy = {correct / total}")
plt.plot(loss_log)
plt.show()