#一个简单的神经网络 # coding:utf-8 import torch from torch.autograd import Variable batch_n = 100 #在一个批次中输入数据的数量 hidden_layer = 100 #用于定义经过隐藏层后保留的数据特征的个数 # 只考虑一层隐藏层,所以在代码中仅仅定义了一个隐藏层的参数; input_data = 1000 #每个数据包含的数据特征有input_data个 output_data = 10 #输出的数据 #将输出的数据看作一个分类结果值得数量,个数10表示我们最后要得到10个分类结果值。 #从输入层到隐藏层,从隐藏层到输出层对应的权重参数 # x = torch.randn(batch_n, input_data) #输入层维度为(100,1000) # y = torch.randn(batch_n, output_data) #输出层维度为(100,10) # # w1 = torch.randn(input_data, hidden_layer) #从输入层到隐藏层的权重参数维度为(1000,100), # w2 = torch.randn(hidden_layer, output_data)# 从隐藏层到输出层的权重参数维度为(100,10) x = Variable(torch.randn(batch_n, input_data), requires_grad=False) y = Variable(torch.randn(batch_n, output_data), requires_grad=False) #如果requires_grad的值是False,那么表示该变量在进行自动梯度计算的过程中不会保留梯度值 w1 = Variable(torch.randn(input_data, hidden_layer), requires_grad=True) w2 = Variable(torch.randn(hidden_layer, output_data), requires_grad=True) #将输入的数据x和输出的数据y的requires_grad参数均设置为False, # 这是因为这两个变量并不是我们的模型需要优化的参数, # 而两个权重w1和w2的requires_grad参数的值为True epoch_n = 30 #后向传播的次数 learning_rate = 1e-6 #梯度下降使用的学习效率 #第一种方法 # for epoch in range(epoch_n): # h1 = x.mm(w1) # 100*1000 # h1 = h1.clamp(min=0) #使用clamp方法进行裁剪,将小于零的值全部重新赋值于0 # y_pred = h1.mm(w2) # 100*10 # 前向传播得到的预测结果 # # print(y_pred) # # loss = (y_pred - y).pow(2).sum() #loss来表示误差值,对误差值的计算使用了均方误差函数 # print("Epoch:{} , Loss:{:.4f}".format(epoch, loss)) # # #后向传播来对权重参数进行优化 #使用的是每个节点的链式求导结果 # gray_y_pred = 2 * (y_pred - y) # gray_w2 = h1.t().mm(gray_y_pred) #每个权重参数对应的梯度 # # grad_h = gray_y_pred.clone() # grad_h = grad_h.mm(w2.t()) # grad_h.clamp_(min=0) # grad_w1 = x.t().mm(grad_h) #每个权重参数对应的梯度 # # w1 -= learning_rate * grad_w1 # w2 -= learning_rate * gray_w2 #第二种方法 # for epoch in range(epoch_n): # y_pred = x.mm(w1).clamp(min=0).mm(w2) # loss = (y_pred - y).pow(2).sum() # print("Epoch:{} , Loss:{:.4f}".format(epoch, loss.data)) # # #后向传播计算部分变成了新代码中的 loss.backward(), # # 这个函数的功能在于让模型根据计算图自动计算每个节点的梯度值并根据需求进行保留 # loss.backward() # w1.data -= learning_rate * w1.grad.data # w2.data -= learning_rate * w2.grad.data # # w1.grad.data.zero_() # w2.grad.data.zero_() # #将本次计算得到的各个参数节点的梯度值通过grad.data.zero_()全部置零, # # 如果不置零,则计算的梯度值会被一直累加,这样就会影响到后续的计算 #第三种方法 #自定义前向传播 forward 函数和后向传播backward函数 class Model(torch.nn.Module): def __init__(self): super(Model, self).__init__() def forward(self, input, w1, w2): x = torch.mm(input, w1) x = torch.clamp(x, min=0) x = torch.mm(x, w2) return x def backward(self): pass model = Model() for epoch in range(epoch_n): # y_pred = x.mm(w1).clamp(min= 0 ).mm(w2) y_pred = model(x, w1, w2) loss = (y_pred - y).pow(2).sum() print("Epoch:{} , Loss:{:.6f}".format(epoch, loss.data)) loss.backward() w1.data -= learning_rate * w1.grad.data w2.data -= learning_rate * w2.grad.data w1.grad.data.zero_() w2.grad.data.zero_()
一个简单的神经网络
最新推荐文章于 2023-11-18 21:13:52 发布