传送门:10.卷积神经网络(基础篇)_哔哩哔哩_bilibili
下面是一个demo介绍卷积神经网络中各个量的意义
import torch in_channels, out_channels= 5, 10 width,height = 100, 100 kernel_size = 3 #3*3的卷积核 batch_size = 1 input = torch.randn(batch_size, in_channels, width, height) #生成了一个形状为(1, 5, 100, 100)的张量,张量中每一个数都是随机数。 #这些随机数是从标准正态分布中抽取的,具有均值为0和标准差为1的性质。 #这种随机初始化的输入通常用于神经网络的权重初始化或数据的增强等任务中。 conv_layer = torch.nn.Conv2d(in_channels, out_channels, padding = 0, stride = 1, bias = False, kernel_size=kernel_size) #padding "填料" #在input外面添加 n 圈 0 ,然后得到的output根原来一样大小 #添加几圈 0 就是让padding的值为多少 #stride "步长" #每一次卷积核移动的距离 # bias 偏置量,默认为false output = conv_layer(input) print(input.shape) print(output.shape) print(conv_layer.weight.shape)
demo,池化:
# subsampling 下采样 # MaxPooling 最大池化层,默认一个stride为2,然后在每一组里找最大值 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) maxpooling_layer = torch.nn.MaxPool2d(kernel_size=2) output = maxpooling_layer(input) print(output)
ReLU的介绍:
在卷积神经网络中,ReLU(修正线性单元)层起着非常重要的作用。其主要功能是对卷积层滤波器生成的图像进行非线性转换,以引入所需的特征。
ReLU层通过将负值映射到零,而保持正数值不变,可以加速网络的训练过程,提高训练效率。这种操作也被称作激活,因为只有被激活的特征才能传递到下一层。
此外,ReLU层还有助于减轻梯度消失的问题。在神经网络中,梯度以指数方式在层中消失,可能导致网络底层的训练速度非常慢。
而ReLU层对输入内容的所有值都应用了函数f(x) = max(0, x),因此,所有的负激活值都会被置为零,从而避免了梯度消失的问题。
ReLU层运用了ReLU函数,它是一种简单的非线性函数,用于将负值映射到零,而保持正数值不变。在神经网络中,ReLU函数对输入内容的所有值都应用了函数f(x) = max(0, x)。
ReLU函数的优点包括使训练快速收敛,解决了梯度弥散问题,以及通过稀疏性提高了网络的性能。其缺点在于,在输入小于0的时候,即使有很大的梯度传播过来也会戛然而止。
在克服ReLU函数的缺点方面,一种改进是Leaky ReLU函数,它在输入x小于0时设定了一个较小的梯度值,而非0,以避免完全抑制负数梯度。
构建的网络如下;
代码如下:
# 我们在写算法之前,要先画出一层一层的图,看看怎么变换的 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 # 准备数据集 batch_size = 64 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) train_dataset = datasets.MNIST(root=r'D:\set', train=True, download=True, transform=transform) train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size) test_dataset = datasets.MNIST(root=r'D:\set', train=False, download=True, transform=transform) test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size) class Net(torch.nn.Module): def __init__(self): super(Net,self).__init__() self.conv1 = torch.nn.Conv2d(1,10,kernel_size = 5) # input output 卷积核大小 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 = self.pooling(F.relu(self.conv1(x))) x = self.pooling(F.relu(self.conv2(x))) x = x.view(batch_size, -1) # flatten x = self.fc(x) # 最后一层不做激活 return x model = Net() # 把模型迁移到GPU device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 我只有一块cuda显卡 #print(torch.cuda.is_available()) # 检测一下GPU在不在 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.0 for batch_idx, data in enumerate(train_loader, 0): inputs, target = data inputs, target = inputs.to(device), target.to(device) # 迁移到GPU 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.0 def test(): correct = 0 total = 0 with torch.no_grad(): for data in test_loader: images, labels = data images, labels = images.to(device), labels.to(device) # 迁移到GPU 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/total if __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()