Pytorch实现手写数字识别,导出权重参数,利用C语言实现推理(正向传播)过程

前言

关键词:FPGA,卷积神经网络,pytorch

将手写数字识别部署在FPGA等嵌入式端时,由于缺少tensorflow,pytorch等框架的使用,需要在PC端先训练出神经网络,导出权重参数再去硬件上只实现前向传播的部分.
本文使用MINIST手写数字识别数据集.先搭建了一个具有一个卷积层,一个池化层,两个全连接层的卷积神经网络.具体结构如下:
网络结构

MINIST手写数字识别数据集:其中图像数据为28x28的灰度图像.训练集:60000个,测试集:10000个
卷积层:共有30个5x5的卷积核
激活函数:ReLU()
池化:最大池化

实现整个模型的前提,你得对你的网络要具有大局观念:

输入数据为28x28,经过30个5x5的卷积核过后,数据变为30x24x24,池化过后数据变为30x12x12 = 4320个,全连接层1将4320个数据映射到100个,全连接层2将100个数据映射到10个输出,其中输出的最大值的索引就为预测值

一.使用pytorch训练数据集

直接上代码,网上对于利用卷积神经网络模型搭建MNIST手写数字识别的教程也很多:这个视频手把手教你.
我直接贴我的代码:

import random

import numpy as np
import pandas as pd
import matplotlib.pyplot  as plt

##Data
import torch
import torchvision
from torch.utils.data import DataLoader

##pytorch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim  as optim

##随机数种子(这个不知道有啥用)
random_seed = 1
torch.manual_seed(random_seed)

##设置超参数
n_epochs = 3
batch_size_train = 64
batch_size_test = 1000
learn_rate = 0.01
momentum = 0.5
log_interval = 10

##一些输出配置(numpy打印输出的时候不显示shenglue号)
np.set_printoptions(threshold = np.inf)

##加载数据集
train_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST(
        './data/',train=True,download=True,
        transform=torchvision.transforms.Compose([
            torchvision.transforms.ToTensor(),
            torchvision.transforms.Normalize((0.1307,),(0.3081,))
            ])),
    batch_size=batch_size_train,shuffle=True
)
test_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST(
        './data/',train=False,download=True,
        transform=torchvision.transforms.Compose([
            torchvision.transforms.ToTensor(),
            torchvision.transforms.Normalize((0.1307,),(0.3081,))
        ])),
    batch_size=batch_size_test,shuffle=True
)

examples = enumerate(test_loader)
batch_idx,(example_data,example_target) = next(examples)


###模型定义  卷积-->激活-->池化-->全连接1-->激活-->全连接2-->softmax  (要改模型直接在这改)
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1,30,kernel_size=5)
        self.fc1 = nn.Linear(4320,100)
        self.fc2 = nn.Linear(100, 10)
    def forward(self,x):
        x = F.max_pool2d(F.relu(self.conv1(x)),2)
        x = x.view(-1, 4320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x,dim=1)
network = Net()
optimizer = optim.SGD(network.parameters(),lr=learn_rate,momentum=momentum)
train_losses = []
train_counter = []
test_losses = []
test_counter = (i*len(train_loader.dataset) for i in range(n_epochs + 1))

##训练器
def train(epoch):
    network.train()
    for batch_idx,(data,target) in enumerate(train_loader):
        optimizer.zero_grad()
        output = network(data) #得到输出
        loss = F.nll_loss(output,target)  ##损失函数
        loss.backward()  #反向传播
        optimizer.step() #梯度优化
        if batch_idx % log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                       100. * batch_idx / len(train_loader), loss.item()))
            train_losses.append(loss.item())
            train_counter.append(
                (batch_idx * 64) + ((epoch - 1) * len(train_loader.dataset)))
            torch.save(network.state_dict(), './model.pth') ##注意,这里是保存训练好的模型参数
            torch.save(optimizer.state_dict(), './optimizer.pth')

def test():
    network.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            output = network(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()
            pred = output.data.max(1, keepdim=True)[1]
            correct += pred.eq(target.data.view_as(pred)).sum() #统计正确率
    test_loss /= len(test_loader.dataset)
    test_losses.append(test_loss)
    print
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值