-
Notifications
You must be signed in to change notification settings - Fork 1
/
DL.jl
160 lines (121 loc) · 5.1 KB
/
DL.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using Flux
using Flux: onehotbatch, onecold, crossentropy
using JLD2, FileIO
using Statistics: mean
include("modulos/dataset_DL.jl");
include("modulos/graphics.jl");
#===============================================================================
COSAS:
· en toFloatArray no me deja hacer un assert de una comp de ints: MethodError: objects of type Int64 are not callable
· ¿por qué filtros de 3x3?
· ¿Están bien las capas convolucionales?
===============================================================================#
interval = 8;
(train_imgs, train_labels,
test_imgs, test_labels) = getInputs("datasets", interval);
#=
for image in train_imgs
display(image);
end;
for image in test_imgs
display(image);
end;
=#
train_imgs = toFloatArray(train_imgs);
test_imgs = toFloatArray(test_imgs);
println("Tamaño de la matriz de entrenamiento: ", size(train_imgs))
println("Tamaño de la matriz de test: ", size(test_imgs))
batch_size = 64;
gruposIndicesBatch = Iterators.partition(1:size(train_imgs,4), batch_size);
println("He creado ", length(gruposIndicesBatch), " grupos de indices para distribuir los patrones en batches");
train_set = [( train_imgs[:,:,:,indicesBatch], Array(onehotbatch(train_labels[indicesBatch], 0:2)) ) for indicesBatch in gruposIndicesBatch]
test_set = (test_imgs, onehotbatch(test_labels, 0:2));
train_imgs = nothing;
test_imgs = nothing;
GC.gc();
funcionTransferenciaCapasConvolucionales = relu;
# Definimos la red con la funcion Chain, que concatena distintas capas
modelo = Chain(
Conv((5, 5), 3=>16, pad=(1,1), funcionTransferenciaCapasConvolucionales),
MaxPool((2,2)),
Conv((5, 5), 16=>32, pad=(1,1), funcionTransferenciaCapasConvolucionales),
MaxPool((2,2)),
Conv((5, 5), 32=>32, pad=(1,1), funcionTransferenciaCapasConvolucionales),
MaxPool((2,2)),
x -> reshape(x, :, size(x, 4)),
Dense(9248, 3),
softmax
);
# Vamos a probar la RNA y poner algunos datos de cada capa
# Usaremos como entrada varios patrones de un batch
numBatchCoger = 1; numImagenEnEseBatch = [12, 6];
entradaCapa = train_set[numBatchCoger][1][:,:,:,numImagenEnEseBatch];
numCapas = length(params(modelo));
println("La RNA tiene ", numCapas, " capas:");
for numCapa in 1:numCapas
println(" Capa ", numCapa, ": ", modelo[numCapa]);
# Le pasamos la entrada a esta capa
global entradaCapa # Esta linea es necesaria porque la variable entradaCapa es global y se modifica en este bucle
capa = modelo[numCapa];
salidaCapa = capa(entradaCapa);
println(" La salida de esta capa tiene dimension ", size(salidaCapa));
entradaCapa = salidaCapa;
end;
modelo(train_set[numBatchCoger][1][:,:,:,numImagenEnEseBatch]);
loss(x, y) = crossentropy(modelo(x), y)
accuracy(batch) = mean(onecold(modelo(batch[1])) .== onecold(batch[2]))
function calculate_loss(array_of_tuples)
return loss(array_of_tuples[1], array_of_tuples[2]);
end;
println("Ciclo 0: Precision en el conjunto de entrenamiento: ", 100*mean(accuracy.(train_set)), " %");
opt = ADAM(0.001);
println("Comenzando entrenamiento...")
mejorPrecision = -Inf;
criterioFin = false;
numCiclo = 0;
numCicloUltimaMejora = 0;
mejorModelo = nothing;
num_ciclos = [];
trainingLosses = [];
testLosses = [];
trainingAccuracies = [];
testAccuracies = [];
while (!criterioFin)
global numCicloUltimaMejora, numCiclo, mejorPrecision, mejorModelo,
criterioFin, num_ciclos, trainingLosses, testLosses,
trainingAccuracies, testAccuracies;
Flux.train!(loss, params(modelo), train_set, opt);
numCiclo += 1;
precisionEntrenamiento = mean(accuracy.(train_set));
println("Ciclo ", numCiclo, ": Precision en el conjunto de entrenamiento: ", 100*precisionEntrenamiento, " %");
precisionTest = accuracy(test_set);
println(" Precision en el conjunto de test: ", 100*precisionTest, " %");
# Calculamos las métricas
push!(num_ciclos, numCiclo);
push!(trainingAccuracies, precisionEntrenamiento);
push!(testAccuracies, precisionTest);
push!(trainingLosses, mean(calculate_loss.(train_set)));
push!(testLosses, mean(calculate_loss(test_set)));
if (precisionEntrenamiento > mejorPrecision)
mejorPrecision = precisionEntrenamiento;
println(" Mejora en el conjunto de entrenamiento -> Precision en el conjunto de test: ", 100*precisionTest, " %");
mejorModelo = deepcopy(modelo);
numCicloUltimaMejora = numCiclo;
end;
#=
if (numCiclo - numCicloUltimaMejora >= 5) && (opt.eta > 1e-6)
opt.eta /= 10.0
println(" No se ha mejorado en 5 ciclos, se baja la tasa de aprendizaje a ", opt.eta);
numCicloUltimaMejora = numCiclo;
end;
=#
if (precisionEntrenamiento >= 0.999)
println(" Se para el entenamiento por haber llegado a una precision de 99.9%")
criterioFin = true;
end;
if (numCiclo - numCicloUltimaMejora >= 10)
println(" Se para el entrenamiento por no haber mejorado la precision en el conjunto de entrenamiento durante 10 ciclos")
criterioFin = true;
end;
end;
print_train_results(num_ciclos, trainingLosses, testLosses, trainingAccuracies, testAccuracies);