Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Tabela de Conteúdos
Resumo
O exemplo Image\GettingStarted\07_Deconvolution_PY.py mostra como usar Deconvolution e Unpooling para gerar um simples codificador de imagem automática (07_Deconvolution_BS.cntk é a versão BrainScript correspondente). Utiliza o conjunto de dados MNIST, que tem uma resolução de 28x28x1, codifica-o numa representação 7x7x1 utilizando convolução e agrupamento e descodifica a resolução original. O critério de formação é um erro de raiz-médio-quadrado (RMSE). A figura acima mostra visualizações da imagem original, a imagem codificada e a imagem descodificada para as primeiras cinco imagens do conjunto de testes do MNIST.
Configuração
Para executar o exemplo, precisa do conjunto de dados do MNIST. Pode obter os dados executando o seguinte comando a Examples\Image\DataSets\MNIST partir da pasta:
python install_mnist.py
Executar o exemplo
O exemplo encontra-se na Examples\Image\GettingStarted pasta. Para executar este exemplo, utilize o seguinte comando para executar a versão Python (a partir de um ambiente Python CNTK):
python 07_Deconvolution_PY.py
ou este comando para a versão BrainScript:
cntk configFile=07_Deconvolution_BS.cntk
Os valores de RMSE para treino e teste são 0.225 e 0.223, respectivamente. Para visualizar as imagens codificadas e descodificada executam o seguinte comando:
python 07_Deconvolution_Visualizer.py
Definido use_brain_script_model=True para o BrainScript modelo e False para o Python modelo.
As visualizações serão armazenadas na Output pasta em conjunto Examples\Image\GettingStarted com uma representação de texto do codificador e da saída do descodificador.
Detalhes técnicos
Abaixo está a definição modelo para o codificador de imagem simples em BrainScript (para o ficheiro completo config ver Image\GettingStarted\07_Deconvolution_BS.cntk)
cMap = 1
model = inputFeatures => {
conv1 = ConvolutionalLayer {cMap, (5:5), pad = true, activation=ReLU}(inputFeatures)
pool1 = MaxPoolingLayer {(4:4), stride=(4:4)}(conv1)
unpool1 = MaxUnpoolingLayer {(4:4), stride=(4:4)}(pool1, conv1)
deconv1 = DeconvLayer {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0), bias=false}(unpool1)
}.deconv1
A definição modelo correspondente em 07_Deconvolution_PY.py é
cMap = 1
conv1 = cntk.layers.Convolution ((5,5), cMap, pad=True, activation=cntk.ops.relu)(scaled_input)
pool1 = cntk.layers.MaxPooling ((4,4), (4,4))(conv1)
unpool1 = cntk.layers.MaxUnpooling ((4,4), (4,4))(pool1, conv1)
z = cntk.layers.Deconvolution((5,5), num_channels, cMap, lower_pad=(0,2,2), upper_pad=(0,2,2), bias=False, init=cntk.glorot_uniform(0.001))(unpool1)
Descrevemos a versão BrainScript aqui, a versão Python é análoga. O modelo aplica primeiro um ConvolutionalLayer com uma profundidade das características de entrada seguida de cMap=1 uma ativação ReLU e utiliza um MaxPoolingLayer com uma forma de filtro e passo de (4:4). Isto resulta num tensor codificado de tamanho 7x7x1. Em seguida, utiliza um MaxUnpoolingLayer e um DeconvLayer com as formas de filtro correspondentes para descodificá-lo de volta à resolução original.
A parte descodificadora comprime os números originais 784 (28x28) para 49 (7x7), um fator de 16. A utilização de apenas uma profundidade para o ConvolutionalLayer tem a vantagem de 1 que os resultados do codificador podem ser visualizados de forma significativa (ver figura no topo desta página). Pode-se aumentar o número de filtros convolucionais, por exemplo, para cMap=3 ter menos compressão e, esperemos, melhores resultados de descodição. Neste exemplo, o RMSE para treinos e testes é reduzido a 0.196. Outra forma de ter menos compressão é usar uma forma de filtro menor e passo para a camada de piscina. A utilização (2:2) tanto para a piscina como para desajustar produz um tensor codificado de tamanho 14x14x1 e reduz o RMSE neste exemplo para 0.136 treino e 0.131 teste. A figura abaixo mostra a visualização da imagem original e a imagem descodificada para as cinco primeiras imagens do conjunto de testes MNIST para as três definições discutidas.
Desconvolução e Unpooling
Vamos olhar um pouco mais de perto para o MaxUnpoolingLayer e o DeconvLayer.
MaxUnpoolingLayer {(4:4), stride=(4:4)}(pool1, conv1)
O MaxPoolingLayer requer duas entradas, que são a saída da camada de agrupamento correspondente (pool1 neste caso) e a entrada da camada de agrupamento correspondente (conv1 neste caso). conv1é necessário em CNTK determinar o alvo da operação Unpooling, uma vez CNTK não armazena as chamadas variáveis switch (consulte aqui para mais detalhes).
DeconvLayer {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0)}
O primeiro parâmetro do DeconvLayer é a profundidade do volume de saída, o segundo é a forma do núcleo (largura:altura) e o terceiro é a profundidade do volume de entrada. Os parâmetros de enchimento devem ser definidos de acordo com a forma do núcleo para alcançar a largura e altura desejadas do tensor de saída (28x28 neste caso). Para mais detalhes no DeconvLayer consulte a página de Referência da Camada.
Codificação de vários camadas de automóveis
Você pode empilhar mais camadas de Conv/Deconv e Pool/Unpool para um codificador de automóveis mais complexo. Segue-se um exemplo com duas camadas de cada tipo em 07_Deconvolution_BS.cntk que pode utilizar (basta substituir a modelo no ficheiro):
inputDim = 1
cMap1 = 5
cMap2 = 1
model = inputFeatures => {
conv_A = ConvolutionalLayer {cMap1, (5:5), pad = true, activation=ReLU}(inputFeatures)
pool_A = MaxPoolingLayer {(2:2), stride=(2:2)}(conv_A)
conv_B = ConvolutionalLayer {cMap2, (5:5), pad = true, activation=ReLU}(pool_A)
pool_B = MaxPoolingLayer {(2:2), stride=(2:2)}(conv_B)
unpool_B = MaxUnpoolingLayer {(2:2), stride=(2:2)}(pool_B, conv_B)
deconv_B = DeconvLayer {cMap1, (5:5), cMap2, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_B)
unpool_A = MaxUnpoolingLayer {(2:2), stride=(2:2)}(deconv_B, conv_A)
deconv_A = DeconvLayer {inputDim, (5:5), cMap1, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_A)
}.deconv_A
Para visualizar os resultados, tem de ser substituído z.pool1z.pool_B07_Deconvolution_Visualizer.py antes de o executar para endereçar o nome correto do nó para a saída do codificante. Para investigar todos os nomes de nó no modelo simplesmente descomprometê-lo print_all_node_names(model_file) no Python script.

