PyTorch学习 Datawhale

2020-12-29 14:17:58 浏览数 (1)

参考链接: 在PyTorch中使用Logistic逻辑回归识别手写数字

Datawhale PyTorch学习

 Pytorchtask·1——PyTorch的基本概念1. 什么是PyTorch,为什么选择PyTorch2. 配置Python环境3. 准备Python管理器4. Pytroch的安装5.PyTorch基础概念6. 通用代码实现流程(实现一个深度学习的代码流程)

   task·2——设立计算图并自动计算1.numpy和pytorch实现梯度下降法梯度下降法的一般步骤numpy实现pytroch实现

    2.numpy和pytorch实现线性回归numpy实现线性回归pytroch实现线性回归

    3.pytorch实现一个简单的神经网络

   task·3——PyTorch实现逻辑回归PyTorch基础实现代码用PyTorch类实现Logistic regression,torch.nn.module写网络结构

Pytorch 

PyTorch的前身便是Torch,其底层和Torch框架一样,但是使用Python重新写了很多内容,不仅更加灵活,支持动态图,而且提供了Python接口。它是由Torch7团队开发,是一个以Python优先的深度学习框架,不仅能够实现强大的GPU加速,同时还支持动态神经网络,这是很多主流深度学习框架比如Tensorflow等都不支持的。 PyTorch既可以看作加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络。 

task·1——PyTorch的基本概念 

PyTorch是使用GPU和CPU优化的深度学习张量库。 

1. 什么是PyTorch,为什么选择PyTorch 

PyTorch的前身便是Torch,其底层和Torch框架一样,但是使用Python重新写了很多内容,不仅更加灵活,支持动态图,而且提供了Python接口。它是由Torch7团队开发,是一个以Python优先的深度学习框架,不仅能够实现强大的GPU加速,同时还支持动态神经网络,这是很多主流深度学习框架比如Tensorflow等都不支持的。 PyTorch既可以看作加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络。 

2. 配置Python环境 

基于Mac环境下的安装 两种方法: 1)使用homebrew工具在命令行中输入brew install python3,敲击回车即可自动安装(homebrew可在homebrew官网下载) 2)进入python官网下载最新的python 版本(自带idle) **python多版本共存配置问题** 解决python不同版本之间的冲突问题 环境变量:在系统环境里配置的变量值 

输入echo $PATH 输入python默认进入python2.7 exit()退出当前的python 查找所需python版本的路径,Mac下使用which: 如whichis python3,敲击回车会返回python路径,将路径复制粘贴即可使用 

增加可执行文件,使python2对应python2.7,python3对应python3.7: 1)使用命令ln -s /usr/bin/python2.7 /usr/bin/python2 2)使用命令ln -s /usr/bin/python3.7 /usr/bin/python3 

3. 准备Python管理器 

安装PyCharm 安装Anaconda (不做详细描述,百度进入官网,选择合适版本下载安装即可) 

4. Pytroch的安装 

终端运行: 

conda install pytorch torchvision -c pytorch

可以在PyTorch官网选择需要的版本 conda方法下载很慢,而且我在下载过程中每次到一半就出现问题,然后换了pip方式,如下。 

pip3 install torch torchvision

参考:https://blog.csdn.net/guihuo2889/article/details/84652733 

5.PyTorch基础概念 

参考: https://blog.csdn.net/herosunly/article/details/88892326 https://blog.csdn.net/herosunly/article/details/88915673 

6. 通用代码实现流程(实现一个深度学习的代码流程) 

参考:Pytorch识别手写数字实例 

# -*- coding: utf-8 -*-

import torch

import torchvision

from torchvision import datasets, transforms

# 1. 加载MNIST手写数字数据集数据和标签

transform = transforms.Compose(

    [transforms.ToTensor(),

     transforms.Normalize((0.5, ), (0.5, ))])

trainset = datasets.MNIST(root='./data', train=True,

                            download=True, transform=transform)

trainsetloader = torch.utils.data.DataLoader(trainset, batch_size=20000, shuffle=True)

testset = datasets.MNIST(root='./data', train=True,

                            download=True, transform=transform)

testsetloader = torch.utils.data.DataLoader(testset, batch_size=20000, shuffle=True)

#######如果你不放心数据有没有加载出可以将图片显示出来看下#######

# dataiter = iter(trainsetloader)

# images, labels = dataiter.next()

# import numpy as np

# import matplotlib.pyplot as plt

# plt.imshow(images[0].numpy().squeeze())

# plt.show()

# print(images.shape)

# print(labels.shape)

##########上面这段是显示图片的代码#############

# 2. 设计网络结构

first_in, first_out, second_out = 28*28,  128, 10

model = torch.nn.Sequential(

    torch.nn.Linear(first_in, first_out),

    torch.nn.ReLU(),

    torch.nn.Linear(first_out, second_out),

)

# 3. 设计损失函数

loss_fn = torch.nn.CrossEntropyLoss()

# 4. 设置用于自动调节神经网络参数的优化器

learning_rate = 1e-4

optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

# 5. 训练神经网络(重复训练10次)

for t in range(10):

    for i, one_batch in enumerate(trainsetloader,0):

        data,label = one_batch

        data[0].view(1,784)# 将28x28的图片变成784的向量

        data = data.view(data.shape[0],-1)

        # 让神经网络根据现有的参数,根据当前的输入计算一个输出

        model_output = model(data)

        # 5.1 用所设计算损失(误差)函数计算误差

        loss = loss_fn(model_output , label)

        if iP0 == 0:

            print(loss)

        # 5.2 每次训练前清零之前计算的梯度(导数)

        optimizer.zero_grad()

        # 5.3 根据误差反向传播计算误差对各个权重的导数

        loss.backward()

        # 5.4 根据优化器里面的算法自动调整神经网络权重

        optimizer.step()

# 保存下训练好的模型,省得下次再重新训练

torch.save(model,'./my_handwrite_recognize_model.pt')

##########现在你已经训练好了#################

# 6. 用这个神经网络解决你的问题,比如手写数字识别,输入一个图片矩阵,然后模型返回一个数字

testdataiter = iter(testsetloader)

testimages, testlabels = testdataiter.next()

img_vector = testimages[0].squeeze().view(1,-1)

# 模型返回的是一个1x10的矩阵,第几个元素值最大那就是表示模型认为当前图片是数字几

result_digit = model(img_vector)

print("该手写数字图片识别结果为:", result_digit.max(1)[1],"标签为:",testlabels[0])

运行结果:  

task·2——设立计算图并自动计算 

什么是梯度下降? 梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。在机器学习中,基于基本的梯度下降法发展了两种梯度下降方法,分别为随机梯度下降法和批量梯度下降法。 

梯度下降法(gradient descent)是一个最优化算法,常用于机器学习和人工智能当中用来递归性地逼近最小偏差模型。 

1.numpy和pytorch实现梯度下降法 

梯度下降法的一般步骤 

(1)设定初始值 (2)求取梯度 (3)在梯度方向上进行参数的更新 

numpy实现 

import matplotlib.pyplot as plt

import numpy

x = 0 

# 学习率

learning_rate= 0.1 

# 迭代次数

epochs = 20

# lambda函数定义一个简单的函数,假装是在算loss :)

y = lambda x: x**2 2*x 1 

for epoch in range(epochs):

    dx = 2*x 2 #梯度

    x = x - learning_rate*dx #在梯度上进行更新

    print('x:',x,'y:',y(x))

pytroch实现 

import torch

from torch.autograd import Variable

# 定义一个pytorch类型 且可自动求导的的初始值

x = torch.Tensor([0])# 定义一个tensor,相当于np.array

x = Variable(x,requires_grad=True) # x转变为一个variable,建立计算图的起点;开启requires_grad表示自动计算梯度

print('grad',x.grad,'data',x.data) # grad表示x的梯度属性,表明当前累计的梯度;data表示tensor值

lr = 0.1

epochs = 20

for epoch in range(epochs):

    # 设置计算图:建立一个函数y,以x为变量

    y = x ** 2 2 * x 1

    # Variable 能自动求导==》requires_grad

    y.backward()  # 对y做反向传导==》自动计算梯度,由于当前变量为1个,所以不需要指定

    print('grad of epoch' str(epoch) ':', x.grad.data)

    x.data -= lr * x.grad.data

    # 在 pytorch 中梯度会累积,则每次需要清0

    x.grad.data.zero_()  # xx_表示对变量做inplace操作;此处将当前梯度清0

print(x.data)

2.numpy和pytorch实现线性回归 

numpy实现线性回归 

import torch

from torch.autograd import Variable

# 设置初始变量

x_data = Variable(torch.Tensor([[1], [2], [3]]))

y_data = Variable(torch.Tensor([[2], [4], [6]]))

epochs = 20

lr = 0.1

w = Variable(torch.FloatTensor([0]), requires_grad=True)  # requires_grad一定不要忘记设置

cost = []

for epoch in range(epochs):

    # 计算梯度

    yhat = x_data * w

    loss = torch.mean((yhat - y_data) ** 2)

    cost.append(loss.data.numpy())  # tensor转化为ndarray

    loss.backward()  # 计算loss偏导(仍用loss做目标优化函数)

    # 更新参数

    w.data -= lr * w.grad.data

    w.grad.data.zero_()

print(w.data)

pytroch实现线性回归 

import torch

from torch.autograd import Variable

# 设置初始变量

x_data = Variable(torch.Tensor([[1], [2], [3]]))

y_data = Variable(torch.Tensor([[2], [4], [6]]))

epochs = 20

lr = 0.1

w = Variable(torch.FloatTensor([0]), requires_grad=True)  # requires_grad一定不要忘记设置

cost = []

for epoch in range(epochs):

    # 计算梯度

    yhat = x_data * w

    loss = torch.mean((yhat - y_data) ** 2)

    cost.append(loss.data.numpy())  # tensor转化为ndarray

    loss.backward()  # 计算loss偏导(仍用loss做目标优化函数)

    # 更新参数

    w.data -= lr * w.grad.data

    w.grad.data.zero_()

print(w.data)

3.pytorch实现一个简单的神经网络 

import torch

# class构建一个类,通过class Model写一个神经网络类

class Model(torch.nn.Module):

    # 初始化

    def __init__(self):

        super(Model, self).__init__()

        # super 用来返回Model的父类,在pytorch下定义的类都是继承一个大的父类torch.nn.Module的父类。

        # torch.nn.Module中包含了各种工具,一般我们都是写的都是子类,通过父类我们可以很容易书写子类。

        self.linear = torch.nn.Linear(1, 1, bias=False)

        # 建立一个linear类,bias表示偏置项,建立一个AX b

        # forward 是torch.nn.Module定义好的模板,表示前向传播

    def forward(self, x):

        y_pred = self.linear(x)

        return y_pred

model = Model()  # 实例化类

criterion = torch.nn.MSELoss(reduction='mean') # 平方误差损失

optimizer = torch.optim.SGD(model.parameters(),lr=0.01) #利用梯度下降算法优化model.parameters

from torch.autograd import Variable

torch.manual_seed(2)

x_data = Variable(torch.Tensor([[1], [2], [3]]))

y_data = Variable(torch.Tensor([[2], [4], [6]]))

epochs = 50

cost = []

for epoch in range(epochs):

    # 建立计算图

    y_hat = model(x_data)  # 预测值

    loss = criterion(y_hat, y_data)

    cost.append(loss.data)

    optimizer.zero_grad()  # 对模型参数做一个优化,并且将梯度清0

    loss.backward()  # 计算梯度

    ## 参数更新

    optimizer.step()

print(list(model.parameters()))

参考: PyTorch实现一个简单的神经网络 

task·3——PyTorch实现逻辑回归 

点击查看参考链接: 线型回归、逻辑回归和神经网络的区别 使用PyTorch实现Logistic回归 

PyTorch基础实现代码 

import torch

from torch.autograd import Variable

N = torch.ones(100, 2) #训练样本数

x0 = Variable(torch.normal(2*N, 1))

y0 = Variable(torch.zeros(100, 1))

x1 = Variable(torch.normal(-2*N, 1))

y1 = Variable(torch.ones(100, 1))

x = torch.cat((x0, x1), 0).type(torch.FloatTensor)

y = torch.cat((y0, y1), 0).type(torch.FloatTensor)

#作出散点图

fig, ax = plt.subplots()

labels = ['class 0','class 1']

ax.scatter(x.numpy()[0:len(x0),0], x.numpy()[0:len(x0),1], label=labels[0])

ax.scatter(x.numpy()[len(x0):len(x),0], x.numpy()[len(x0):len(x),1], label=labels[1])

ax.legend()

用PyTorch类实现Logistic regression,torch.nn.module写网络结构

0 人点赞