街景字符编码识别-Task3:字符识别模型

街景字符编码识别-Task3:字符识别模型

3.1 学习目标

  • 学习CNN基础和原理
  • 使用Pytorch框架构建CNN模型,并完成训练

3.2 CNN简介

  • 卷积神经网络(简称CNN)是一类特殊的人工神经网络,是深度学习中重要的一个分支。CNN在很多领域都表现优异,精度和速度比传统计算学习算法高很多。特别是在计算机视觉领域,CNN是解决图像分类、图像检索、物体检测和语义分割的主流模型。

  • CNN每一层由众多的卷积核组成,每个卷积核对输入的像素进行卷积操作,得到下一次的输入。随着网络层的增加卷积核会逐渐扩大感受野,并缩减图像的尺寸。

  • CNN是一种层次模型,输入的是原始的像素数据。CNN通过卷积(convolution)、池化(pooling)、非线性激活函数(non-linear activation function)和全连接层(fully connected layer)构成。

  • 经典的LeNet模型结构如下:
    在这里插入图片描述

3.4 Pytorch构建CNN模型

本次重点学习如何用Pytorch搭建一个简单的CNN网络

  • 在Pytorch中构建CNN模型非常简单,只需要定义好模型的参数和正向传播即可,Pytorch会根据正向传播自动计算反向传播。
  • 下面将讲解如何搭建一个多输出的CNN网络
  • 注:卷积计算公式如下 N = (W − F + 2P )/S+1 (下取整)
  • w为原边长 F为卷积核大小 P为填充大小 S为步长 N为输出大小
import torch
torch.manual_seed(0)
torch.backends.cudnn.deterministic = False
torch.backends.cudnn.benchmark = True

import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torch.utils.data.dataset import Dataset

# 搭建网络
class SVHN_Model1(nn.Module):
    def __init__(self):
        super(SVHN_Model1, self).__init__()
# torch.nn.Sequential是一个Sequential容器,模块将按照构造函数中传递的顺序添加到模块中。优点是不用挨个给每一层起变量名,并且写forward也是很简单的事情,不用一层一层地去运算了。
#也可以构造一个空容器然后向里面添加网络
#self.layer1 = torch.nn.Sequential()
#self.layer1.add_module('conv1', torch.nn.Conv2d(3, 32, 3, 1, padding=1))//输入3维,输出32维,输出大小32*32
         #size(n,3,64,128)  输入
        self.cnn = nn.Sequential(
            nn.Conv2d(3, 16, kernel_size=(3, 3), stride=(2, 2)),#size(n,16,31,63)
            nn.ReLU(),  
            nn.MaxPool2d(2),#size(n,16,15,31)
            nn.Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2)),#size(n,32,7,15)
            nn.ReLU(), 
            nn.MaxPool2d(2),
        )#szie(n,32,3,7)
        #构建6个并列的全连接层,用于多输出
        self.fc1 = nn.Linear(32*3*7, 11)
        self.fc2 = nn.Linear(32*3*7, 11)
        self.fc3 = nn.Linear(32*3*7, 11)
        self.fc4 = nn.Linear(32*3*7, 11)
        self.fc5 = nn.Linear(32*3*7, 11)
        self.fc6 = nn.Linear(32*3*7, 11)
    
    def forward(self, img):        
        feat = self.cnn(img)
        feat = feat.view(feat.shape[0], -1)
        c1 = self.fc1(feat)
        c2 = self.fc2(feat)
        c3 = self.fc3(feat)
        c4 = self.fc4(feat)
        c5 = self.fc5(feat)
        c6 = self.fc6(feat)
        return c1, c2, c3, c4, c5, c6
#实例化对象    
model = SVHN_Model1()
  • 接下来是训练代码以及模型的保存和继续训练:
# 损失函数
criterion = nn.CrossEntropyLoss()
# 优化器
optimizer = torch.optim.Adam(model.parameters(), 0.005)

# 如果有保存的参数模型,则加载模型,并在其基础上继续训练
#log_dir = 'epoch10.pth'
#if os.path.exists(log_dir):
#    checkpoint = torch.load(log_dir)
#    model.load_state_dict(checkpoint['model'])
#    optimizer.load_state_dict(checkpoint['optimizer'])
#    start_epoch = checkpoint['epoch']
#   print('加载 epoch {} 成功!'.format(start_epoch))

#可视化训练损失
def show_curve(ys, title):
    x = np.array(range(len(ys)))
    y = np.array(ys)
    plt.plot(x, y, c='b')
    plt.axis()
    plt.title('{} curve'.format(title))
    plt.xlabel('epoch')
    plt.ylabel('{}'.format(title))
    plt.show()
# 迭代10个Epoch
for epoch in range(1, 11):
    print(epoch)
    total_loss = 0
    for i, (images, targets) in enumerate(train_loader):
        # targets = torch.LongTensor(targets)
        c0, c1, c2, c3, c4, c5 = model(images)
        targets = targets.long()
        loss = criterion(c0, targets[:, 0]) + \
               criterion(c1, targets[:, 1]) + \
               criterion(c2, targets[:, 2]) + \
               criterion(c3, targets[:, 3]) + \
               criterion(c4, targets[:, 4]) + \
               criterion(c5, targets[:, 5])
        loss /= 6
        optimizer.zero_grad()
        loss.backward()#向后传播
        optimizer.step()
        total_loss += loss.item()
        # loss_plot.append(loss.item())
        if (i + 1) % 100 == 0:
            print("Step [{}/{}] Train Loss: {:.4f}"
                  .format(i + 1, len(train_loader), loss.item()))
    print('loss':total_loss/len(train_loader))
    total_list.append(total_loss/len(train_loader))
    #模型参数的保存
    state = {'model': model.state_dict(), 'optimizer': optimizer.state_dict(), 'epoch': epoch}
    torch.save(state, './epoch{}.pth'.format(epoch))
show_curve(total_list, 'train loss')

Task2中封装好的数据训练10轮,结果如下:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
天池是一个著名的数据科学竞赛平台,而datawhale是一家致力于数据科学教育和社群建设的组织。街景字符编码识别是指通过计算机视觉技术,对街道场景中的字符进行自动识别和分类。 街景字符编码识别是一项重要的研究领域,对于提高交通安全、城市管理和智能驾驶技术都具有重要意义。街道场景中的字符包括道路标志、车牌号码、店铺招牌等。通过对这些字符进行准确的识别,可以辅助交通管理人员进行交通监管、道路规划和交通流量分析。同时,在智能驾驶领域,街景字符编码识别也是一项关键技术,可以帮助自动驾驶系统准确地识别和理解道路上的各种标志和标识,为自动驾驶提供可靠的环境感知能力。 天池和datawhale联合举办街景字符编码识别竞赛,旨在吸引全球数据科学和计算机视觉领域的优秀人才,集思广益,共同推动该领域的研究和发展。通过这个竞赛,参赛选手可以使用各种机器学习和深度学习算法,基于提供的街景字符数据集,设计和训练模型,实现准确的字符编码识别。这个竞赛不仅有助于促进算法研发和技术创新,也为各参赛选手提供了一个学习、交流和展示自己技能的平台。 总之,天池datawhale街景字符编码识别是一个具有挑战性和实际应用需求的竞赛项目,旨在推动计算机视觉和智能交通领域的技术发展,同时也为数据科学爱好者提供了一个学习和展示自己能力的机会。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值