• NLP(3)--利用nn反向计算参数


    前言

    仅记录学习过程,有问题欢迎讨论

    获取数据

    自定义一个方程,获取一批数据X,Y

    import matplotlib.pyplot as pyplot
    import math
    import sys
    
    X = [0.01 * x for x in range(100)]
    Y = [2*x**2 + 3*x + 4 for x in X]
    print(X)
    print(Y)
    pyplot.scatter(X, Y, color='red')
    pyplot.show()
    input()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    利用nn模型计算w

    X = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18,
         0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35000000000000003,
         0.36, 0.37, 0.38, 0.39, 0.4, 0.41000000000000003, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47000000000000003, 0.48, 0.49,
         0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.5700000000000001, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66,
         0.67, 0.68, 0.6900000000000001, 0.7000000000000001, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8,
         0.81, 0.8200000000000001, 0.8300000000000001, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.9, 0.91, 0.92, 0.93,
         0.9400000000000001, 0.9500000000000001, 0.96, 0.97, 0.98, 0.99]
    Y = [4.0, 4.0302, 4.0608, 4.0918, 4.1232, 4.155, 4.1872, 4.2198, 4.2528, 4.2862, 4.32, 4.3542, 4.3888, 4.4238, 4.4592,
         4.495, 4.5312, 4.5678, 4.6048, 4.6422, 4.68, 4.7181999999999995, 4.7568, 4.7958, 4.8352, 4.875, 4.9152000000000005,
         4.9558, 4.9968, 5.0382, 5.08, 5.122199999999999, 5.1648, 5.2078, 5.2512, 5.295, 5.3392, 5.3838, 5.4288, 5.4742,
         5.5200000000000005, 5.5662, 5.6128, 5.6598, 5.7072, 5.755, 5.8032, 5.851800000000001, 5.9008, 5.9502, 6.0, 6.0502,
         6.1008, 6.1518, 6.203200000000001, 6.255000000000001, 6.3072, 6.3598, 6.4128, 6.4662, 6.52, 6.5742, 6.6288, 6.6838,
         6.7392, 6.795, 6.8512, 6.9078, 6.9648, 7.022200000000001, 7.08, 7.138199999999999, 7.1968, 7.2558, 7.3152, 7.375,
         7.4352, 7.4958, 7.5568, 7.6182, 7.680000000000001, 7.7422, 7.8048, 7.867800000000001, 7.9312, 7.994999999999999,
         8.0592, 8.1238, 8.1888, 8.2542, 8.32, 8.3862, 8.4528, 8.5198, 8.587200000000001, 8.655000000000001, 8.7232, 8.7918,
         8.8608, 8.9302]
    
    # 标签
    def func(x):
        y = w1 * x**2 + w2 * x + w3
        return y
    
    # 损失函数
    def loss(y_pre, y_true):
        return (y_true - y_pre) ** 2
    
    
    # 随机定义 w
    w1, w2, w3 = 1, 2, 3
    # 学习率
    lr = 0.1
    
    # 训练过程
    for epoch in range(500):
        epoch_loss = 0
        for x, y_true in zip(X, Y):
            y_pre = func(x)
            # 本轮loss 总值
            epoch_loss += loss(y_pre, y_true)
            # 梯度计算
            grad_w1 = 2 * (y_pre - y_true) * x ** 2
            grad_w2 = 2 * (y_pre - y_true) * x
            grad_w3 = 2 * (y_pre - y_true)
            # 权重更新
            w1 = w1 - lr * grad_w1  # sgd
            w2 = w2 - lr * grad_w2
            w3 = w3 - lr * grad_w3
        # 本轮结束 计算平均loss
        epoch_loss /= len(X)
        print("第%d轮, loss %f" % (epoch, epoch_loss))
        if epoch_loss < 0.00001:
            break
    
    print(f"训练后权重:w1:{w1} w2:{w2} w3:{w3}")
    # #使用训练后模型输出预测值
    Yp = [func(i) for i in X]
    # 预测值与真实值比对数据分布
    pyplot.scatter(X, Y, color="red")
    pyplot.scatter(X, Yp)
    pyplot.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    优化梯度、权重计算

    X = [0.0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18,
         0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35000000000000003,
         0.36, 0.37, 0.38, 0.39, 0.4, 0.41000000000000003, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47000000000000003, 0.48, 0.49,
         0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.5700000000000001, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66,
         0.67, 0.68, 0.6900000000000001, 0.7000000000000001, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8,
         0.81, 0.8200000000000001, 0.8300000000000001, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.9, 0.91, 0.92, 0.93,
         0.9400000000000001, 0.9500000000000001, 0.96, 0.97, 0.98, 0.99]
    Y = [4.0, 4.0302, 4.0608, 4.0918, 4.1232, 4.155, 4.1872, 4.2198, 4.2528, 4.2862, 4.32, 4.3542, 4.3888, 4.4238, 4.4592,
         4.495, 4.5312, 4.5678, 4.6048, 4.6422, 4.68, 4.7181999999999995, 4.7568, 4.7958, 4.8352, 4.875, 4.9152000000000005,
         4.9558, 4.9968, 5.0382, 5.08, 5.122199999999999, 5.1648, 5.2078, 5.2512, 5.295, 5.3392, 5.3838, 5.4288, 5.4742,
         5.5200000000000005, 5.5662, 5.6128, 5.6598, 5.7072, 5.755, 5.8032, 5.851800000000001, 5.9008, 5.9502, 6.0, 6.0502,
         6.1008, 6.1518, 6.203200000000001, 6.255000000000001, 6.3072, 6.3598, 6.4128, 6.4662, 6.52, 6.5742, 6.6288, 6.6838,
         6.7392, 6.795, 6.8512, 6.9078, 6.9648, 7.022200000000001, 7.08, 7.138199999999999, 7.1968, 7.2558, 7.3152, 7.375,
         7.4352, 7.4958, 7.5568, 7.6182, 7.680000000000001, 7.7422, 7.8048, 7.867800000000001, 7.9312, 7.994999999999999,
         8.0592, 8.1238, 8.1888, 8.2542, 8.32, 8.3862, 8.4528, 8.5198, 8.587200000000001, 8.655000000000001, 8.7232, 8.7918,
         8.8608, 8.9302]
    
    # 标签
    def func(x):
        y = w1 * x**2 + w2 * x + w3
        return y
    
    # 损失函数
    def loss(y_pre, y_true):
        return (y_true - y_pre) ** 2
    
    
    # 随机定义 w
    w1, w2, w3 = 1, 2, 3
    # 学习率
    lr = 0.1
    
    batch_size = 20
    # 训练过程
    for epoch in range(500):
        epoch_loss = 0
        count = 0
        grad_w1 = 0
        grad_w2 = 0
        grad_w3 = 0
        for x, y_true in zip(X, Y):
            count += 1
            y_pre = func(x)
            # 本轮loss 总值
            epoch_loss += loss(y_pre, y_true)
            # 梯度计算
            grad_w1 += 2 * (y_pre - y_true) * x ** 2
            grad_w2 += 2 * (y_pre - y_true) * x
            grad_w3 += 2 * (y_pre - y_true)
            # 更新权重
            if count == batch_size:
                count = 0
                # 权重更新
                w1 = w1 - lr * grad_w1/batch_size  # sgd
                w2 = w2 - lr * grad_w2/batch_size
                w3 = w3 - lr * grad_w3/batch_size
        # 本轮结束 计算平均loss
        epoch_loss /= len(X)
        print("第%d轮, loss %f" % (epoch, epoch_loss))
        if epoch_loss < 0.00001:
            break
    
    print(f"训练后权重:w1:{w1} w2:{w2} w3:{w3}")
    # #使用训练后模型输出预测值
    Yp = [func(i) for i in X]
    # 预测值与真实值比对数据分布
    pyplot.scatter(X, Y, color="red")
    pyplot.scatter(X, Yp)
    pyplot.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    利用轮子优化代码

    import numpy
    import numpy as np
    import torch
    import torch.utils.data as Data
    
    
    
    true_w = torch.from_numpy(numpy.array([5, 6, 7])).float()
    true_b = 7
    print(true_w)
    # 定义模型
    feature = torch.tensor(numpy.random.normal(0, 1, (100, 2)), dtype=float).float()
    print(feature)
    labels = true_w[0] * feature[:, 0] + true_w[1] * feature[:, 1] + true_b
    labels += torch.tensor(numpy.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)
    lr = 0.2
    batch_size = 20
    dateset = Data.TensorDataset(feature, labels)
    data_iter = Data.DataLoader(dateset, batch_size, shuffle=True)
    
    for X,y in data_iter:
        print(X,y)
        break
    net = torch.nn.Sequential(
        torch.nn.Linear(2, 1)
    )
    print("net =", net)
    # 使用net前 需要初始化参数 初始化
    torch.nn.init.normal(net[0].weight, mean=0, std=0.01)
    torch.nn.init.constant_(net[0].bias, val=0)
    
    loss = torch.nn.MSELoss()
    optimizer = torch.optim.SGD(net.parameters(), lr=0.2)
    
    for epoch in range(10):
        for X,y_ture in data_iter:
            y_pre = net(X)
            l = loss(y_pre,y_ture.view(-1,1))
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
        print('epoch %d, loss: %f' % (epoch, l.item()))
    
        # 比较学到的模型参数和真实的模型参数
        print('result ==================')
        dense = net[0]
        print(true_w, dense.weight)
        print(true_b, dense.bias)
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
  • 相关阅读:
    ssm小微企业人事管理系统的设计与实现毕业设计源码261630
    全面深入理解TCP协议(超详细)
    前端面试必看(手写Promise+js设计模式+继承+函数柯里化等)JavaScript面试全通关(1/3)
    VMware 16开启虚拟机电脑就蓝屏W11解决方法
    C语言练习题——分支和循环
    Flink 数据目录体系:深入理解 Catalog、Database 及 Table 概念
    NVM安装及如何使用NVM
    OpenCV-滤波矩阵(java版)
    SpringBoot分布式框架
    Matlab与.m脚本文件没有关联,怎么破?
  • 原文地址:https://blog.csdn.net/njh1147394013/article/details/137937702