专栏首页拇指笔记【动手学深度学习笔记】之Pytorch实现线性回归

【动手学深度学习笔记】之Pytorch实现线性回归

框架实现线性回归

创建数据集

创建数据集与之前一样,因为没有数据集,所以需要直接创建数据集。

#生成数据集
num_inputs = 2  #特征数,数据集的列数
num_examples = 1000  #样本数,数据集的行数
true_w = [2,-3.4]  #线性模型的真实权重
true_b = 4.2    #线性模型的真实偏差

featrues = torch.randn(num_examples,num_inputs,dtype = torch.float32)
#使用随机张量函数,生成一个1000行2列的随机张量
labels = true_w[0]*featrues[:,0]+true_w[1]*featrues[:,1]+true_b
#使用随机张量作为输入生成一组标签
labels += torch.tensor(np.random.normal(0,0.01,size = labels.size()),dtype = torch.float32)
#为标签加随机噪声,生成随机噪声方法:使用numpy库的random.normal生成一个均值为0,标准差为0.0.1的正态分布,其大小为1行2000个的行向量。
#在这一部分,使用了两种随机矩阵生成的方法,主要区别是第二个为正态分布。且第二种生成的行向量。

读取数据

2020/2/23/19:35

pytorch提供了data包来读取数据。

import torch.utils.data as Data
#避免重名,换名处理

batch_size = 10		#小批量数设置为10
dataset = Data.TensorDataset(features,labels)
#将features和labels转化为pytorch框架可以识别的数据集类型。
#数据集的类型是TensorDataset。
data_iter = Data.DataLoader(dataset,batch_size,shuffle=True)
#DataLoader,生成一个迭代器,shuffle:是否开启打乱顺序。

Data.DataLoader包含多个参数

参数

功能

dataset

Dataset类型,从其中加载数据

batch_size

int类型,每个批量加载多少个数

shuffle

bool类型,每个学习周期都打乱顺序

num_workers

int类型,加载数据时使用多少子进程。默认值为0.

collate_fn

定义如何取样本,可通过定义自己的函数来实现。(太深奥,暂且跳过)

pin_memory

锁页内存处理。(太深奥了,暂且跳过)

drop_last

bool类型,如果有剩余的样本,True表示丢弃;Flase表示不丢弃

使用时牢记

  1. 第一步导入:import torch.utils.data as Data
  2. 第二步转化类型:数据集 = Data.TensorDataset(样本集1,样本集2)
  3. 第三步生成迭代器:迭代器 = Data.DataLoader(数据集,加载数)

定义模型

Pytorch提供了大量预定义的层,使用框架时,主要是需要关注使用哪些层来构造模型。

方法一

使用nn.Module搭配forward来撰写网络或层

class LinearNet(nn.module):
    def __init__(self,n_feature):
        super(LinearNet,self).__init__()
        #类中固有的
        
        self.linear = nn.Linear(n_feature,1)
        #定义一个层。
        
    #定义前向传播
    def forward(self,x):
        y = self.linear(x)
        return y
    
#这一步是打印出网络的结构
net = LinearNet(num_inputs)
print(net)

方法二

使用nn.Sequential来搭建网络,Sequential是一个有序容器,网络层将按照传入容器的顺序依次添加到计算图中。

#这里只介绍一种方法
net = nn.Sequential(
	nn.Linear(num_inputs,1)
    #还可以添加其他层
)

#同样的输出方法
print(net)
#输出第一层
print(net[0])

查看模型参数

通过net.parameters(),可查看模型所有的可学习参数(如权重和偏差),注意:net.parameters()是一个生成器,而非一个函数,所以通过for循环来查看。

for param in net.parameters():
    print(param)

初始化模型参数

使用网络前,需要初始化模型参数,如线性回归模型中的权重和偏差。

#首先导入pytorch中的init模块
from torch.nn import init

#使用init.normal_将第一层的权重参数初始化为均值为0,标准差为0.01的正态分布
init.normal_(net.linear.weight,mean=0,std=0.01)	#这种写法对应方法一
init.normal_(net[0].weight,mean=0,std=0.01)		#这种写法对应方法二

#使用init.constant_将偏差初始化为0
init.normal_(net.linear.bias,val=0)	#这种写法对应方法一
init.constant_(net[0].bias,val=0)	#这种写法对应方法二

#net[0]只适用于net是一个容器时

定义损失函数

pytorch提供了各种损失函数,这些损失函数可看作是一种特殊的层,所以这些损失函数实现为nn.Module的子类。

#本节使用均方差损失作为损失函数
loss = nn.MSELoss()

定义优化算法

pytorch在torch.optim模块中提供了很多优化算法

#本节使用小批量随机梯度下降算法(SGD)
import torch.optim as optim

optimizer = optim.SGD(net.parameters(),lr=0.03)
#lr,设置学习率为0.03;net.parameters()导入模型的参数
print(optimizer)	#输出优化算法的各项参数

扩展内容:

#为不同网络设置不同学习率
optimizer = optim.SGD([
    {'params':net.subnet1.parameters()},	#不设置lr,默认使用最外层的
	{'params':net.subnet2.parameters(),lr=0.01}
],lr = 0.03)
#调整学习率
for param_group in optimizer.param_groups:
    param_group['lr']*=0.1		#学习率调整为之前的0.1倍

训练模型

num_epochs = 3 #学习周期为3
for epoch in range(1,num_epochs+1):
    for X,y in data_iter:
        output = net(X)	#特征值对应的标签
        l = loss(output,y.view(-1,1))	#y.view(-1,1)将y转化为一列的形式,行数无要求
        optimizer.zero_grad()	#同样的梯度需要清零
        l.backward()	#对损失函数求梯度
        optimizer.step()#调用优化函数,计算模型参数
        
    print('epoch %d loss:%f' %(epoch,l.item()))

程序

#需要导入的库
import torch  #张量计算
from IPython import display    #嵌入显示图像
from matplotlib import pyplot as plt  #绘制图像
import numpy as np  #矩阵运算
import random  #生成随机数
import torch.utils.data as Data  #避免重名,换名处理
from torch.nn import init  #导入初始化模块
import torch.nn as nn  #导入构建层需要的模块
import torch.optim as optim  #导入内置优化算法的模块

#生成数据集
num_inputs = 2  #特征数,数据集的列数
num_examples = 1000  #样本数,数据集的行数
true_w = [2,-3.4]  #线性模型的真实权重
true_b = 4.2    #线性模型的真实偏差

featrues = torch.randn(num_examples,num_inputs,dtype = torch.float32)
#使用随机张量函数,生成一个1000行2列的随机张量
labels = true_w[0]*featrues[:,0]+true_w[1]*featrues[:,1]+true_b
#使用随机张量作为输入生成一组标签
labels += torch.tensor(np.random.normal(0,0.01,size = labels.size()),dtype = torch.float32)
#为标签加随机噪声,生成随机噪声方法:使用numpy库的random.normal生成一个均值为0,标准差为0.0.1的正态分布,其大小为1行2000个的行向量。
#在这一部分,使用了两种随机矩阵生成的方法,主要区别是第二个为正态分布。且第二种生成的行向量。
batch_size = 10
dataset = Data.TensorDataset(featrues,labels)

data_iter = Data.DataLoader(dataset,batch_size,shuffle=True)

#输出第一组X和y做测试
# for X,y in data_iter:
#     print(X,y)
#     break

#定义模型
class Linear(nn.Module):
    def __init__(self,n_feature):
        super(Linear,self).__init__()
        
        self.linear = nn.Linear(n_feature,1)
        
    def forward(self,x):
        y = self.linear(x)
        return y

net = Linear(num_inputs)  #实例化这个类

#参数初始化
init.normal_(net.linear.weight,mean=0,std = 0.01)  #初始化权重为均值为0,标准差为0.01正态分布
init.constant_(net.linear.bias,val=0)  #初始化偏差为0

#定义损失函数(均方差损失函数)
loss = nn.MSELoss()

#定义优化算法(同样的小批量随机梯度下降算法)
optimizer = optim.SGD(net.parameters(),lr = 0.03)

#训练过程
num_epochs = 3  #学习周期

for epoch in range(1,num_epochs+1):
    for X,y in data_iter:
        output = net(X)
        l = loss(output,y.view(-1,1))
        optimizer.zero_grad()  #梯度清零
        l.backward()
        optimizer.step()  #计算出优化得到的参数值
    print('epoch %d | loss:%f' %(epoch,l.item()))
    
print(true_w,'\n',net.linear.weight)
print(true_b,'\n',net.linear.bias)

本文分享自微信公众号 - 拇指笔记(shuzhi990),作者:拇指笔记

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【动手学深度学习笔记】之构造MLP模型的几种方法

    Module类是nn模块里提供的一个模型构造类,通过继承Module实现MLP的程序如下

    树枝990
  • 【动手学深度学习笔记】之自定义层

    神经网络中存在着全连接层、卷积层、池化层和循环层等各种各样的层。虽然PyTorch提供了大量常用的层,但有时还是需要我们自定义层。本篇文章介绍如何使用Modul...

    树枝990
  • 三步修改jupyter notebook主题和页面宽度

    最近每天都对着jupyter notebook的默认主题,感觉实在是单调了点。而且jupyter notebook的宽度,实在是让人难受...

    树枝990
  • 深度学习——CNN(3)CNN-AlexNetCNN-GoogleNet其他网络结构

    DC童生
  • LeetCode 402. 移掉K位数字(贪心,单调栈)

    给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

    Michael阿明
  • Hive快速入门系列(4) | 如何将Hive元数据配置到MySql

      上一篇博文我们讲了怎样安装MySql,这篇文章为上篇的后续,此篇文章讲的是如何将Hive元数据配置到MySql。

    不温卜火
  • 全错位排列

    全错位排列是由著名数学家欧拉提出的。 最典型的问题是装错信封问题 一个人写了n封不同的信及相应的n个不同的信封,他把这n封信都装错了信封,问都装错信封的装法有多...

    magicsoar
  • 内网信息搜集(Windows)- 信息搜集篇 - 渗透红队笔记

    LISTENING:表示监听中,这个端口正在开放,可以提供服务 CLOSING:表示关闭的,表示端口人为或者防火墙使其关闭(也许服务被卸载)

    渗透攻击红队
  • 计蒜客蓝桥杯模拟赛 方格填数

    例如: 1×2+9×7=13×5 10×8+12×3=11×4 只要有任意一个方块代表的数字不同,就算两种不同的方案。 请你计算,一共有多...

    小二哥
  • 内网渗透 | 内网中的信息收集

    下文仅限于域内的信息收集,均不会涉及域内认证原理等概念,后面会对windows认证方式单独写一篇总结。

    HACK学习

扫码关注云+社区

领取腾讯云代金券