莫烦pytorch学习记录
感谢莫烦大神Pytorch B站视频:https://www.bilibili.com/video/av15997678?p=11
一个博主的笔记:https://blog.csdn.net/Will_Ye/article/details/104516423
一、PyTorch是什么?
它是一个基于Python的科学计算包,其主要是为了解决两类场景:
1、一种是可以替代Numpy进行科学计算,同时还可以使用张量在GPU上进行加速运算。
2、一个深度学习的研究平台,提供最大的灵活性和速度。
二、Numpy与Torch之间的转换
import torch
import numpy as np
from torch.autograd import Variable # torch 中 Variable 模块 ### Torch 自称为神经网络界的 Numpy,
# 因为他能将 torch 产生的 tensor 放在 GPU 中加速运算
np_data = np.arange(6).reshape((2,3))
torch_data = torch.from_numpy(np_data) #torch形式
tensor2array = torch_data.numpy() # numpy形式
# torch 做的和 numpy 能很好的兼容.
# 比如这样就能自由地转换 numpy array 和 torch tensor 了
print(
'\nnumpy array:', np_data, # [[0 1 2], [3 4 5]]
'\ntorch tensor:', torch_data, # 0 1 2 \n 3 4 5 [torch.LongTensor of size 2x3]
'\ntensor to array:', tensor2array, # [[0 1 2], [3 4 5]]
)
numpy array: [[0 1 2]
[3 4 5]]
torch tensor: tensor([[0, 1, 2],
[3, 4, 5]], dtype=torch.int32)
tensor to array: [[0 1 2]
[3 4 5]]
三、Torch中的数学运算与numpy的对比
API手册
常用计算: 注意!!!!所有在pytorch
里的计算,都要先转换为tensor
的形式,不然就报错,切记!!!
#abs绝对值运算
data = [-1, -2, 1, 2]
tensor = torch.FloatTensor(data) # 转换成32位浮点tensor
print(
'\nabs',
'\nnumpy: ', np.abs(data), # [1 2 1 2]
'\ntorch: ', torch.abs(tensor) # [1 2 1 2]
) #sin 三角函数 sin
print(
'\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
)
矩阵计算:注意,有些numpy的封装的函数跟pytorch的不一样,这一点一定要区分清楚,也是很容易出问题的一个地方。
# matrix multiplication 矩阵点乘
data = [[1,2], [3,4]]
tensor = torch.FloatTensor(data) # 转换成32位浮点 tensor
# correct method
print(
'\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 中可行
# 关于 tensor.dot() 有了新的改变, 它只能针对于一维的数组. 所以上面的有所改变.
# '\ntorch: ', tensor.dot(tensor) # torch 会转换成 [1,2,3,4].dot([1,2,3,4) = 30.0
# 变为
# '\ntorch: ', torch.dot(tensor.dot(tensor))#
)
四、Variable
tensor = torch.FloatTensor([[1,2],[3,4]])
# 里面的值会不停的变化. 就像一个裝鸡蛋的篮子, 鸡蛋数会不停变动.
# 那谁是里面的鸡蛋呢, 自然就是 Torch 的 Tensor 咯.
# 如果用一个 Variable 进行计算, 那返回的也是一个同类型的 Variable.
# 把鸡蛋放到篮子里,
variable = Variable(tensor, requires_grad=True)#requires_grad是参不参与误差反向传播, 要不要计算梯度 print('\n',tensor)
"""
1 2
3 4
[torch.FloatTensor of size 2x2]
""" print(variable)
"""
Variable containing:
1 2
3 4
[torch.FloatTensor of size 2x2]
"""
variable的计算
模仿一个计算梯度的情况
比较tensor的计算和variable的计算,在正向传播它们是看不出有什么不同的,而且variable
和tensor
有个很大的区别,variable
是存储变量的,是会改变的,而tensor
是不会改变的,是我们输入时就设定好的参数,variable
会在反向传播后修正自己的数值。 这是我觉得他们最大的不同。
t_out = torch.mean(tensor*tensor) # x^2
v_out = torch.mean(variable*variable) # x^2
print('\n',t_out)
print('\n',v_out) # 7.5
假设mean的均值做为结果的误差,对误差反向传播得到各项梯度。利用这个例子去看,在反向传播中它们之间的不同。
v_out = torch.mean(variable*variable)
就是给各个variable
搭建一个运算的步骤,搭建的网络也是其中一种运算的步骤。
v_out.backward() # 模拟 v_out 的误差反向传递,在背景计算图中加速运算
# 下面两步看不懂没关系, 只要知道 Variable 是计算图的一部分, 可以用来传递误差就好.
# v_out = 1/4 * sum(variable*variable) 这是计算图中的 v_out 计算步骤
# 针对于 v_out 的梯度就是, d(v_out)/d(variable) = 1/4*2*variable = variable/2
print('\n',variable.grad) # 初始 Variable 的梯度
'''
0.5000 1.0000
1.5000 2.0000
'''
可以看到,在backward中已经计算好梯度了,利用*.grad将背景中计算好的variable的各项梯度print出来。
这样如果是个网络的运算步骤也可以在backward中将各个梯度计算好。
获取Variable里面的数据
直接print(variable)
只会输出 Variable
形式的数据, 在很多时候是用不了的(比如想要用 plt
画图), 需要转换成tensor
形式.
## 获取 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.]]
"""
五、常用几种激励函数及图像
常用几种激励函数:relu
, sigmoid
, tanh
, softplus
# 做一些假数据来观看图像
x = torch.linspace(-5, 5, 200) # x data (tensor), shape=(100, 1)
x = Variable(x)
# Torch 中的激励函数有很多, 不过我们平时要用到的就这几个.
# relu, sigmoid, tanh, softplus. 那我们就看看他们各自长什么样啦.
x_np = x.data.numpy() # 换成 numpy array, 出图时用
莫烦大神那时的版本用的是torch.nn.relu
,但后来版本改了,直接用torch.relu
就可以,其他激励函数也一样。
# 几种常用的 激励函数
y_relu = F.relu(x).data.numpy()
y_sigmoid = torch.sigmoid(x).data.numpy()
y_tanh = torch.tanh(x).data.numpy()
y_softplus = F.softplus(x).data.numpy()
# y_softmax = F.softmax(x) softmax 比较特殊, 不能直接显示, 不过他是关于概率的, 用于分类
#用pit画
plt.figure(1,figsize=(8,6))
plt.subplot(221)
plt.plot(x_np,y_relu, c='red', label='relu')
plt.ylim(-1,5)
plt.legend(loc='best') plt.subplot(222)
plt.plot(x_np,y_sigmoid, c='red',label='sigmoid')
plt.ylim(-0.2,1.2)
plt.legend(loc='best') plt.subplot(223)
plt.plot(x_np,y_tanh, c='red',label='tanh')
plt.ylim(-1.2,1.2)
plt.legend(loc='best') plt.subplot(224)
plt.plot(x_np,y_softplus, c='red',label='softplus')
plt.ylim(-0.2,6)
plt.legend(loc='best')
#用ax画
fig, ax = plt.subplots(2,2,figsize=(8,6))
ax[0,0].plot(x_np,y_relu,c='red', label='relu')
ax[0,0].set_title('relu',fontsize=18)
ax[0,0].set_ylim(-1,5)
ax[0,0].legend() ax[0,1].plot(x_np,y_sigmoid)
ax[1,0].plot(x_np,y_tanh)
ax[1,1].plot(x_np,y_softplus)
plt.show()
六、线性拟合回归
import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F
#######捏造数据#######
x = torch.unsqueeze(torch.linspace(-1,1,500),dim=1)#x的数据,shape=(500,1)
y = x.pow(2) + 0.2*torch.rand(x.size())
# 画图看看捏的数据咋样
fig,ax = plt.subplots(2,1)
ax[0].scatter(x.data.numpy(),y.data.numpy())
ax[0].set_title("Pinched data",fontsize=18)
搭建网络
# 建立一个神经网络我们可以直接运用 torch 中的体系. 先定义所有的层属性(__init__()),
# 然后再一层层搭建(forward(x))层于层的关系链接. 建立关系的时候, 我们会用到激励函数.
class Net(torch.nn.Module): #继承torch中的Module
def __init__(self,n_feature,n_hidden,n_output):
super(Net, self).__init__() #继承__init__功能
# 定义每层用什么样的形式
self.hidden = torch.nn.Linear(n_feature,n_hidden) # 隐藏层线性输出
self.predict = torch.nn.Linear(n_hidden,n_output) # 输出层线性输出 def forward(self,x): # 这同时也是Module中的forward功能
# 正向传播输入值,神经网络分析出输出值
x = F.relu(self.hidden(x)) # 激励函数(隐藏层的线性值)
x = self.predict(x) # 输出值
return x net = Net(n_feature=1, n_hidden=10, n_output=1)
print(net)
"""
Net (
(hidden): Linear (1 -> 10)
(predict): Linear (10 -> 1)
)
"""
开始训练
#optimizer训练工具
optimizer = torch.optim.SGD(net.parameters(), lr=0.2) # 传入net的所有参数,学习率
loss_func = torch.nn.MSELoss() # 预测值和真实值的误差计算公式(均方差) plt.ion()
for t in range(10000):
prediction = net(x) # 喂给net训练数据x,输出预测值
loss = loss_func(prediction, y) # 计算两者的误差,#要预测值在前,label在后 optimizer.zero_grad() # 清空上一步的残余更新参数值,#net.parameters()所有参数梯度变为0
loss.backward() # 误差反向传播,计算参数更新
optimizer.step() # 将参数更新施加到net的parameters上,#optimizr优化parameters
可视化训练过程
if t % 5 == 0:
# plot and show learning process
ax[1].cla()
ax[1].scatter(x.data.numpy(), y.data.numpy())
ax[1].plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
ax[1].text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})
plt.pause(0.01)
#如果在脚本中使用ion()命令开启了交互模式,没有使用ioff()关闭的话,
# 则图像会一闪而过,并不会常留。要想防止这种情况,需要在plt.show()之前加上ioff()命令。
plt.ioff()
plt.show()
七、区分类型 (分类)
捏个数据
import torch
import matplotlib.pyplot as plt # 假数据
n_data = torch.ones(100, 2) # 数据的基本形态
x0 = torch.normal(2*n_data, 1) # 类型0 x data (tensor), shape=(100, 2)
y0 = torch.zeros(100) # 类型0 y data (tensor), shape=(100, )
x1 = torch.normal(-2*n_data, 1) # 类型1 x data (tensor), shape=(100, 1)
y1 = torch.ones(100) # 类型1 y data (tensor), shape=(100, ) # 注意 x, y 数据的数据形式是一定要像下面一样 (torch.cat 是在合并数据)
x = torch.cat((x0, x1), 0).type(torch.FloatTensor) # FloatTensor = 32-bit floating
y = torch.cat((y0, y1), ).type(torch.LongTensor) # LongTensor = 64-bit integer # 画图 会出错:会报错,因为画图x和y的数量不相同,x矩阵的形状是(200,2)的,而y矩阵的形状是(200),
# 所以需要把x分成两部分来画图才可以的。
# plt.scatter(x.data.numpy(), y.data.numpy())
# plt.show()
# 画图
plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=y.data.numpy(), s=100, lw=0, cmap='RdYlGn')
plt.show()
搭个网络
class Net(torch.nn.Module):
def __init__(self,n_feature,n_hidden,n_outpot):
super(Net,self).__init__() #继承__init__的功能
self.hidden = torch.nn.Linear(n_feature,n_hidden)
self.out = torch.nn.Linear(n_hidden,n_outpot) def forward(self,x):
x = torch.relu(self.hidden(x))
x = self.out(x)
return x net = Net(n_feature=2,n_hidden=10,n_outpot=2) print(net)
训练网络
optimizer = torch.optim.SGD(net.parameters(), lr=0.02) # 传入 net 的所有参数, 学习率
# 算误差的时候, 注意真实值!不是! one-hot 形式的, 而是1D Tensor, (batch,)
# 但是预测值是2D tensor (batch, n_classes)
loss_func = torch.nn.CrossEntropyLoss() for t in range(100):
out = net(x) # 喂给 net 训练数据 x, 输出分析值 loss = loss_func(out, y) # 计算两者的误差 optimizer.zero_grad() # 清空上一步的残余更新参数值
loss.backward() # 误差反向传播, 计算参数更新值
optimizer.step() # 将参数更新值施加到 net 的 parameters 上
可视化
plt.ion()
for t in range(100):
out = net(x) # 喂给 net 训练数据 x, 输出分析值 loss = loss_func(out, y) # 计算两者的误差 optimizer.zero_grad() # 清空上一步的残余更新参数值
loss.backward() # 误差反向传播, 计算参数更新值
optimizer.step() # 将参数更新值施加到 net 的 parameters 上
# 接着上面来
if t % 2 == 0:
plt.cla()
# 过了一道 softmax 的激励函数后的最大概率才是预测值
prediction = torch.max(F.softmax(out), 1)[1]
#prediction=torch.max(F.softmax(out), 1) 中的1,表示【0,0,1】预测结果中,结果为1的结果的位置。
pred_y = prediction.data.numpy().squeeze()#利用squeeze()函数将表示向量的数组转换为秩为1的数组,这样利用matplotlib库函数画图时,就可以正常的显示结果了
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) / 200. # 预测中有多少和真实值一样
plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy, fontdict={'size': 20, 'color': 'red'})
plt.pause(0.1) plt.ioff()
plt.show()
八、快速搭建法
Torch 中提供了很多方便的途径, 同样是神经网络, 能快则快, 我们看看如何用更简单的方式搭建同样的回归神经网络.
上一节用的方法更加底层,其实有更加快速的方法,对比一下就很清楚了:
Method 1
我们用 class 继承了一个 torch 中的神经网络结构, 然后对其进行了修改
class Net(torch.nn.Module): #我们用 class 继承了一个 torch 中的神经网络结构, 然后对其进行了修改
def __init__(self,n_feature,n_hidden,n_outpot):
super(Net,self).__init__() #继承__init__的功能,
self.hidden = torch.nn.Linear(n_feature,n_hidden)
self.out = torch.nn.Linear(n_hidden,n_outpot) def forward(self,x):
x = torch.relu(self.hidden(x))
x = self.out(x)
return x net1 = Net(n_feature=2,n_hidden=10,n_outpot=2)
Method 2
用nn
库里一个函数就能快速搭建了,注意ReLU
也算做一层加入到网络序列中
net2 = torch.nn.Sequential(
torch.nn.Linear(2,10),
torch.nn.ReLU(),
torch.nn.Linear(10,2)
)
print(net1)
print(net2)
结果是类似的:就是net2中将ReLU也做为一个神经层
print(net1)
"""
Net(
(hidden): Linear(in_features=2, out_features=10, bias=True)
(out): Linear(in_features=10, out_features=2, bias=True)
)
"""
print(net2)
"""
Sequential(
(0): Linear(in_features=2, out_features=10, bias=True)
(1): ReLU()
(2): Linear(in_features=10, out_features=2, bias=True)
)
"""
九、保存与提取网络
保存
#######捏造数据#######
torch.manual_seed(1) # reproducible 使得每次随机初始化的随机数是一致的
x = torch.unsqueeze(torch.linspace(-1,1,500),dim=1)#x的数据,shape=(500,1)
y = x.pow(2) + 0.2*torch.rand(x.size()) def save():
# 搭建网络
net1 = torch.nn.Sequential(
torch.nn.Linear(1, 10),
torch.nn.ReLU(),
torch.nn.Linear(10, 1),
)
optimizer = torch.optim.SGD(net1.parameters(), lr=0.5)
loss_func = torch.nn.MSELoss()
# 训练
for t in range(100):
prediction = net1(x)
loss = loss_func(prediction, y)
optimizer.zero_grad()
loss.backward()
optimizer.step() torch.save(net1, 'net.pkl') # 保存整个网络
torch.save(net1.state_dict(), 'net_params.pkl') # 只保存网络中的参数 (速度快, 占内存少)
提取网络
# 这种方式将会提取整个神经网络, 网络大的时候可能会比较慢.
def restore_net():
# restore entire net1 to net2
net2 = torch.load('net.pkl')
prediction = net2(x)
只提取网络参数
# 这种方式将会提取所有的参数, 然后再放到你的新建网络中.
def restore_params():
# 新建 net3
net3 = torch.nn.Sequential(
torch.nn.Linear(1, 10),
torch.nn.ReLU(),
torch.nn.Linear(10, 1)
) # 将保存的参数复制到 net3
net3.load_state_dict(torch.load('net_params.pkl'))
prediction = net3(x)
完整代码并查看三个网络模型的结果
import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F
from matplotlib import animation
#######捏造数据#######
torch.manual_seed(1) # reproducible 使得每次随机初始化的随机数是一致的
x = torch.unsqueeze(torch.linspace(-1,1,100),dim=1)#x的数据,shape=(500,1)
y = x.pow(2) + 0.2*torch.rand(x.size()) def save():
# 搭建网络
net1 = torch.nn.Sequential(
torch.nn.Linear(1, 100),
torch.nn.ReLU(),
torch.nn.Linear(100, 1),
)
optimizer = torch.optim.SGD(net1.parameters(), lr=0.3)
loss_func = torch.nn.MSELoss()
# 训练
for t in range(1000):
prediction = net1(x)
loss = loss_func(prediction, y)
optimizer.zero_grad()
loss.backward()
optimizer.step() torch.save(net1, 'net.pkl') # 保存整个网络
torch.save(net1.state_dict(), 'net_params.pkl') # 只保存网络中的参数 (速度快, 占内存少) # plot result
plt.figure(1, figsize=(10,3))
plt.subplot(131)
plt.title('Net1')
plt.scatter(x.data.numpy(), y.data.numpy())
plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5) # 这种方式将会提取整个神经网络, 网络大的时候可能会比较慢.
def restore_net():
# restore entire net1 to net2
net2 = torch.load('net.pkl')
prediction = net2(x) # plot result
plt.figure(1, figsize=(10,3))
plt.subplot(132)
plt.title('Net2')
plt.scatter(x.data.numpy(), y.data.numpy())
plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5) # 这种方式将会提取所有的参数, 然后再放到你的新建网络中.
def restore_params():
# 新建 net3
net3 = torch.nn.Sequential(
torch.nn.Linear(1, 100),
torch.nn.ReLU(),
torch.nn.Linear(100, 1)
) # 将保存的参数复制到 net3
net3.load_state_dict(torch.load('net_params.pkl'))
prediction = net3(x)
# plot result
plt.figure(1, figsize=(10,3))
plt.subplot(133)
plt.title('Net3')
plt.scatter(x.data.numpy(), y.data.numpy())
plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5) # 保存 net1 (1. 整个网络, 2. 只有参数)
save() # 提取整个网络
restore_net() # 提取网络参数, 复制到新网络
restore_params() plt.show()
十、批训练
进行批量训练需要用到一个很好用的工具DataLoader
。
注意,莫烦大神用的版本跟现在新版还是有些出入的,用Data.TensorDataset
这个函数,不要指定data_tensor
和target_tensor
会报错的,因为新版的库改了,直接输入x
和y
就行了。
数据分批
import torch
import torch.utils.data as tud
torch.manual_seed(1) BATCH_SIZE = 20 #批训练的数据个数,每批20个
#######捏造数据#######
x = torch.unsqueeze(torch.linspace(-1,1,100),dim=1)#x的数据,shape=(100,1)
y = x.pow(2) + 0.2*torch.rand(x.size()) # 先转换成 torch 能识别的 Dataset
# torch_dataset = DL.TensorDataset(data_tensor=x, target_tensor=y)
# 新版的库改了,直接输入x和y就行了。
torch_dataset = tud.TensorDataset(x,y) # 把dataset放入DataLoader
loader = tud.DataLoader(
dataset=torch_dataset, # 转换好的torch能识别的dataset导入DataLoader
batch_size=BATCH_SIZE, # 每批的大小是多大
shuffle=True, # 要不要打乱数据顺序(一般打乱比较好)
num_workers=2 # 多线程来读取数据 )
分批训练
epoch表示整体数据训练次数,step则是每一批数据里面有几组数据
def show_batch():
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()) if __name__ == '__main__':
show_batch()
"""
Epoch: 0 |Step: 0 |batch x: [ 5. 7. 10. 3. 4.] |batch y: [6. 4. 1. 8. 7.]
Epoch: 0 |Step: 1 |batch x: [2. 1. 8. 9. 6.] |batch y: [ 9. 10. 3. 2. 5.]
Epoch: 1 |Step: 0 |batch x: [ 4. 6. 7. 10. 8.] |batch y: [7. 5. 4. 1. 3.]
Epoch: 1 |Step: 1 |batch x: [5. 3. 2. 1. 9.] |batch y: [ 6. 8. 9. 10. 2.]
Epoch: 2 |Step: 0 |batch x: [ 4. 2. 5. 6. 10.] |batch y: [7. 9. 6. 5. 1.]
Epoch: 2 |Step: 1 |batch x: [3. 9. 1. 8. 7.] |batch y: [ 8. 2. 10. 3. 4.]
"""
可以看出, 每步都导出了5个数据进行学习. 然后每个 epoch 的导出数据都是先打乱了以后再导出。
改变一下 BATCH_SIZE = 8
, 这样我们就知道, step=0
会导出8个数据, 但是, step=1
时数据库中的数据不够 8个, 这时怎么办呢:这时, 在 step=1
就只给你返回这个 epoch 中剩下的数据就好了.
Epoch: 0 |Step: 0 |batch x: [ 5. 7. 10. 3. 4. 2. 1. 8.] |batch y: [ 6. 4. 1. 8. 7. 9. 10. 3.]
Epoch: 0 |Step: 1 |batch x: [9. 6.] |batch y: [2. 5.]
Epoch: 1 |Step: 0 |batch x: [ 4. 6. 7. 10. 8. 5. 3. 2.] |batch y: [7. 5. 4. 1. 3. 6. 8. 9.]
Epoch: 1 |Step: 1 |batch x: [1. 9.] |batch y: [10. 2.]
Epoch: 2 |Step: 0 |batch x: [ 4. 2. 5. 6. 10. 3. 9. 1.] |batch y: [ 7. 9. 6. 5. 1. 8. 2. 10.]
Epoch: 2 |Step: 1 |batch x: [8. 7.] |batch y: [3. 4.]
十一、Optimizer 优化器
各种不同的优化器 在同一个网路上的对比
SGD
是最普通的优化器, 也可以说没有加速效果, 而 Momentum
是 SGD
的改良版, 它加入了动量原则. 后面的 RMSprop
又是 Momentum
的升级版. 而 Adam
又是 RMSprop
的升级版. 不过从这个结果中我们看到, Adam
的效果似乎比 RMSprop
要差一点. 所以说并不是越先进的优化器, 结果越佳.
1.捏一个数据
import torch
import torch.utils.data as tud
import matplotlib.pyplot as plt torch.manual_seed(1) LR = 0.01
BATCH_SIZE = 32
EPOCH = 12 ######捏一个数据######
x = torch.unsqueeze(torch.linspace(-1,1,1000),dim=1)
y = x.pow(2) + 0.1*torch.normal(torch.zeros(*x.size())) plt.scatter(x.numpy(),y.numpy())
plt.show()
torch_dataset = tud.TensorDataset(x,y)
loader = tud.DataLoader(
dataset=torch_dataset,
batch_size=BATCH_SIZE,
shuffle=True,
num_workers=2
)
2.建立同样的网络
# 搭建同样的网络Net
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(1,20)
self.predict = torch.nn.Linear(20,1) def forward(self,x):
x = torch.ReLU(self.hidden(x))
x = self.predict(x)
return x
# 为每个优化器创建一个net
net_SGD = Net()
net_Momentum = Net()
net_RMSprop = Net()
net_Adam = Net()
nets = [net_SGD,net_Momentum,net_RMSprop,net_Adam]
3.不同的optimizer
接下来在创建不同的优化器, 用来训练不同的网络. 并创建一个 loss_func
用来计算误差. 我们用几种常见的优化器, SGD
, Momentum
, RMSprop
, Adam
.
# different optimizers
opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam] loss_func = torch.nn.MSELoss()
losses_his = [[], [], [], []] # 记录 training 时不同神经网络的 loss
4.训练出图
for epoch in range(EPOCH):
print('Epoch',epoch)
for step,(b_x,b_y) in enumerate(loader):
# 对每个优化器, 优化属于他的神经网络
for net, opt, l_his in zip(nets, optimizers, losses_his):
output = net(b_x) # 获得每个网络的输出
loss = loss_func(output, b_y) # compute loss for every net
opt.zero_grad() # clear gradients for next train
loss.backward() # backpropagation, compute gradients
opt.step() # apply gradients
l_his.append(loss.data.numpy()) # loss recoder labels = ['SGD', 'MoMENTUM', 'RMSPROP', 'Adam']
for i, l_his in enumerate(losses_his):
plt.plot(l_his, label=labels[i])
plt.legend(loc='best')
plt.xlabel('Steps')
plt.ylabel('Loss')
plt.ylim((0, 0.2))
plt.show()
完整代码
import torch
import torch.utils.data as tud
import matplotlib.pyplot as plt
import torch.nn.functional as F
torch.manual_seed(1) LR = 0.01
BATCH_SIZE = 32
EPOCH = 12 ######捏一个数据######
x = torch.unsqueeze(torch.linspace(-1,1,1000),dim=1)
y = x.pow(2) + 0.1*torch.normal(torch.zeros(*x.size())) # plt.scatter(x.numpy(),y.numpy())
# plt.show() torch_dataset = tud.TensorDataset(x,y)
loader = tud.DataLoader(
dataset=torch_dataset,
batch_size=BATCH_SIZE,
shuffle=True,
num_workers=2
) # 搭建同样的网络Net
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(1,20)
self.predict = torch.nn.Linear(20,1) def forward(self,x):
x = F.relu(self.hidden(x))
x = self.predict(x)
return x if __name__== '__main__':
# 为每个优化器创建一个net
net_SGD = Net()
net_Momentum = Net()
net_RMSprop = Net()
net_Adam = Net()
nets = [net_SGD,net_Momentum,net_RMSprop,net_Adam] # different optimizers
opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam] loss_func = torch.nn.MSELoss()
losses_his = [[], [], [], []] # 记录 training 时不同神经网络的 loss for epoch in range(EPOCH):
print('Epoch',epoch)
for step,(b_x,b_y) in enumerate(loader):
# 对每个优化器, 优化属于他的神经网络
for net, opt, l_his in zip(nets, optimizers, losses_his):
output = net(b_x) # 获得每个网络的输出
loss = loss_func(output, b_y) # compute loss for every net
opt.zero_grad() # clear gradients for next train
loss.backward() # backpropagation, compute gradients
opt.step() # apply gradients
l_his.append(loss.data.numpy()) # loss recoder labels = ['SGD', 'MoMENTUM', 'RMSPROP', 'Adam']
for i, l_his in enumerate(losses_his):
plt.plot(l_his, label=labels[i])
plt.legend(loc='best')
plt.xlabel('Steps')
plt.ylabel('Loss')
plt.ylim((0, 0.2))
plt.show()
十二、CNN_classification
1、MINIST手写数据
import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision # 数据库模块
import matplotlib.pyplot as plt torch.manual_seed(1) # reproducible # Hyper Parameters
EPOCH = 1 # 训练整批数据多少次, 为了节约时间, 我们只训练一次
BATCH_SIZE = 50
LR = 0.001 # 学习率
DOWNLOAD_MNIST = True # 如果你已经下载好了mnist数据就写上 False # Mnist 手写数字
train_data = torchvision.datasets.MNIST(
root='./mnist/', # 保存或者提取位置
train=True, # this is training data
transform=torchvision.transforms.ToTensor(), # 转换 PIL.Image or numpy.ndarray 成
# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间
download=DOWNLOAD_MNIST, # 没下载就下载, 下载了就不用再下了
) test_data = torchvision.datasets.MNIST(root='./mnist/', train=False) # 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) # 为了节约时间, 我们测试时只测试前2000个
test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.test_labels[:2000]
2、CNN模型
和以前一样, 我们用一个 class 来建立 CNN 模型. 这个 CNN 整体流程是
卷积(Conv2d
) -> 激励函数(ReLU
) -> 池化, 向下采样 (MaxPooling
)
-> 再来一遍 -> 展平多维的卷积成的特征图 -> 接入全连接层 (Linear
) -> 输出
# CNN模型搭建
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Sequential( # input shape (1,28,28)
nn.Conv2d(
in_channels=1, # 输入高度
out_channels=16, # n_filters 输出高度
kernel_size=5, # 卷积核大小 filter size
stride=1, # 卷积核步进或者说步长,filter movement/step
padding=2, # 如果想要 con2d 出来的图片长宽没有变化, padding=(kernel_size-1)/2 当 stride=1 ), ## output shape (16, 28, 28)
nn.ReLU(), # activation
nn.MaxPool2d(kernel_size=2), #在2*2 空间里向下采样,output shape (16, 14, 14)
)
self.conv2 = nn.Sequential( # input shape (16,14,14)
nn.Conv2d(16,32,5,1,2), # output shape(32,14,14)
nn.ReLU(),
nn.MaxPool2d(2), # output size (32,7,7)
)
self.out = nn.Linear(32*7*7,10) # 全连接层输出10个类
def forword(self,x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1) # 展平多维的卷积图成 (batch_size, 32 * 7 * 7)
output = self.out(x)
return output cnn = CNN()
print(cnn)
CNN(
(conv1): Sequential(
(0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(conv2): Sequential(
(0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(out): Linear(in_features=1568, out_features=10, bias=True)
)
3、训练,全部代码
下面我们开始训练, 将 x
y
都用 Variable
包起来, 然后放入 cnn
中计算 output
, 最后再计算误差.下面代码省略了计算精确度 accuracy
的部分
import os
import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision # 数据库模块
import matplotlib.pyplot as plt
from matplotlib import cm torch.manual_seed(1) # reproducible # Hyper Parameters
EPOCH = 1 # 训练整批数据多少次, 为了节约时间, 我们只训练一次
BATCH_SIZE = 50
LR = 0.001 # 学习率
DOWNLOAD_MNIST = False # 如果你已经下载好了mnist数据就写上 False if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'):
# not mnist dir or mnist is empyt dir
DOWNLOAD_MNIST = True # Mnist 手写数字
train_data = torchvision.datasets.MNIST(
root='./mnist/', # 保存或者提取位置
train=True, # this is training data
transform=torchvision.transforms.ToTensor(), # 转换 PIL.Image or numpy.ndarray 成
# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间
download=DOWNLOAD_MNIST, # 没下载就下载, 下载了就不用再下了
) test_data = torchvision.datasets.MNIST(root='./mnist/', train=False) # plot one example
print(train_data.data.size()) # (60000, 28, 28)
print(train_data.targets.size()) # (60000)
plt.imshow(train_data.data[0].numpy(), cmap='gray')
plt.title('%i' % train_data.targets[0])
plt.show() # 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) # 为了节约时间, 我们测试时只测试前2000个
test_x = torch.unsqueeze(test_data.data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.targets[:2000] # CNN模型搭建
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Sequential( # input shape (1,28,28)
nn.Conv2d(
in_channels=1, # 输入高度
out_channels=16, # n_filters 输出高度
kernel_size=5, # 卷积核大小 filter size
stride=1, # 卷积核步进或者说步长,filter movement/step
padding=2, # 如果想要 con2d 出来的图片长宽没有变化, padding=(kernel_size-1)/2 当 stride=1 ), ## output shape (16, 28, 28)
nn.ReLU(), # activation
nn.MaxPool2d(kernel_size=2), #在2*2 空间里向下采样,output shape (16, 14, 14)
)
self.conv2 = nn.Sequential( # input shape (16,14,14)
nn.Conv2d(16,32,5,1,2), # output shape(32,14,14)
nn.ReLU(),
nn.MaxPool2d(2), # output size (32,7,7)
)
self.out = nn.Linear(32*7*7,10) # 全连接层输出10个类 def forward(self,x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1) # 展平多维的卷积图成 (batch_size, 32 * 7 * 7)
output = self.out(x)
return output, x def train_save():
cnn = CNN()
print(cnn) optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) # 优化整一个CNN的参数
loss_func = nn.CrossEntropyLoss() try:
from sklearn.manifold import TSNE;HAS_SK = True
except:
HAS_SK = False;
print('Please install sklearn for layer visualization') def plot_with_labels(lowDWeights, labels):
plt.cla()
X, Y = lowDWeights[:, 0], lowDWeights[:, 1]
for x, y, s in zip(X, Y, labels):
c = cm.rainbow(int(255 * s / 9));
plt.text(x, y, s, backgroundcolor=c, fontsize=9)
plt.xlim(X.min(), X.max());
plt.ylim(Y.min(), Y.max());
plt.title('Visualize last layer');
plt.show();
plt.pause(0.01) plt.ion() # training and testing
for epoch in range(EPOCH):
for step, (b_x, b_y) in enumerate(train_loader): # gives batch data, normalize x when iterate train_loader output = cnn(b_x)[0] # cnn output
loss = loss_func(output, b_y) # cross entropy loss
optimizer.zero_grad() # clear gradients for this training step
loss.backward() # backpropagation, compute gradients
optimizer.step() # apply gradients if step % 50 == 0:
test_output, last_layer = cnn(test_x)
pred_y = torch.max(test_output, 1)[1].data.numpy()
accuracy = float((pred_y == test_y.data.numpy()).astype(int).sum()) / float(test_y.size(0))
print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy(), '| test accuracy: %.2f' % accuracy)
if HAS_SK:
# Visualization of trained flatten layer (T-SNE)
tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000)
plot_only = 500
low_dim_embs = tsne.fit_transform(last_layer.data.numpy()[:plot_only, :])
labels = test_y.numpy()[:plot_only]
plot_with_labels(low_dim_embs, labels)
plt.ioff() torch.save(cnn, './mnist_net/cnn_classification_net.pkl') # 保存整个网络
torch.save(cnn.state_dict(), './mnist_net/cnn_classification_net_params.pkl') # 只保存网络中的参数 (速度快, 占内存少) """
...
Epoch: 0 | train loss: 0.0306 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0147 | test accuracy: 0.98
Epoch: 0 | train loss: 0.0427 | test accuracy: 0.98
Epoch: 0 | train loss: 0.0078 | test accuracy: 0.98
""" # print 10 predictions from test data
test_output, _ = cnn(test_x[:10])
pred_y = torch.max(test_output, 1)[1].data.numpy()
print(pred_y, 'prediction number')
print(test_y[:10].numpy(), 'real number')
"""
[7 2 1 0 4 1 4 9 5 9] prediction number
[7 2 1 0 4 1 4 9 5 9] real number
""" # 这种方式将会提取整个神经网络, 网络大的时候可能会比较慢.
def restore_net():
# restore entire net1 to net2
net2 = torch.load('./mnist_net/cnn_classification_net.pkl')
test_output, _ = net2(test_x[:20])
pred_y = torch.max(test_output, 1)[1].data.numpy()
print(pred_y, 'prediction number')
print(test_y[:20].numpy(), 'real number') if __name__ == '__main__':
train = True
if train:
train_save()
else:
restore_net()
十三、RNN_classification
1、MINIST手写数据
import os
import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision # 数据库模块
import matplotlib.pyplot as plt
from matplotlib import cm
import torchvision.transforms as transforms
torch.manual_seed(1) # reproducible # Hyper Parameters
EPOCH = 1 # 训练整批数据多少次, 为了节约时间, 我们只训练一次
BATCH_SIZE = 64
TIME_STEP = 28
INPUT_SIZE = 28
LR = 0.01 # 学习率
DOWNLOAD_MNIST = False # 如果你已经下载好了mnist数据就写上 False if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'):
# not mnist dir or mnist is empyt dir
DOWNLOAD_MNIST = True # Mnist 手写数字
train_data = torchvision.datasets.MNIST(
root='./mnist/', # 保存或者提取位置
train=True, # this is training data
transform=torchvision.transforms.ToTensor(), # 转换 PIL.Image or numpy.ndarray 成
# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间
download=DOWNLOAD_MNIST, # 没下载就下载, 下载了就不用再下了
) test_data = torchvision.datasets.MNIST(root='./mnist/', train=False, transform=transforms.ToTensor()) # 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) # 为了节约时间, 我们测试时只测试前2000个
test_x = torch.unsqueeze(test_data.data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
# test_x = test_data.test_data.type(torch.FloatTensor)[:2000]/255.
test_y = test_data.targets[:2000]
2.RNN模型
和以前一样, 我们用一个 class 来建立 RNN 模型. 这个 RNN 整体流程是
(input0, state0)
->LSTM
->(output0, state1)
;(input1, state1)
->LSTM
->(output1, state2)
;- …
(inputN, stateN)
->LSTM
->(outputN, stateN+1)
;outputN
->Linear
->prediction
. 通过LSTM
分析每一时刻的值, 并且将这一时刻和前面时刻的理解合并在一起, 生成当前时刻对前面数据的理解或记忆. 传递这种理解给下一时刻分析.
class RNN(nn.Module):
def __init__(self):
super(RNN, self).__init__()
self.rnn = nn.LSTM( # input shape (1,28,28)LSTM 效果要比 nn.RNN() 好多了
input_size=28, # 图片每行的数据像素点
hidden_size=64, # rnn hidden unit
num_layers=1, # 有几层 RNN layers
batch_first=True, # input & output 会是以 batch size 为第一维度的特征集 e.g. (batch, time_step, input_size)
)
self.out = nn.Linear(64, 10) # 输出层 def forward(self,x):
# x shape (batch, time_step, input_size)
# r_out shape (batch, time_step, output_size)
# h_n shape (n_layers, batch, hidden_size) LSTM 有两个 hidden states, h_n 是分线, h_c 是主线
# h_c shape (n_layers, batch, hidden_size)
r_out, (h_n, h_c) = self.rnn(x, None) ## None 表示 hidden state 会用全0的 state
# 选取最后一个时间点的 r_out 输出
# 这里 r_out[:, -1, :] 的值也是 h_n 的值
out = self.out(r_out[:, -1, :])
return out
3、训练&完整代码
我们将图片数据看成一个时间上的连续数据, 每一行的像素点都是这个时刻的输入, 读完整张图片就是从上而下的读完了每行的像素点. 然后我们就可以拿出 RNN 在最后一步的分析值判断图片是哪一类了.
import os
import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision # 数据库模块
import matplotlib.pyplot as plt
from matplotlib import cm
import torchvision.transforms as transforms
torch.manual_seed(1) # reproducible # Hyper Parameters
EPOCH = 1 # 训练整批数据多少次, 为了节约时间, 我们只训练一次
BATCH_SIZE = 64
TIME_STEP = 28
INPUT_SIZE = 28
LR = 0.01 # 学习率
DOWNLOAD_MNIST = False # 如果你已经下载好了mnist数据就写上 False if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'):
# not mnist dir or mnist is empyt dir
DOWNLOAD_MNIST = True # Mnist 手写数字
train_data = torchvision.datasets.MNIST(
root='./mnist/', # 保存或者提取位置
train=True, # this is training data
transform=torchvision.transforms.ToTensor(), # 转换 PIL.Image or numpy.ndarray 成
# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间
download=DOWNLOAD_MNIST, # 没下载就下载, 下载了就不用再下了
) test_data = torchvision.datasets.MNIST(root='./mnist/', train=False, transform=transforms.ToTensor()) # 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) # 为了节约时间, 我们测试时只测试前2000个
test_x = test_data.data.type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.targets.numpy()[:2000] # CNN模型搭建
class RNN(nn.Module):
def __init__(self):
super(RNN, self).__init__()
self.rnn = nn.LSTM( # input shape (1,28,28)LSTM 效果要比 nn.RNN() 好多了
input_size=28, # 图片每行的数据像素点
hidden_size=64, # rnn hidden unit
num_layers=1, # 有几层 RNN layers
batch_first=True, # input & output 会是以 batch size 为第一维度的特征集 e.g. (batch, time_step, input_size)
)
self.out = nn.Linear(64, 10) # 输出层 def forward(self,x):
# x shape (batch, time_step, input_size)
# r_out shape (batch, time_step, output_size)
# h_n shape (n_layers, batch, hidden_size) LSTM 有两个 hidden states, h_n 是分线, h_c 是主线
# h_c shape (n_layers, batch, hidden_size)
r_out, (h_n, h_c) = self.rnn(x, None) ## None 表示 hidden state 会用全0的 state
# 选取最后一个时间点的 r_out 输出
# 这里 r_out[:, -1, :] 的值也是 h_n 的值
out = self.out(r_out[:, -1, :])
return out def train_save():
rnn = RNN()
print(rnn) optimizer = torch.optim.Adam(rnn.parameters(), lr=LR) # 优化整一个CNN的参数
loss_func = nn.CrossEntropyLoss() # training and testing
for epoch in range(EPOCH):
for step, (b_x, b_y) in enumerate(train_loader): # gives batch data, normalize x when iterate train_loader b_x = b_x.view(-1, 28, 28) # reshape x to (batch, time_step, input_size) output = rnn(b_x) # cnn output
loss = loss_func(output, b_y) # cross entropy loss
optimizer.zero_grad() # clear gradients for this training step
loss.backward() # backpropagation, compute gradients
optimizer.step() # apply gradients if step % 50 == 0:
test_output = rnn(test_x) # (samples, time_step, input_size)
pred_y = torch.max(test_output, 1)[1].data.numpy() accuracy = float((pred_y == test_y).astype(int).sum()) / float(test_y.size)
print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy(), '| test accuracy: %.2f' % accuracy) torch.save(rnn, './mnist_net/rnn_classification_net.pkl') # 保存整个网络
torch.save(rnn.state_dict(), './mnist_net/rnn_classification_net_params.pkl') # 只保存网络中的参数 (速度快, 占内存少) """
...
Epoch: 0 | train loss: 0.0306 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0147 | test accuracy: 0.98
Epoch: 0 | train loss: 0.0427 | test accuracy: 0.98
Epoch: 0 | train loss: 0.0078 | test accuracy: 0.98
""" # print 10 predictions from test data
test_output = rnn(test_x[:10].view(-1, 28, 28))
pred_y = torch.max(test_output, 1)[1].data.numpy()
print(pred_y, 'prediction number')
print(test_y[:10], 'real number')
"""
[7 2 1 0 4 1 4 9 5 9] prediction number
[7 2 1 0 4 1 4 9 5 9] real number
""" # 这种方式将会提取整个神经网络, 网络大的时候可能会比较慢.
def restore_net():
# restore entire net1 to net2
net2 = torch.load('./mnist_net/rnn_classification_net.pkl')
test_output = net2(test_x[:100].view(-1, 28, 28))
pred_y = torch.max(test_output, 1)[1].data.numpy()
accuracy = float((pred_y == test_y[:100]).astype(int).sum()) / 100
print(pred_y, 'prediction number')
print(test_y[:100], 'real number')
print('accuracy: ',accuracy) if __name__ == '__main__':
GO_train = False # False表示不训练直接调用训练好的模型,True表示训练
if GO_train:
train_save()
else:
restore_net()
十四、RNN_regression
用 RNN 来及时预测时间序列
1、训练数据
用 sin
的曲线预测出 cos
的曲线
import torch
from torch import nn
import numpy as np
import matplotlib.pyplot as plt torch.manual_seed(1) # 超参数
TIME_STEP = 10 # rnn时间步长/图像高度
INPUT_SIZE = 1 # rnn输入大小/图像宽度
LR = 0.02 # 学习率 # 显示数据
steps = np.linspace(0, np.pi*2, 100, dtype=np.float32) # float32 for converting torch FloatTensor
x_np = np.sin(steps)
y_np = np.cos(steps)
plt.plot(steps, y_np, 'r-', label = 'target(cos)')
plt.plot(steps, x_np, 'b-', label = 'input(sin)')
plt.legend(loc='best')
plt.show()
2、RNN网络
class RNN(nn.Module):
def __init__(self):
super(RNN, self).__init__()
self.rnn = nn.RNN( # 一个普通的RNN就能胜任
input_size=INPUT_SIZE,
hidden_size=32,
num_layers=1,
batch_first=True,
)
self.out = nn.Linear(32, 1) def forward(self, x, h_state): # 因为 hidden state 是连续的, 所以我们要一直传递这一个 state
# x (batch, time_step, input_size)
# h_state (n_layers, batch, hidden_size)
# r_out (batch, time_step, output_size)
r_out, h_state = self.rnn(x, h_state) # h_state 也要做为RNN的输入 这次具有时间序列特征
outs = [] # 保存所有时间点的预测值
for time_step in range(r_out.size(1)): # 对每一个时间点计算 output
outs.append(self.out(r_out[:, time_step, :]))
return torch.stack(outs, dim=1), h_state # 其实熟悉RNN的朋友应该知道, forward过程中的对每个时间点求输出还有一招使得计算量比较小的.不过上面的内容主要是为了呈现
# PyTorch在动态构图上的优势, 所以我用了一个for loop 来搭建那套输出系统.下面介绍一个替换方式.使用 reshape 的方式整批计算.
# def forward(self, x, h_state):
# r_out, h_state = self.rnn(x, h_state)
# r_out = r_out.view(-1, 32)
# outs = self.out(r_out)
# return outs.view(-1, 32, TIME_STEP), h_state rnn = RNN()
print(rnn)
"""
RNN(
(rnn): RNN(1, 32, batch_first=True)
(out): Linear(in_features=32, out_features=1, bias=True)
)
"""
3、训练
可以看出, 我们使用 x
作为输入的 sin
值, 然后 y
作为想要拟合的输出, cos
值. 因为他们两条曲线是存在某种关系的, 所以我们就能用 sin 来预测 cos
. rnn
会理解他们的关系, 并用里面的参数分析出来这个时刻 sin
曲线上的点如何对应上 cos
曲线上的点.
optimizer = torch.optim.Adam(rnn.parameters(), lr=LR) # optimize all rnn parameters
loss_func = nn.MSELoss() h_state = None # 要使用初始 hidden state, 可以设成 None for step in range(100):
start, end = step * np.pi, (step+1)*np.pi # time steps
# sin 预测 cos
steps = np.linspace(start, end, TIME_STEP, dtype=np.float32, endpoint=False) # float32 for converting torch FloatTensor
x_np = np.sin(steps) # float32 for converting torch FloatTensor
y_np = np.cos(steps) # 原来只有一维的数据,利用np.newaxis,np.newaxis的作用就是在这一位置增加一个一维,这一位置指的是np.newaxis所在的位置
x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis]) # shape (batch, time_step, input_size) (1,10,1)
y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis]) prediction, h_state = rnn(x, h_state) # rnn 对于每个 step 的 prediction, 还有最后一个 step 的 h_state
# !! 下一步十分重要 !!
h_state = h_state.data # 要把 h_state 重新包装一下才能放入下一个 iteration, 不然会报错 loss = loss_func(prediction, y) # cross entropy loss
optimizer.zero_grad() # clear gradients for this training step
loss.backward() # backpropagation, compute gradients
optimizer.step() # apply gradients
# plotting
plt.plot(steps, y_np.flatten(), 'r-')
plt.plot(steps, prediction.data.numpy().flatten(), 'b-')
plt.draw(); plt.pause(0.05) plt.ioff()
plt.show()
4、完整代码
import torch
from torch import nn
import numpy as np
import matplotlib.pyplot as plt torch.manual_seed(1) # 超参数
TIME_STEP = 10 # rnn时间步长/图像高度
INPUT_SIZE = 1 # rnn输入大小/图像宽度
LR = 0.02 # 学习率 # 显示数据
steps = np.linspace(0, np.pi*2, 100, dtype=np.float32) # float32 for converting torch FloatTensor
x_np = np.sin(steps)
y_np = np.cos(steps) # plt.plot(steps, y_np, 'r-', label = 'target(cos)')
# plt.plot(steps, x_np, 'b-', label = 'input(sin)')
# plt.legend(loc='best')
# plt.show() class RNN(nn.Module):
def __init__(self):
super(RNN, self).__init__()
self.rnn = nn.RNN( # 一个普通的RNN就能胜任
input_size=INPUT_SIZE,
hidden_size=32,
num_layers=1,
batch_first=True,
)
self.out = nn.Linear(32, 1) def forward(self, x, h_state): # 因为 hidden state 是连续的, 所以我们要一直传递这一个 state
# x (batch, time_step, input_size)
# h_state (n_layers, batch, hidden_size)
# r_out (batch, time_step, output_size)
r_out, h_state = self.rnn(x, h_state) # h_state 也要做为RNN的输入 这次具有时间序列特征
outs = [] # 保存所有时间点的预测值
for time_step in range(r_out.size(1)): # 对每一个时间点计算 output
outs.append(self.out(r_out[:, time_step, :]))
return torch.stack(outs, dim=1), h_state # 其实熟悉RNN的朋友应该知道, forward过程中的对每个时间点求输出还有一招使得计算量比较小的.不过上面的内容主要是为了呈现
# PyTorch在动态构图上的优势, 所以我用了一个for loop 来搭建那套输出系统.下面介绍一个替换方式.使用 reshape 的方式整批计算.
# def forward(self, x, h_state):
# r_out, h_state = self.rnn(x, h_state)
# r_out = r_out.view(-1, 32)
# outs = self.out(r_out)
# return outs.view(-1, 32, TIME_STEP), h_state rnn = RNN()
print(rnn)
"""
RNN(
(rnn): RNN(1, 32, batch_first=True)
(out): Linear(in_features=32, out_features=1, bias=True)
)
""" optimizer = torch.optim.Adam(rnn.parameters(), lr=LR) # optimize all rnn parameters
loss_func = nn.MSELoss() h_state = None # 要使用初始 hidden state, 可以设成 None for step in range(100):
start, end = step * np.pi, (step+1)*np.pi # time steps
# sin 预测 cos
steps = np.linspace(start, end, TIME_STEP, dtype=np.float32, endpoint=False) # float32 for converting torch FloatTensor
x_np = np.sin(steps) # float32 for converting torch FloatTensor
y_np = np.cos(steps) # 原来只有一维的数据,利用np.newaxis,np.newaxis的作用就是在这一位置增加一个一维,这一位置指的是np.newaxis所在的位置
x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis]) # shape (batch, time_step, input_size) (1,10,1)
y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis]) prediction, h_state = rnn(x, h_state) # rnn 对于每个 step 的 prediction, 还有最后一个 step 的 h_state
# !! 下一步十分重要 !!
h_state = h_state.data # 要把 h_state 重新包装一下才能放入下一个 iteration, 不然会报错 loss = loss_func(prediction, y) # cross entropy loss
optimizer.zero_grad() # clear gradients for this training step
loss.backward() # backpropagation, compute gradients
optimizer.step() # apply gradients
# plotting
plt.plot(steps, y_np.flatten(), 'r-')
plt.plot(steps, prediction.data.numpy().flatten(), 'b-')
plt.draw(); plt.pause(0.05) plt.ioff()
plt.show()
十五、GAN生成对抗网络
https://mofanpy.com/tutorials/machine-learning/torch//intro-GAN/
https://mofanpy.com/tutorials/machine-learning/torch/GAN/
我的一句话介绍 GAN 就是: Generator 是新手画家, Discriminator 是新手鉴赏家, 你是高级鉴赏家. 你将著名画家的品和新手画家的作品都给新手鉴赏家评定, 并告诉新手鉴赏家哪些是新手画家画的, 哪些是著名画家画的, 新手鉴赏家就慢慢学习怎么区分新手画家和著名画家的画, 但是新手画家和新手鉴赏家是好朋友, 新手鉴赏家会告诉新手画家要怎么样画得更像著名画家, 新手画家就能将自己的突然来的灵感 (random noise) 画得更像著名画家。
下面是本节内容的效果, 绿线的变化是新手画家慢慢学习如何踏上画家之路的过程. 而能被认定为著名的画作在 upper bound
和 lower bound
之间.。
1、超参数设定
新手画家 (Generator) 在作画的时候需要有一些灵感 (random noise), 我们这些灵感的个数定义为 N_IDEAS
. 而一幅画需要有一些规格, 我们将这幅画的画笔数定义一下, N_COMPONENTS
就是一条一元二次曲线(这幅画画)上的点个数. 为了进行批训练, 我们将一整批话的点都规定一下(PAINT_POINTS
).
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt torch.manual_seed(1)
np.random.seed(1) # 超参数
BATCH_SIZE = 64
LR_G = 0.0001
LR_D = 0.0001
N_IDEAS = 5 # think of this as number of ideas for generating an art work (Generator)
ART_COMPONENTS = 15 # 一条一元二次曲线(这幅画画)上的点个数 it could be total point G can draw in the canvas
PAINT_POINTS = np.vstack([np.linspace(-1,1,ART_COMPONENTS) for _ in range(BATCH_SIZE)])
2、来自著名艺术家的绘画(真实目标)
def artist_works(): # 来自著名艺术家的绘画(真实目标)
a = np.random.uniform(1, 2, size=BATCH_SIZE)[:, np.newaxis]
paintings = a * np.power(PAINT_POINTS, 2) + (a-1)
paintings = torch.from_numpy(paintings).float()
return paintings
3、GAN网络
这里会创建两个神经网络, 分别是 Generator (新手画家), Discriminator(新手鉴赏家). G
会拿着自己的一些灵感当做输入, 输出一元二次曲线上的点 (G
的画).
D
会接收一幅画作 (一元二次曲线), 输出这幅画作到底是不是著名画家的画(是著名画家的画的概率).
G = nn.Sequential( # Generator
nn.Linear(N_IDEAS, 128), # random ideas (could from normal distribution)
nn.ReLU(),
nn.Linear(128, ART_COMPONENTS), # making a painting from these random ideas
) D = nn.Sequential( # Discriminator
nn.Linear(ART_COMPONENTS, 128), # receive art work either from the famous artist or a newbie like G
nn.ReLU(),
nn.Linear(128, 1),
nn.Sigmoid(), # tell the probability that the art work is made by artist
) opt_D = torch.optim.Adam(D.parameters(), lr=LR_D)
opt_G = torch.optim.Adam(G.parameters(), lr=LR_G)
# 有弹幕说 RMSprop 比较好
4、训练
接着我们来同时训练 D
和 G
. 训练之前, 我们来看看G
作画的原理. G
首先会有些灵感, G_ideas
就会拿到这些随机灵感 (可以是正态分布的随机数), 然后 G
会根据这些灵感画画. 接着我们拿着著名画家的画和 G
的画, 让 D
来判定这两批画作是著名画家画的概率
for step in range(10000):
artist_paintings = artist_works() # real painting from artist
G_ideas = torch.randn(BATCH_SIZE, N_IDEAS, requires_grad=True) # random ideas\n
G_paintings = G(G_ideas) # fake painting from G (random ideas)
prob_artist1 = D(G_paintings) # D try to reduce this prob
G_loss = torch.mean(torch.log(1. - prob_artist1))
opt_G.zero_grad()
G_loss.backward()
opt_G.step() prob_artist0 = D(artist_paintings) # D try to increase this prob D尝试增加这个概率
prob_artist1 = D(G_paintings.detach()) # D try to reduce this prob D尝试减少这个概率
然后计算有多少来之画家的画猜对了, 有多少来自 G
的画猜对了, 我们想最大化这些猜对的次数. 这也就是 log(D(x)) + log(1-D(G(z))
在论文中的形式. 而因为 torch 中提升参数的形式是最小化误差, 那我们把最大化 score
转换成最小化 loss
, 在两个 score
的合的地方加一个符号就好. 而 G
的提升就是要减小 D
猜测 G
生成数据的正确率, 也就是减小 D_score1
.
D_loss = - torch.mean(torch.log(prob_artist0) + torch.log(1. - prob_artist1))
G_loss = torch.mean(torch.log(1. - prob_artist1))
最后我们在根据 loss
提升神经网络就好了.
opt_D.zero_grad()
D_loss.backward(retain_graph=True) # retain_graph 这个参数是为了再次使用计算图纸
opt_D.step() opt_G.zero_grad()
G_loss.backward()
opt_G.step()
5、完整代码
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt torch.manual_seed(1)
np.random.seed(1) # 超参数
BATCH_SIZE = 64
LR_G = 0.0001
LR_D = 0.0001
N_IDEAS = 5 # think of this as number of ideas for generating an art work (Generator)
ART_COMPONENTS = 15 # 一条一元二次曲线(这幅画画)上的点个数 it could be total point G can draw in the canvas
PAINT_POINTS = np.vstack([np.linspace(-1,1,ART_COMPONENTS) for _ in range(BATCH_SIZE)]) # show our beautiful painting range
# plt.plot(PAINT_POINTS[0], 2 * np.power(PAINT_POINTS[0], 2) + 1, c='#74BCFF', lw=3, label='upper bound')
# plt.plot(PAINT_POINTS[0], 1 * np.power(PAINT_POINTS[0], 2) + 0, c='#FF9359', lw=3, label='lower bound')
# plt.legend(loc='upper right')
# plt.show() def artist_works(): # 来自著名艺术家的绘画(真实目标)
a = np.random.uniform(1, 2, size=BATCH_SIZE)[:, np.newaxis]
paintings = a * np.power(PAINT_POINTS, 2) + (a-1)
paintings = torch.from_numpy(paintings).float()
return paintings G = nn.Sequential( # Generator
nn.Linear(N_IDEAS, 128), # random ideas (could from normal distribution)
nn.ReLU(),
nn.Linear(128, ART_COMPONENTS), # making a painting from these random ideas
) D = nn.Sequential( # Discriminator
nn.Linear(ART_COMPONENTS, 128), # receive art work either from the famous artist or a newbie like G
nn.ReLU(),
nn.Linear(128, 1),
nn.Sigmoid(), # tell the probability that the art work is made by artist
) opt_D = torch.optim.Adam(D.parameters(), lr=LR_D)
opt_G = torch.optim.Adam(G.parameters(), lr=LR_G)
# 有弹幕说 RMSprop 比较好 plt.ion() for step in range(10000):
artist_paintings = artist_works() # real painting from artist
G_ideas = torch.randn(BATCH_SIZE, N_IDEAS, requires_grad=True) # random ideas\n
G_paintings = G(G_ideas) # fake painting from G (random ideas)
prob_artist1 = D(G_paintings) # D try to reduce this prob
G_loss = torch.mean(torch.log(1. - prob_artist1))
opt_G.zero_grad()
G_loss.backward()
opt_G.step() prob_artist0 = D(artist_paintings) # D try to increase this prob D尝试增加这个概率
prob_artist1 = D(G_paintings.detach()) # D try to reduce this prob D尝试减少这个概率
D_loss = - torch.mean(torch.log(prob_artist0) + torch.log(1. - prob_artist1))
opt_D.zero_grad()
D_loss.backward(retain_graph=True) # reusing computational graph
opt_D.step() if step % 50 == 0: # plotting
plt.cla()
plt.plot(PAINT_POINTS[0], G_paintings.data.numpy()[0], c='#4AD631', lw=3, label='Generated painting', )
plt.plot(PAINT_POINTS[0], 2 * np.power(PAINT_POINTS[0], 2) + 1, c='#74BCFF', lw=3, label='upper bound')
plt.plot(PAINT_POINTS[0], 1 * np.power(PAINT_POINTS[0], 2) + 0, c='#FF9359', lw=3, label='lower bound')
plt.text(-.5, 2.3, 'D accuracy=%.2f (0.5 for D to converge)' % prob_artist0.data.numpy().mean(),
fontdict={'size': 13})
plt.text(-.5, 2, 'D score= %.2f (-1.38 for G to converge)' % -D_loss.data.numpy(), fontdict={'size': 13})
plt.ylim((0, 3));
plt.legend(loc='upper right', fontsize=10);
plt.draw();
plt.pause(0.01) plt.ioff()
plt.show()
十六、GPU 加速运算
import os
import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision # 数据库模块 torch.manual_seed(1) # reproducible
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # 使用编号为1,2号的GPU # Hyper Parameters
EPOCH = 1 # 训练整批数据多少次, 为了节约时间, 我们只训练一次
BATCH_SIZE = 50
LR = 0.001 # 学习率
DOWNLOAD_MNIST = False # 如果你已经下载好了mnist数据就写上 False if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'):
# not mnist dir or mnist is empyt dir
DOWNLOAD_MNIST = True # Mnist 手写数字
train_data = torchvision.datasets.MNIST(
root='./mnist/', # 保存或者提取位置
train=True, # this is training data
transform=torchvision.transforms.ToTensor(), # 转换 PIL.Image or numpy.ndarray 成
# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间
download=DOWNLOAD_MNIST, # 没下载就下载, 下载了就不用再下了
) test_data = torchvision.datasets.MNIST(root='./mnist/', train=False) # 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) # 为了节约时间, 我们测试时只测试前2000个 # ############# 这里加cuda ###############
test_x = torch.unsqueeze(test_data.data, dim=1).type(torch.FloatTensor)[:2000].cuda()/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)
test_y = test_data.targets[:2000].cuda() # CNN模型搭建
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Sequential( # input shape (1,28,28)
nn.Conv2d(
in_channels=1, # 输入高度
out_channels=16, # n_filters 输出高度
kernel_size=5, # 卷积核大小 filter size
stride=1, # 卷积核步进或者说步长,filter movement/step
padding=2, # 如果想要 con2d 出来的图片长宽没有变化, padding=(kernel_size-1)/2 当 stride=1 ), ## output shape (16, 28, 28)
nn.ReLU(), # activation
nn.MaxPool2d(kernel_size=2), #在2*2 空间里向下采样,output shape (16, 14, 14)
)
self.conv2 = nn.Sequential( # input shape (16,14,14)
nn.Conv2d(16,32,5,1,2), # output shape(32,14,14)
nn.ReLU(),
nn.MaxPool2d(2), # output size (32,7,7)
)
self.out = nn.Linear(32*7*7,10) # 全连接层输出10个类 def forward(self,x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1) # 展平多维的卷积图成 (batch_size, 32 * 7 * 7)
output = self.out(x)
return output, x def train_save():
cnn = CNN()
# ############# 这里加cuda ###############
cnn.cuda()###将所有模型参数和缓冲区转移到GPU print(cnn) optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) # 优化整一个CNN的参数
loss_func = nn.CrossEntropyLoss() # training and testing
for epoch in range(EPOCH):
for step, (b_x, b_y) in enumerate(train_loader): # gives batch data, normalize x when iterate train_loader
# !!!!!!!! 这里有修改 !!!!!!!!! #
b_x = b_x.cuda() # Tensor on GPU
b_y = b_y.cuda() # Tensor on GPU output = cnn(b_x)[0] # cnn output
loss = loss_func(output, b_y) # cross entropy loss
optimizer.zero_grad() # clear gradients for this training step
loss.backward() # backpropagation, compute gradients
optimizer.step() # apply gradients if step % 50 == 0:
test_output, last_layer = cnn(test_x) # !!!!!!!! 这里有修改 !!!!!!!!! #
pred_y = torch.max(test_output, 1)[1].cuda().data # 将操作放去 GPU
accuracy = torch.sum(pred_y == test_y).type(torch.FloatTensor) / test_y.size(0)
print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.cpu().numpy(), '| test accuracy: %.2f' % accuracy) torch.save(cnn, './mnist_net/cnn_classification_net.pkl') # 保存整个网络
torch.save(cnn.state_dict(), './mnist_net/cnn_classification_net_params.pkl') # 只保存网络中的参数 (速度快, 占内存少) """
...
Epoch: 0 | train loss: 0.0306 | test accuracy: 0.97
Epoch: 0 | train loss: 0.0147 | test accuracy: 0.98
Epoch: 0 | train loss: 0.0427 | test accuracy: 0.98
Epoch: 0 | train loss: 0.0078 | test accuracy: 0.98
""" # print 10 predictions from test data
test_output, _ = cnn(test_x[:10]) # !!!!!!!! 这里有修改 !!!!!!!!! #
pred_y = torch.max(test_output, 1)[1].cuda().data
print(pred_y, 'prediction number')
print(test_y[:10], 'real number')
"""
[7 2 1 0 4 1 4 9 5 9] prediction number
[7 2 1 0 4 1 4 9 5 9] real number
""" # 这种方式将会提取整个神经网络, 网络大的时候可能会比较慢.
def restore_net():
# restore entire net1 to net2
net2 = torch.load('./mnist_net/cnn_classification_net.pkl')
net2.cuda()
test_output, _ = net2(test_x[:20])
pred_y = torch.max(test_output, 1)[1].cuda().data
print(pred_y, 'prediction number')
print(test_y[:20], 'real number') if __name__ == '__main__':
GO_train = False
if GO_train:
train_save()
else:
restore_net()
莫烦pytorch学习记录的更多相关文章
- 莫烦pytorch学习笔记(七)——Optimizer优化器
各种优化器的比较 莫烦的对各种优化通俗理解的视频 import torch import torch.utils.data as Data import torch.nn.functional as ...
- 莫烦pytorch学习笔记(八)——卷积神经网络(手写数字识别实现)
莫烦视频网址 这个代码实现了预测和可视化 import os # third-party library import torch import torch.nn as nn import torch ...
- 莫烦PyTorch学习笔记(五)——模型的存取
import torch from torch.autograd import Variable import matplotlib.pyplot as plt torch.manual_seed() ...
- 莫烦PyTorch学习笔记(六)——批处理
1.要点 Torch 中提供了一种帮你整理你的数据结构的好东西, 叫做 DataLoader, 我们能用它来包装自己的数据, 进行批训练. 而且批训练可以有很多种途径. 2.DataLoader Da ...
- 莫烦pytorch学习笔记(二)——variable
.简介 torch.autograd.Variable是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现 Variable和tensor的区别和联系 Variable是篮子, ...
- 莫烦 - Pytorch学习笔记 [ 二 ] CNN ( 1 )
CNN原理和结构 观点提出 关于照片的三种观点引出了CNN的作用. 局部性:某一特征只出现在一张image的局部位置中. 相同性: 同一特征重复出现.例如鸟的羽毛. 不变性:subsampling下图 ...
- 莫烦 - Pytorch学习笔记 [ 一 ]
1. Numpy VS Torch #相互转换 np_data = torch_data.numpy() torch_data = torch.from_numpy(np_data) #abs dat ...
- 莫烦PyTorch学习笔记(五)——分类
import torch from torch.autograd import Variable import torch.nn.functional as F import matplotlib.p ...
- 莫烦PyTorch学习笔记(四)——回归
下面的代码说明个整个神经网络模拟回归的过程,代码含有详细注释,直接贴下来了 import torch from torch.autograd import Variable import torch. ...
- 莫烦PyTorch学习笔记(三)——激励函数
1. sigmod函数 函数公式和图表如下图 在sigmod函数中我们可以看到,其输出是在(0,1)这个开区间内,这点很有意思,可以联想到概率,但是严格意义上讲,不要当成概率.sigmod函数 ...
随机推荐
- k8s 深入篇———— docker 是什么[一]
前言 简单的整理一下一些基本概念. 正文 简单运行一个容器: 创建一个容器: docker run -it busybox /bin/bash 然后看下进程: ps -ef 做了一个障眼法,使用的是p ...
- axios 使用与 拦截器
未拦截使用使用: 由于axios每个请求都是异步.例如有ABC三个请求,C需要拿到AB请求回来的值作为参数,则需同步加载才能,所以使用axios.all才好完成.... 拦截器:为了处理axios中g ...
- 【笔记】Java相关大杂烩①
[笔记]Java相关大杂烩 Java 程序的执行流程是? *.java 文件-->*.class 文件-->类装载器-->字节码校验器-->解释器-->操作系统平台 Ja ...
- 3月2日,阿里云开源 PolarDB 企业级架构将迎来重磅发布
简介:2022年3月2日,开源 PolarDB 企业级架构将迎来重磅发布!本次发布会将首次公开开源 PolarDB 的总体结构设计和企业级特性,对 PolarDB for PostgreSQL 的存储 ...
- 内含干货PPT下载|一站式数据管理DMS关键技术解读
简介: 深入解读实时数据流.库仓一体数据处理等核心技术 "数聚云端·智驭未来"--阿里云数据库创新上云峰会暨第3届数据库性能挑战赛决赛颁奖典礼已圆满结束,更多干货内容欢迎大家观看 ...
- 从技术到科学,中国AI向何处去?
简介: 如果从达特茅斯会议起算,AI已经走过65年历程,尤其是近些年深度学习兴起后,AI迎来了空前未有的繁荣.不过,最近两年中国AI热潮似乎有所回落,在理论突破和落地应用上都遇到了挑战,外界不乏批评 ...
- [FAQ] swagger-php 支持 Authorization Bearer token 校验的用法
@OA\SecurityScheme 可以是 Controller 层面也可以是 Action 层面. 类型 type="apiKey". in="header" ...
- WPF 从零自己实现从 RealTimeStylus 获取触摸信息
本文将告诉大家什么是 RealTimeStylus 以及如何从零开始不使用 WPF 框架提供的功能从 RealTimeStylus 获取到触摸信息 开始之前先复习一下 Windows 的触摸演进.在上 ...
- C51笔记-#点灯#流水灯#延时#库函数
- 推荐一款轻量级堡垒机系统让你防护“rm -rf 删库跑路”
大家好,我是 Java陈序员. 我们在开发工作中,会经常与服务器打交道,而服务器的资源又是十分宝贵,特别是服务器里面的数据资源. 但是,偶尔会经常因为疏忽而导致服务器数据资源丢失,给自己和公司带来巨大 ...