3.1 从零实现多层感知机
import torch
import torchvision
from torchvision import transforms
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader
from torch import nn
from tqdm import tqdm
from sklearn.metrics import accuracy_score
def get_fashion_mnist_labels(labels):
"""返回Fashion-MNIST数据集的文本标签"""
text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
labels=text_labels[labels]
return labels
def draw_fashion_mnist(row,col,num_fig,img_data):
fig,axes=plt.subplots(row,col,figsize=(row*col,4))
for i in range(num_fig):
img,label=img_data[i]
label=get_fashion_mnist_labels(label)
img=img.squeeze(0)
row_d,col_d=divmod(i,col)
ax=axes[row_d][col_d]
ax.imshow(img.numpy(),cmap='coolwarm')
ax.set_title(f"{label}")
ax.axis('off')
plt.tight_layout()
plt.show()
def draw_fashion_mnist_test(model,num_input,row,col,num_fig,img_data):
fig,axes=plt.subplots(row,col,figsize=(row*col,4))
for i in range(num_fig):
img,label=img_data[i]
probs=model(img,num_input)
pred=probs.argmax(dim=1).detach().cpu().numpy()
pred=get_fashion_mnist_labels(int(pred))
label=get_fashion_mnist_labels(label)
img=img.squeeze(0)
row_d,col_d=divmod(i,col)
ax=axes[row_d][col_d]
ax.imshow(img.numpy(),cmap='coolwarm')
ax.set_title(f"{label}\n{pred}")
ax.axis('off')
plt.tight_layout()
plt.show()
def relu(x):
a=torch.zeros_like(x)
return torch.max(x,a)
def model(x,num_inputs):
x=x.reshape(x.shape[0],-1)
h=relu(x@w1+b1)
return (h@w2+b2)
def train_model(train_data,test_data,num_epochs,num_input):
for epoch in range(num_epochs):
total_loss=0
total_acc_sample=0
total_samples=0
loop=tqdm(train_data,desc=f"EPOCHS[{epoch+1}/{num_epochs}]")
for X,y in loop:
y_hat=model(X,num_input)
loss=CEloss(y_hat,y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss+=loss.item()*X.shape[0]
y_pred=y_hat.argmax(dim=1).detach().cpu().numpy()
y_true=y.detach().cpu().numpy()
total_acc_sample+=accuracy_score(y_pred,y_true)*X.shape[0]
total_samples+=X.shape[0]
test_acc_samples=0
test_samples=0
for X,y in test_data:
X=X.reshape(X.shape[0],-1)
y_hat=model(X,num_input)
y_pred=y_hat.argmax(dim=1).detach().cpu().numpy()
y_true=y.detach().cpu().numpy()
test_acc_samples+=accuracy_score(y_pred,y_true)*X.shape[0]
test_samples+=X.shape[0]
print(f"Epoch {epoch+1}: Loss: {total_loss/total_samples:.4f},Trian Accuracy: {total_acc_sample/total_samples:.4f},test Accuracy: {test_acc_samples/test_samples:.4f}")
return model
transforms=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,),(0.5,))
])
train_img=torchvision.datasets.FashionMNIST(root="../data",train=True,transform=transforms,download=True)
test_img=torchvision.datasets.FashionMNIST(root="../data",train=False,transform=transforms,download=True)
train_data=DataLoader(train_img,batch_size=200,num_workers=4,shuffle=True)
test_data=DataLoader(test_img,batch_size=200,num_workers=4)
batch_size=256
num_input,num_ouput,num_hiddens=784,10,256
w1=nn.Parameter(torch.randn(num_input,num_hiddens,requires_grad=True)*0.01)
b1=nn.Parameter(torch.zeros(num_hiddens,requires_grad=True))
w2=nn.Parameter(torch.randn(num_hiddens,num_ouput,requires_grad=True)*0.01)
b2=nn.Parameter(torch.zeros(num_ouput,requires_grad=True))
params=[w1,b1,w2,b2]
num_epochs=10
lr=0.05
CEloss=nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(params,lr=lr)
model=train_model(train_data,test_data,num_epochs,num_input)
draw_fashion_mnist_test(model,num_input=num_input,row=2,col=9,num_fig=18,img_data=test_img)
3.2 简洁实现多层感知机
import torch
import torchvision
from torchvision import transforms
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader
from torch import nn
from tqdm import tqdm
from sklearn.metrics import accuracy_score
def get_fashion_mnist_labels(labels):
"""返回Fashion-MNIST数据集的文本标签"""
text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
labels=text_labels[labels]
return labels
def draw_fashion_mnist(row,col,num_fig,img_data):
fig,axes=plt.subplots(row,col,figsize=(row*col,4))
for i in range(num_fig):
img,label=img_data[i]
label=get_fashion_mnist_labels(label)
img=img.squeeze(0)
row_d,col_d=divmod(i,col)
ax=axes[row_d][col_d]
ax.imshow(img.numpy(),cmap='coolwarm')
ax.set_title(f"{label}")
ax.axis('off')
plt.tight_layout()
plt.show()
def draw_fashion_mnist_test(model,row,col,num_fig,img_data):
fig,axes=plt.subplots(row,col,figsize=(row*col,4))
for i in range(num_fig):
img,label=img_data[i]
probs=model(img)
pred=probs.argmax(dim=1).detach().cpu().numpy()
pred=get_fashion_mnist_labels(int(pred))
label=get_fashion_mnist_labels(label)
img=img.squeeze(0)
row_d,col_d=divmod(i,col)
ax=axes[row_d][col_d]
ax.imshow(img.numpy(),cmap='coolwarm')
ax.set_title(f"{label}\n{pred}")
ax.axis('off')
plt.tight_layout()
plt.show()
def init_weights(model):
if type(model)==nn.Linear:
nn.init.normal_(model.weight,mean=0.0,std=0.1)
if model.bias is not None:
nn.init.zeros_(model.bias)
def xavier_init_weights(model):
if type(model)==nn.Linear:
nn.init.xavier_normal_(model.weight)
if model.bias is not None:
nn.init.zeros_(model.bias)
def kaiming_init_weights(model):
if type(model)==nn.Linear:
nn.init.kaiming_normal_(model.weight,nonlinearity='relu')
if model.bias is not None:
nn.init.zeros_(model.bias)
def train_model(model,train_data,test_data,num_epochs):
for epoch in range(num_epochs):
total_loss=0
total_acc_sample=0
total_samples=0
loop=tqdm(train_data,desc=f"EPOCHS[{epoch+1}/{num_epochs}]")
for X,y in loop:
y_hat=model(X)
loss=CEloss(y_hat,y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss+=loss.item()*X.shape[0]
y_pred=y_hat.argmax(dim=1).detach().cpu().numpy()
y_true=y.detach().cpu().numpy()
total_acc_sample+=accuracy_score(y_pred,y_true)*X.shape[0]
total_samples+=X.shape[0]
test_acc_samples=0
test_samples=0
for X,y in test_data:
X=X.reshape(X.shape[0],-1)
y_hat=model(X)
y_pred=y_hat.argmax(dim=1).detach().cpu().numpy()
y_true=y.detach().cpu().numpy()
test_acc_samples+=accuracy_score(y_pred,y_true)*X.shape[0]
test_samples+=X.shape[0]
print(f"Epoch {epoch+1}: Loss: {total_loss/total_samples:.4f},Trian Accuracy: {total_acc_sample/total_samples:.4f},test Accuracy: {test_acc_samples/test_samples:.4f}")
return model
transforms=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,),(0.5,))
])
train_img=torchvision.datasets.FashionMNIST(root="../data",train=True,transform=transforms,download=True)
test_img=torchvision.datasets.FashionMNIST(root="../data",train=False,transform=transforms,download=True)
train_data=DataLoader(train_img,batch_size=200,num_workers=4,shuffle=True)
test_data=DataLoader(test_img,batch_size=200,num_workers=4)
batch_size=256
num_input,num_ouput,num_hiddens=784,10,256
w1=nn.Parameter(torch.randn(num_input,num_hiddens,requires_grad=True)*0.01)
b1=nn.Parameter(torch.zeros(num_hiddens,requires_grad=True))
w2=nn.Parameter(torch.randn(num_hiddens,num_ouput,requires_grad=True)*0.01)
b2=nn.Parameter(torch.zeros(num_ouput,requires_grad=True))
params=[w1,b1,w2,b2]
num_epochs=10
lr=0.05
model=nn.Sequential(nn.Flatten(),
nn.Linear(784,256),
nn.ReLU(),
nn.Linear(256,10))
model.apply(kaiming_init_weights)
CEloss=nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(model.parameters(),lr=lr)
model=train_model(model,train_data,test_data,num_epochs=num_epochs)
draw_fashion_mnist_test(model,row=2,col=9,num_fig=18,img_data=test_img)