欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Pytorch实现softmax回归

程序员文章站 2022-05-26 21:06:05
...

1.导入相关包

#【1】导入相关包
import torch
from torch import nn
from torch.nn import init
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import time
import numpy as np
import sys
sys.path.append("..")#导入本地文件。两个点代表上一层目录。
import my_pytorch as mp

2.获取和读取数据

#【2】获取和读取数据

#【2.1】定义获取label对应的值,及可视化数据(图像)的方法
def get_fashion_mnist_labels(labels):
	text_labels=['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]#labels是0-9的数字组成的list

def show_fashion_mnist(images,labels):
	#mp.use_svg_display()
	_,figs=plt.subplots(1,len(images),figsize=(12,12))
	for f,img,lbl in zip(figs,images,labels):
		f.imshow(img.view((28,28)).numpy())#img现在是tensor,要转numpy数组
		f.set_title(lbl)
		f.axes.get_xaxis().set_visible(False)
		f.axes.get_yaxis().set_visible(False)
	plt.show()
	
#【2.2】获取、显示、读取数据
	
batch_size=256

def load_data_fashion_mnist():
	#【2.2.1】使用torchvision.datasets模块下载数据集
	mnist_train=torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',train=False,download=True,transform=transforms.ToTensor())	
    mnist_test=torchvision.datasets.FashionMNIST(root='~/Datasets/FashionMNIST',train=True,download=True,transform=transforms.ToTensor())
    #【2.2.2】查看数据集大小
    print(len(mnist_train),len(mnist_test))
    #【2.2.3】查看数据属性
    feature,label=mnist_train[0]
    print(feature.shape,label)#ChannelxHeightxWidth
    #输出:torch.Size([1, 28, 28]) tensor(9) 
    #【2.2.4】显示数据:把训练集的10张图像显示在1行
    X,y=[],[]
	for i in range(10):#显示10张图像
		X.append(mnist_train[i][0])
		y.append(mnist_train[i][1])
	show_fashion_mnist(X,get_fashion_mnist_labels(y))
    #【2.2.5】小批量读取数据
    if sys.platform.startswith('win'):
    	num_workers.=0
    else:
    	num_workers=4
    train_iter=torcn.utils.data.DataLoader(mnist_train,batch_size=batch_size,num_workers=num_workers)
    test_iter=torcn.utils.data.DataLoader(mnist_test,batch_size=batch_size,num_workers=num_workers)
    
#【2.3】调用读取数据的方法,返回train和test的迭代器
train_iter,test_iter=load_data_fashion_mnist(batch_size)

3.初始化模型参数

#【3】初始化模型参数
num_inputs=784 #28x28
num_outputs=10

W=torch.tensor(np.random.normal(0,0.01,(num_inputs,num_outputs),dtype=torch.float))
b=torch.zeros(num_outputs,dtype=torch.float)
W.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)

4.实现softmax运算

演示tensor的按行、按列求和:

#演示tensor的按行、按列求和
X=torch.tensor([[1,2,3],[4,5,6]])#2x3
print(X.sum(dim=0,keepdim=True))#tensor([[5, 7, 9]])
print(X.sum(dim=1,keepdim=True))
#tensor([[ 6],
#        [15]])

Pytorch实现softmax回归
softmax函数实现:

#【4】实现softmax函数
def softmax(X):
	X_exp=X.exp()
	partition=X.exp.sum(dim=1,keepdim=True)
	return X_exp/partition
#测试softmax函数:
X=torch.rand(2,5)
X_prob=softmax(X)
print(X_prob,X_prob.sum(dim=1))#得到的每一行值都为1

5.定义模型

#【5】定义模型
def net(X):
	return softmax(torch.mm(X.view(-1,num_inputs)),W)+b)#X是(C,H,W)的Tensor。W是784x10的Tensor。b是10x1的Tensor。

6.定义损失函数

gather函数演示:

y_hat=torch.tensor([[0.1,0.3,0.6],[0.3,0.2,0.5]])#2个样本在3个类别的预测概率
y=torch.LongTensor([0,2])#这2个样本的标签类别
y_hat.gather(1,y.view(-1,1))#得到2个样本的标签的预测概率

输出:

tensor([[0.1000],
        [0.5000]])

定义交叉熵损失函数:
Pytorch实现softmax回归

#交叉熵损失函数
def cross_entropy(y_hat,y):
	return -torch.log(y_hat.gather(1,y.view(-1,1)))

7.计算分类准确率

定义准确率accuracy函数:

def accuracy(y_hat,y):
	return (y_hat.argmax(dim=1)==y).float().mean().item()
  • y_hat.argmax(dim=1)返回矩阵y_hat每行中最大元素的索引,且返回结果与变量y形状相同。
  • (y_hat.argmax(dim=1) == y)是一个类型为ByteTensor的Tensor,我们用float()将其转换为值为0(相等为假)或1(相等为真)的浮点型Tensor。

评价模型net在数据集data_iter上的准确率:

def evaluate_accuracy(data_iter,net):
	acc_sum,n=0.0,0
	for X,y in data_iter:
		acc_sum+=(net(X).argmax(dim=1)==y).float().sum().item()
		n+=y.shape[0]
	return acc_sum/n

8.训练模型

num_epochs,lr=5,0.1

def train(net,train_iter,test_iter,loss,num_epochs,batch_size,	params=None,lr=None,optimizer=None):
	for epoch in range(num_epochs):
		train_l_sum,train_acc_sum,n=0.0,0.0,0#为了计算损失、准确率
		for X,y in train_iter:#在每一个batch_size中
			y_hat=net(X)
			l=loss(y_hat,y).sum()
			#梯度清零
			if optimizer is not None:
				optimizer.zero_grad()
			elif params is not None and params[0].grad is not None:
				for param in params:
					param.grad.data.zero_()
			l.backward()#计算梯度
			if optimizer is None:
				mp.sgd(params,lr,batch_size)
			else:
				optimizer.step() 				
			train_l_sum+=l.item()#累加loss
			train_acc_sum+=(y_hat.argmax(dim=1)==y).sum().item()#累加准确个数
			n+=y.shape[0]
			
		test_acc=evaluate_accuracy(test_iter,net)
		print('epoch %d,loss %.4f,train acc %.3f,test acc %.3f'
			% (epoch+1,train_l_sum/n,train_acc_sum/n,test_acc))

#调用训练函数
train(net,train_iter,test_iter,cross_entropy,num_epochs,batch_size,[W,b],lr)		

9.预测

X,y=iter(test_iter).next()
true_labels=mp.get_fashion_mnist_labels(y.numpy())
pred_labels=mp.get_fashion_mnist_labels(net(X).argmax(dim=1).numpy())
titles=[true+'\n'+pred for true,pred in zip(true_labels,pred_labels)
mp.show_fashion_mnist(X[0:9],titles[0:9])
相关标签: 人工智能