1 pytorch和numpy的对比
import torch
import numpy as np
np_data = np.arange(6).reshape((2,3))
torch_data = torch.from_numpy(np_data)
print(
'numpy\n',np_data,
'\ntorch\n',torch_data
)
numpy和torch的数据类型是不一样的一个是numpy的数据类型一个是torch的数据类型
如果要讲torch转变回numpy数据类型,直接加一个.numpy()
就可以了
tensor2array = torch_data.numpy()
print('\ntensor2array\n',tensor2array)
abs的对比
#abs
data = [-1,-2,1,2]
tensor = torch.FloatTensor(data)
print(tensor)
print(np.abs(data))
print(torch.abs(tensor))
可以参考
https://pytorch.org/docs/stable/torch.html#math-operations
查看torch里各种运算的使用
矩阵相乘
data = [[1,2],[3,4]]
tensor = torch.FloatTensor(data) #32-bit floating point
#print(tensor)
print('\nnumpy',np.matmul(data,data),
'\ntorch',torch.mm(tensor,tensor))
mean的对比
print(np.mean(data))
print(torch.mean(tensor))
2 Variable变量
torch用tensor来计算,神经网络里流动的参数都是variable变量形式的,要把数据放在variable里面,让variable逐步更新神经网络
variable默认是不需要求导的,即requires_grad属性默认为False,如果某一个节点requires_grad被设置为True,那么所有依赖它的节点requires_grad都为True。
import torch
import numpy as np
from torch.autograd import Variable
tensor = torch.FloatTensor([[1,2],[3,4]])
variable = Variable(tensor,requires_grad = True)
#这里requires_grad指的是要不要把variable涉及到反向传播中去
#如果要就用True,否则用False
print(tensor)
print(variable)
import torch
import numpy as np
from torch.autograd import Variable
data = [[1,2],[3,4]]
tensor = torch.FloatTensor([[1,2],[3,4]])
variable = Variable(tensor,requires_grad = True)
#参数require_grad = True 表示计算梯度记录下来
print(tensor)
print(variable)
t_out = torch.mean(tensor*tensor)
v_out = torch.mean(variable*variable)
#
#
v_out.backward()#把误差反向传递
##v_out = 1/4*sum(variable*variable)
##d(v_out)/d(var) = 1/4*2*variable = variable/2
#
print(variable.grad) #打印传递后的梯度
print(variable.data) #打印variable里的tensor
#如果要把tensor转变为numpy的形式,要先.data再.numpy
print(variable.data.numpy())
3 激励函数
activate function是用来解决非线性问题的
线性方程y = Wx
将线性方程套上激励就变成了非线性问题y = AF(Wx)
激励函数:relu,tanh,sigmoid
仿真一下各个激励函数的样子:
import torch
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.pyplot as plt
x = torch.linspace(-5,5,200) #在-5到5之间取200个数据点,x的数据类型是tensor的
x = Variable(x) #把tensor变成variable
#画图的时候tensor和variable都不能被matplotlib识别,所以要换成numpy类型
x_np = x.data.numpy()
#F.AF(x)就是用激励函数去处理这个x数据,x是一个variable的数据
#处理出来的也是一个variable类型的要.data换成tensor类型的再.numpy变成numpy类型的
y_relu = F.relu(x).data.numpy()
y_sigmoid = F.sigmoid(x).data.numpy()
y_tanh = F.tanh(x).data.numpy()
y_softplus = F.softplus(x).data.numpy()
#y_softmax = F.softmax(x) 是一个求概率的几率函数,对于分类问题的求解使用的
###然后画四个图来表示激励=函数的结果
plt.figure(1,figsize = (8,6))
plt.subplot(221)
plt.plot(x_np,y_relu,c = 'red',label = 'relu')
plt.ylim((-1,5))
plt.legend(loc = 'best')
plt.subplot(222)
plt.plot(x_np,y_sigmoid,c = 'red',label = 'sigmoid')
plt.ylim((-0.2,1.2))
plt.legend(loc = 'best')
plt.subplot(223)
plt.plot(x_np,y_tanh,c = 'red',label = 'tanh')
plt.ylim((-1.2,1.2))
plt.legend(loc = 'best')
plt.subplot(224)
plt.plot(x_np,y_softplus,c = 'red',label = 'softplus')
plt.ylim((-0.2,6))
plt.legend(loc = 'best')
4 Regression回归问题
回归是将不同属性的一个问题,最后得出一个最后的值,分析各个成分,给一些权重,得到一个评价值。
import torch
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.pyplot as plt
xx = torch.linspace(-1,1,100)
x = torch.unsqueeze(torch.linspace(-1,1,100),dim = 1)
#这个unsqueeze就是把一维的tensor变成二维的,在torch中只能处理二维的数据
print(xx.shape) #torch.Size([100])
print(x.shape) #torch.Size([100, 1])
y = x.pow(2) + 0.2*torch.rand(x.size())#y = x^2 + 一些噪点的影响
#要想用torch的神经网络处理,必须把tensor都变成variable
x,y = Variable(x),Variable(y)
###打印散点图
plt.scatter(x.data.numpy(),y.data.numpy())
plt.show()
上面构造一些数据,然后将用回归的办法来拟合一条曲线
###开始定义神经网络
class Net(torch.nn.Module): #从Module模块继承
#定义阶段
def __init__(self,n_feature,n_hidden,n_output):
super(Net,self).__init__() #继承Net到模块
self.hidden = torch.nn.Linear(n_feature,n_hidden)#隐藏层
self.predict = torch.nn.Linear(n_hidden,n_output)#输出层
#搭建神经网络过程
def forward(self,x):#神经网络前向传递的过程
x = F.relu(self.hidden(x))
x = self.predict(x) #在输出的时候不用激励函数,因为用激励还输会截断一部分值的数据
return x
net = Net(1,10,1) #feature为一维的,只有一个属性x,
print(net)
打印网络看一下
然后开始动态拟合曲线并表示出动态效果:
spyder不显示动态figure:参考
参考之后,窗口能独立显示
import numpy as np
import torch
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.pyplot as plt
xx = torch.linspace(-1,1,100)
x = torch.unsqueeze(torch.linspace(-1,1,100),dim = 1)
#这个unsqueeze就是把一维的tensor变成二维的,在torch中只能处理二维的数据
print(xx.shape) #torch.Size([100])
print(x.shape) #torch.Size([100, 1])
y = x.pow(2) + 0.2*torch.rand(x.size())#y = x^2 + 一些噪点的影响
#rand(size)表示size个0-1的随机数
#要想用torch的神经网络处理,必须把tensor都变成variable
x,y = Variable(x),Variable(y)
####打印散点图
#plt.scatter(x.data.numpy(),y.data.numpy())
#plt.show()
###开始定义神经网络
class Net(torch.nn.Module): #从Module模块继承
#定义阶段
def __init__(self,n_feature,n_hidden,n_output):
super(Net,self).__init__() #继承Net到模块
self.hidden = torch.nn.Linear(n_feature,n_hidden)#隐藏层
self.predict = torch.nn.Linear(n_hidden,n_output)#输出层
#搭建神经网络过程
def forward(self,x):#神经网络前向传递的过程
x = F.relu(self.hidden(x))
x = self.predict(x) #在输出的时候不用激励函数,因为用激励还输会截断一部分值的数据
return x
net = Net(1,10,1) #feature为一维的,只有一个属性x,
print(net)
#可视化步骤
plt.ion() #设置plt为一个动态打印的
#plt.show()
#开始优化
optimizer = torch.optim.SGD(net.parameters(),lr = 0.2)
#用SGD优化器来优化,传入net的参数,学习率是0.2,越高就学习的越快,但是过快会忽略一些细节
#loss function
loss_func = torch.nn.MSELoss()#均方差
#构造一个列表存prediction和loss
prediction_list = []
loss_list = []
for t in range(1000):
prediction = net(x)
loss = loss_func(prediction,y)#计算prediction和y的误差
prediction_list.append(prediction.data.numpy())
loss_list.append(loss.data.numpy())
#优化
optimizer.zero_grad()#每一次反向传递初,将所有梯度归零
loss.backward()#将loss反向传递
optimizer.step() #优化梯度
for t in range(1000):
if t%5 == 0: #每学习五次就打印一次学习结果
plt.pause(0.2)
plt.cla()
plt.scatter(x.data.numpy(),y.data.numpy())#画散点图
plt.plot(x.data.numpy(),prediction_list[t],'r-',lw = 5)#每一次的预测数据,用线画出来
plt.text(-0.5,1.0,'Loss = %.4f' % loss_list[t],fontdict = {'size':20,'color':'red'})
plt.show()
#
plt.ioff()
每次运行的初始数据是不一样的,得到的拟合曲线也不一样,loss也不一样,以上为两次不同的运行结果
刚开始采用0.5的学习率。学习太快了,不收敛,于是,调整到0.2,并加大训练次数100到1000,使结果loss更小一点
5 Classification 分类
首先来构造数据:
import numpy as np
import torch
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.pyplot as plt
n_data = torch.ones(100,2)
x0 = torch.normal(2*n_data,1)
y0 = torch.zeros(100) #这一堆点的标签为0
x1 = torch.normal(-2*n_data,1)
y1 = torch.ones(100) #这一堆点的标签为1
#其中x0,y0,x1,y1分别是两个点簇的坐标和标签值
x = torch.cat((x0,x1),0).type(torch.FloatTensor) #FloatTensor = 32-bit floating
y = torch.cat((y0,y1),).type(torch.LongTensor) #LongTensor = 64-bit integer
#要想用torch的神经网络处理,必须把tensor都变成variable
x,y = Variable(x),Variable(y)
###打印散点图
plt.scatter(x.data.numpy()[:,0],x.data.numpy()[:,1],c = y.data.numpy(),s = 100,lw = 0)
plt.show()
构造两个点簇,表示不同的类,用于神经网络的训练
打印出来结果:
其中:torch.normal()
表示返回一个张量,张量里面的随机数是从相互独立的正态分布中随机生成的
查看神经网络:
import numpy as np
import torch
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.pyplot as plt
n_data = torch.ones(100,2)
x0 = torch.normal(2*n_data)
y0 = torch.zeros(100) #这一堆点的标签为0
x1 = torch.normal(-2*n_data)
y1 = torch.ones(100) #这一堆点的标签为1
#其中x0,y0,x1,y1分别是两个点簇的坐标和标签值
x = torch.cat((x0,x1),0).type(torch.FloatTensor) #FloatTensor = 32-bit floating
y = torch.cat((y0,y1),).type(torch.LongTensor) #LongTensor = 64-bit integer
#要想用torch的神经网络处理,必须把tensor都变成variable
x,y = Variable(x),Variable(y)
####打印散点图
#plt.scatter(x.data.numpy()[:,0],x.data.numpy()[:,1],c = y.data.numpy(),s = 100,lw = 0)
#plt.show()
###开始定义神经网络
class Net(torch.nn.Module): #从Module模块继承
#定义阶段
def __init__(self,n_feature,n_hidden,n_output):
super(Net,self).__init__() #继承Net到模块
self.hidden = torch.nn.Linear(n_feature,n_hidden)#隐藏层
self.predict = torch.nn.Linear(n_hidden,n_output)#输出层
#搭建神经网络过程
def forward(self,x):#神经网络前向传递的过程
x = F.relu(self.hidden(x))
x = self.predict(x) #在输出的时候不用激励函数,因为用激励还输会截断一部分值的数据
return x
net = Net(2,10,2) #feature为二维的,有两个属性x,y
#输出可能是[0,1]表示分类为第一类
#输出为[1,0]表示分类为第0类
print(net)
这个时候loss_function需要使用CrossEntropyLoss,针对于分类问题,会得出一个概率[0.1,0.3,0.6],概率和为1,表示这个数据被分为每一个类的概率是多少
import numpy as np
import torch
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.pyplot as plt
n_data = torch.ones(100,2)
x0 = torch.normal(2*n_data)
y0 = torch.zeros(100) #这一堆点的标签为0
x1 = torch.normal(-2*n_data)
y1 = torch.ones(100) #这一堆点的标签为1
#其中x0,y0,x1,y1分别是两个点簇的坐标和标签值
x = torch.cat((x0,x1),0).type(torch.FloatTensor) #FloatTensor = 32-bit floating
y = torch.cat((y0,y1),).type(torch.LongTensor) #LongTensor = 64-bit integer
#要想用torch的神经网络处理,必须把tensor都变成variable
x,y = Variable(x),Variable(y)
####打印散点图
#plt.scatter(x.data.numpy()[:,0],x.data.numpy()[:,1],c = y.data.numpy(),s = 100,lw = 0)
#plt.show()
###开始定义神经网络
class Net(torch.nn.Module): #从Module模块继承
#定义阶段
def __init__(self,n_feature,n_hidden,n_output):
super(Net,self).__init__() #继承Net到模块
self.hidden = torch.nn.Linear(n_feature,n_hidden)#隐藏层
self.predict = torch.nn.Linear(n_hidden,n_output)#输出层
#搭建神经网络过程
def forward(self,x):#神经网络前向传递的过程
x = F.relu(self.hidden(x))
x = self.predict(x) #在输出的时候不用激励函数,因为用激励还输会截断一部分值的数据
return x
net = Net(2,10,2) #feature为二维的,有两个属性x,y
#输出可能是[0,1]表示分类为第一类
#输出为[1,0]表示分类为第0类
print(net)
#可视化步骤
plt.ion() #设置plt为一个动态打印的
#plt.show()
#开始优化
optimizer = torch.optim.SGD(net.parameters(),lr = 0.02)
#用SGD优化器来优化,传入net的参数,学习率是0.02,越高就学习的越快,但是过快会忽略一些细节
#loss function
#loss_func = torch.nn.MSELoss()#均方差
loss_func = torch.nn.CrossEntropyLoss()
for t in range(100):
out = net(x)#此时的输出可能是[-2,-12,20,18]要在后面转化为概率
loss = loss_func(out,y)#计算prediction和y的误差
#优化
optimizer.zero_grad()#每一次反向传递初,将所有梯度归零
loss.backward()#将loss反向传递
optimizer.step() #优化梯度
if t%2 == 0:
plt.cla()
prediction = torch.max(F.softmax(out),1)[1] #softmax转换成概率,并取出概率最大的一个
pred_y = prediction.data.numpy().squeeze()
target_y = y.data.numpy()
plt.scatter(x.data.numpy()[:,0],x.data.numpy()[:,1],c = pred_y,s = 100,lw = 0)
accuracy = sum(pred_y == target_y)/200
plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy, fontdict={'size': 20, 'color': 'red'})
plt.pause(0.1)
##
plt.ioff()
plt.show()