文章目录
多维特征数据的输入
对于一个多维数据,其行表示一个样本,列表示样本的特征
对于多维特征的运算,实质上可以当做特征的映射
代码
import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
xy=np.loadtxt('./data/Diabetes_class.csv.gz',delimiter=',',dtype=np.float32)#加载训练集合
x_data = torch.from_numpy(xy[:,:-1])#取前八列
y_data = torch.from_numpy(xy[:,[-1]])#取最后一列
test =np.loadtxt('./data/test_class.csv.gz',delimiter=',',dtype=np.float32)#加载测试集合,这里我用数据集的最后一个样本做测试,训练集中没有最后一个样本
test_x = torch.from_numpy(test)
class Model(torch.nn.Module):
def __init__(self):#构造函数
super(Model,self).__init__()
self.linear1 = torch.nn.Linear(8,6)#8维到6维
self.linear2 = torch.nn.Linear(6, 4)#6维到4维
self.linear3 = torch.nn.Linear(4, 1)#4维到1维
self.sigmoid = torch.nn.Sigmoid()#因为他里边也没有权重需要更新,所以要一个就行了,单纯的算个数
def forward(self, x):#构建一个计算图,就像上面图片画的那样
x = self.sigmoid(self.linear1(x))
x = self.sigmoid(self.linear2(x))#将上面一行的输出作为输入
x = self.sigmoid(self.linear3(x))
return x
model = Model()#实例化模型
criterion = torch.nn.BCELoss(size_average=False)
#model.parameters()会扫描module中的所有成员,如果成员中有相应权重,那么都会将结果加到要训练的参数集合上
optimizer = torch.optim.SGD(model.parameters(),lr=0.1)#lr为学习率,因为0.01太小了,我改成了0.1
for epoch in range(1000):
#Forward
y_pred = model(x_data)
loss = criterion(y_pred,y_data)
print(epoch,loss.item())
#Backward
optimizer.zero_grad()
loss.backward()
#update
optimizer.step()
y_pred = model(x_data)
print(y_pred.detach().numpy())
y_pred2 = model(test_x)
print(y_pred2.data.item())
加载数据集
概念
# Training cycle
for epoch in range(training_epochs):
# Loop over all batches
for i in range(total_batch)
- epoch:表示训练的周期,表示所有的样本都经过前向传播和后向传播才叫一个训练周期
- batch-size:每一次训练的时候所需要的样本数量,这个训练包括了前向传播和后向传播
- iterations:内层循环一共执行了多少次,= 样本数量 ÷ batch-size
np.loadtxt()读取数据
loadtxt适合读取 txt 和 csv 文件,默认读取float类型的值
numpy.loadtxt(
fname, dtype=, comments='#',
delimiter=None, converters=None,
skiprows=0, usecols=None,
unpack=False, ndmin=0)
- frame:表示要读取的文件路径
- dtype:默认是 np.float32
- delimiter:表示分隔符,默认是空格
- skiprows:表示跳过前几行读取,默认是0,如skiprows=2
- usecols:表示要读取哪一些列,从0开始
- unpack:如果设置为true表示分列读取,类似于矩阵的转置,默认是按照行读取
dataloader
可以自动进行小批量数据的生成
#in pcdet/datasets/__init__.py
dataloader = DataLoader(
dataset,
batch_size=batch_size,
num_workers=workers,
shuffle=True,
)
- batch_size:批量的大小
- shuffle:=true时表示随机打乱数据,使得小批量数据具有随机性
- num_workers:读取数据的时候,是否要并行的进程读取数据
torchvision获取数据集
import torchvision
from torch.utils.data import DataLoader
'''
手写数字的数据集,其中训练集有60000个样本,测试集有10000个样本,共分为0-9,10个类
'''
train_set=torchvision.datasets.MNIST(root='./dataset/mnist',train=True,download=True)
test_set=torchvision.datasets.MNIST(root='./dataset/mnist',train=False,download=True)
train_loader=DataLoader(dataset=train_set,batch_size=32,shuffle=True)
test_loader=DataLoader(dataset=test_set,batch_size=32,shuffle=False)
代码
import torch
import numpy as np
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
'''
Dataset是一个抽象函数,不能直接实例化,所以我们要创建一个自己类,继承Dataset
继承Dataset后我们必须实现三个函数:
__init__()是初始化函数,之后我们可以提供数据集路径进行数据的加载
__getitem__()帮助我们通过索引找到某个样本,下标操作
__len__()帮助我们返回数据集大小
DataLoader对数据集先打乱(shuffle),然后划分成mini_batch。
'''
class DiabetesDataset(Dataset):
def __init__(self,filepath):
xy = np.loadtxt(filepath,delimiter=',',dtype=np.float32)
#shape本身是一个二元组(x,y)对应数据集的行数和列数,这里[0]我们取行数,即样本数
self.len = xy.shape[0]
self.x_data = torch.from_numpy(xy[:, :-1])
self.y_data = torch.from_numpy(xy[:, [-1]])
def __getitem__(self, index):
return self.x_data[index],self.y_data[index]
def __len__(self):
return self.len
#定义好DiabetesDataset后我们就可以实例化他了
dataset = DiabetesDataset('./data/Diabetes_class.csv.gz')
#我们用DataLoader为数据进行分组,batch_size是一个组中有多少个样本,shuffle表示要不要对样本进行随机排列
#一般来说,训练集我们随机排列,测试集不。num_workers表示我们可以用多少进程并行的运算
train_loader = DataLoader(dataset=dataset,batch_size=32,shuffle=True,num_workers=2)
class Model(torch.nn.Module):
def __init__(self):#构造函数
super(Model,self).__init__()
self.linear1 = torch.nn.Linear(8,6)#8维到6维
self.linear2 = torch.nn.Linear(6, 4)#6维到4维
self.linear3 = torch.nn.Linear(4, 1)#4维到1维
self.sigmoid = torch.nn.Sigmoid()#因为他里边也没有权重需要更新,所以要一个就行了,单纯的算个数
def forward(self, x):#构建一个计算图,就像上面图片画的那样
x = self.sigmoid(self.linear1(x))
x = self.sigmoid(self.linear2(x))
x = self.sigmoid(self.linear3(x))
return x
model = Model()#实例化模型
criterion = torch.nn.BCELoss(size_average=False)
#model.parameters()会扫描module中的所有成员,如果成员中有相应权重,那么都会将结果加到要训练的参数集合上
optimizer = torch.optim.SGD(model.parameters(),lr=0.1)#lr为学习率
if __name__=='__main__':#if这条语句在windows系统下一定要加,否则会报错
for epoch in range(1000):
for i,data in enumerate(train_loader,0):#取出一个bath
# repare data
inputs,labels = data#将输入的数据赋给inputs,结果赋给labels
#Forward
y_pred = model(inputs)
loss = criterion(y_pred,labels)
print(epoch,loss.item())
#Backward
optimizer.zero_grad()
loss.backward()
#update
optimizer.step()
三种梯度下降
批量梯度下降、随机梯度下降和小批量梯度下降详解
在前面的学习中,前向传播是为了计算损失函数,而后向传播是为了更新各种的参数,在线性回归中,常用梯度下降来更新参数。
这里假设有数据 X = [ [ x 1 1 , x 2 1 ] , [ x 1 2 , x 2 2 ] , … … , [ x 1 n , x 2 n ] ] n × 2 X=[[x_1^1,x_2^1],[x_1^2,x_2^2],……,[x_1^n,x_2^n]]_{n×2} X=[[x11,x21],[x12,x22],……,[x1n,x2n]]n×2, y = [ [ y 1 ] , [ y 2 ] , … … , [ y n ] ] n × 1 y=[[y^1],[y^2],……,[y^n]]_{n×1} y=