目录

  • 数据预处理
  • 自定义数据集
  • 构建网络结构
  • 对卷积神经网络进行训练和评估
  • 对数据进行预测
  • 保存预测数据,提交代码

SNN由于无法考虑到图片数据的维度关系,在预测精度上会被限制,本章我们采用CNN卷积神经网络来实现手写字识别,引入卷积层和池化层,来提高准确度,同时改进优化器利用adam方法来求取权重。
比赛的详细信息及数据请看主页 Pytorch入门练习1。

数据预处理

查看目录结构

# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to loadimport numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directoryimport os
for dirname, _, filenames in os.walk('/kaggle/input'):for filename in filenames:print(os.path.join(dirname, filename))# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All"
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session


导入数据查看数据结构

import pandas as pd
import numpy as np
data_df = pd.read_csv("/kaggle/input/digit-recognizer/train.csv")
data_df.head()


训练集有42000条数据,共有785列,第一列为Label标签数据,第2~784列为图像灰度值数据

label_df = data_df["label"]
feature_df = data_df.drop("label", axis=1)
# 归一化处理
feature_df = feature_df/255.0
# 进行数据变换,变换成1*28*28(C*H*W)的图像输入形式
feature_df = feature_df.apply(lambda x:x.values.reshape(1,28,28), axis=1)
feature_df.head()

自定义数据集

自定义自己的数据集,方便后续的处理。

import torch
from torch.nn import Module
from torch.utils.data import Dataset,DataLoader
from torchvision import transformsclass DigitRecongnizerDataset(Dataset):def __init__(self, label_df, feature_df, transform=None, target_transforms=None):self.label_df = label_dfself.images = feature_dfself.transfrom = transformself.target_transforms = target_transformsdef __len__(self):return len(label_df)def __getitem__(self, item):image = self.images[item]label = self.label_df[item]if self.transfrom:self.transfrom(image)if self.target_transforms:self.target_transforms(label_df)return label,imagedrDataset = DigitRecongnizerDataset(label_df, feature_df, transform=transforms.ToTensor())

可视化展示图片

可视化展示一下图片
import matplotlib.pyplot as plt
figure = plt.figure(figsize=(8, 8))
cols, rows = 3, 3
for i in range(1, cols * rows + 1):sample_idx = torch.randint(len(drDataset), size=(1,)).item()label, img = drDataset[sample_idx]figure.add_subplot(rows, cols, i)plt.title(label)plt.axis("off") # 不显示坐标轴# squeeze是降维,去除度数1的维度,如灰度图像中C(通道)=1,绘制图像时不需要通道C这个维度,直接传递二维矩阵即可,所以将其去除,但这里由于img是28*28的矩阵不带C这个维度,所以不需要squeeze(),所以不需要squeeze在这里不起作用plt.imshow(img.squeeze(), cmap="gray")
plt.show()

构建网络结构

这里搭建的是一个2层卷积层,1层池化层和3层全连接层的网络结构。
nn.Conv1d 用于文本数据的卷积处理,对宽度进行卷积
nn.Conv2d 用于对图像数据进行卷积处理,对矩阵的长宽进行卷积

Conv2d(in_channels, out_channel, kernel_size)

  • in_channels为输入的输入的通道数
  • out_channel为卷积以后输出的通道数,可以理解为提取多少个特征出来
  • kernel_size 表示卷积核的大小,我的理解是考虑一个像素点与周围多少圈像素点的关系。如kernel_size=3,卷积核为3*3的矩阵,那么每次卷积就会考虑到中心点卷积核(2,2)位置与周围一圈位置像素之间的关系。

注意:池化层中panding(图像周围填充多少层0) <= kernel_size
/2.

from torch import nn
class CNN(Module):def __init__(self):super(CNN, self).__init__()# 卷积池化层self.convd_relu_stack = nn.Sequential(# 卷积操作以后变为10*24*24nn.Conv2d(in_channels=1, out_channels=10, kernel_size=5),nn.ReLU(),# 池化以后10*6*6nn.MaxPool2d(kernel_size=4),# 卷积以后变为:20*4*4nn.Conv2d(10, 20, 3),nn.ReLU())# 全连接层self.linear_relu_stack = nn.Sequential(nn.Linear(20*4*4, 160),nn.ReLU(),nn.Linear(160,20),nn.ReLU(),nn.Linear(20, 10),nn.Softmax(dim=1))def forward(self,x):batch_size = x.size(0) # 获取batch_size值convd_result = self.convd_relu_stack(x)# 将结果的(64,20,4,4)压平成(64,20*4*4),输入到全连接层中convd_result = convd_result.view(batch_size,-1)result_ts = self.linear_relu_stack(convd_result)return result_ts

对卷积神经网络进行训练和评估

将dataset数据按训练集:测试集 = 8:2的形式进行分割

from torch.utils.data import random_split
train_size = int(0.8*len(drDataset))
test_size = int(0.2*len(drDataset))
# 训练集:测试集≈8:2
train_dataset,test_dataset = random_split(drDataset,[train_size,test_size])

将dataset转换为可迭代的dataloader形式

# batch_size为每次批处理的数据量,可以根据自己需求进行设置,我这里习惯性设置为64
# shuffle表示是否洗牌,就是每次取出64个数据以后要不要将数据打乱顺序,由于该数据没有时序关系,所以可以设置为true
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=True)
n_epochs = 10 # 迭代次数
learn_rate = 0.001 # 学习率
size = test_size + train_size
device = 'cuda' if torch.cuda.is_available() else "cpu"
model = CNN().to(device)
import torch.optim as optim
# 定义交叉熵损失函数
loss_fn = nn.CrossEntropyLoss()
# 定义adam优化器
optimizer = optim.Adam(model.parameters(), lr=learn_rate)
def train_loop(dataloader,model,loss_fn, optimizer):for n,(y,x) in enumerate(dataloader):# 注意要和权重的类型保持相同x = x.float().to(device)y = y.to(device)pred = model(x)loss = loss_fn(pred,y)# 存储的变量梯度清零optimizer.zero_grad()# 求反向传播的梯度loss.backward()# 开始优化权重optimizer.step()# 共33600条数据,每进行100个batch输出一次值if n%100==0:loss,current = loss.item(), (n + 1) * len(x)print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")def test_loop(dataloader, model, loss_fn):test_loss, corrent = 0, 0size = len(dataloader.dataset)batchNum =  len(dataloader)with torch.no_grad():for y,x in dataloader:x = x.float().to(device)y = y.to(device)pred_y = model(x)test_loss += loss_fn(pred_y, y).item()# argmax(1)将独热编码的形式解释成标签(0,1,2,3..)最初的形式,type()是为了将bool类型的true转为1,false转为0,这样可以使corrent来计算出预测正确的个数corrent += (pred_y.argmax(1)==y).type(torch.float).sum().item()# 平均损失,总共的损失除以batch的个数arg_loss = test_loss/batchNum# 准确率correct_rate = corrent/sizeprint(f"Test Describe:\nAccuracy: {(100*correct_rate):>0.1f}%, Avg loss: {arg_loss:>8f} \n")# 对模型进行训练
for n in range(n_epochs):print(f"======{n}======")train_loop(train_dataloader, model, loss_fn, optimizer)test_loop(test_dataloader, model, loss_fn)print("Done!")


可以看到最后可以达到97.8%的效果,比较前面的SNN的82%有很大的提升。

对数据进行预测

读取预测数据

pred_df = pd.read_csv("/kaggle/input/digit-recognizer/test.csv")
pred_df.head()

对预测数据做同样的处理

# 对预测数据的形状进行变换,使其与训练数据保持一致,同时要注意数据类型也要与上面保持一致为float类型
pred_ts = torch.from_numpy(pred_df.values).float().reshape(len(pred_df), 1, 28, 28)
print(pred_ts.shape)
pred_y = model(pred_ts)
# 选取概率值最大的类别,作为标签
pred_y = pred_y.argmax(1)
# 将tensor转换为numpy类型数据
pred_y_np = pred_y.numpy()
# 转为pandas类型以方便查看和存储,index+1 是为了和sample_submission.csv结果文件的id保持一致。
pred_y_pd = pd.DataFrame({"Label":pred_y_np.tolist()},index=pred_df.index+1)
pred_y_pd

保存预测数据,提交代码

pred_y_pd.index.name = "ImageId"
pred_y_pd.to_csv("/kaggle/working/submission.csv")


得分97.125%,

Pytorch入门练习2-kaggle手写字识别神经网络(CNN)实现相关推荐

  1. Pytorch入门练习-kaggle手写字识别神经网络(SNN)实现

    采用pytorch搭建神经网络,解决kaggle平台手写字识别问题. 数据来源:https://www.kaggle.com/competitions/digit-recognizer/data 参考 ...

  2. Pytorch入门--详解Mnist手写字识别

    1 什么是Mnist?         Mnist是计算机视觉领域中最为基础的一个数据集. MNIST数据集(Mixed National Institute of Standards and Tec ...

  3. 基于tensorflow的MNIST手写字识别

    一.卷积神经网络模型知识要点卷积卷积 1.卷积 2.池化 3.全连接 4.梯度下降法 5.softmax 本次就是用最简单的方法给大家讲解这些概念,因为具体的各种论文网上都有,连推导都有,所以本文主要 ...

  4. 最终章 | TensorFlow战Kaggle“手写识别达成99%准确率

    刘颖,某互联网创业公司COO,技术出身,做产品里最懂运营的. 这是一个TensorFlow的系列文章,本文是第三篇,在这个系列中,你讲了解到机器学习的一些基本概念.TensorFlow的使用,并能实际 ...

  5. 利用卷积神经网络实现手写字识别

    本文我们介绍一下卷积神经网络,然后基于pytorch实现一个卷积神经网络,并实现手写字识别 卷积神经网络介绍 传统神经网络处理图片问题的不足 让我们先复习一下神经网络的工作流程: 搭建一个神经网络 将 ...

  6. 利用神经网络实现手写字识别

    神经网络介绍 神经网络即多层感知机 如果不知道感知机的可以看博主之前的文章感知机及Python实现 神经网络实现及手写字识别 关于数据集: 从http://yann.lecun.com/exdb/mn ...

  7. 用TensorFlow教你手写字识别

    1.MNIST数据集 基于MNIST数据集实现手写字识别可谓是深度学习经典入门必会的技能,该数据集由60000张训练图片和10000张测试图片组成,每张均为28*28像素的黑白图片.关于数据集的获取, ...

  8. TensorFlow基于minist数据集实现手写字识别实战的三个模型

    手写字识别 model1:输入层→全连接→输出层softmax model2:输入层→全连接→隐含层→全连接→输出层softmax model3:输入层→卷积层1→卷积层2→全连接→dropout层→ ...

  9. python手写汉字识别_TensorFlow 2.0实践之中文手写字识别

    问题导读: 1.相比于简单minist识别,汉字识别具有哪些难点? 2.如何快速的构建一个OCR网络模型? 3.读取的时候有哪些点需要注意? 4.如何让模型更简单的收敛? 还在玩minist?fash ...

最新文章

  1. linux上安全狗的安装
  2. android studio大坑 executing external native build for cmake
  3. 【python】字符串连接错误,类型错误 TypeError: coercing to Unicode
  4. 13004.循环数组队列(C语言)
  5. 缓冲区溢出攻击初学者手册(更新版)
  6. Dummies Guide to Trains in Japan
  7. BSGS-BabyStepGiantStep算法+拓展
  8. JQuery Form AjaxSubmit(options)在Asp.net中的应用注意事项
  9. 算法基础:排序算法:7个常用的衡量指标
  10. LPC1788 UART-DMA遇到的问题
  11. js原生touch事件实现微信语音按住录音,上滑取消。
  12. 微信小程序获取openid和用户信息
  13. 如何在宝塔面板中屏蔽垃圾蜘蛛?
  14. Python爬虫抓取考试试题
  15. 苹果电脑上android环境的搭建
  16. 【Linux】SSH相关命令
  17. crh寄存器_CRL,CRH寄存器
  18. 关于pip 下载从清华源或者豆瓣源下载的命令总结
  19. oscp——Hacker Fest: 2019
  20. VBA之正则表达式(19)-- 相对引用转绝对引用

热门文章

  1. 均衡之刃这款球拍是谁创作的
  2. Blob分析---check_hazelnut_wafers.hdev(检测榛子饼干的质量)
  3. 新《三国》的两点观后感
  4. 如何在 Ubuntu 服务器上安装 Gerrit?
  5. QSettings详细使用方法,避免错误
  6. raiders storm 苹果_搏击长空:风暴突击队 Sky Gamblers - Storm Raiders for Mac v1.3.0
  7. Spring Jpa实体中出现数据库关键字解决方法
  8. java实现九宫格小游戏
  9. python导入pyx文件_使用cython从多个pyx文件制作可执行文件
  10. AA制夫妻:分钱还是分感情