手写数字识别 手动实现+基于Pytorch实现

利用sklearn中的数据集手动实现:

import numpy as np
from sklearn.datasets import load_digits
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
import warnings
import random
warnings.filterwarnings('ignore')
random.seed(1)

digits=load_digits()

X=digits.data
Y=digits.target

VV=np.random.random((64,100))*2-1
WW=np.random.random((100,10))*2-1

X_train,X_test,Y_train,Y_test=train_test_split(X,Y)
print(Y_train)
#one hot
labels_train=LabelBinarizer().fit_transform(Y_train)

def sigmod(x):
    return 1/(1+np.exp(-x))

def derivation_sigmod(x):
    return np.exp(-x)/((1+np.exp(-x))*(1+np.exp(-x)))

def predict(X,Y,V,W):
    res=0
    for flag in range(X.shape[0]):#SGG
        x=X[flag]
        y=Y[flag]
        x=np.atleast_2d(x)
        x=x.reshape(64,1)

        h_in=np.matmul(V.T,x)
        h_out=sigmod(h_in)
        y_in=np.matmul(W.T,h_out)
        y_out=sigmod(y_in)

        if np.argmax(y_out)==y:
            res+=1
    return res/X.shape[0]

def train(X,Y,V,W,steps=10000,learning_rate=0.1):
    for n in range(steps+1):#SGD
        flag=np.random.randint(X.shape[0])
        x=X[flag]
        y=Y[flag]
        x=np.atleast_2d(x)
        x=x.reshape(64,1)
        y=y.reshape(10,1)

        h_in=np.matmul(V.T,x)
        h_out=sigmod(h_in)
        y_in=np.matmul(W.T,h_out)
        y_out=sigmod(y_in)

        delta_y_in=derivation_sigmod(y_in)*(y_out-y)
        delta_h_in=derivation_sigmod(h_in)*np.matmul(W,delta_y_in)

        delta_W=np.matmul(h_out,delta_y_in.T)
        delta_V=np.matmul(x,delta_h_in.T)

        W-=learning_rate*delta_W
        V-=learning_rate*delta_V

        #if(n<3):
        #    print(W[:3][:3])

        # train 1000 times to get a prediction
        if n%1000==0:
            acc=predict(X_test,Y_test,V,W)
            print('steps:',n,'accuracy:',acc)

train(X_train,labels_train,VV,WW,30000)

利用Pytorch中的数据集基于Pytorch实现:

(首先是普通前馈神经网络,其次是注释中的卷积神经网络)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch import optim
from torch.utils.data import DataLoader
from torch.utils.data import TensorDataset
import torchvision
import warnings
warnings.filterwarnings('ignore')

LR=0.01
EPOCH=100
BATCH_SIZE=50

class Mnist_CNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=2, padding=1)
        self.conv2 = nn.Conv2d(16, 16, kernel_size=3, stride=2, padding=1)
        self.conv3 = nn.Conv2d(16, 10, kernel_size=3, stride=2, padding=1)
    def forward(self, xb):
        xb = xb.view(-1, 1, 28, 28)
        xb = F.relu(self.conv1(xb))
        xb = F.relu(self.conv2(xb))
        xb = F.relu(self.conv3(xb))
        xb = F.avg_pool2d(xb, 4)
        return xb.view(-1, xb.size(1))

def get_data():
    train_data = torchvision.datasets.MNIST(root='./mnist/', train=True, transform=torchvision.transforms.ToTensor())
    test_data = torchvision.datasets.MNIST(root='./mnist/', train=False, transform=torchvision.transforms.ToTensor())
    x_train, y_train, x_test, y_test = map(
        torch.tensor, (train_data.train_data/255.0, train_data.train_labels, test_data.test_data/255.0, test_data.test_labels)
    )
    train_ds = TensorDataset(x_train, y_train)
    train_dl = DataLoader(train_ds, batch_size=BATCH_SIZE)
    test_ds = TensorDataset(x_test, y_test)
    test_dl = DataLoader(test_ds, batch_size=BATCH_SIZE)
    return train_dl, test_dl

def get_model():
    model = Mnist_CNN()
    optimizer = optim.SGD(model.parameters(),lr=LR)
    loss_func = F.cross_entropy
    return model, optimizer, loss_func

def loss_batch(model, loss_func, xb, yb, optimizer=None):
    pred = model(xb)
    loss = loss_func(pred, yb)
    pred = torch.argmax(pred, dim=1)
    match = sum(pred == yb)
    if optimizer is not None:
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()
    return loss.item(), match, len(xb)

def fit(epochs, model, optimizer, loss_func, train_dl, test_dl):
    for epoch in range(epochs):
        model.train()
        for xb, yb in train_dl:
            loss_batch(model, loss_func, xb, yb, optimizer)

        model.eval()
        with torch.no_grad():
            losses, match, nums = zip(
                *[loss_batch(model, loss_func, xb, yb) for xb, yb in test_dl]
            )
        val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)
        accuracy = np.sum(match) / np.sum(nums)
        print(epoch, val_loss, accuracy)

train_dl, test_dl = get_data()
model,optimizer,loss_func = get_model()
fit(EPOCH,model,optimizer,loss_func,train_dl,test_dl)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值