卷积神经网络(基础篇)
說(shuō)明 0、前一部分叫做Feature Extraction,后一部分叫做classification
? ? ? ? 1、每一個(gè)卷積核它的通道數(shù)量要求和輸入通道是一樣的。這種卷積核的總數(shù)有多少個(gè)和你輸出通道的數(shù)量是一樣的。
? ? ? ? 2、卷積(convolution)后,C(Channels)變,W(width)和H(Height)可變可不變,取決于是否padding。subsampling(或pooling)后,C不變,W和H變。
? ? ? ? 3、卷積層:保留圖像的空間信息。
? ? ? ?4、卷積層要求輸入輸出是四維張量(B,C,W,H),全連接層的輸入與輸出都是二維張量(B,Input_feature)。
? ? ? ? ? ? ?傳送門 PyTorch的nn.Linear()詳解
? ? ? 5、卷積(線性變換),激活函數(shù)(非線性變換),池化;這個(gè)過(guò)程若干次后,view打平,進(jìn)入全連接層~
?
?
?
1. 卷積操作
import torch # 定義輸入、輸出通道 in_channels, out_channels = 5, 10 # 定義圖像尺寸 width, height = 100, 100 # 定義卷積核的大小,下式表示大小為3*3的正方形,同時(shí),卷積核的通道數(shù)與輸入圖像的通道數(shù)一致,均為5 kernel_size = 3 # 定義一次輸入圖像的數(shù)量 batch_size = 1input = torch.randn(batch_size,in_channels,width,height)# out_channels 決定了卷積核的數(shù)量, 即一共有10個(gè)3*3*5的卷積核 conv_layer = torch.nn.Conv2d(in_channels,out_channels,kernel_size=kernel_size) output = conv_layer(input)print(input.shape) print(output.shape) print(conv_layer.weight.shape)輸出:
torch.Size([1, 5, 100, 100]) torch.Size([1, 10, 98, 98]) torch.Size([10, 5, 3, 3])有時(shí),我們希望獲得與原圖像相同大小的卷積后的圖像,這時(shí)需要屬性padding,默認(rèn)為0
conv_layer_with_padding = torch.nn.Conv2d(in_channels,out_channels,padding=1,kernel_size = kernel_size) output_with_padding = conv_layer_with_padding(input) print(output_with_padding.shape)輸出:
torch.Size([1, 10, 100, 100])還有時(shí),我們希望再次降低網(wǎng)絡(luò)的大小,以降低運(yùn)算量。此時(shí)引入卷積核移動(dòng)步長(zhǎng)stride的概念,默認(rèn)為1
conv_layer_with_stride = torch.nn.Conv2d(in_channels,out_channels,stride=2,kernel_size=kernel_size)output_with_stride = conv_layer_with_stride(input) print(output_with_stride.shape)輸出:
torch.Size([1, 10, 49, 49])2. 下采樣
下采樣與卷積無(wú)本質(zhì)區(qū)別,不同的在于目的。下采樣的目的是將數(shù)據(jù)維度再次減少。
最常用的下采樣手段是Max Pooling 最大池化。
輸出:
tensor([[[[4., 8.],[9., 8.]]]])3. 卷積神經(jīng)基礎(chǔ)代碼
?
代碼說(shuō)明:
1、torch.nn.Conv2d(1,10,kernel_size=3,stride=2,bias=False)
?1是指輸入的Channel,灰色圖像是1維的;10是指輸出的Channel,也可以說(shuō)第一個(gè)卷積層需要10個(gè)卷積核;kernel_size=3,卷積核大小是3x3;stride=2進(jìn)行卷積運(yùn)算時(shí)的步長(zhǎng),默認(rèn)為1;bias=False卷積運(yùn)算是否需要偏置bias,默認(rèn)為False。padding = 0,卷積操作是否補(bǔ)0。
2、self.fc = torch.nn.Linear(320, 10),這個(gè)320獲取的方式,可以通過(guò)x = x.view(batch_size, -1)
# print(x.shape)可得到(64,320),64指的是batch,320就是指要進(jìn)行全連接操作時(shí),輸入的特征維度。
import torch from torchvision import transforms from torchvision import datasets from torch.utils.data import DataLoader import torch.nn.functional as F import torch.optim as optim import matplotlib.pyplot as plt# prepare datasetbatch_size = 64 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True,download=True, transform=transform) train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size) test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False,download=True, transform=transform) test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)# design model using classclass Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)self.pooling = torch.nn.MaxPool2d(2)self.fc = torch.nn.Linear(320, 10)def forward(self, x):# flatten data from (n,1,28,28) to (n, 784)batch_size = x.size(0)x = F.relu(self.pooling(self.conv1(x)))x = F.relu(self.pooling(self.conv2(x)))x = x.view(batch_size, -1) # -1 此處自動(dòng)算出的是320# print("x.shape",x.shape)x = self.fc(x)return xmodel = Net() device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device)# construct loss and optimizer criterion = torch.nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)# training cycle forward, backward, update def train(epoch):running_loss = 0.0for batch_idx, data in enumerate(train_loader, 0):inputs, target = datainputs, target = inputs.to(device), target.to(device)optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % 300 == 299:print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))running_loss = 0.0def test():correct = 0total = 0with torch.no_grad():for data in test_loader:images, labels = dataimages, labels = images.to(device), labels.to(device)outputs = model(images)_, predicted = torch.max(outputs.data, dim=1)total += labels.size(0)correct += (predicted == labels).sum().item()print('accuracy on test set: %d %% ' % (100 * correct / total))return correct / totalif __name__ == '__main__':epoch_list = []acc_list = []for epoch in range(10):train(epoch)acc = test()epoch_list.append(epoch)acc_list.append(acc)plt.plot(epoch_list, acc_list)plt.ylabel('accuracy')plt.xlabel('epoch')plt.show()總結(jié)
以上是生活随笔為你收集整理的卷积神经网络(基础篇)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 读书笔记——信息的表示与处理
- 下一篇: java jstack 工具_java命