-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
321 lines (288 loc) · 22.4 KB
/
index.html
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link type="text/css" rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@observablehq/inspector@5/dist/inspector.css">
<title>Visualize & Reinforce</title>
<link rel="icon" href="icon.png" type="image/png">
</head>
<body>
<section id="splash">
<!-- <h1>
<span>Visualize</span><span>Reinforce</span>
</h1>
<h2 style="display: none; border-bottom: none" class="authors">
<span>Gustavo Sanches</span> <span>Rodrigo Pintucci</span> <span>Lucas Treuke</span>
</h2> -->
<h1>
<span>Classificando</span><span>Florestas</span>
</h1>
<br>
<!-- <h3>COMO CLASSIFICAR ÁRVORES EFICIENTEMENTE?</h3> -->
<!-- <div class="title">
<h2>Como classificar árvores</h2>
<div><span>eficientemente?</span></div>
<p>Classificando árvores usando suas copas e Aprendizado de Máquina.</p>
<div class="bkg"></div>
</div> -->
<h3 style="text-align: center;">Classificando árvores em uma floresta densa</h3>
<div id="splashgraphic">
<div class="gap"></div>
<div id="treetops">
<div id="observablehq-viewof-page-ae147ea2"></div>
<div title="Essa visualização usa a linha do tempo" style="left: 10px; bottom: auto; top: 40px;" class="timeMarker">⌛</div>
</div>
<div class="legenda">
<div id="observablehq-legend_trees-ae147ea2"></div>
</div>
</div>
</section>
<div class="timeline">
<div class="help">
<span class="hint">Passe o mouse aqui 🛈</span>
<div>
Use essa linha do tempo para interagir com as visualizações marcadas com ⌛
</div>
</div>
<div id="observablehq-viewof-iterationSlider-ae147ea2"></div>
</div>
<content>
<section id="introduction">
<h1>Introdução</h1>
<p>
Mapear as espécies de árvores em uma vasta floresta é uma tarefa desafiadora. Uma das principais complicações decorre da escassez de dados anotados, ou seja, é frequente encontrar conjuntos de dados em que as amostras não possuem informações sobre a variável a ser prevista. No contexto do estudo em questão, a proporção de árvores das quais possuímos conhecimento das espécies e daquelas das quais não possuímos é bastante reduzida. Com base nessa premissa, propomos a aplicação do algoritmo de pseudo-rotulagem em conjunto com o Aprendizado por Reforço.
</p>
<p>
De acordo com Liu (2021), o algoritmo de Pseudo-rotulagem tem sido amplamente adotado devido à sua eficiência e utilidade na classificação de <b>conjuntos de dados com poucas anotações</b>. O algoritmo opera da seguinte maneira: em primeiro lugar, um modelo de classificação é treinado utilizando os poucos dados que possuem rótulos; em seguida, são selecionados e categorizados os dados do conjunto que não possuem rótulos; por fim, os dados selecionados são utilizados em conjunto com os dados originalmente rotulados para re-treinar o classificador na etapa inicial.
</p>
<p>
O Aprendizado de Máquinas será utilizado como parte do processo de escolha de quais dados devem ser categorizados e quais entrarão para o conjunto de treinamento. O objetivo dessa parte é tentar escolher apenas dados que são mais representativos e que expliquem melhor a distribuição de cada classe.
</p>
<div id="fluxograma">
<!-- importando imagem_interativa.svg de modo que possa ser aplicado funções em elementos seus -->
<object type="image/svg+xml" data="mockImages/imagem_interativa.svg" width="100%" height="100%" ></object>
<div id="fluxograma_svg">
<svg width="1354" height="598" viewBox="0 0 1354 598" xmlns="http://www.w3.org/2000/svg">
<rect data-info="
Conjunto inicial dos dados que possuem suas
classes anotadas."
class="infoBox" x="87.5" y="78.75" width="197" height="164" rx="14.06"/>
<rect data-info="
Conjunto inicial dos dados que não possuem
suas classes anotadas."
class="infoBox" x="90.87" y="336.42" width="197" height="164" rx="14.06"/>
<rect data-info="
Rede neural treinada com os dados vindo do treino 0
ou do treino n, que tem como objetivo fazer a
predição dos dados não classificados."
class="infoBox" x="575.66" y="78.75" width="197" height="164" rx="14.06"/>
<rect data-info="
Conjunto com a predições de classes de cada árvore,
será utilizado para escolher quais dessas predições
entrarão para o conjunto de treino."
class="infoBox" x="786.49" y="336.42" width="197" height="164" rx="14.06"/>
<rect data-info="
Algoritmo de aprendizado por reforço (RL) que decidirá
com base em regras de negócio quais dessas predições
serão tomadas como verdadeiras, e adicionadas ao
conjunto de treino."
class="infoBox" x="1064.66" y="336.42" width="197" height="164" rx="14.06"/>
<rect data-info="
O novo conjunto de treino consiste nos dados do
conjunto inicial adicionado todas as amostras com os
pseudo-rótulos das iterações anteriores."
class="infoBox" x="1064.66" y="78.75" width="197" height="164" rx="14.06"/>
<circle data-info="
primeira etapa de treinamento do classificador,
utilizando apenas a porção dos dados classificados.
" class="infoBox" cx="427.79" cy="157" r="22.25"/>
<circle data-info="
Etapa n de treinamento do classificador, a cada adição
no conjunto de treino, é necessário retreinar o classificador
a fim de melhorar suas predições.
" class="infoBox" cx="918.79" cy="157" r="22.25"/>
<circle data-info="
Uma matriz contendo a probabilidade de cada árvore ser
de cada espécie/classe.
" class="infoBox" cx="675.79" cy="418.42" r="22.25"/>
</svg>
</div>
</div>
<p id="diagram_text"><b style="color: black;">O overview do projeto pode ser visto na figura acima, passe o mouse por cima para ver breves explicações de cada etapa!</b></p>
</section>
<section id="Método">
<h1>Base de dados</h1>
<p>No estudo realizado por La Rosa (2021), foram utilizadas imagens hiperespectrais juntamente com uma rede neural convolucional para identificar as copas das árvores e construir uma base de dados contendo características específicas de cada árvore, totalizando 14 classes de árvores com anotações. Neste trabalho, optaremos por simular os dados com o objetivo de avaliar a eficácia do método em um ambiente totalmente controlado. Em trabalhos futuros, pretendemos utilizar imagens reais das copas de árvores em conjunto com a pseudo-rotulagem.</p>
<div class="center">
<div id="observablehq-viewof-gaussian_mixture-ae147ea2"></div>
<div class="samplelabels"></div>
</div>
<p>A nossa amostragem toma partido da premissa de que as árvores possuem 5 atributos principais: Posição em X, posição em Y, característica 1, característica 2 e classe. A geração tanto da posição no eixo X quanto no Y foi feita apartir de uma váriavel aleatória uniforme com parâmetros 0 a 100, ou seja, as árvores tem igual probabilidade de estarem posicionadas em qualquer lugar do campo. Para as features e para a classe, foram criadas distribuições gaussianas por classe, e amostrado da mistura dessas distribuições.</p>
<h1>Metodo</h1>
<div class="pseudo-label">
<div>
<div class="left">
<h3>Predições: pseudo-rótulos</h3>
<div id="ps-label-graphic">
<div id="observablehq-viewof-pseudoLabel-ae147ea2"></div>
<div class="subtitles" id="observablehq-viewof-legend_pseudoLabel-ae147ea2"></div>
<div style="transform: translatex(-32px);" title="Essa visualização usa a linha do tempo" class="timeMarker">⌛</div>
</div>
</div>
<div class="right">
<h2>Pseudo-rotulagem</h2>
<p>
O algoritmo de pseudo-rotulagem consiste em alimentar o conjunto de treinamento com labels virtuais. Para isso, utiliza-se dos poucos dados anotados disponíveis no dataset para treinar um classificador, e com base nessas classificações feitas podemos decidir incluir ou não novas amostras no conjunto de treino.
Uma forma que, segundo Cascante-Bonila (2020), acompanha o estado da arte é utilizar de análise de currículo juntamente com a pseudo-rotulagem, que consiste em avaliar apenas os pontos com maior probabilidade de ser de determinada classe.
</p>
</div>
</div>
<p>
O gráfico acima representa o algoritmo de pseudo-rotulagem com análise de currículo classificando 900 pontos tendo acesso inicialmente a apenas 100. Embora esse método seja considerado acompanhar o estado da arte de acordo com Cascante-Bonilla (2020), ele possui a limitação de dar prioridade aos pontos que não descrevem adequadamente a distribuição. No caso de uma variável gaussiana, ele privilegiaria pontos mais próximos da moda. Para resolver essa problemática, deseja-se além de utilizar da análise de currículo, incluir um algoritmo de RL que tome a decisão de incluir, ou não, os novos pontos. Dessa forma conseguimos adicionar informações adicionais na hora da decisão, como por exemplo a proporção da distribuição das árvores na floresta (30% macieira e 70% bananeira).
</p>
</div>
</section>
<section id="resultados">
<h1>resultados</h1>
<p>O método de pseudo-rotulagem revelou-se altamente efetivo na amostra gerada neste estudo, o que pode ser claramente observado na matriz de confusão a seguir. Conforme as iterações avançam, os valores se concentram cada vez mais na diagonal principal, indicando que o método está atribuindo corretamente as classes.</p>
<br>
<br>
<br>
<h3>Matriz de confusão</h3>
<div class="confusionMatrix">
<div class="left">
<div id="observablehq-viewof-matrix-ae147ea2"></div>
<div style="bottom: auto; top: 42px;" title="Essa visualização usa a linha do tempo" class="timeMarker">⌛</div>
</div>
<div class="right">
<div id="observablehq-viewof-matrix_legend-ae147ea2"></div>
</div>
</div>
<p>Embora neste exemplo tenhamos obtido resultados positivos, durante os testes com o método, encontramos diversos casos nos quais o classificador apresentou desempenho inferior ao selecionar classes aleatoriamente. Essa situação ocorre principalmente por dois motivos principais:</p>
<p>Como mencionado anteriormente, o método seleciona pontos que oferecem pouca informação sobre a distribuição das amostras, o que resulta em decisões baseadas em uma visão pouco esclarecedora do problema.</p>
<p>O desempenho do método é altamente dependente das condições iniciais, ou seja, quais pontos foram selecionados inicialmente? Esse problema é agravado pelo fato de os dados serem simulados.</p>
<p>Para abordar ambas as questões mencionadas, propõe-se a adoção de um algoritmo modificado com aprendizado por reforço (RL), que proporcionaria uma curva de decisão mais suave e permitiria tomadas de decisões mais conscientes dos resultados obtidos.</p>
<h1>Apêndices</h1>
<p>Vale ressaltar que os algoritmos de classificação utilizam apenas das informações de feature e da classe, o valor de X e Y ficam apenas para ilustração e visualizações. Para entender melhor o processos de amostragem que nós utilizamos, <b>interaja com o box abaixo</b>:</p>
</section>
<section id="sampling" class="box">
<div class="innerbox">
<h2>Faça sua própria amostragem</h2>
<p>
Para compreender melhor o processo utilizado na geração dos dados neste trabalho, explore as visualizações a seguir:
</p>
<p>Em primeiro lugar, é fundamental compreender como criar amostras a partir de uma distribuição qualquer. Neste estudo, estamos utilizando a distribuição gaussiana. No gráfico abaixo, é possível ajustar a média e a variância das distribuições que governam o comportamento dos eixos. Aumentar a altura da curva altera a variância dos dados, enquanto deslocá-la lateralmente significa modificar a média. Manipule livremente as bolinhas no topo das curvas para observar esse efeito aplicado a cada eixo.</p>
<div class="sampling-from-normals">
<div class="positioning">
<div class="controller" id="controllers-x">
<div id="observablehq-viewof-draggableNormals1-ae147ea2"></div>
<div id="observablehq-normalcontrollers1-ae147ea2"></div>
</div>
</div>
<div class="gap">
<div id="observablehq-viewof-callafunction_btn-ae147ea2"></div>
<div id="observablehq-viewof-sampling_parameters-ae147ea2"></div>
</div>
<div id="observablehq-viewof-scatterOfSamples-ae147ea2"></div>
<div class="positioning reverse-y">
<div class="controller" id="controllers-y">
<div id="observablehq-viewof-draggableNormals2-ae147ea2"></div>
<div id="observablehq-normalcontrollers2-ae147ea2"></div>
</div>
</div>
</div>
<p>Uma vez que somos capazes de criar essas amostras, é importante entender como fazê-lo para pontos de classes diferentes. O que ocorre é que cada classe de árvore possui sua própria distribuição, com uma probabilidade associada de ser escolhida para a amostra. Dessa forma, conseguimos controlar a proporção de cada classe de árvore na amostra final. O resultado desse processo, em cada eixo, é uma combinação de distribuições gaussianas.</p>
<div class="center normal-mix">
<div class="controller">
<div id="observablehq-normalcontrollersMix-ae147ea2"></div>
<div id="observablehq-viewof-normalMixturePlot-ae147ea2"></div>
</div>
<div class="legenda">
<div class="parameters" id="observablehq-viewof-gaussian_mixture_parameters-ae147ea2"></div>
<div id="observablehq-viewof-legend_normalmixture-ae147ea2"></div>
</div>
<div id="observablehq-viewof-weight-ae147ea2"></div>
</div>
<p>
No gráfico acima, temos duas curvas gaussianas (representando características de duas classes diferentes) e uma que representa a mistura das duas, ou seja, a distribuição geral dos pontos.
</p>
</div>
</section>
<section id="referencias">
<h1>Bibliografia</h1>
<ul>
<li>R. Feitosa C. Almeida M. Schimalski D. Oliveira L. Rosa, C. Sothe.Multi-task
fully convolutional network for tree species mapping in denseforests
using small training hyperspectral data. arXiv:2106.00799v2, 2021. </li>
<li>F. Qi V. Ordonez P. Cascante-Bonilla, Y. Tan. Curriculum labeling:
Revis-iting pseudo-labeling for semi-supervised learning. arXiv:2001.06001v2,</li>
</ul>
<h2>
Visualizações por
</h2>
<div class="authors">
<span>Gustavo Sanches</span> <span>Rodrigo Pintucci</span> <span>Lucas Treuke</span>
<a class="about" href="./about">About</a>
</div>
<p>Observable notebook: <a href="https://observablehq.com/d/31ca7950886a92d8">Reinforcement Learning by amigos</a></p>
</section>
</content>
<script type="module">
import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@5/dist/runtime.js";
import define from "https://api.observablehq.com/d/[email protected]?v=3";
new Runtime().module(define, name => {
if (name === "viewof iterationSlider") return new Inspector(document.querySelector("#observablehq-viewof-iterationSlider-ae147ea2"));
if (name === "viewof pseudoLabel") return new Inspector(document.querySelector("#observablehq-viewof-pseudoLabel-ae147ea2"));
if (name === "viewof legend_pseudoLabel") return new Inspector(document.querySelector("#observablehq-viewof-legend_pseudoLabel-ae147ea2"));
if (name === "viewof gaussian_mixture") return new Inspector(document.querySelector("#observablehq-viewof-gaussian_mixture-ae147ea2"));
if (name === "viewof page") return new Inspector(document.querySelector("#observablehq-viewof-page-ae147ea2"));
if (name === "legend_trees") return new Inspector(document.querySelector("#observablehq-legend_trees-ae147ea2"));
if (name === "viewof matrix") return new Inspector(document.querySelector("#observablehq-viewof-matrix-ae147ea2"));
if (name === "viewof matrix_legend") return new Inspector(document.querySelector("#observablehq-viewof-matrix_legend-ae147ea2"));
if (name === "viewof sampling_parameters") return new Inspector(document.querySelector("#observablehq-viewof-sampling_parameters-ae147ea2"));
if (name === "viewof draggableNormals1") return new Inspector(document.querySelector("#observablehq-viewof-draggableNormals1-ae147ea2"));
if (name === "normalcontrollers1") return new Inspector(document.querySelector("#observablehq-normalcontrollers1-ae147ea2"));
if (name === "viewof draggableNormals2") return new Inspector(document.querySelector("#observablehq-viewof-draggableNormals2-ae147ea2"));
if (name === "normalcontrollers2") return new Inspector(document.querySelector("#observablehq-normalcontrollers2-ae147ea2"));
if (name === "viewof scatterOfSamples") return new Inspector(document.querySelector("#observablehq-viewof-scatterOfSamples-ae147ea2"));
if (name === "viewof callafunction_btn") return new Inspector(document.querySelector("#observablehq-viewof-callafunction_btn-ae147ea2"));
if (name === "viewof weight") return new Inspector(document.querySelector("#observablehq-viewof-weight-ae147ea2"));
if (name === "normalcontrollersMix") return new Inspector(document.querySelector("#observablehq-normalcontrollersMix-ae147ea2"));
if (name === "viewof normalMixturePlot") return new Inspector(document.querySelector("#observablehq-viewof-normalMixturePlot-ae147ea2"));
if (name === "viewof legend_normalmixture") return new Inspector(document.querySelector("#observablehq-viewof-legend_normalmixture-ae147ea2"));
if (name === "viewof gaussian_mixture_parameters") return new Inspector(document.querySelector("#observablehq-viewof-gaussian_mixture_parameters-ae147ea2"));
return ["data_matrix","data_trees","data_pseudo","filter","trees","normal_colors","drag","normalMixture_configuration"].includes(name);
});
// lets add a function that will run when the document is loaded
document.addEventListener("DOMContentLoaded", function(event) {
let boxes = document.getElementsByClassName("infoBox")
let diagram_text = document.getElementById("diagram_text")
// we apply a hover function on each box, that will get his data-info attribute and place this text at the diagram text
for (let i = 0; i < boxes.length; i++) {
boxes[i].addEventListener("mouseover", function() {
diagram_text.classList.add("info")
diagram_text.innerHTML = this.getAttribute("data-info")
})
}
for (let i = 0; i < boxes.length; i++) {
boxes[i].addEventListener("mouseout", function() {
diagram_text.classList.remove("info")
diagram_text.innerHTML = "Passe o mouse sobre os elementos para ver mais informações"
})
}
});
// fazendo com que os hints tenham o texto substítuido por 🛈 no primeiro hover
document.addEventListener("DOMContentLoaded", function(event) {
let hints = document.getElementsByClassName("hint")
for (let i = 0; i < hints.length; i++) {
hints[i].addEventListener("mouseover", function() {
this.innerHTML = "🛈"
})
}
});
</script>
</body>
</html>