利用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)