卷积神经网络CNN

卷积神经网络

CNN的结构

图像 → \rightarrow 卷积层 → \rightarrow 池化层 → \rightarrow 全连接层 → \rightarrow 输出

卷积层

卷积:通过对图像进行卷积运算,对图像的某个特诊进行选择性地增强或者减弱。

卷积层中使用多个过滤器对输入图像的特征进行侦测。图像的值对应的是该点的颜色。

通道数:在一般的图像数据中,每个颜色都包含RGB三种颜色。一副图像的张数称为通道数。过滤器与输入图像有相同数量的通道。

偏置:每个过滤器都对应一个偏置。

池化层

池化:池化层负责将图像的各个区域进行划分,并将各个区域的代表特征抽取出来,重新排列组合成一副新图像。

每个区域的最大值被作为代表此区域的值。这种池化的方法被称为最大池化。

全连接层

全连接层是指普通的神经网络中所使用的网络层。

卷积层和池化层的输出被传递到全连接层的输入时,图像被转化成平坦的向量。

填充

在卷积层和池化层中,将输入的图像包围在中心进行设置的处理方法被称为填充。

经过填充处理之后,图像的尺寸就变大了,填充的目的:确保经过卷积处理的图像大小能保持不变。卷积运算的特征决定了对图像边缘的卷积运算次数比较少,而经过填充后的边缘数据能够更多地参与卷积运算,因此进行填充能够更多地获取图像边缘的特征。

步长

步长:在卷积运算中,步长指过滤器每次移动的间隔距离。(步长一般设置为1)

输入图像的尺寸 I h × I w I_h×I_w Ih×Iw,过滤器尺寸为 F h × F w F_h×F_w Fh×Fw,填充的幅度为 D D D,步长大小为 S S S,则得到的输出图像的高度为 O h O_h Oh O w O_w Ow

O h = I h − F h + 2 D S + 1 O_h=\frac{I_h-F_h+2D}{S}+1 Oh=SIhFh+2D+1

O w = I w − F w + 2 D S + 1 O_w=\frac{I_w-F_w+2D}{S}+1 Ow=SIwFw+2D+1

CNN的学习

网络层误差的传播参与学习的参数
卷积层过滤器,偏置
池化层
全连接层权重,偏置

卷积神经网络的实战

通过CNN分类识别Fashion—MNIST数据集。

库函数的引入

import numpy  as np
import pandas as pd
from sklearn.metrics import accuracy_score,confusion_matrix,classification_report
import matplotlib.pyplot as plt
import seaborn as sns
import copy
import time
import torch
import torch.nn as nn
from torch.optim import Adam
import torch.utils.data as Data
from torchvision import transforms
from torchvision.datasets import FashionMNIST

数据集的下载与展示

train_data = FashionMNIST(
    root = "./data/FashionMNIST",
    train = True,
    transform = transforms.ToTensor(),
    download = False
)
train_loader = Data.DataLoader(
    dataset = train_data,
    batch_size = 64,
    shuffle = False,
    num_workers = 2,
)
print("train_loader的batch数量为:",len(train_loader))  ## 938
for step,(b_x,b_y) in enumerate(train_loader):
    if step > 0:
        break
batch_x = b_x.squeeze().numpy()
batch_y = b_y.numpy()
class_label = train_data.classes
class_label[0] = "T_shirt"
plt.figure(figsize = (12,5))
for ii in np.arange(len(batch_y)):
    plt.subplot(4,16,ii+1)
    plt.imshow(batch_x[ii,:,:],cmap = plt.cm.gray)
    plt.title(class_label[batch_y[ii]],size = 9)
    plt.axis("off")
    plt.subplots_adjust(wspace = 0.05) # wspace 左右的距离

在这里插入图片描述

数据的预处理与神经网络的定义

test_data = FashionMNIST(
    root = "./data/FashionMNIST",
    train = False,
    download = False,
)
test_data_x = test_data.data.type(torch.FloatTensor)/255.0
test_data_x = torch.unsqueeze(test_data_x,dim = 1)
test_data_y = test_data.targets
print("test_data_x.shape:",test_data_x.shape) #test_data_x.shape: torch.Size([10000, 1, 28, 28])
print("test_data_y.shape:",test_data_y.shape) #test_data_y.shape: torch.Size([10000])
class MyConvet(nn.Module):
    def __init__(self):
        super(MyConvet,self).__init__()
        self.conv1 = nn.Sequential(
            nn.Conv2d(
                in_channels = 1,
                out_channels = 16,
                kernel_size = 3,
                stride = 1,
                padding = 1,
            ),
            nn.ReLU(),
            nn.AvgPool2d(
                kernel_size = 2,
                stride = 2,
            ),
        )
        self.conv2 = nn.Sequential(
            nn.Conv2d(16,32,3,1,0),
            nn.ReLU(),
            nn.AvgPool2d(2,2),
        )
        self.classifier = nn.Sequential(
            nn.Linear(32*6*6,256),
            nn.ReLU(),
            nn.Linear(256,128),
            nn.ReLU(),
            nn.Linear(128,10)
        )
    def forward(self,x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0),-1)
        output = self.classifier(x)
        return output

myconvet = MyConvet().to(device)
print(myconvet)

在这里插入图片描述

模型的训练

def train_model(model,traindataloader,train_rate,criterion,optimizer,num_epochs=25):
    batch_num = len(traindataloader)
    train_batch_num = round(batch_num * train_rate)   # round()返回四舍五入值
    best_model_wts = copy.deepcopy(model.state_dict())  
    #state_dict变量存放训练过程中需要学习的权重和偏执系数
    best_acc = 0.0
    train_loss_all = []
    train_acc_all =[]
    val_loss_all = []
    val_acc_all = []
    since = time.time()                                   #time.time() 返回当前时间的时间戳
    for epoch in range(num_epochs):
        print('Epoch{}/{}'.format(epoch+1,num_epochs + 1))
        print('-'*10)
        train_loss = 0.0
        train_corrects = 0
        train_num = 0
        val_loss = 0.0
        val_corrects = 0
        val_num = 0
        for step,(b_x,b_y)in enumerate(traindataloader):
            if step < train_batch_num:
                model.train()
                output = model(b_x)
                pre_lab = torch.argmax(output,1)
                loss = criterion(output, b_y)
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
                train_loss += loss.item() * b_x.size(0)
                train_corrects += torch.sum(pre_lab ==b_y.data)
                train_num += b_x.size(0)
            else:
                model.eval()
                output = model(b_x)
                pre_lab = torch.argmax(output,1)
                loss = criterion(output,b_y)
                val_loss += loss.item() * b_x.size(0)
                val_corrects += torch.sum(pre_lab ==b_y.data)
                val_num += b_x.size(0)
        train_loss_all.append(train_loss/train_num)
        train_acc_all.append(train_corrects.double().item()/train_num)
        val_loss_all.append(val_loss/val_num)
        val_acc_all.append(val_corrects.double().item()/val_num)
        print('{} Train Loss: {:.4f} Train Acc:{:.4f}'.format(epoch,train_loss_all[-1],train_acc_all[-1]))
        print('{} Val Loss: {:.4f} Val Acc: {:.4f}'.format(epoch,val_loss_all[-1],val_acc_all[-1]))
        if val_acc_all[-1] > best_acc:
            best_acc = val_acc_all[-1]
            best_model_wts = copy.deepcopy(model.state_dict())
        time_use = time.time() -since
        print("Train and val compelete in {:.0f}m {:.0f}s".format(time_use//60,time_use%60))
    model.load_state_dict(best_model_wts)
    train_process = pd.DataFrame(
        data={"epoch":range(num_epochs),
              "train_loss_all":train_loss_all,
              "val_loss_all":val_loss_all,
             "train_acc_all":train_acc_all,
             "val_acc_all":val_acc_all})
    return model,train_process
optimizer = torch.optim.Adam(myconvet.parameters(),lr = 0.0003)  # 优化器
criterion = nn.CrossEntropyLoss()                                # 损失函数
myconvet,train_process = train_model(myconvet,train_loader,0.8,criterion,optimizer,num_epochs=25)# 模型的训练

最终的结果与图像

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

love2study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值