9_Basic CNN

传送门: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()
 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值