第一章 线性模型

news2024/11/20 21:17:12

目录

  • 一、线性模型基本概念
  • 二、梯度下降
  • 三、反向传播
  • 四、使用 Pytorch 实现线性模型

一、线性模型基本概念

线性模型: y ^ = x ∗ ω + b \hat{y} = x * \omega + b y^=xω+b

简化版本,将 b b b 加入到权重矩阵 ω \omega ω 中: y ^ = x ∗ ω \hat{y} = x * \omega y^=xω

单个样本的损失函数: l o s s = ( y ^ − y ) 2 = ( x ∗ ω − y ) 2 loss = (\hat{y} - y)^2 = (x * \omega - y)^2 loss=(y^y)2=(xωy)2

整个 t r a i n i n g   s e t training\ set training set 的损失函数(Mean Square Error, MSE): c o s t = 1 N ∑ n = 1 N ( y n ^ − y n ) 2 cost = \frac{1}{N} \sum_{n=1}^N (\hat{y_n} - y_n)^2 cost=N1n=1N(yn^yn)2

代码实现及绘图:

import numpy as np
import matplotlib.pyplot as plt

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]


def forward(x):  # 定义模型
    return x * w


def loss(x, y):  # 损失函数
    y_pred = forward(x)
    return (y_pred - y) * (y_pred - y)


w_list = []
mse_list = []

for w in np.arange(0.0, 4.1, 0.1):
    print('w=', w)
    l_sum = 0
    for x_val, y_val in zip(x_data, y_data):
        y_pred_val = forward(x_val)
        loss_val = loss(x_val, y_val)
        l_sum += loss_val
        print('\t', x_val, y_val, y_pred_val, loss_val)
    print('MSE=', l_sum / 3)
    w_list.append(w)
    mse_list.append(l_sum / 3)

plt.plot(w_list, mse_list)
plt.ylabel('loss')
plt.xlabel('w')
plt.show()

二、梯度下降

损失函数 MSE c o s t = 1 N ∑ n = 1 N ( y n ^ − y n ) 2 cost = \frac{1}{N} \sum_{n=1}^N (\hat{y_n} - y_n)^2 cost=N1n=1N(yn^yn)2

为了使损失函数最小,即需要找到一个 ω ∗ \omega^* ω 使得 c o s t cost cost 值最小: ω ∗ = a r g   m i n   c o s t ( ω ) ω \omega^* = \underset{\omega} {arg \ min \ cost(\omega)} ω=ωarg min cost(ω)

梯度: G r a d i e n t = ∂ c o s t ∂ ω = ∂ ∂ ω 1 N ∑ n = 1 N ( x n ⋅   ω − y n ) 2 = 1 N ∑ n = 1 N ∂ ∂ ω ( x n ⋅   ω − y n ) 2 = 1 N ∑ n = 1 N 2 ⋅   ( x n ⋅   ω − y n ) ∂ ( x n ⋅   ω − y n ) ∂ ω = 1 N ∑ n = 1 N 2 ⋅   x n ⋅   ( x n ⋅   ω − y n ) \begin{aligned} Gradient &= \frac{\partial cost}{\partial \omega} \\ &= \frac{\partial}{\partial \omega} \frac{1}{N} \sum^N_{n=1} (x_n \cdot\ \omega - y_n)^2 \\ &= \frac{1}{N} \sum_{n=1}^N \frac{\partial}{\partial \omega} (x_n \cdot \ \omega - y_n)^2 \\ &= \frac{1}{N} \sum_{n=1}^N 2 \cdot \ (x_n \cdot \ \omega - y_n) \frac{\partial (x_n \cdot \ \omega - y_n)}{\partial \omega} \\ &= \frac{1}{N} \sum_{n=1}^N 2 \cdot \ x_n \cdot \ (x_n \cdot \ \omega - y_n) \end{aligned} Gradient=ωcost=ωN1n=1N(xn ωyn)2=N1n=1Nω(xn ωyn)2=N1n=1N2 (xn ωyn)ω(xn ωyn)=N1n=1N2 xn (xn ωyn)

梯度更新: ω = ω − α ∂ c o s t ∂ ω = ω − α 1 N ∑ n = 1 N 2 ⋅ x n ⋅   ( x n ⋅   ω − y n ) \begin{aligned} \omega &= \omega - \alpha \frac{\partial cost}{\partial \omega} \\ &= \omega - \alpha \frac{1}{N} \sum_{n=1}^N 2 \cdot x_n \cdot \ (x_n \cdot \ \omega - y_n) \end{aligned} ω=ωαωcost=ωαN1n=1N2xn (xn ωyn)

代码实现:

import matplotlib.pyplot as plt

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

w = 1.0


def forward(x):
    return x * w


def cost(xs, ys):
    cost = 0
    for x, y in zip(xs, ys):
        y_pred = forward(x)
        cost += (y_pred - y) ** 2
    return cost / len(xs)


def gradinet(xs, ys):
    grad = 0
    for x, y in zip(xs, ys):
        grad += 2 * x * (x * w - y)
    return grad / len(xs)


print('Predict (before training)', 4, forward(4))

Epoch_list = []
loss_list = []

for epoch in range(100):
    cost_val = cost(x_data, y_data)
    grad_val = gradinet(x_data, y_data)
    w -= 0.01 * grad_val
    Epoch_list.append(epoch)
    loss_list.append(cost_val)
    print('Epoch:', epoch, 'w=', w, 'loss=', cost_val)

print('Predict (after training)', 4, forward(4))

plt.plot(Epoch_list, loss_list)
plt.xlabel('Epoch')
plt.ylabel('cost')
plt.show()

随机梯度下降(Stochastic Gradient Desce,SGD),多指 mini-batch 的随机梯度下降。

三、反向传播

首先了解计算图,对于一个两层的神经网络模型: y ^ = W 2 ( W 1 ⋅ X + b 1 ) + b 2 = W 2 ⋅ W 1 ⋅ X + ( W 2 b 1 + b 2 ) = W ⋅ X + b \begin{aligned} \hat{y} &= W_2(W_1 \cdot X + b_1) + b_2 \\ &= W_2 \cdot W_1 \cdot X + (W_2b_1 + b_2) \\ &= W \cdot X + b\\ \end{aligned} y^=W2(W1X+b1)+b2=W2W1X+(W2b1+b2)=WX+b对于这个模型,可以构建计算图如下:在这里插入图片描述
由上式可以知道,不管多少层的一个线性的神经网络模型,都可以化简为一个仅包含一层的神经网络模型,这样的话,那些设计多个隐藏层的神经网络模型就没有意义了。所以在每一层的结尾都需要一个非线性函数,改进后的模型如下,其中 σ \sigma σ 表示一个非线性函数。
在这里插入图片描述

课程中这里有对链式求导法则的讲解,但是那个很简单,这里就跳过了。

有了计算图,就可以开始了解传播算法了。下面是一个例子,先进性前馈传播,再进行反向传播,虽然在 Pytorch 这样的框架里面实现了自动求解梯度的功能,但是下面的两张图是原理的解释。

在这里插入图片描述
下面是一个计算的实例:
在这里插入图片描述
下面使用 Pytorch 实现一下传播算法。

注意,在 Pytorch 中的一个基本单位是张量(Tensor),它可以用于动态创建计算图,其中包含数据(data)以及损失函数对于该张量(一般是指权重)的梯度(grad)。

import torch
import matplotlib.pyplot as plt

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

# 创建一个张量并且需要自动计算梯度
w = torch.Tensor([1.0])
w.requires_grad = True


# 构建计算图
def forward(x):
    return x * w  # 注意这里计算的时候x也被转换为了张量


def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2


print('predict (before training)', 4, forward(4).item())

epoch_list = []
l_list = []

for epoch in range(100):
    for x, y in zip(x_data, y_data):
        l = loss(x, y)
        l.backward()
        epoch_list.append(epoch)
        l_list.append(l.item())
        print('\tgrad:', x, y, w.grad.item())
        w.data = w.data - 0.01 * w.grad.data
        w.grad.data.zero_()  # 梯度置零,否则会累加
    print('progress:', epoch, l.item())

print('predict (after training)', 4, forward(4).item())

plt.plot(epoch_list, l_list)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

四、使用 Pytorch 实现线性模型

import torch

x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[2.0], [4.0], [6.0]])


class LinearModel(torch.nn.Module):
    def __init__(self):
        super(LinearModel, self).__init__()  # 调用父类的构造函数
        self.linear = torch.nn.Linear(1, 1)  # 权重和偏置值的维度feature

    def forward(self, x):
        y_pred = self.linear(x)  # 对象后面接参数,调用了__call__()方法
        return y_pred


model = LinearModel()

criterion = torch.nn.MSELoss(reduction='sum')  # 损失函数
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)  # 优化方法:梯度下降

for epoch in range(1000):
    y_pred = model(x_data)  # forward,调用了__call__()方法
    loss = criterion(y_pred, y_data)
    print(epoch, loss.item())

    optimizer.zero_grad()  # 梯度置零
    loss.backward()
    optimizer.step()  # 更新梯度


print('w=', model.linear.weight.item())
print('b=', model.linear.bias.item())

x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred=', y_test.item())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/541000.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新榜 | “淄博”现象专项观察报告

在过去的一个月中,淄博烧烤的相关话题霸屏网络,这些媒介话题里承载了多少受众的向往与想象? 根据2022年淄博市文旅局公开年报,去年,淄博官方就着力融媒体,在抖音、快手等平台创新使用“淄博到底有多牛”主题…

javascript-核心知识总结

目录 (一)DOM基础 1、DOM对象 2、节点类型 3、获取元素 4、创造元素 5、插入元素 6、删除元素 7、复制元素 8、替换元素 (二)DOM进阶 1、用DOM对象对HTML属性操作 2、用DOM对象对CSS操作 3、DOM查找(遍历&…

浅析基于AI智能识别技术边缘计算硬件在智慧食安监管场景中的应用

一、背景分析 自2014年开始,国家市场监督管理总局在强化企业主体责任、严格实施全过程监管、创新监管方式的方针下,推行“互联网明厨亮灶"工程建设。系统以四个端为整体规划,实现亮后厨、亮证、亮照、亮评估,通过以网管网措…

微信小程序xr-frame实现多光源效果

1.基础知识: 灯光 灯光组件Light用于给场景提供照明,也是阴影的核心。相机组件一般被代理到灯光元素XRLight中使用,其派生自XRNode,对应在xml中的标签为xr-light。 主光源以及参数 类型uniforms宏说明书写环境光颜色和亮度u_a…

Linux Shell 实现一键部署virtualbox

VirtualBox 前言 VirtualBox 是一款开源虚拟机软件。VirtualBox 是由德国 Innotek 公司开发,由Sun Microsystems公司出品的软件,使用Qt编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。Innotek 以 GNU General Public Licens…

从零开始 Spring Boot 30:数据校验

从零开始 Spring Boot 30:数据校验 图源:简书 (jianshu.com) 在从零开始 Spring Boot 13:参数校验 - 红茶的个人站点 (icexmoon.cn)一文中,我讨论了一些可以用于参数校验的注解。实际上这些注解都是来自于Jakarta Bean Validatio…

第7章异常、断言和曰志

Java和C异 在C中,throw说明符在运行时执行。Java在编译时执行。 处理错误 异常处理的任务就是将控制权从产生错误的地方转移到能够处理这种情况的错误处理器。 如果由于出现错误而使得某些操作没有完成,程序应该:返回到一种安全状态&#…

ChatGLM + PEFT 进行finetune

一、前言 1.1 硬件需求 注:r 为LoRA 维数大小,p 为前缀词表大小,l 为微调层数,ex/s 为每秒训练的样本数。gradient_accumulation_steps 参数设置为 1。上述结果均来自于单个 Tesla V100 GPU,仅供参考。 1.2 微调方法…

开放原子训练营第一季——铜锁探“密” 圆满落幕!

【开放原子训练营第一季结营总结】——铜锁探“密” 开放原子训练营第一季「铜锁探密」由开放原子开源基金会&铜锁社区共同举办,包含 5 次课程,以“抽丝剥茧,循序渐进,一起揭开商用密码的面纱”为主题,让参与者更加…

c++面向对象之类

一、类的定义 class 类名{成员属性构造函数析构函数成员函数 }Person.h #include <string> #include <iostream> using namespace std;class Person {int m_age;string m_name;Person();Person(int age,string name);~Person();int getAge();void setAge(int age…

蓝鲸平台通过标准运维 API 安装 Agent

目录 一、背景 二、目的 三、创建安装agent流程 四、通过标准运维 API 安装 Agent 五、总结 一、背景 蓝鲸平台正常情况纳管主机需要在节点管理手工安装agent&#xff0c;不能达到完成自动化安装agent的效果。想通过脚本一键安装agent&#xff0c;而不需要在蓝鲸平台进行过…

Golang指针的操作以及常用的指针函数

目录 指针的操作 定义指针 获取变量地址 解引用指针 指针作为函数参数 指针的空值 常用的指针函数 new 函数 make 函数 append 函数 copy 函数 指针的操作 在Go语言中&#xff0c;指针是一种非常重要的类型&#xff0c;可以用来传递变量的地址而不是变量本身。 定…

【leetcode刷题总结】——代码随想录(链表总结)

代码随想录按照数组-> 链表-> 哈希表->字符串->栈与队列->树->回溯->贪心->动态规划->图论->高级数据结构&#xff0c;再从简单刷起&#xff0c;做了几个类型题目之后&#xff0c;再慢慢做中等题目、困难题目。 以下是个人刷题总结&#xff0c;官…

多个Node.js版本之间切换

本篇文章会讲windows和Mac系统下实现多个node.js版本之间的切换。 1.windows下采用nvm&#xff08;nvm-window&#xff09; 2.Mac下采用nvm和n 注&#xff1a;window和mac下的nvm地址是不一样的 一、windows系统 什么是nvm&#xff1f; nvm是一个简单的bash脚本&#xff…

真题详解(有限自动机)-软件设计(七十七)

确定有限自动机 和 不确定有限自动机 解析&#xff1a; M1的A当0的时候&#xff0c;会变成A&#xff0c;也可能变成B&#xff0c; 所以M1是不确定有限自动机。 M2的A1的时候只会使A&#xff0c;0的时候只会是B B的0只会是B&#xff0c;1的时候只会是C。 C0的时候只会是B&a…

中小型企业需要“数据防泄露”吗?

数据防泄露是指企业采取的各种管理、技术与监督措施&#xff0c;以防止敏感和关键数据在传输、存储与使用过程中被未经授权访问或窃取&#xff0c;从而导致机密性、完整性或可用性受到损害。 数据防泄露工作通常包括数据分类与风险评估、权限管理与访问控制、加密与安全技术、数…

基于Gabor-小波滤波深度图表面法线的特征提取算法【通过正常Gabor-小波的直方图进行2D或3D特征提取】研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Bean的生命周期揭秘:从诞生到消亡,一个对象的壮丽演绎!

大家好&#xff0c;我是你们的小米。今天我要给大家揭秘一下Java开发中重要的概念——Spring Bean的生命周期。作为Java开发者&#xff0c;无论是在面试还是实际工作中&#xff0c;了解Bean的生命周期都是必备的知识点。让我们一起来深入了解吧&#xff01; 什么是Spring Bean …

【zabbix】PostgreSQL表信息查询收集监控

昨天开发那边给了一个需求&#xff0c;每隔一段时间查询一下数据库某表中的数据是否在最近更新&#xff0c;让我这边做一个监控信息收集 一、agent linux侧配置 这边目前就直接在zabbix上实现&#xff0c;首先就是脚本&#xff0c;我用python2实现 脚本名&#xff1a;check_y…

软件测试学什么——如何才能按时上线?

目录 引言 一、提前介入测试&#xff0c;认真做好需求分析。 二、测试计划没必要花太多精力。 三、测试用例编写 四、测试执行的关键点 五、测试环境 【一套系统提升学习的好资料】 阅读书籍文档 总结 引言 上线&#xff0c;永远是软件测试工程师最关注的问题。 上线…