Aplicação de Visão Computacional 11 - Aplicação de Rede Neural Convolucional e Mecanismo de Atenção Baseado na Estrutura Pytorch para Reconhecimento de Números de Ruas

Olá a todos, sou Weixue AI. Hoje apresentarei a vocês a aplicação de visão computacional 11 - a aplicação de rede neural convolucional e mecanismo de atenção baseado na estrutura pytorch para o reconhecimento de números de casas de rua. Neste artigo, usamos PyTorch para construir e treinar volumes rapidamente. Modelos como rede neural de produto (CNN) para obter identificação precisa de números de casas de rua. Introduzir um mecanismo de atenção, que é um método para imitar o mecanismo de atenção visual humana, que possui uma ampla gama de aplicações em tarefas de processamento de imagens. Ao introduzir um mecanismo de atenção, o modelo pode focar automaticamente na área da imagem que está relacionada com o número da casa, melhorando a precisão e robustez do reconhecimento.

1. Introdução do projeto

O reconhecimento do número das casas das ruas é uma tarefa importante na visão computacional. Através do reconhecimento automático dos números das casas das ruas, as imagens das ruas podem ser melhor compreendidas e analisadas. Este artigo irá apresentar como usar a estrutura PyTorch e o mecanismo de atenção, combinados com o conjunto de dados SVHN, para realizar a classificação e reconhecimento de números de casas de rua.

2. Conjunto de dados SVHN

SVHN (Street View House Numbers) é um conjunto de dados de imagens digitais de ruas em grande escala disponível publicamente. Este conjunto de dados contém imagens de números de casas obtidas do Google Street View, que podem ser usadas para treinar e testar modelos de aprendizado de máquina para reconhecer automaticamente números de casas de ruas.

2.1 Download e carregamento do conjunto de dados

Primeiro, precisamos baixar e carregar o conjunto de dados SVHN. No PyTorch, podemos usar o módulo de conjuntos de dados na biblioteca torchvision para realizar esta etapa.

Download e visualização do conjunto de dados:

train_dataset = datasets.SVHN(root='./data', split='train', download=True)

images = train_dataset.data[:10]  # shape: (10, 3, 32, 32)
labels = train_dataset.labels[:10]

images = np.transpose(images, (0, 2, 3, 1))

# Plot the images
fig, axs = plt.subplots(2, 5, figsize=(12, 6))
axs = axs.ravel()

for i in range(10):
    axs[i].imshow(images[i])
    axs[i].set_title(f"Label: {
      
      labels[i]}")
    axs[i].axis('off')

plt.tight_layout()
plt.show()

insira a descrição da imagem aqui

Carregamento de conjunto de dados, pré-processamento, fácil treinamento de modelo de entrada:

import torch
from torchvision import datasets, transforms

# 数据预处理
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))])

# 下载并加载SVHN数据集
trainset = datasets.SVHN(root='./data', split='train', download=True, transform=transform)
testset = datasets.SVHN(root='./data', split='test', download=True, transform=transform)

trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=True)

3. Construção de rede convolucional

Use PyTorch para construir uma rede neural convolucional. Rede Neural Convolucional (CNN) é uma rede neural usada principalmente para processar dados com uma estrutura semelhante a uma grade, como imagens (grade 2D de pixels) ou texto (grade 1D de palavras).

3.1 Definição de estrutura de rede

A seguir está um modelo básico de rede neural convolucional, que contém duas camadas convolucionais, duas camadas de pooling máximo e duas camadas totalmente conectadas.

from torch import nn

class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(3, 32, kernel_size=5, stride=1, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.layer2 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.drop_out = nn.Dropout()
        self.fc1 = nn.Linear(7 * 7 * 64, 1000)
        self.fc2 = nn.Linear(1000, 10)

    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.reshape(out.size(0), -1)
        out = self.drop_out(out)
        out = self.fc1(out)
        return self.fc2(out)

4. Adicione mecanismo de atenção

O mecanismo de atenção é uma técnica que pode melhorar o desempenho dos modelos. Em nosso modelo, adicionaremos uma camada de atenção para ajudar o modelo a focar melhor em partes importantes da imagem de entrada.

4.1 Definição da Camada de Atenção

Implementarei a camada de atenção básica, que gerará um mapa de atenção do mesmo tamanho da entrada e, em seguida, multiplicarei a entrada pelos elementos correspondentes do mapa de atenção para ponderar a entrada.

O princípio matemático da camada do mecanismo de atenção:
o princípio matemático do mecanismo de atenção pode ser expresso pela seguinte fórmula:

Dado um tensor de entrada x ∈ R b × c × h × wx \in \mathbb{R}^{b \times c \times h \times w}xRb × c × h × w ondebbb é o tamanho do lote,ccc é o número do canal,hhh é altura,www é a largura. O mecanismo de atenção é dividido em duas etapas: extração de recursos e ponderação de recursos.
1. Estágio de extração de recursos:xx
é passado pela camada de pooling médio adaptativo (AdaptiveAvgPool2d)x realiza agrupamento médio em altura e largura, resultando em uma forma deb × c × 1 × 1 b \times c \times 1 \times 1b×c×1×Tensoryy de 1você . O pooling médio adaptativo é usado aqui para fazer o tensoryyy também produz a mesma saída em entradas de tamanhos diferentes.
2. Estágio de ponderação de recursos:
Em seguida, através da camada totalmente conectada (Linear) e da função de ativação não linear ReLU para o tensoryyy realiza transformação de recursos, reduz o número de canais e preserva recursos importantes. Em seguida, passe outra camada totalmente conectada e a função de ativação Sigmóide para obter o tensor de pesoy ′ ∈ R b × c × 1 × 1 y' \in \mathbb{R}^{b \times c \times 1 \times 1}sim'Rb × c × 1 × 1 , representando o valor do peso de cada canal. O valor do peso aqui está entre 0 e 1, que é usado para controlar a proporção de cada canal em cálculos subsequentes. O tensor de pesoy 'y'sim' expande para o mesmo tensor de entradaxxmesma forma que x e multiplique-a pelo tensor de entrada para obter o tensor de recurso ponderado por atenção. Isso permite a ponderação adaptativa de recursos de tensores de entrada.

数学表示为:
y = AdaptiveAvgPool2d ( x ) y ′ = Sigmoid ( Linear ( ReLU ( Linear ( y ) ) ) ) saída = x ⊙ y ′ y = \text{AdaptiveAvgPool2d}(x) \\ y' = \text{ Sigmóide}(\text{Linear}(\text{ReLU}(\text{Linear}(y)))) \\ \text{saída} = x \odot y'sim=AdaptativoAvgPool2d ( x )sim'=Sigmóide ( Linear ( ReLU ( Linear ( y ))))saída=xsim'

onde ⊙ \odot significa operação de multiplicação elemento a elemento.

O código de construção da camada do mecanismo de atenção:

class AttentionLayer(nn.Module):
    def __init__(self, channel, reduction=16):
        super(AttentionLayer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(channel, channel// reduction, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(channel // reduction, channel, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        return x * y.expand_as(x)

4.2 Adicionando uma camada de atenção à rede

Adicionamos a camada de atenção ao modelo ConvNet:

class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(3, 32, kernel_size=5, stride=1, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2),
            AttentionLayer(32))
        self.layer2 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2),
            AttentionLayer(64))
        self.drop_out = nn.Dropout()
        self.fc1 = nn.Linear(8 * 8 * 64, 1000)
        self.fc2 = nn.Linear(1000, 10)

    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.reshape(out.size(0), -1)
        out = self.drop_out(out)
        out = self.fc1(out)
        return self.fc2(out)

5. Treinamento e teste de modelo

A seguir, treinaremos e testaremos o modelo.

5.1 Treinamento de Modelo

import torch.optim as optim

model = ConvNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

for epoch in range(10):  # loop over the dataset multiple times
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 20 == 0:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

5.2 Teste de modelo

correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))

6. Conclusão

Este artigo é como um mapa fantástico que leva você ao incrível mundo das tarefas de visão computacional. Neste mundo, você estará de mãos dadas com dois parceiros poderosos, PyTorch e o mecanismo de atenção, para explorar os mistérios do reconhecimento de números de casas nas ruas.

Imagine que você está em uma rua movimentada, com números de casas desafiando sua visão. Mas você tem uma visão mágica e pode identificar facilmente cada número. Essa habilidade extraordinária é a magia das tarefas de visão computacional.

Queremos trabalhar com PyTorch, uma ferramenta poderosa, que é como uma varinha mágica inteligente que pode nos ajudar a construir modelos de redes neurais poderosos. Com o PyTorch, podemos definir com flexibilidade a estrutura do modelo, definir vários parâmetros e realizar treinamento e inferência eficientes.

Encontramos o mecanismo de atenção, que é como um farol brilhante, iluminando a direção para onde estamos indo. O mecanismo de atenção permite que a rede neural se concentre em áreas importantes da imagem, melhorando assim a precisão do reconhecimento. Utilizando este mecanismo, podemos tornar o modelo mais inteligente para prestar atenção à localização e aos detalhes do número da rua, para melhor reconhecê-lo. O conjunto de dados SVHN é o nosso guia para a expedição, que contém um grande número de imagens de números de casas de ruas do mundo real. Ao importar esses dados, podemos deixar o modelo aprender com eles e melhorar sua capacidade de reconhecimento. Estas imagens nos levarão pelos recantos da cidade e sentiremos os desafios e mudanças em diferentes cenários. Através deste artigo, podemos não apenas obter uma compreensão mais profunda da natureza das tarefas de visão computacional, mas também nos inspirar. Como uma aventura fantástica, aprenderemos como usar o PyTorch e o mecanismo de atenção para realizar a tarefa de reconhecer números de casas de ruas. Vamos seguir juntos essa jornada fascinante, ampliar nossos horizontes e buscar novas possibilidades!

Acho que você gosta

Origin blog.csdn.net/weixin_42878111/article/details/132377671
Recomendado
Clasificación