MNIST-手写数字识别-TensorFlow&&Pytorch

本文详细介绍使用PyTorch和TensorFlow实现手写数字识别的过程,包括数据预处理、模型构建、训练及测试,适合深度学习初学者。

作为深度学习的第一个任务呢,一般都会选择手写数字识别作为我们的第一个项目,因为识别起来并不是很困难,而且精度可以达到0.99。下面就正式开始我们的第一个小项目吧。

先来说一下流程:
1. 准备数据集,可以在kaggle上下载csv文件的数据集,对于新手来说,以便好的理解数据,后者是利用TensorFlow后pytorch直接下载数据,.pt格式的(不推荐新手)。
2. 加载数据以及对数据进行一些处理(归一化,resize等),对原始数据进行合适的处理常常大大提升模型的精度。
3. 选择合适的模型,也就是网络,当然也可以自己构建。
4. 选择合适的优化函数以及损失函数。
5. 开始训练,然后在测试数据上测试模型的精度,保存模式。

在以后的学习中一般都是这几大步,所以对于初学者来说,记住了后,有利于代码的编写。

在这个小项目中,由于识别难度不是很大,所以我们可以自己构建简单的网络,这里可以使用线性层(识别精度大概在90%)也可以使用卷积神经网络(识别精度大概在98%)。

先导入相关的库

import numpy as np
import pandas as pd

下面来开始第一步:加载数据
先看一些数据的前几行
在这里插入图片描述
label是标签,后面是图片展开的数据,这里的每一张图片都是28×28的大小,而且是灰度的。

data = pd.read_csv('train.csv')      				#读取数据
label = data['label'].values     					#获取标签
img = data.loc[:,data.columns != 'label'].values.astype(np.float32)	#获取图片

第二步:对数据进行归一化处理,这里只想做简单的处理

img = img / 255.0

第三步:构建网络

在这里我们自己构建网络,分别用线性层,和卷积层来构建。

import torch
import torch.nn as nn
import torch.nn.functional as F

class Network(nn.Model):
	def __init__(self):
		super(Network,self).__init__()
		self.fc1 = nn.Linear(28*28,1024)
		self.fc2 = nn.Linear(1024,2048)
		self.fc3 = nn.Linear(2048,100)
		self.fc4 = nn.Linear(100,10)
		
	def forward(self,x):
		x = self.fc1(x)
		x = self.fc2(x)
		x = self.fc3(x)
		x = self.fc4(x)
		x = F.softmax(x,dim=1)
		return x
		

上面是线性层,下面来用卷积层

import torch
import torch.nn as nn
import torch.nn.functional as F

class Network(nn.Model):
	def __init__(self):
		super(Network,self).__init__()
		self.conv1 = nn.Conv2d(1,16,kernel_size=3,stride=1,padding=1) # 16  28  28
		self.pool1 = nn.MaxPool2d(kernel_size=2,stride=2)    #16 14  14
		self.conv2 = nn.Conv2d(16,32,3,1,1) 	#32  14   14
		self.pool2 = nn.MaxPool2d(2,2)			#32  7     7
		
		self.fc1 = nn.Linear(32*7*7,1024)
		self.fc2 = nn.Linear(1024,10)
	
	def forward(self,x):
		x =F.ReLU(self.conv1(x),inplace=True)
		x = self.pool1(x)
		x = F.ReLU(self.conv2(x),inplace=True)
		x = self.pool2(x)
		x = x.view(x.size(0),-1)   #将x打平
		x = self.fc1(x)
		x = F.softmax(self.fc2(x))
		return x

选择模型已经构建出来了下一步是选择合适的优化函数和损失函数了。

第四步:优化函数和损失函数的选取
一般的情况下,对于分类问题,我们都会选取交叉熵损失函数,对于优化函数没太多限制,这里选择SGD(随机梯度下降)

import torch.optim

optimizer = torch.optim.SGD(x.parameters(),lr=0.001)   #x为实例化的网络,这里先用x代替
error = nn.CrossEntropyLoss()        #交叉熵

第五步:进行训练
这里直接上代码

from torch.autograd import Variable
from sklearn.preprocessing import OneHotEncoder

for i in range(25):
   
    for img,label in data:    #data为经过DataLoader处理过了的

        lb = OneHotEncoder(categories='auto')
        lb.fit(label.reshape(-1,1))
        label = lb.transform(label.reshape(-1,1)).toarray()  #将label进行one_hot编码

        img = Variable(img)
        label = torch.from_numpy(label).long()
        label = Variable(label)
        optimizers.zero_grad()
        predict = cnn(img)
        loss = losses(predict,label)
        loss.backward()
        optimizers.step()

在这里我们已经对用pytorch进行MNIST识别有了大概的了解。
TensorFlow的代码也和pytorch差不多,弄懂了上面的代码,那么对于TensorFlow的代码也可以很快地知道该怎样运用了,下面就直接给出TensorFlow2.0的代码(线性层的)
由于pytorch上面已经说了,就不给出全部的代码了。

import tensorflow as tf
import numpy as np
import pandas as pd
from tensorflow.keras import Model,layers

data = pd.read_csv('train.csv')
x = data.loc[:,data.columns != 'label'].values.astype(np.float32)
y = data['label'].values
x = x / 255.0
data_loader = tf.data.Dataset.from_tensor_slices((x,y))    
data_loader = data_loader.repeat().shuffle(5000).batch(256).prefetch(1)    #在之前的文章中已经说过了这两行代码的意思了,就不再累赘。

class NeuralNet(Model):
    def __init__(self):
        super(NeuralNet,self).__init__()
        self.fc1 = layers.Dense(256,activation=tf.nn.relu)   
        self.fc2 = layers.Dense(512,activation=tf.nn.relu)
        self.out = layers.Dense(10,activation=tf.nn.softmax)
    def call(self,x):
        x = self.fc1(x)
        x = self.fc2(x)
        return x
neural_net = NeuralNet()

def cross_entropy_loss(x,y):
    y = tf.cast(y,tf.int64)
    loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=x)
    return tf.reduce_mean(loss)
def accuracy(y_pred,y_true):
    correct_prediction = tf.equal(tf.argmax(y_pred,1),tf.cast(y_true,tf.int64))
    return tf.reduce_mean(tf.cast(correct_prediction,tf.float32),axis=-1)
    
optimizer = tf.optimizers.SGD(0.01)

def run_optimization(x,y):
    with tf.GradientTape() as g:
        pred = neural_net(x)
        loss = cross_entropy_loss(pred,y)
    trainable_cariables = neural_net.trainable_variables
    gradients = g.gradient(loss,trainable_cariables)
    optimizer.apply_gradients(zip(gradients,trainable_cariables))

for step,(batch_x,batch_y) in enumerate(data_loader.take(2000),1):
    run_optimization(batch_x,batch_y)
    if step % 50 == 0:
        pred = neural_net(batch_x)
        loss = cross_entropy_loss(pred,batch_y)
        acc = accuracy(pred,batch_y)
        print("step:%i,loss:%f,accuracy:%f"%(step,loss,acc))

以上TensorFlow代码学习于: https://github.com/aymericdamien/TensorFlow-Examples

上面就是TensorFlow的全部代码了,这一讲就完了。

Thank for your reading !!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

FPGA之旅

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

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

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

打赏作者

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

抵扣说明:

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

余额充值