机器学习-->深度学习-->pytorch学习
来源:互联网 发布:淘宝买iphonex靠谱吗 编辑:程序博客网 时间:2024/03/29 06:14
本篇博文将大概的总结下深度学习框架pytorch的使用,其内容来自我在pytorch官方教程还有网上一些相关资料的总结,加上了一些自己的见解。
张量的说明
标量(Scalar)是只有大小,没有方向的量,如1,2,3等
向量(Vector)是有大小和方向的量,其实就是一串数字,如(1,2)
矩阵(Matrix)是好几个向量拍成一排合并而成的一堆数字,如[1,2;3,4]
标量,向量,矩阵它们三个也是张量,标量是零维的张量,向量是一维的张量,矩阵是二维的张量。
除此之外,张量还可以是四维的、五维等等。
代码示例:
import torchx=torch.Tensor(2,3)##二维的张量print x1.0860e+32 4.5848e-41 7.0424e-380.0000e+00 4.4842e-44 0.0000e+00[torch.FloatTensor of size 2x3]
import torchx=torch.Tensor(4,2,3)##三维张量print x(0 ,.,.) = -7.7057e-06 4.5772e-41 -7.7057e-06 4.5772e-41 0.0000e+00 0.0000e+00(1 ,.,.) = 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 8.1459e-38 0.0000e+00(2 ,.,.) = nan 0.0000e+00 7.7143e-28 2.5353e+30 1.8460e+31 1.7466e+19(3 ,.,.) = 1.8430e-37 0.0000e+00 nan nan 6.0185e-36 2.4062e-38[torch.FloatTensor of size 4x2x3]
4x2x3的张量y由4个2x3的矩阵构成。
torch.tensor与numpy.array的转换
import torchimport numpy as npnp_data = np.arange(6).reshape((2, 3))torch_data = torch.from_numpy(np_data)##将numpy.array转成torch.tensortensor2array = torch_data.numpy()## 将torch.tensort转成numpy.arrayprint torch_dataprint tensor2array,type(tensor2array) 0 1 2 3 4 5[torch.LongTensor of size 2x3][[0 1 2][3 4 5]] <type 'numpy.ndarray'>
pytorch中的一些数学运算
# abs 绝对值计算data = [-1, -2, 1, 2]tensor = torch.FloatTensor(data) # 转换成32位浮点 tensorprint( '\nabs', '\nnumpy: ', np.abs(data), # [1 2 1 2] '\ntorch: ', torch.abs(tensor) # [1 2 1 2])# sin 三角函数 sinprint( '\nsin', '\nnumpy: ', np.sin(data), # [-0.84147098 -0.90929743 0.84147098 0.90929743] '\ntorch: ', torch.sin(tensor) # [-0.8415 -0.9093 0.8415 0.9093])# mean 均值print( '\nmean', '\nnumpy: ', np.mean(data), # 0.0 '\ntorch: ', torch.mean(tensor) # 0.0)
矩阵运算:
# matrix multiplication 矩阵点乘data = [[1,2], [3,4]]tensor = torch.FloatTensor(data) # 转换成32位浮点 tensor# correct methodprint( '\nmatrix multiplication (matmul)', '\nnumpy: ', np.matmul(data, data), # [[7, 10], [15, 22]] '\ntorch: ', torch.mm(tensor, tensor) # [[7, 10], [15, 22]])# !!!! 下面是错误的方法 !!!!data = np.array(data)print( '\nmatrix multiplication (dot)', '\nnumpy: ', data.dot(data), # [[7, 10], [15, 22]] 在numpy 中可行 '\ntorch: ', tensor.dot(tensor) # torch 会转换成 [1,2,3,4].dot([1,2,3,4) = 30.0)
矩阵加法:
import torchimport numpy as npa=torch.rand(5,3)b=torch.rand(5,3)print "a",aprint "b",bprint "a+b",a+bprint "torch.add(a,b)",torch.add(a,b)res=torch.Tensor(5,3)print "torch.add(a,b,out=res)",torch.add(a,b,out=res)##把运算结果存储到res上print "b.add_(a)",b.add_(a)##结果覆盖ba 0.0540 0.2670 0.6704 0.7695 0.9178 0.8770 0.6552 0.4423 0.1735 0.1376 0.1208 0.6674 0.7257 0.1426 0.1134[torch.FloatTensor of size 5x3]b 0.4811 0.7744 0.7762 0.5247 0.6045 0.6148 0.8366 0.8996 0.5378 0.5236 0.4987 0.9592 0.8462 0.8286 0.5010[torch.FloatTensor of size 5x3]a+b 0.5350 1.0413 1.4466 1.2942 1.5223 1.4918 1.4918 1.3419 0.7113 0.6612 0.6195 1.6266 1.5719 0.9712 0.6144[torch.FloatTensor of size 5x3]torch.add(a,b) 0.5350 1.0413 1.4466 1.2942 1.5223 1.4918 1.4918 1.3419 0.7113 0.6612 0.6195 1.6266 1.5719 0.9712 0.6144[torch.FloatTensor of size 5x3]torch.add(a,b,out=res) 0.5350 1.0413 1.4466 1.2942 1.5223 1.4918 1.4918 1.3419 0.7113 0.6612 0.6195 1.6266 1.5719 0.9712 0.6144[torch.FloatTensor of size 5x3]b.add_(a) 0.5350 1.0413 1.4466 1.2942 1.5223 1.4918 1.4918 1.3419 0.7113 0.6612 0.6195 1.6266 1.5719 0.9712 0.6144[torch.FloatTensor of size 5x3]
Tensor的部分截取和numpy里面的切片很类似,操作几乎一样。
autograd自动微分
Variable:
我们把每个张量Tensor理解为鸡蛋,那么Variable就是存放这些鸡蛋(torch.Tensor)的篮子。
import torchfrom torch.autograd import Variable # torch 中 Variable 模块# 先生鸡蛋tensor = torch.FloatTensor([[1,2],[3,4]])# 把鸡蛋放到篮子里, requires_grad是参不参与误差反向传播, 要不要计算梯度variable = Variable(tensor, requires_grad=True)print(tensor)""" 1 2 3 4[torch.FloatTensor of size 2x2]"""print(variable)"""Variable containing: 1 2 3 4[torch.FloatTensor of size 2x2]
Variable 计算, 梯度
Variable用来包裹tensor, 用Variable代替包住的tensor来进行一系列的运算 , 它在背景幕布后面一步步默默地搭建着一个庞大的系统, 叫做计算图, computational graph. 这个图是用来干嘛的? 原来是将所有的计算步骤 (节点) 都连接起来, 最后进行误差反向传递的时候, 一次性将所有 variable 里面的修改幅度 (梯度) 都计算出来。
import torchimport numpy as npfrom torch.autograd import Variablex=Variable(torch.ones(2),requires_grad=True)##用Variable包住一个(2*1)的tensor,并且设置requires_grad=True参与误差反向传播, 要计算梯度z=4*x*xy=z.norm()print "y:",yy.backward()## 反向计算print "x.grad:",x.grad##计算y对x的梯度打印输出y: Variable containing: 5.6569[torch.FloatTensor of size 1]x.grad: Variable containing: 5.6569 5.6569[torch.FloatTensor of size 2]
需要注意:autograd是专门为了BP算法设计的,所以这autograd只对输出值为标量的有用,因为损失函数的输出是一个标量。如果y是一个向量,那么backward()函数就会失效。
autograd的内部机理:
之所以可以实现autograd多亏了Variable和Function这两种数据类型的功劳。要进行autograd必需先将tensor数据包成Variable。Varibale和tensor基本一致,所区别在于多了下面几个属性。
其中data属性返回Variable里面包裹的原始tensor值,就可以将一个Variable类型转换成tensor类型;grad属性返回其梯度值。
variable和function它们是彼此不分开的:
如图,假设我们有一个输入变量input(数据类型为Variable)input是用户输入的,所以其创造者creator为null值,input经过第一个数据操作operation1(比如加减乘除运算)得到output1变量(数据类型仍为Variable),这个过程中会自动生成一个function1的变量(数据类型为Function的一个实例),而output1的创造者就是这个function1。随后,output1再经过一个数据操作生成output2,这个过程也会生成另外一个实例function2,output2的创造者creator为function2。
在这个向前传播的过程中,function1和function2记录了数据input的所有操作历史,当output2运行其backward函数时,会使得function2和function1自动反向计算input的导数值并存储在grad属性中。
creator为null的变量才能被返回导数,比如input,若把整个操作流看成是一张图(Graph),那么像input这种creator为null的被称之为图的叶子(graph leaf)。而creator非null的变量比如output1和output2,是不能被返回导数的,它们的grad均为0。所以只有叶子节点才能被autograd。
获取 Variable 里面的数据
print(variable) # Variable 形式"""Variable containing: 1 2 3 4[torch.FloatTensor of size 2x2]"""print(variable.data) # tensor 形式""" 1 2 3 4[torch.FloatTensor of size 2x2]"""print(variable.data.numpy()) # numpy 形式"""[[ 1. 2.] [ 3. 4.]]
激励函数
import torchimport torch.nn.functional as F # 激励函数都在这from torch.autograd import Variable# 做一些假数据来观看图像x = torch.linspace(-5, 5, 200) # x data (tensor), shape=(100, 1)x = Variable(x)x_np = x.data.numpy() # 换成 numpy array, 出图时用# 几种常用的 激励函数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) softmax 比较特殊, 不能直接显示, 不过他是关于概率的, 用于分类
批训练
DataLoader 是 torch 给你用来包装你的数据的工具. 将 (numpy array 或其他) 数据形式装换成 Tensor, 然后再放进这个包装器中。使用 DataLoader 有什么好处呢? 就是他们帮你有效地迭代数据。
import torchimport torch.utils.data as Datatorch.manual_seed(1) # reproducibleBATCH_SIZE = 5 # 批训练的数据个数x = torch.linspace(1, 10, 10) # x data (torch tensor)y = torch.linspace(10, 1, 10) # y data (torch tensor)# 先转换成 torch 能识别的 Datasettorch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)# 把 dataset 放入 DataLoaderloader = Data.DataLoader( dataset=torch_dataset, # torch TensorDataset format batch_size=BATCH_SIZE, # mini batch size shuffle=True, # 要不要打乱数据 (打乱比较好) num_workers=2, # 多线程来读数据)for epoch in range(3): # 训练所有!整套!数据 3 次 for step, (batch_x, batch_y) in enumerate(loader): # 每一步 loader 释放一小批数据用来学习 # 假设这里就是你训练的地方... # 打出来一些数据 print('Epoch: ', epoch, '| Step: ', step, '| batch x: ', batch_x.numpy(), '| batch y: ', batch_y.numpy())
在神经网络里面输出值和输入值都是Variable类型
利用pytorch实现回归拟合
创建一些假数据来模拟真实的情况. 比如一个一元二次函数: y = a * x^2 + b, 我们给 y 数据加上一点噪声来更加真实的展示它。
#coding:utf-8import torchfrom torch.autograd import Variableimport matplotlib.pyplot as pltimport torch.nn.functional as Fx=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)##torch.unsqueeze返回一个新的tensor,并且在1位置处添加一个新的维度,返回一个shape为(100,1)的tensory=x.pow(2)+0.2*torch.rand(x.size()) ##对y添加一点噪音x,y=Variable(x),Variable(y) ##用Variabvle包裹tensor方便以后求梯度,而且神经网络只能接受Variable类型数据class Net(torch.nn.Module): def __init__(self,n_feature,n_hidden,n_output):##自定义各种层结构 super(Net,self).__init__() 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到达hiddenlayer并且经过relu激活 x=self.predict(x)##x到达输出层,输出层不需要激活,因为回归问题中预测值大小没有区间限制,如果用激活层那么会截断一部分。 return x##在神经网络里面输出值和输入值都是Variable类型net=Net(n_feature=1,n_hidden=10,n_output=1)print netoptimizer=torch.optim.Adam(net.parameters(),lr=0.2) # 传入 net 的所有参数, 学习率loss_func=torch.nn.MSELoss()# 预测值和真实值的误差计算公式 (均方差)plt.ion()plt.show()for t in range(100): prediction=net(x)# 喂给 net 训练数据 x, 输出预测值 loss=loss_func(prediction,y) # 计算两者的误差 optimizer.zero_grad()# 清空上一次反向更新所有参数时的残留的参数梯度,因为每次在反向更新参数(BP算法)时,都会保留上一次每个参数的梯度 loss.backward() ##根据误差计算出每个参数的梯度 optimizer.step() # 以学习效率lr=0.2来更新参数,w=w-lr*alpha(loss)/alpha(w) if t%5 == 0: plt.cla()##动态画图时,每次画出新的图时,擦除上一时刻画出的图。 plt.scatter(x.data.numpy(),y.data.numpy()) plt.plot(x.data.numpy(),prediction.data.numpy(),'r-',lw=5) plt.pause(0.5)
利用pytorch实现分类
#coding:utf-8import torchfrom torch.autograd import Variableimport matplotlib.pyplot as pltimport torch.nn.functional as Fimport torch.nn as nnn_data=torch.ones(100,2)##返回shape为(100,2)的全1张量x0=torch.normal(2*n_data,1)##返回hape为(100,2)的张量,并且每个元素都是从均值为2,方差为1的正态分布中随机获取。y0=torch.zeros(100)##返回shape为(100,1)的全0张量x1=torch.normal(-2*n_data,1)y1=torch.ones(100)# 注意 x, y 数据的数据形式是一定要像下面一样 (torch.cat 是在合并数据)x=torch.cat((x0,x1),0).type(torch.FloatTensor)# FloatTensor = 32-bit floating,dim=0表示在行的方向进行连接y=torch.cat((y0,y1),).type(torch.LongTensor)# LongTensor = 64-bit integer,注意在pytorch分类问题中,标签默认的要设置为LongTensor类型x,y=Variable(x),Variable(y)##将X,y tensor用Variable包裹起来,然后放进神经网络里面class Net(torch.nn.Module): def __init__(self,n_feature,n_hidden,n_output): super(Net,self).__init__() 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 xnet=Net(n_feature=2,n_hidden=10,n_output=2)print netoptimizer=torch.optim.Adam(net.parameters(),lr=0.01)# 传入 net 的所有参数, 学习率loss_func=nn.CrossEntropyLoss()# 预测值和真实值的误差计算公式 (交叉熵)plt.ion()plt.show()##在神经网络里面输出值和输入值都是Variable类型for t in range(100): out=net(x) loss=loss_func(out,y) optimizer.zero_grad() loss.backward() optimizer.step() if t%2==0: plt.cla() #F.softmax(out)得出二维的概率值,是个Variavle类型,1表示在列这个维度上得出每行的最大值,返回最大值和在这个行上的位置index local prediction=torch.max(F.softmax(out),1)[1] pred_y=prediction.data.numpy().squeeze()##.data先将Variable类型转成tensor;.numpy再转成numpy.array类型。 ##squeeze是将多维数据压缩后仅剩1维,那么这里面为什么要加squeeze()呢? ## 因为下边要计算accuracy=sum(pred_y==target_y)/float(200),那么pred_y和target_y要在格式上对齐 ## target_y的shape为(200,)而prediction.data.numpy()的shape为(200,1) target_y=y.data.numpy() plt.scatter(x.data.numpy()[:,0],x.data.numpy()[:,1],c=pred_y,s=100,lw=0,cmap='RdYlGn') accuracy=sum(pred_y==target_y)/float(200) print "accuracy:",accuracy plt.pause(0.2)plt.ioff()plt.show()
利用pytorch实现卷积神经网络(CNN)
#coding:utf-8import torchfrom torch.autograd import Variableimport torch.nn.functional as Fimport torch.nn as nnimport torchvisionimport matplotlib.pyplot as plttorch.manual_seed(1)Epoche=1Batch_size=50LR=0.001Download_mnist=Falsetrain_data=torchvision.datasets.MNIST( root='./mnist/', train=True, transform=torchvision.transforms.ToTensor(),##将numpy.array转成tensor类型,并且将每个像素点从(0-255)压缩到(0-1) download=Download_mnist)torchvision.datasetsprint train_data.train_data.size()print train_data.train_labels.size()print type(train_data)train_loader=torch.utils.data.DataLoader(dataset=train_data,batch_size=Batch_size,shuffle=True)test_data=torchvision.datasets.MNIST( root='./mnist/', train=False, download=True, transform=torchvision.transforms.ToTensor())#test_x=Variable(torch.unsqueeze(test_data.test_data,dim=1),volatile=True).type(torch.FloatTensor)[:20000]/255print 'test_data:',test_data.test_data.size() #(10000L, 28L, 28L) (batch_szie,width,height)test=torch.unsqueeze(test_data.test_data,dim=1)print 'test:',test.size() #转成下面定义的神经网络输入格式,输入格式(10000L, 1L, 28L, 28L) (batch_size,in_channel,width,height)test_x=Variable(test,volatile=True).type(torch.FloatTensor)[:20000]test_y=test_data.test_labels[:20000]class CNN(nn.Module): def __init__(self): super(CNN,self).__init__() self.conv1=nn.Sequential( #input shape(1,28,28) 此时不考虑batch_size nn.Conv2d( in_channels=1,#输入的通道数目,这里只有一个通道 out_channels=16,##输出16张特征图, kernel_size=5,##卷积核5×5 stride=1,#每次移动的步长1 padding=2,##padding=(kernel_size-stride)/2 ), ##output shape(16,28,28) nn.ReLU(), nn.MaxPool2d(kernel_size=2), #output shape(16,14,14) ) self.conv2=nn.Sequential( nn.Conv2d(16,32,5,1,2), ##output shape(32,14,14) nn.ReLU(), nn.MaxPool2d(kernel_size=2), ##output shape(32,7,7) ) self.out=nn.Linear(32*7*7,10) def forward(self,x): x=self.conv1(x) x=self.conv2(x) x=x.view(x.size(0),-1) ##x此时的shape(batch_size,32,7,7),x.size(0)=batch_size,x.view将其变为(batch_size,32*7*7) output=self.out(x)## 上面一步x.view将(batch_size,32,7,7)-->(batch_size,32*7*7),32*7*7的格式满足out输入格式。 return outputcnn=CNN()print cnnoptimizer=torch.optim.Adam(cnn.parameters(),lr=LR)loss_func=nn.CrossEntropyLoss()## 神经网络里面的输入值和输出值都必须是Variable类型for epoch in range(Epoche): for step,(x,y) in enumerate(train_loader): b_x=Variable(x) b_y=Variable(y) output=cnn(b_x) optimizer.zero_grad() loss=loss_func(output,b_y) loss.backward() optimizer.step() if step%50==0: test_output=cnn(test_x) pred_y=torch.max(test_output,1)[1].data.squeeze() accuracy=sum(pred_y==test_y)/float(test_y.size(0)) print('Epoch: ', epoch, '| train loss: %.4f' % loss.data[0], '| test accuracy: %.2f' % accuracy)test_output = cnn(test_x[:10])pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()print(pred_y, 'prediction number')print(test_y[:10].numpy(), 'real number')
- 机器学习-->深度学习-->pytorch学习
- Pytorch写深度学习
- 机器学习&深度学习
- 机器学习&深度学习
- 机器学习&&深度学习
- PyTorch学习
- pytorch 学习
- PyTorch深度学习:60分钟入门(Translation)
- PyTorch 深度学习:60分钟快速入门
- 荐书丨深度学习入门之PyTorch
- 深度学习:pytorch常见错误总结
- PyTorch深度学习:60分钟入门(Translation) PyTorch深度学习:60分钟入门(Translation)
- 机器学习、深度学习概念
- 面试:机器学习--深度学习
- 机器学习之深度学习
- 深度学习&&机器学习&&模式识别
- 机器学习&深度学习资料
- 深度学习 血战 机器学习
- python RuntimeError: maximum recursion depth exceeded
- RxJava 详解
- 揭秘刘安和兄弟连不是骗子吗,手法如此传销,培训机构竟利用网络营销上市 现在互联网这么大,娱乐界乱搞,教育界还乱搞,如今泛媒体时代,人人都是KOL,每个人都是意见领袖,一人一个自媒体号,人人都可以发飙
- JavaScript RegExp对象的方法
- hadoop实例1:MaxTemperature
- 机器学习-->深度学习-->pytorch学习
- JAVA 根据Url把多文件打包成ZIP下载
- CentOS 7安装cmake 2.8.12.2
- angular 学习笔记(一)
- 关于sting临时地址返回问题
- CentOS7使用firewalld打开关闭防火墙与端口
- HDU 6103 Kirinriki(尺取)
- 堆排序建堆的时间复杂度
- hash个人总结c++