python基础知识
##设置变量范围
numpy.arrange(0.0,4.0,1.0) # 表示0,1,2,3
##2D画图
import matplotlib.pyplot as plt
plt.plot(x,y)
plt.xlabel('x轴名称')
plt.ylabel('y轴名称')
plt.show()
##3D画图
https://blog.csdn.net/guduruyu/article/details/78050268
##训练过程中实时绘图,Visdom可视化,创建一个web服务,在代码里访问
##训练过程中断点重开,定期存盘
https://zhuanlan.zhihu.com/p/133250753
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
def function(*args,**kwargs) # *args表示不限制输入参数的个数function(1,2,3,x=4)中的1,2,3,**kwargs表示不限制x=4这类的个数
梯度下降
对cost求梯度:采用for循环,对所有样本求梯度(效率高)
对loss求梯度:对一个样本求梯度,加入随机噪声避免陷入鞍点(性能好,耗时)
折中:采用batch,即mini-batch
反向传播
w=torch.Tensor([1.0]) # 创建一个张量
w.requires_grad=True # 该张量需要计算梯度,默认不计算
#计算图越多,容易吃光内存
## 权重更新
w.data=w.data-0.01*w.grad.data # 因为w是tensor,w.grad也是tensor,如果直接计算就要建立计算图,所以要取tensor里面的值进行计算
w.grad.item() # 把w.grad中的值拿出来变成标量,防止产生计算图
w.grad.data.zero_() # 每次更新完梯度需要清零,防止被累加
线性回归
定义一个类
#必须继承于nn.Module或者自己的function封装成一个module
#必须有构造函数__init__,初始化
#必须有forward函数,前馈过程中要执行的计算
class 类名称(torch.nn.Module)
def __init__(self):
super(类名称,self).__init__() #super赋类
self.XX=torch.nn.Linear(1,1) #Linear表示y=wx+b,数字代表权重和偏置的个数,权重个数为输入特征维数,b为输出的维数
def forward(self,x) #前向传播
out=self.XX(x)
return out
model=类名称() #实例化,继承
y=model(x)
optimizer.zero_grad() #清零
loss.backward() #求梯度
optimizer.step() #更新
步骤:求预测值(前馈)→求损失→梯度清零→backward(反馈)→更新
logistic回归
用于分类任务,前馈网络加上logistics,损失函数也要变化。
非线性变换
- 数据集下载
import torchvision
train_set=torchvision.datasets.数据集(root='', train=True, download=True)
test_set=torchvision.datasets.数据集(root='', train=False, download=True)
- 原理
在输出前进行如下公式计算,保证输出值在[0,1]输出概率
经过logistics function后得到的输出需要用于损失函数的计算。
- 损失函数部分
由线性模型的MSE损失变为BCE损失
交叉熵损失BCE:评价两个数据的相似度,越小越好。
#与线性模型代码相似,区别在于前馈网络中需要加上sigmoid函数等
#损失函数需要修改
import torch.nn.functional as F
class 类名称(torch.nn.Module)
def __init__(self):
super(类名称,self).__init__() #super赋类
self.XX=torch.nn.Linear(1,1) #Linear表示y=wx+b,数字代表权重和偏置,权重个数为输入特征维数,b为输出的维数
def forward(self,x) #前向传播
out=F.sigmoid(self.XX(x)) # 进行logistics
return out
model=类名称() #实例化,继承
y=model(x)
criterion=torch.nn.BCELoss(size_average=False) # 交叉熵损失,设置不用求均值,只会影响学习率的设置
loss=criterion(y——pred,y_data)
print(loss.item())
或者
class 类名称(torch.nn.Module)
def __init__(self):
super(类名称,self).__init__() #super赋类
self.XX=torch.nn.Linear(1,1) #Linear表示y=wx+b,数字代表权重和偏置,权重个数为输入特征维数,b为输出的维数
self.sigmoid=torch.nn.Sigmoid()
def forward(self,x) #前向传播
out=self.sigmoid(self.XX(x)) # 进行logistics
return out
处理多维特征的输入
先从8D降6D,6D降4D,4D降1D等
import numpy as np
xy=np.loadtxt('XX.csv',delimiter=',',dtype=np.float32) # loadtxt读取csv文件,delimiter用于定位分隔符
x_data=torch.from_numpy(xy[:,:-1]) # 所有行中最后一列不要,存的是前几列表示特征
y_data=torch.from_numpy(xy[:,[-1]]) # [-1]表示拿出的最后一列以矩阵形式表示,不用[]就表示是向量
#from_numpy创建的是tensor
加载数据集
dataload加载mini-batch数据集。
#训练过程中,外层用于epoch训练周期,内层对batch迭代
for epoch in range(training_epochs):
for i in range(total_batch):
#自建数据集
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
class 数据集名(Dataset):
def __init__(self):
pass
def __getitem__(self,index)
return self.x_data[index],self.y_data[index] # 可以拿出元素内的数进行操作
def __len__(self)
return self.len # 返回数据条数
dataset=数据集名()
train_loader=DataLoader(dataset=datset,batch_size=32,shuffle=True,num_workers=2) #在加载数据集中,训练集shuffle=True,用于打乱顺序,测试集shuffle=False
#训练
for epoch in range(100)
for i,data in enumerate(train_loader,0): # train_loader里面存储的x和y放data中
#1. 准备数据
inputs,labels=data #此处input和label为tensor
#2. 前馈网络
y_pred = model(inputs)
loss=criterion(y_pred,labels)
#3. 反馈
optimizer.zero_grad()
loss.backward()
#4. 更新
optimizer.step()
步骤:准备数据→用class设计模型→构造损失和优化器→循环训练
在torchvision.datasets中内置很多数据集,可从torch.utils.data.Dataset,需要实现__getitem__和__len__,可以用dataloader加载,然后使用多进程加速torch.multiprocessing。
多分类问题
softmax公式中zi为最后一层的输出
使用NLLoss
y=np.array([1,0,0])
z=np.array([0.2,0.1,-0.1]) #最后一层的输出
y_pred=np.exp(z)/np.exp(z).sum() # softmax
loss=(-t*np.log(y_pred)).sum() #NLLoss,可以使用loss=nn.NLLoss()
或者使用交叉熵损失,损失函数与NNLoss相同,但是不做激活
CrossEntropyLoss=LogSoftmax+NLLLoss
#交叉熵损失,最后一层不做激活(非线性)
y=torch.LongTensor([0]) #使用longtensor类型
z=torch.Tensor([[0.2,0.1,-0.1]])
criterion=torch.nnCrossEntropyLoss()
loss=criterion(z,y)
对于图像,需要将[0,255]的像素转成[0,1]的tensor,从(W,H)到(C,W,H)。使用transforms.ToTensor()实现。
transform=transforms.Composed([transforms.ToTensor(),transforms.Normalize((0.1307, ),(0.3081, ))]) #transforms.ToTensor()将图像转为tensor,Normalize正则化,0.1307和0.3081分别为数据集计算出的均值和标准差,该值为minist数据集公开的均值和方差,不同数据集的均值和方差不同。
训练和测试封装成函数
test部分没有梯度更新
if __name__=='__main__':
for epoch in range(10):
train(epoch)
#if epoch%10=0 #每10轮测试一次
test()