Veja também:
Aprendizado de máquina. Redes Neurais (Parte 1): O Processo de Aprendizagem Perceptron
Aprendizado de máquina. Redes neurais (parte 2): modelagem OR, XOR com TensorFlow.js
Em artigos anteriores, apenas um dos tipos de camadas de rede neural foi usado - densa, totalmente conectada, quando cada neurônio da camada original tem uma conexão com todos os neurônios das camadas anteriores.
Para lidar com uma imagem preto e branco 24x24, por exemplo, teríamos que transformar a representação da matriz da imagem em um vetor que contém 24x24 = 576 elementos. Como você pode imaginar, com essa transformação, perdemos um atributo importante - a posição relativa dos pixels nas direções vertical e horizontal dos eixos, e também, provavelmente, na maioria dos casos, o pixel localizado no canto superior esquerdo da imagem dificilmente tem qualquer efeito logicamente explicável no pixel em canto inferior direito.
Para eliminar essas deficiências, camadas convolucionais (CNN) são usadas para processamento de imagem.
O principal objetivo da CNN é extrair pequenas partes da imagem original que contenham recursos (recursos) de suporte (características), como arestas, contornos, arcos ou faces. Nos próximos níveis de processamento, fragmentos repetíveis mais complexos de texturas (círculos, formas quadradas, etc.) podem ser reconhecidos a partir dessas bordas, que podem então ser dobradas em texturas ainda mais complexas (parte do rosto, roda do carro, etc.).
Por exemplo, considere um problema clássico - reconhecimento de imagem de números. Cada número tem seu próprio conjunto de figuras características deles (círculos, linhas). Ao mesmo tempo, cada círculo ou linha pode ser composto de arestas menores (Figura 1)

1. (convolutional layer)
CNN ( ), c () , . – CNN – .
, 2x2 ( K) , 2x2 ( N), :
, .
, (fully-connected, dense layers):
, - , – - , ( ).
2. , , , .

(kernel size) – 3, 5, 7.
(kernel) [kh, kw], [nh, nw], ( 3):
![3 – [3,3] 3 – [3,3]](https://habrastorage.org/getpro/habr/upload_files/ebc/66a/8ef/ebc66a8ef2e7f8268951b9d3bcaf08ba.png)
, . , . , .
, – (padding). , . , ph pw , :
, , , :

- . , (stride). – (stride).

, sw, sh, :
, ( – ). (). , (CONV1) 9x9x1 ( – - ), 2 1x1 (stride) (padding) , , . 9x9x2 2 – (. 6). CONV2 , , 2x2, , 2, 2x2x2. (CONV2) 9x9x4, 4 – .

, kw kh , nw x nh x nd, nd - , , kw x kh x nd ( 6, CONV2).
7 , RGB, 3x3. , (3 ), 3x3x3.

TensorFlow.js
, : tf.layers.conv2d, – , :
- filter – number –
- kernelSize – number | number[] – , number, , –
- strides – number | number[] - , [1,1], .
- padding – ‘same’, ‘valid’ – , ‘valid’
.
'same'
, , () (stride) . , - 11 , – 5, 13/5=2.6, – 3 ( 8).

stride=1, ( 9), , ( 8).

'valid'
, strides , 8.
TensorFlow.js
, . :
- :
- :
, , tf.browser.fromPixels. , img canvas .
<img src="./sources/itechart.png" alt="Init image" id="target-image"/>
<canvas id="output-image-01"></canvas>
<script>
const imgSource = document.getElementById('target-image');
const image = tf.browser.fromPixels(imgSource, 1);
</script>, , , 3x3, “same” ‘relu’:
const model = tf.sequential({
layers: [
tf.layers.conv2d({
inputShape: image.shape,
filters: 1,
kernelSize: 3,
padding: 'same',
activation: 'relu'
})
]
});[NUM_SAMPLES, WIDTH, HEIGHT,CHANNEL], tf.browser.fromPixel [WIDTH, HEIGHT, CHANNEL], – ( , ):
const input = image.reshape([1].concat(image.shape));. , setWeights Layer, :
model.getLayer(null, 0).setWeights([
tf.tensor([
1, 1, 1,
0, 0, 0,
-1, -1, -1
], [3, 3, 1, 1]),
tf.tensor([0])
]);, , 0-255, NUM_SAMPLES:
const output = model.predict(input);
const max = output.max().arraySync();
const min = output.min().arraySync();
const outputImage = output.reshape(image.shape)
.sub(min)
.div(max - min)
.mul(255)
.cast('int32');canvas, tf.browser.toPixels:
tf.browser.toPixels(outputImage, document.getElementById('output-image-01'));:

2. (pooling layer)
, ( ), , . , , (pooling layer, subsample layer), . MaxPooling .
, .
. (kernel) , (stride) 1x1, . , (. 10).

, 4x4, 2x2 (stride) , 2x2, .
, ( 11) . , , MaxPooling . (translation invariance). , , 50%. , , MaxPooling .

, .
, , – (stride).
MaxPooling AveragePooling, , , . , MaxPooling. AveragePooling , , MaxPooling .
TensorFlow.js (pooling layer)
tf.layers.maxPooling2d tf.layers.averagePooling2d. – , :
- poolSize - number | número [] - a dimensão do filtro, se o número for especificado, a dimensão do filtro assume a forma quadrada; se for especificado como uma matriz, a altura e a largura podem ser diferentes
- passadas - número | number [] é um passo à frente, um parâmetro opcional e por padrão tem a mesma dimensão que o poolSize especificado.
- preenchimento - 'mesmo', 'válido' - configuração de preenchimento zero, por padrão 'válido'