Torch搭网络学习笔记(一)逻辑回归
逻辑回归 regression logistic
逻辑回归的基本思想是寻求一个逻辑函数,将输入的特征(x1,x2)映射到(0-1)内,然后按照是否大于0.5进行二分类。
为了能够进行数学描述,现设定映射关系核逻辑函数;假设该映射关系为线性关系,则有:
即
此时f(x)的值可以是任何值,需要通过逻辑函数进行(0-1)再映射。
逻辑回归中逻辑函数为h(z),即sigmoid函数:
将h(z)在z域上画出,图像为:
可见,在f(x)>0时,特征X将被归于1类,f(x)<0时,特征X将被归于0类。
损失函数:cost损失函数应该越小越好。所以在真实标签为1时,h(z)越接近于1越好,则有:
越接近于0;在真实标签为0时,h(z)越接近于0越好,则有越接近于0;所以最终的损失函数定义为:
上式可以改写为:
有了损失函数,就可利用梯度下降法进行求导优化了。
torch
torch是专门用于搭建神经网络的框架工具,其中封装了nn.Module父类网络结构,可变参数张量Variable,nn.BCEWithLogitsLoss逻辑回归损失函数,.optim.SGD梯度下降函数等一系列网络函数,可以方便快捷的搭建一个神经网络。
1、Variable
就是 变量 的意思。实质上也就是可以变化的量,区别于int变量,它是一种可以变化的变量,这正好就符合了反向传播,参数更新的属性。
具体来说,在pytorch中的Variable就是一个存放会变化值的地理位置,里面的值会不停发生变化,就像一个装鸡蛋的篮子,鸡蛋数会不断发生变化。那谁是里面的鸡蛋呢,自然就是pytorch中的tensor了。(也就是说,pytorch都是由tensor计算的,而tensor里面的参数都是Variable的形式)。如果用Variable计算的话,那返回的也是一个同类型的Variable。tensor 是一个多维矩阵。
2、torch.Tensor([1,2])
生成张量,[1.0,2.0],网络中数据必须是张量,而torch.tensor则是函数,将某类型值转为tensor.
3、torch.manual_seed(2)
设定CPU固定随机数并设定维数,torch.cuda.manual_seed(number
)则为 GPU设定固定随机数,设定后,torch.rand(2)执行时,每次都会生成相同的随机数,便于观察模型的改进和优化。
举个栗子:
现在对数字的大小进行2分类,设定模式类别为大于2的数字分类到1,小于等于2的则分类到0.
假设训练样本一共有4个,样本及标签如下:
,
则利用torch搭建自己的网络并训练的代码如下:
import torch
from torch.autograd import Variable
torch.manual_seed(2)
x_data = Variable(torch.Tensor([[1.0], [2.0], [3.0], [4.0]]))
y_data = Variable(torch.Tensor([[0.0], [0.0], [1.0], [1.0]]))
#定义网络模型
#先建立一个基类Module,都是从父类torch.nn.Module继承过来,Pytorch写网络的固定写法
class Model(torch.nn.Module):
def __init__(self):##固定写法,定义构造函数,参数为self
super(Model, self).__init__() #继承父类,初始父类 or nn.Module.__init__(self)
####定义类中要用到的层和函数
self.linear = torch.nn.Linear(1, 1) #线性映射层,torch自带封装,输入维度和输出维度都为1,即y=linear(x)==y=wx+b,会自动按照
####x和y的维数确定W和B的维数。
def forward(self, x):###定义网络的前向传递过程图
y_pred = self.linear(x)
return y_pred
model = Model() #网络实例化
#定义loss和优化方法
criterion = torch.nn.BCEWithLogitsLoss() #损失函数,封装好的逻辑损失函数即cost函数
optimizer = torch.optim.SGD(model.parameters(), lr=0.01) #进行优化梯度下降
#optimizer = torch.optim.SGD(model.parameters(), lr=0.01, weight_decay=0.001)
#Pytorch类方法正则化方法,添加一个weight_decay参数进行正则化
#befor training
hour_var = Variable(torch.Tensor([[2.5]]))
y_pred = model(hour_var)####有x输入时,会调用forward函数,直接预测一个2.5的分类
print("predict (before training)given", 4, 'is', float(model(hour_var).data[0][0]>0.5))
########
#####开始训练
epochs = 40##迭代次数
for epoch in range(epochs):
#计算grads和cost
y_pred = model(x_data) #x_data输入数据进入模型中####y为预测结果
loss = criterion(y_pred, y_data)#####求损失
print('epoch = ', epoch+1, loss.data[0])
#反向传播三件套,固定使用。定义了loss是某种损失后,直接loss.backword即可更新线性映射中的w和b,直到分类正确。
optimizer.zero_grad() #梯度清零
loss.backward() #反向传播
optimizer.step() #优化迭代
#After training
hour_var = Variable(torch.Tensor([[4.0]]))
y_pred = model(hour_var)
print("predict (after training)given", 4, 'is', float(model(hour_var).data[0][0]>0.5))
运行结果如下:
predict (before training)given 4 is 0.0
predict (after training)given 4 is 1.0
可见,经过训练可以实现正确2分类.
推荐阅读