文章目录

  • 0. 前言
  • 1 遇到的问题
    • 1.1 NameError: name 'cv2' is not defined
      • 1.1.1 OpenCV下载
      • 1.1.2 OpenCV安装
        • 打开Anacoda3下的Anacoda Prompt
        • 激活pytorch_gpu环境
          • 在进入OpenCV本地文件所在的文件夹
        • pip install OpenCV
      • 1.1.3 OpenCV验证
    • 1.2 RuntimeError: CUDA out of memory.
    • 1.3 所有用到的库
  • 2 data.py 数据转录文件
  • 3 model.py 网络描述文件
    • 3.1 定义网络结构★★★
    • 3.2 保存和读取网络参数
  • 4 train.py 网络训练文件★★★
    • 设置epoch,batch_size
    • 加载训练数据
    • 调用网络,使用交叉熵损失函数
    • main()
      • 设置优化器
      • 训练模式
      • 保存网络参数
      • 验证模式
  • 5 test.py 网络测试文件★★★
    • 读取测试集test的相关属性
    • 调用网络,使用验证模式
    • main()
      • 读取网络参数
      • 加载测试数据
      • 设置验证集图片数量N,batch_size并分块
      • 按块测试,并保存5个最匹配的汉字的索引
      • 对测试集图片遍历,找出匹配索引在训练集中对应的汉字
      • 将测试结果保存为.csv,并打印
  • 结语
  • 参考链接

0. 前言

选修课《神经网络与深度学习》的实验为TinyMind 汉字书法识别自由练习赛(初级难度)
对应网址为:https://www.tinymind.cn/competitions/41#result_list

搜到Link2Link大神给出的源码。
该代码的github地址:https://github.com/Link2Link/TinyMind-start-with-0
对应的CSDN博客为:深度学习入门指南:从零开始TinyMind汉字书法识别
对应的TinyMind参赛经验贴为:【参赛经验】深度学习入门指南:从零开始TinyMind汉字书法识别——by:Link
修改路径后能跑到96+,无其他错误!再次感谢大神的源码!

在刚开始自己啃的一脸懵逼时,还大致过了一遍:PyTorch 动态神经网络 (莫烦 Python 教学)
B站链接为:https://www.bilibili.com/video/BV1Vx411j7kT?from=search&seid=15124761477393382413
对应的学习资源为:https://morvanzhou.github.io/tutorials/machine-learning/torch/
感谢莫烦大神!

PyTorch安装可以参考上一篇博客的安装步骤:
Win10下 NIVIDIA(CUDA+CUDNN)+Anaconda安装PyTorch(GPU版)

1 遇到的问题

上来遇到了两个问题,先行列出。

1.1 NameError: name ‘cv2’ is not defined

未安装OpenCV。
如果要用OpenCV,就需要import cv2

安装步骤见参考链接1.

1.1.1 OpenCV下载

OpenCV下载地址为:https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv

找到OpenCV下选择对应的版本下载
建议下载opencv_python+contrib
因为opencv-contrib-python包含了主要模块以及扩展模块,扩展模块主要是包含了一些带专利的收费算法(如shift特征检测)以及一些在测试的新的算法(稳定后会合并到主要模块)。
见参考链接2.

我下载的是

opencv_python-4.1.2+contrib-cp36-cp36m-win_amd64.whl

cp36:PyTorch虚拟环境安装的python版本为3.6
win_amd64:64位Windows

1.1.2 OpenCV安装

打开Anacoda3下的Anacoda Prompt

激活pytorch_gpu环境

输入 activate 你的PyTorch环境名(我的为 activate pytorch_gpu
如果想退出当前环境,则输入 deactivate

在进入OpenCV本地文件所在的文件夹

注:因为是在pytorch_gpu环境下安装OpenCV,所以先需要激活pytorch_gpu环境,再在该环境下切换到OpenCV本地文件存放的地方

pip install OpenCV

pip install opencv_python-4.1.2+contrib-cp36-cp36m-win_amd64.whl
按你下载的文件名替换,安装即可

1.1.3 OpenCV验证

在pytorch_gpu环境下,输入python 进入代码环境,再输入import cv2。如正常运行,说明安装成功。

1.2 RuntimeError: CUDA out of memory.

GPU用尽。用的GTX 1650, 4G显存。该显卡性能不够好。

见参考链接3.
人为减小bath_size。
把bath_size由512改为了256,即可解决。

在测试该网络之前,我只遇到了这两个问题。解决了之后,我们就可以继续往下走了。

1.3 所有用到的库

如有类似上述OpenCV的错误,进入激活pytorch_gpu环境,conda install对应库即可
numpy
pytorch
opencv-python
PIL
tqdm
pandas

2 data.py 数据转录文件

通过函数transData(),将训练集train转录为numpy矩阵,生成data.npy及label.npy

共100个文件夹(即100个汉字),每个文件夹400张图片
data.npy大小为:(40000, 128, 128)
label.npy大小为:(40000, 100)
注:博客为img_size = (256, 256),GitHub下载的为img_size = (128, 128)。
这并不影响整体理解。

并提供了将测试集test文件夹下图片转录为.npy的函数:loadtestdata()

为了训练时给PyTorch使用,最方便的方法是使用PyTorch做好的loader工具,为此需要实现自己的 data.Dataset。只需继承data.Dataset,并且重写getitem和len两个方法就可以。
Pytorch中有工具函数torch.utils.Data.DataLoader,通过这个函数我们在准备加载数据集使用mini-batch的时候可以使用多线程并行处理,这样可以加快我们准备数据集的速度。
稍微详细的说明,见参考链接4.

不同训练集的格式不同,也对应着不同的转录格式。
这部分就不做详细介绍了。

3 model.py 网络描述文件

定义了网络net,也定义了保存网络参数的函数save_checkpoint和加载网络参数的函数load_checkpoint

3.1 定义网络结构★★★

见参考链接5.

附自己加上的部分注释,代码及注释如下:

# 网络名为net,继承自nn.Moudule的类
class net(nn.Module):# 搭建神经网络各层所需要的信息,用于组成前向通道def __init__(self):super(net, self).__init__()# 池化self.pool = nn.MaxPool2d(2)# Dropoutself.drop = nn.Dropout(p=0.5)# Conv, Normself.conv1 = nn.Conv2d(1, 32, 7, stride=2, padding=3)self.norm1 = nn.BatchNorm2d(32)self.conv2 = nn.Conv2d(32, 32, 3, stride=1, padding=1)self.norm2 = nn.BatchNorm2d(32)self.conv3 = nn.Conv2d(32, 64, 3, stride=1, padding=1)self.norm3 = nn.BatchNorm2d(64)# Sequential 是连续操作的写法self.convs = nn.Sequential(nn.Conv2d(64, 128, 3, stride=1, padding=1),nn.BatchNorm2d(128),# ReLU激活nn.ReLU(),nn.Conv2d(128, 128, 3, stride=1, padding=1),nn.BatchNorm2d(128),nn.ReLU(),)# FCself.out_layers = nn.Sequential(nn.Linear(128 * 8 * 8, 1024),nn.BatchNorm1d(1024),nn.ReLU(),nn.Linear(1024, 256),nn.BatchNorm1d(256),nn.ReLU(),nn.Linear(256, 100),nn.BatchNorm1d(100),nn.ReLU(),)# 神经网络前向通道,反向计算会由PyTorch自动实现def forward(self, x):x = F.relu(self.norm1(self.conv1(x)))   # Conv BN ReLUx = self.pool(x)                        # 池化x = F.relu(self.norm2(self.conv2(x)))   # Conv BN ReLUx = F.relu(self.norm3(self.conv3(x)))   # Conv BN ReLUx = self.pool(x)                        # 池化x = self.convs(x)                       # 连续操作:Conv -> BN -> ReLU -> Conv -> BN -> ReLUx = self.pool(x)                     # 池化x = x.view(-1, 128 * 8 * 8)             # 将图像拉直为向量x = self.drop(x)                        # Dropoutx = self.out_layers(x)                  # FCreturn x

为方便理解,假设对应格式为:(n_H,n_W,n_C),则该网络的处理流程为:

3.2 保存和读取网络参数

训练时:save_checkpoint将网络参数保存到model_save文件夹下,名字为model_parameters.pth.tar
测试时:load_checkpoint读取对应的文件,加载到网络中

def save_checkpoint(state, save_adress='model_save'):name = 'model_parameters.pth.tar'folder = os.path.exists(save_adress)if not folder:os.mkdir(save_adress)print('--- create a new folder ---')fulladress = save_adress + '\\' + nametorch.save(state, fulladress)print('model saved:', fulladress)def load_checkpoint(save_adress='model_save'):name = 'model_parameters.pth.tar'fulladress = save_adress + '\\' + namereturn torch.load(fulladress)

4 train.py 网络训练文件★★★

附自己加上的部分注释,代码及注释如下:

设置epoch,batch_size

n_epoch, batch_size = 10, 512

加载训练数据

训练集train分为两部分:90%的训练集,10%的验证集

trainset = data.TrainSet(eval=False)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)
evalset = data.TrainSet(eval=True)
evalloader = torch.utils.data.DataLoader(evalset, batch_size=batch_size, shuffle=True)

调用网络,使用交叉熵损失函数

net = model.net()
if torch.cuda.is_available():# 使用GPU加速计算net.cuda()
criterion = nn.CrossEntropyLoss()

main()

设置优化器

    optimizer = optim.Adam(net.parameters(), lr=1e-3, betas=(0.9, 0.999), weight_decay=0)

训练模式

见参考链接6.

def train(epoch):net.train() # 网络处于训练模式,会导致dropout启用correct = 0sum = 0T = 0# 加载数据for batch_index, (datas, labels) in enumerate(trainloader, 0):# 转化为Tensorlabels = labels.max(1)[1]datas = Variable(datas).float()datas = datas.view(-1, 1, 128, 128)labels = Variable(labels).long()if torch.cuda.is_available():datas = datas.cuda()labels = labels.cuda()# 将梯度初始化为零optimizer.zero_grad()# 网络输出outputs = net(datas)# 计算损失loss = criterion(outputs, labels)# 反向求导 loss.backward()# 权值更新optimizer.step()T += 1# 列出预测的标签pred_choice = outputs.data.max(1)[1]# 将预测值与真实值比较correct += pred_choice.eq(labels.data).cpu().sum()sum += len(labels)# 打印batch索引,epoch,以及准确率print('batch_index: [%d/%d]' % (batch_index, len(trainloader)),'Train epoch: [%d]' % (epoch),'correct/sum:%d/%d, %.4f' % (correct, sum, correct / sum))

保存网络参数

将训练得到的网络参数保存,用于之后的测试。

     checkpoint = {'epoch': epoch, 'state_dict': net.state_dict(), 'optimizer': optimizer.state_dict()}model.save_checkpoint(checkpoint)

验证模式

大致同训练模式。

def eval(epoch):net.eval()  # 弯网络处于测试模式,dropout停用,BN放射变换停止correct = 0sum = 0for batch_index, (datas, labels) in enumerate(evalloader, 0):labels = labels.max(1)[1]datas = Variable(datas).cuda().float()datas = datas.view(-1, 1, 128, 128)labels = Variable(labels).cuda().long()# optimizer.zero_grad()outputs = net(datas)# loss = criterion(outputs, labels)# loss.backward()# optimizer.step()pred_choice = outputs.data.max(1)[1]correct += pred_choice.eq(labels.data).cpu().sum()sum += len(labels)print('batch_index: [%d/%d]' % (batch_index, len(evalloader)),'Eval epoch: [%d]' % (epoch),'correct/sum:%d/%d, %.4f' % (correct, sum, correct / sum))

5 test.py 网络测试文件★★★

附自己加上的部分注释,代码及注释如下:

读取测试集test的相关属性

test1path = 'test1\\'
trainpath = 'train\\'filename = os.listdir(test1path)
words = os.listdir(trainpath)   # 按时间排序 从早到晚
words = np.array(words)
testnumber = len(filename)
category_number = len(words)

调用网络,使用验证模式

net = model.net()
if torch.cuda.is_available():net.cuda()
net.eval()

main()

读取网络参数

 checkpoint = model.load_checkpoint()net.load_state_dict(checkpoint['state_dict'])

加载测试数据

 testdatas = data.loadtestdata()testdatas.astype(np.float)

设置验证集图片数量N,batch_size并分块

 n = 0N = 10000batch_size = 8pre = np.array([])batch_site = []while n < N:n += batch_sizeif n < N:n1 = n - batch_sizen2 = nelse:n1 = n2n2 = Nbatch_site.append([n1, n2])

按块测试,并保存5个最匹配的汉字的索引

 pred_choice = []for site in tqdm(batch_site):test_batch = testdatas[site[0]:site[1]]test_batch = torch.from_numpy(test_batch)datas = Variable(test_batch).cuda().float()datas = datas.view(-1, 1, 128, 128)outputs = net(datas)outputs = outputs.cpu()outputs = outputs.data.numpy()# 提取出五个最匹配的汉字for out in outputs:K = 5index = np.argpartition(out, -K)[-K:]pred_choice.append(index)pre = np.array(pred_choice)

对测试集图片遍历,找出匹配索引在训练集中对应的汉字

predicts = []for k in range(testnumber):index = pre[k]predict5 = words[index]predict5 = "".join(predict5)predicts.append(predict5)

将测试结果保存为.csv,并打印

dataframe = pd.DataFrame({'filename': filename, 'label': predicts})dataframe.to_csv("test.csv", index=False, encoding='utf-8')read = pd.read_csv('test.csv')print(read)

结语

第29篇

等写完这门课的结课报告,又能结束一门课。
框架虽好,不明白基础也是白搭。
调参调的一塌糊涂,没有方向,这是门学问。
深度学习水太深。
路漫漫。

神经网络与深度学习到此为止,有缘再见。

个人水平有限,有问题欢迎各位大神批评指正!

参考链接

  1. 安装OpenCV–conda建立虚拟环境 在jupyter 中添加此环境的kernel
    https://zhuanlan.zhihu.com/p/37708958
  2. Opencv-contrib-python与opencv-python有何不同?
    https://www.zhihu.com/question/344438707/answer/816909254
  3. RuntimeError: CUDA out of memory.
    https://blog.csdn.net/iamjingong/article/details/100974742
  4. 定义自己的数据集及加载训练
    https://blog.csdn.net/sinat_42239797/article/details/90641659
  5. Pytorch CNN的各种参数
    https://blog.csdn.net/weixin_30703911/article/details/96285800
  6. Pytorch optimizer.step() 和loss.backward()和scheduler.step()的关系与区别 (Pytorch 代码讲解)
    https://blog.csdn.net/xiaoxifei/article/details/87797935

基于PyTorch的TinyMind 汉字书法识别部分代码详解相关推荐

  1. 【AI参赛经验】深度学习入门指南:从零开始TinyMind汉字书法识别——by:Link

    各位人工智能爱好者,大家好! 由TinyMind发起的#第一届汉字书法识别挑战赛#正在火热进行中,比赛才开始3周,已有数只黑马冲进榜单.目前TOP54全部为90分以上!可谓竞争激烈,高手如林.不是比赛 ...

  2. 深度学习入门指南:从零开始TinyMind汉字书法识别

    深度学习入门指南:从零开始TinyMind汉字书法识别 这几天在刷这个新出的比赛,受举办方邀请谢了一篇文章,也转到CSDN来和大家分享下吧.话说TinyMind不是被CSDN收购了么,我这算不算把统一 ...

  3. TinyMind 汉字书法识别竞赛开启总决赛啦!!

    手写字体识别一直是人工智能领域一个热门研究方向,TinyMind联合书法领域的权威合作伙伴举办了一次汉字书法识别大赛,为广大人工智能和手写字体识别技术爱好者提供了一个练习和交流的机会. 竞赛开始后,高 ...

  4. 【AI竞赛】TinyMind汉字书法识别挑战赛开始报名啦!!

    书法是中国及深受中国文化影响过的国家和地区特有的一种文字美的艺术表现形式.书法艺术的背景是中国传统文化.书法植根于中国传统文化土壤,传统文化是书法赖以生存.发展的背景.我们今天能够看到的汉代以来的书法 ...

  5. NLP【05】pytorch实现glove词向量(附代码详解)

    上一篇:NLP[04]tensorflow 实现Wordvec(附代码详解) 下一篇:NLP[06]RCNN原理及文本分类实战(附代码详解) 完整代码下载:https://github.com/ttj ...

  6. TinyMind汉字书法识别大赛2018百度-西交大·大数据竞赛 比赛模板

    最近真的太忙太忙太忙/(ㄒoㄒ)/~ --------------------------------------- 某些新手(没错,说的就是我)在刚接触深度学习比赛的时候,往往会有些不知所措.嗯,直 ...

  7. 基于Tomcat5.0和Axis2开发Web Service代码详解

    本文将详细介绍HelloWorld中使用的server和client端代码.阅读之前,你应该首先了解SOAP1.1协议.<?xml:namespace prefix = o ns = " ...

  8. Pytorch实现yolov3(train)训练代码详解(二)

    上篇我们讲解了如何进行数据预处理,读取数据.接下来我们一起分析yolov3训练过程与training procedure.想真正读懂这个部分,要对inference部分有所了解. 数据加载 def t ...

  9. 基于机器学习的恶意样本静态检测的代码详解(ember)

    文章目录 1. 类与类之间的关系 2. 每个类的详细分析 2.1 ByteHistogram 2.2 ByteEntropyHistogram 2.3 SectionInfo 2.4 ImportsI ...

最新文章

  1. 车联网系统会不会只是智能手机系统的翻版?
  2. ****CI框架源码阅读笔记7 配置管理组件 Config.php
  3. [力扣] 501. 二叉搜索树中的众数
  4. 使用HMTL5 API监控前端性能
  5. Using the Cordova Camera API
  6. React开发(155):请求方式得问题
  7. 令Django 视图有默认 login_required
  8. c语言计算24游戏,C语言解24点游戏程序
  9. oracle rds 运维服务_从Oracle一条新闻说起,为什么我们需要更好更开放的RDS服务?...
  10. python怎么找一个矩阵_Python(NumPy,SciPy),找到矩阵的零空间
  11. windows安装jdk与配置环境变量详解
  12. SpringBoot 系列
  13. 绑定touch事件后click无效,vue项目解决棒法
  14. 项目进度管理:估算活动持续时间
  15. c语言utc时间转换,gps时转换为utc时间方法
  16. 【智能车】模糊PID控制原理详解与代码实现
  17. window10 删除桌面删除不掉的ie图标(快捷方式)
  18. 工商银行转账出现java_工行企业网银转账提示信息代码4506是什么意思?
  19. android studio找不到aar,AndroidStudio 引入aar时常见问题
  20. FFmpeg 音视频转封装(MP4与FLV互转,流数据转FLV、MP4)

热门文章

  1. 后端开发应彻底掌握的13 种锁的实现方式
  2. win10关闭防火墙的方法
  3. 阿里云ecs安装mysql数据库途中遇到的坑
  4. 进程间通信方式(一)-- 无名管道、有名管道
  5. 利用PYHTON爬虫爬取恋家网房价
  6. 五子棋java_java简易五子棋
  7. 一文简述如何使用嵌套交叉验证方法处理时序数据 @ 机器之心
  8. python各种插件安装_如何在各种环境下正确地安装python——Windows
  9. oracle循环数据字典,Oracle数据字典使用
  10. SylixOS学习二—— SylixOS启程之旅_ SylixOS系统配置