赞
踩
机器学习笔记——梯度下降、反向传播
机器学习笔记——用pytorch实现线性回归
机器学习笔记——pytorch实现逻辑斯蒂回归Logistic regression
机器学习笔记——多层线性(回归)模型 Multilevel (Linear Regression) Model
深度学习笔记——pytorch构造数据集 Dataset and Dataloader
深度学习笔记——pytorch解决多分类问题 Multi-Class Classification
深度学习笔记——pytorch实现卷积神经网络CNN
深度学习笔记——卷积神经网络CNN进阶
深度学习笔记——循环神经网络 RNN
深度学习笔记——pytorch实现GRU
在全连接神经网络下,由于我们直接将数据压缩,所以会损失数据的空间关系等信息。于是卷积神经网络先提取数据的特征,保留数据一部分的位置信息,进行计算、再提取特征、再计算…最后通过全连接层进行处理输出结果。
假设有这样一张图片,其通道数为channel=3,宽width,高heigh。指定一个c,w,h的patch,通过patch遍历这个图像。
例如,这里有一个5✖5的单通道(单层)图像;patch为单通道,大小为3✖3;卷积核kernel为单通道,大小为3✖3。patch从图像的左上角遍历图像,patch覆盖的图像部分与卷积核kernel做数乘运算。注意:不是做矩阵相乘运算,而是对应的位置的数相乘,最后相加。
例如,第一次patch与卷积核kernel数乘得到211,填入到输出矩阵中,而后patch向右移一格,新的patch矩阵又与卷积核kernel做数乘运算,得到295,填入到输出矩阵中。
依次类推,最后得到我们的输出矩阵
我们已经知道了单通道(单层)图像如何进行卷积计算
以三通道(三层)的图像为例,仍旧选取3✖3的patch,每一个通道的图像分别对应一个卷积核kernel,按照上述的方式进行卷积,分别得到三个输出矩阵,最后将三个矩阵相加就得到了最终的输出矩阵。
三通道(三层)的图像,通过三通道(三层)的卷积核,得到一个单通道(单层)的矩阵。
n个通道(n层)的图像,可以通过n个通道(n层)的卷积核,可以得到一个单通道(单层)的输出矩阵。
那么如何得到一个多通道(多层)的输出矩阵呢?
一张n个通道的图像,可以通过一个n通道的卷积核得到一个单通道的输出矩阵,那么用这张图像通过m个n通道的卷积核,就可以得到m个单通道的输出矩阵。
这要求我们的卷积核是一个四维的张量,m代表个数,n代表通道数,以及宽度和长度。
#!/user/bin/env python3 # -*- coding: utf-8 -*- import torch in_channels, out_channels = 5, 10 # 输入通道数,输出通道数 width, height = 100, 100 # 输入矩阵的宽高 batch_size = 1 kernel_size = 3 # 卷积核的大小----3*3的矩阵 # 用torch产生一个随机矩阵,当做输入 input = torch.randn(batch_size, in_channels, width, height) # 卷积层 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) # 卷积核矩阵的形状``` # 二、使用步骤 ## 1.引入库 >代码如下(示例): ```c import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import warnings warnings.filterwarnings('ignore') import ssl ssl._create_default_https_context = ssl._create_unverified_context
输出结果:
输出结果解析:
输入矩阵的batch_size=1,通道数c=5,宽width=100,高height=100.
输出矩阵的batch_size=1,通道数c=10,宽width=98,高height=98.因为卷积核矩阵是3*3的,所以宽和高会减少2.
卷积核矩阵的个数m=10,通道数c=5,宽width=3,高height=3.
卷积核矩阵的通道数必须和输入矩阵的通道数相同,卷积核矩阵的个数决定输出矩阵的通道数。
如果我们想要输出矩阵的大小和输入的图像矩阵大小相同,可以在外围填充0.
上述图片的实现代码:
import torch input = [3, 4, 6, 5, 7, 2, 4, 6, 8, 2, 1, 6, 7, 8, 4, 9, 7, 4, 6, 2, 3, 7, 5, 4, 1] # 将输入转为张量,并转为矩阵 input = torch.Tensor(input).view(1, 1, 5, 5) # batch_size,channel,width,height # 卷积层 conv_layer = torch.nn.Conv2d(1, 1, kernel_size=3, padding=1, bias=False) # 输入通道=1,输出通道=1,卷积核矩阵=3*3,padding=1 即给输入矩阵填充一圈0,不要偏置量 # 自定义卷积矩阵kernel kernel = torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9]).view(1, 1, 3, 3) # 个数为1,输入矩阵通道为1,width=3,height=3 conv_layer.weight.data = kernel.data # 计算 output = conv_layer(input) # 输出 print(output) print(output.shape)
运行结果:
如果我们设置步长stride=2,那么patch矩阵每次会向右移动两格,得到一个更小的输出矩阵
import torch input = [3, 4, 6, 5, 7, 2, 4, 6, 8, 2, 1, 6, 7, 8, 4, 9, 7, 4, 6, 2, 3, 7, 5, 4, 1] # 将输入转为张量,并转为矩阵 input = torch.Tensor(input).view(1, 1, 5, 5) # batch_size,channel,width,height # 卷积层 conv_layer = torch.nn.Conv2d(1, 1, kernel_size=3, stride=2, bias=False) # 输入通道=1,输出通道=1,卷积核矩阵=3*3,padding=1 即给输入矩阵填充一圈0,不要偏置量 # 自定义卷积矩阵kernel kernel = torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9]).view(1, 1, 3, 3) # 个数为1,输入矩阵通道为1,width=3,height=3 conv_layer.weight.data = kernel.data # 计算 output = conv_layer(input) # 输出 print(output) print(output.shape)
运行结果:
如图,我们选择一个22的maxpooling,它会将输入矩阵分成若干个22大小的矩阵,每个矩阵取其中最大的数,形成新的矩阵。
代码:
import torch
input = [3, 4, 6, 5,
2, 4, 6, 8,
1, 6, 7, 8,
9, 7, 4, 6]
# 将输入转为张量,再转为指定大小的矩阵
input = torch.Tensor(input).view(1, 1, 4, 4) # batch_size=1,c=1,width=1,h=1
# 池化层
maxpooling_layer = torch.nn.MaxPool2d(kernel_size=2)
# 计算
output = maxpooling_layer(input)
# 输出
print(output)
运行结果:
import torch from torchvision import datasets from torchvision import transforms from torch.utils.data import DataLoader import matplotlib.pyplot as plt batch_size = 64 # 图像预处理 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) # 数据集 train_data = datasets.MNIST(root='mnist/', train=True, download=True, transform=transform) test_data = datasets.MNIST(root='mnist/', train=False, download=True, transform=transform) # 数据装载 train_batch = DataLoader(train_data, batch_size=batch_size, shuffle=True) test_batch = DataLoader(test_data, batch_size=batch_size, shuffle=False) # 模型 class CNNModel(torch.nn.Module): def __init__(self): super(CNNModel, self).__init__() self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5) # 卷积层1 self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5) # 卷积层2 self.pooling = torch.nn.MaxPool2d(2) # 池化层 self.activate = torch.nn.ReLU() # 激活函数 self.linear = torch.nn.Linear(320, 10) # 线性层 def forward(self, x): batch_size = x.size(0) x = self.activate(self.pooling(self.conv1(x))) x = self.activate(self.pooling(self.conv2(x))) x = x.view(batch_size, -1) # 将矩阵变形,变成(batch_size,320)形状 x = self.linear(x) return x model = CNNModel() # 让gpu进行运算 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model.to(device) # 将模型数据传给gpu # 损失函数 criterion = torch.nn.CrossEntropyLoss() # 优化器 optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.5) # 可视化数据 epoch_list = [] accuracy_list = [] # 训练 def model_train(epoch): running_loss = 0.0 for batch_idx, data in enumerate(train_batch, 1): inputs, targets = data inputs, targets = inputs.to(device), targets.to(device) # 将输入数据传入gpu optimizer.zero_grad() # forward pred = model(inputs) loss = criterion(pred, targets) # backward loss.backward() # update optimizer.step() # 输出 running_loss += loss.item() print('epoch:%d,loss=%.4f' % (epoch, running_loss / batch_idx)) running_loss = 0.0 # 测试 def model_test(): correct = 0 total = 0 with torch.no_grad(): for (inputs, targets) in test_batch: inputs, targets = inputs.to(device), targets.to(device) pred = model(inputs) _, predicted = torch.max(pred.data, dim=1) total += targets.size(0) correct += (predicted == targets).sum().item() print('Accuracy on test set:%d %%' % (100 * correct / total)) return correct / total if __name__ == '__main__': for epoch in range(10): epoch_list.append(epoch) model_train(epoch) accuracy = model_test() accuracy_list.append(accuracy) # 绘图 plt.plot(epoch_list, accuracy_list) plt.xlabel('epoch') plt.ylabel('accuracy') plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。