参考链接: 在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写网络结构