黃山搜索引擎優(yōu)化dz論壇seo
大家好,我是微學(xué)AI,今天給大家介紹一下計(jì)算機(jī)視覺(jué)的應(yīng)用11-基于pytorch框架的卷積神經(jīng)網(wǎng)絡(luò)與注意力機(jī)制對(duì)街道房屋號(hào)碼的識(shí)別應(yīng)用,本文我們借助PyTorch,快速構(gòu)建和訓(xùn)練卷積神經(jīng)網(wǎng)絡(luò)(CNN)等模型,以實(shí)現(xiàn)街道房屋號(hào)碼的準(zhǔn)確識(shí)別。引入并注意力機(jī)制,它是一種模仿人類(lèi)視覺(jué)注意機(jī)制的方法,在圖像處理任務(wù)中具有廣泛應(yīng)用。通過(guò)引入注意力機(jī)制,模型可以自動(dòng)關(guān)注圖像中與房屋號(hào)碼相關(guān)的區(qū)域,提高識(shí)別的準(zhǔn)確性和魯棒性。
一、項(xiàng)目介紹
街道房屋號(hào)碼識(shí)別是計(jì)算機(jī)視覺(jué)中的一個(gè)重要任務(wù),通過(guò)對(duì)街道房屋號(hào)碼的自動(dòng)識(shí)別,可以對(duì)街道圖像進(jìn)行更好的理解和分析。本文將介紹如何使用PyTorch框架和注意力機(jī)制,結(jié)合SVHN數(shù)據(jù)集,來(lái)實(shí)現(xiàn)街道房屋號(hào)碼的分類(lèi)識(shí)別。
二、SVHN數(shù)據(jù)集
SVHN(Street View House Numbers)是一個(gè)公開(kāi)的大規(guī)模街道數(shù)字圖像數(shù)據(jù)集。該數(shù)據(jù)集包含了從Google Street View中獲取的房屋門(mén)牌號(hào)碼圖像,可以用于訓(xùn)練和測(cè)試機(jī)器學(xué)習(xí)模型,以實(shí)現(xiàn)自動(dòng)識(shí)別街道房屋號(hào)碼的任務(wù)。
2.1 數(shù)據(jù)集下載和加載
首先,我們需要下載并加載SVHN數(shù)據(jù)集。在PyTorch中,我們可以使用torchvision庫(kù)中的datasets模塊來(lái)實(shí)現(xiàn)這一步。
數(shù)據(jù)集的下載與查看:
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()
數(shù)據(jù)集的加載,預(yù)處理,便于輸入模型訓(xùn)練:
import torch
from torchvision import datasets, transforms# 數(shù)據(jù)預(yù)處理
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))])# 下載并加載SVHN數(shù)據(jù)集
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)
三、卷積網(wǎng)絡(luò)搭建
使用PyTorch搭建卷積神經(jīng)網(wǎng)絡(luò)。卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network, CNN)是一種主要用于處理具有類(lèi)似網(wǎng)格結(jié)構(gòu)的數(shù)據(jù)的神經(jīng)網(wǎng)絡(luò),如圖像(2D網(wǎng)格的像素點(diǎn))或者文本(1D網(wǎng)格的單詞)。
3.1 網(wǎng)絡(luò)結(jié)構(gòu)定義
下面是一個(gè)基礎(chǔ)的卷積神經(jīng)網(wǎng)絡(luò)模型,包含兩個(gè)卷積層、兩個(gè)最大池化層和兩個(gè)全連接層。
from torch import nnclass 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)
四、加入注意力機(jī)制
注意力機(jī)制是一種能夠改進(jìn)模型性能的技術(shù)。在我們的模型中,我們將添加一個(gè)注意力層來(lái)幫助模型更好地專(zhuān)注于輸入圖像中的重要部分。
4.1 注意力層定義
我將實(shí)現(xiàn)基本的注意力層,這個(gè)層將會(huì)生成一個(gè)和輸入同樣大小的注意力圖,然后將輸入和這個(gè)注意力圖對(duì)應(yīng)元素相乘,以此來(lái)實(shí)現(xiàn)對(duì)輸入的加權(quán)。
注意力機(jī)制層的數(shù)學(xué)原理:
注意力機(jī)制的數(shù)學(xué)原理可以用以下公式表示:
給定輸入張量 x ∈ R b × c × h × w x \in \mathbb{R}^{b \times c \times h \times w} x∈Rb×c×h×w,其中 b b b 是批量大小, c c c 是通道數(shù), h h h 是高度, w w w 是寬度。注意力機(jī)制分為兩個(gè)階段:特征提取和特征加權(quán)。
1.特征提取階段:
首先,通過(guò)自適應(yīng)平均池化層(AdaptiveAvgPool2d)將輸入張量 x x x 在高度和寬度上進(jìn)行平均池化,得到形狀為 b × c × 1 × 1 b \times c \times 1 \times 1 b×c×1×1 的張量 y y y。這里使用自適應(yīng)平均池化是為了使得張量 y y y 在不同尺寸的輸入上也能產(chǎn)生相同的輸出。
2.特征加權(quán)階段:
接下來(lái),通過(guò)全連接層(Linear)和非線性激活函數(shù)ReLU對(duì)張量 y y y 進(jìn)行特征變換,減少通道數(shù),并保留重要特征。然后再通過(guò)另一個(gè)全連接層和Sigmoid激活函數(shù)得到權(quán)重張量 y ′ ∈ R b × c × 1 × 1 y' \in \mathbb{R}^{b \times c \times 1 \times 1} y′∈Rb×c×1×1,表示每個(gè)通道的權(quán)重值。這里的權(quán)重值在0到1之間,用于控制每個(gè)通道在后續(xù)的計(jì)算中所占的比重。將權(quán)重張量 y ′ y' y′ 擴(kuò)展成與輸入張量 x x x 相同的形狀,并將其與輸入張量相乘,得到經(jīng)過(guò)注意力加權(quán)的特征張量。這樣就實(shí)現(xiàn)了對(duì)輸入張量的自適應(yīng)特征加權(quán)。
數(shù)學(xué)表示為:
y = AdaptiveAvgPool2d ( x ) y ′ = Sigmoid ( Linear ( ReLU ( Linear ( y ) ) ) ) output = x ⊙ y ′ y = \text{AdaptiveAvgPool2d}(x) \\ y' = \text{Sigmoid}(\text{Linear}(\text{ReLU}(\text{Linear}(y)))) \\ \text{output} = x \odot y' y=AdaptiveAvgPool2d(x)y′=Sigmoid(Linear(ReLU(Linear(y))))output=x⊙y′
其中 ⊙ \odot ⊙ 表示按元素相乘操作。
注意力機(jī)制層的搭建代碼:
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 在網(wǎng)絡(luò)中加入注意力層
我們將注意力層加入到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)
五、模型訓(xùn)練與測(cè)試
接下來(lái),我們將進(jìn)行模型的訓(xùn)練和測(cè)試。
5.1 模型訓(xùn)練
import torch.optim as optimmodel = 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 timesrunning_loss = 0.0for i, data in enumerate(trainloader, 0):# get the inputs; data is a list of [inputs, labels]inputs, labels = data# zero the parameter gradientsoptimizer.zero_grad()# forward + backward + optimizeoutputs = model(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# print statisticsrunning_loss += loss.item()if i % 20 == 0: # print every 2000 mini-batchesprint('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 2000))running_loss = 0.0print('Finished Training')
5.2 模型測(cè)試
correct = 0
total = 0
with torch.no_grad():for data in testloader:images, labels = dataoutputs = 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))
六、結(jié)論
這篇文章就像是一張奇妙的地圖,引領(lǐng)你進(jìn)入計(jì)算機(jī)視覺(jué)任務(wù)的神奇世界。在這個(gè)世界里,你將與PyTorch和注意力機(jī)制這兩位強(qiáng)大的伙伴結(jié)伴前行,共同探索街道房屋號(hào)碼識(shí)別的奧秘。
想象一下,你置身于繁忙的街道上,滿目琳瑯的房屋號(hào)碼挑戰(zhàn)著你的視力。而你卻擁有了一種神奇的眼力,能輕松識(shí)別出每一個(gè)號(hào)碼。這種超凡能力正是計(jì)算機(jī)視覺(jué)任務(wù)的魔法所在。
我們要攜手PyTorch這位強(qiáng)大的工具,它如同一把巧妙的魔法棒,能幫助我們構(gòu)建強(qiáng)大的神經(jīng)網(wǎng)絡(luò)模型。通過(guò)PyTorch,我們可以靈活地定義模型的結(jié)構(gòu),設(shè)置各種參數(shù),并進(jìn)行高效的訓(xùn)練和推理。
我們遇到了注意力機(jī)制,就像是一盞明亮的燈塔,照亮了我們前進(jìn)的方向。注意力機(jī)制能夠使神經(jīng)網(wǎng)絡(luò)集中注意力于圖像中的重要區(qū)域,從而提高識(shí)別的準(zhǔn)確性。利用這種機(jī)制,我們可以讓模型更加聰明地注重街道房屋號(hào)碼所在的位置和細(xì)節(jié),從而更好地進(jìn)行識(shí)別。而SVHN數(shù)據(jù)集則是我們探險(xiǎn)的指南,其中包含了大量真實(shí)世界中的街道房屋號(hào)碼圖像。通過(guò)導(dǎo)入這些數(shù)據(jù),我們可以讓模型從中學(xué)習(xí)并提高自己的識(shí)別能力。這些圖像將帶領(lǐng)我們穿越城市的角落,感受不同場(chǎng)景下的挑戰(zhàn)和變化。通過(guò)這篇文章,我們不僅可以更深入地理解計(jì)算機(jī)視覺(jué)任務(wù)的本質(zhì),還能獲得啟發(fā)。就像是一次奇妙的冒險(xiǎn),我們將學(xué)會(huì)如何使用PyTorch和注意力機(jī)制來(lái)實(shí)現(xiàn)街道房屋號(hào)碼的識(shí)別任務(wù)。讓我們一起跟隨這個(gè)引人入勝的旅程,開(kāi)拓視野,追尋新的可能性吧!