一个简单的神经网络

#一个简单的神经网络
# 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_()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值