PyTorch学习 Datawhale

这篇博客介绍了PyTorch的基本概念,包括其起源、特点以及与numpy的对比。详细阐述了如何配置Python环境、安装PyTorch,并通过任务形式讲解了PyTorch的计算图和自动求导功能,以及如何使用PyTorch实现线性回归和简单的神经网络。最后,通过实现逻辑回归展示了PyTorch在分类问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.youkuaiyun.com/guihuo2889/article/details/84652733

5.PyTorch基础概念

参考:
https://blog.youkuaiyun.com/herosunly/article/details/88892326
https://blog.youkuaiyun.com/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 i%500 == 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写网络结构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值