赞
踩
神经网络可以分成两种类型:分类(如房价问题)和回归(两类或多类)
- import torch
- from torch.autograd import Variable
- import torch.nn.functional as F
- import matplotlib.pyplot as plt
-
- # 在torch当中,数据是有维度的
- # torch.unsqueeze()把一维数据变成二维数据,torch只会处理二维数据
- # [1,2,3,4] 一维数据
- # [[1,2,3,4]]二维数据
-
- x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100,1)
- y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100,1)
-
- x, y = Variable(x), Variable(y)
-
- # 打印散点图
- # plt.scatter(x.data.numpy(), y.data.numpy())
- # plt.show()
-
- # 定义Neural Network
- # 继承从torch来的模块Module
- class Net(torch.nn.Module):
- # __init__搭建层所需要的信息
- def __init__(self, n_feature, n_hidden, n_output):
- # 搭图之前继承Net到这个模块
- super(Net, self).__init__()
- # 层命名为hidden
- self.hidden = torch.nn.Linear(n_feature, n_hidden) # 一层神经网络(隐藏层),输入数据的个数,输出神经元的个数
- # 预测的神经层
- self.predict = torch.nn.Linear(n_hidden, n_output) # 预测y的值
-
- # forward神经网络前向传递的过程
- # 前面的层信息放到forward上面一个一个组合起来,在torch当中搭流程图
- def forward(self, x):
- x = F.relu(self.hidden(x))
- # self.hidden(x)输出n个hidden units,再用激活函数Rule激活
- x = self.predict(x)
- return x
-
-
- net = Net(1, 10, 1)
- print(net)
-
- # 可视化过程
- plt.ion()
- plt.show()
-
- # 优化神经网络
- # SGD 随机梯度下降
- optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
- # lr 为学习率,一般小于1。
- # 学习率是调节每一次梯度更新的步长,即神经网络优化一次的步幅,神经网络优化类似于寻找某个(Loss)函数的最小值
- # 方法就是随机选个点,然后一点一点挪到最小值
- # 如果学习率过大,可能你会离某个局部最小值越跳越远
-
- # 计算误差的手段 MSELoss 均方差代价函数
- loss_function = torch.nn.MSELoss()
-
- # 开始训练,t为训练步数
- for t in range(100):
- prediction = net(x) # 预测值
-
- loss = loss_function(prediction, y) # 计算预测值与真实值y两者误差
-
- optimizer.zero_grad() # 把所有参数的梯度降为0
- loss.backward() # 反向传递
- optimizer.step() # 以学习效率0.5优化梯度
-
- # 可视化过程
- if t % 5 == 0:
- # plot and show learning process
- plt.cla()
- plt.scatter(x.data.numpy(), y.data.numpy())
- plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
- plt.text(0.5, 0, 'Loss=%.4f' % loss.data, fontdict={'size':20, 'color': 'red'})
- plt.pause(0.1)
-
- plt.ioff()
- plt.show()
- import torch
- from torch.autograd import Variable
- import torch.nn.functional as F
- import matplotlib.pyplot as plt
-
- n_data = torch.ones(100, 2) # data的基数
- x0 = torch.normal(2*n_data, 1) # class0 x data (tensor), shape=(100, 2)
- # x0数据的标签是0(zeros)
- y0 = torch.zeros(100) # class0 y data (tensor), shape=(100, 1)
- x1 = torch.normal(-2*n_data, 1) # class1 x data (tensor), shape=(100, 1)
- # x1数据的标签是1(ones)
- y1 = torch.ones(100) # class1 y data (tensor), shape=(100, 1)
- # cat将x0和x1合并在一起当作数据
- x = torch.cat((x0, x1), 0).type(torch.FloatTensor) # FloatTensor = 32-bit floating
- # 将y0和y1合并在一起当作标签
- y = torch.cat((y0, y1), ).type(torch.LongTensor) # LongTensor = 64-bit integer
-
- # x, y = Variable(x), Variable(y)
- # 新版本的tensor和Variable合并啦
-
- # 可视化
- # 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_output):
- super(Net, self).__init__()
- self.hidden = torch.nn.Linear(n_feature, n_hidden)
- self.predict = torch.nn.Linear(n_hidden, n_output)
-
- def forward(self, x):
- x = F.relu(self.hidden(x))
- x = self.predict(x)
- return x
-
- net = Net(2, 10, 2)
- # 输出结果为one-hot形式:使用N位状态寄存器来对N个状态进行编码
- # 例如,在二分类中
- # [0, 1] 为第二类
- # [1, 0] 为第一类
- # 在三分类中
- # [0, 1, 0] 为第二类
- print(net)
-
- # 可视化过程
- plt.ion()
- plt.show()
-
- optimizer = torch.optim.SGD(net.parameters(), lr=0.02)
- loss_function = torch.nn.CrossEntropyLoss()
- # [0.2, 0.1, 0.7] = 1 预测值,概率总和为 1
- # [0, 0, 1]标签值,CrossEntropyLoss计算标签值和预测值间的误差
-
- for t in range(100):
- out = net(x) # F.softmax(out)将输出的结果转换成概率值
- loss = loss_function(out, y)
- optimizer.zero_grad()
- loss.backward()
- optimizer.step()
-
- if t % 2 == 0:
- # plot and show learning process
- plt.cla()
- prediction = torch.max(F.softmax(out), 1)[1]
- # torch.max()的返回值有两个,第一个是max值是多少,第二个是max的index,这里返回的是index
- pred_y = prediction.data.numpy().squeeze()
- 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()
- # 定义神经网络的两种 methods
- # method1
- class Net(torch.nn.Module):
- def __init__(self, n_feature, n_hidden, n_output):
- super(Net, self).__init__()
- self.hidden = torch.nn.Linear(n_feature, n_hidden)
- self.predict = torch.nn.Linear(n_hidden, n_output)
-
- def forward(self, x):
- x = F.relu(self.hidden(x)) # relu是一个函数
- x = self.predict(x)
- return x
-
- net1 = Net(2, 10, 2)
-
- # method2 不用创建class
- net2 = torch.nn.Sequential( # 一层一层罗列神经层
- torch.nn.Linear(2, 10),
- torch.nn.ReLU(), # ReLU是一个类
- torch.nn.Linear(10, 2)
- )
-
- print(net1)
- print(net2)
- 输出结果:
- Net(
- (hidden): Linear(in_features=2, out_features=10, bias=True)
- (predict): Linear(in_features=10, out_features=2, bias=True)
- )
- Sequential(
- (0): Linear(in_features=2, out_features=10, bias=True)
- (1): ReLU()
- (2): Linear(in_features=10, out_features=2, bias=True)
- )
-
- Process finished with exit code 0
- import torch
- from torch.autograd import Variable
- import matplotlib.pyplot as plt
-
- torch.manual_seed(1) # reproducible
-
- # fake data
- x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1)
- y = x.pow(2) + 0.2*torch.rand(x.size()) #noisy y data (tensor), shape=(100,1)
-
- # 保存神经网络
- def save():
- # save net1
- 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.2)
- 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') # save entire net
- torch.save(net1.state_dict(), 'net_params.pkl')
- # save parameters,神经网络的状态,包括神经元的参数、dropout的参数
- # 速度快,占内存小
-
-
- # 提取神经网络
- def restore_net():
- net2 = torch.load('net.pkl')
-
- def restore_params():
- # 首先建立一个跟net1一模一样的神经网络
- # 然后将net1的参数复制到net3中
- net3 = torch.nn.Sequential(
- torch.nn.Linear(1, 10),
- torch.nn.ReLU(),
- torch.nn.Linear(10, 1)
- )
- net3.load_state_dict(torch.load('net_params.pkl'))
-
- # 保存net1(1.整个网络 2.只有参数)
- save()
-
- # 提取整个网络
- restore_net()
-
- # 提取网络参数,复制到新网络
- restore_params()
批训练可以提升速度,相对于单图训练而言的,因为全部数据过大,所以分批。
minibatch 集合了批梯度下降和随机梯度下降的优点。
- import torch
- import torch.utils.data as Data
-
- # 5个为一组
- BATCH_SIZE = 5
-
- # 对于BATCH_SIZE不能整除数据量时,最后返回的是模数
-
- x = torch.linspace(1, 10, 10) # this is x data (torch tensor)
- y = torch.linspace(10, 1, 10) # this is y data (torch tensor)
-
- # 定义一个数据库
- # 旧版本为torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)
- torch_dataset = Data.TensorDataset(x, y)
- loader = Data.DataLoader(
- dataset=torch_dataset,
- batch_size=BATCH_SIZE,
- shuffle=True, # shuffle 定义的是要不要在训练时随机打乱数据,然后再随机开始抽样
- # num_workers=2, # 每一次loader提取出batch_x和batch_y的时候,用两个进程来提取的,效率更高
- )
-
- # epoch是整个训练集被训练算法遍历的次数
- for epoch in range(3):
- for step, (batch_x, batch_y) in enumerate(loader):
- # batch_x, batch_y 是通过 enumerate 提取 x 和 y ,step 是每组(x, y)的序号
- # x 有10个数据,BATCH_SIZE 为5,即2个为一组,step 即为2
- # 相当于有 n 个训练样本,BATCH_SIZE 为 m,则每个 epoch 都要进行 n/m 个 step
- # training...
- print('Epoch: ', epoch, '| Step: ', '| batch_x: ',
- batch_x.numpy(), '| batch_y: ', batch_y.numpy())
- 注意:windows用户如果报RuntimeError,需要把num_workers=2注释掉
- 或者可以将epoch迭代写进函数main(),然后if__name__=='__main__':main();
1. 准备工作
- # prepare
- import torch
- import torch.utils.data as Data
- import torch.nn.functional as F
-
- # hyper parameters
- 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()))
-
- torch_dataset = Data.TensorDataset(x, y)
- loader = Data.DataLoader(dataset=torch_dataset, batch_size=BATCH_SIZE, shuffle=True)
-
- # 默认的神经网络框架
- class Net(torch.nn.Module):
- def __init__(self,):
- super(Net, self).__init__()
- self.hidden = torch.nn.Linear(1, 20) # hidden layer 20个神经元的隐藏层
- self.predict = torch.nn.Linear(20, 1) # output layer
-
- def forward(self, x):
- x = F.relu(self.hidden(x)) # activation function for hidden layer
- x = self.predict(x) # linear output
- return x
2. 优化方法:大多方法是在更新神经网络参数那一步做改动
- # 利用默认神经网络框架建立神经网络,并用优化方法进行优化
- net_SGD = Net()
-
- # 建立优化器
- opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
- net_Momentum = Net()
- opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
- # Momentum 和 SGD 就差了一个 b1*m,可以将 SGD 看作是 momentum(动量)=0 的Momentum
- net_RMSprop = Net()
- opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
- net_Adam = Net()
- opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
3. 开始训练
- loss_func = torch.nn.MSELoss()
- losses_his = [] # record loss(history)
-
- for epoch in range(EPOCH):
- print(epoch)
- for step, (batch_x, batch_y) in enumerate(loader):
- for net, opt, l_his in zip(nets, optimizers, losses_his):
- output = net(batch_x) # get output for every net
- loss = loss_func(output, batch_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[0]) # loss recoder
- # 新版使用loss.item
- # tensor里只有一个数的时候可以用.item()直接提取
- l_his.append(loss.item())
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。