首页 > 其他分享 >《深度学习入门——自制框架》读书笔记

《深度学习入门——自制框架》读书笔记

时间:2023-12-01 19:56:28浏览次数:52  
标签:__ 入门 读书笔记 self forward input data 自制 def

1. 自动微分

step2 创建变量的函数

# 箱子类,存放一个变量数据
class Variable: 
	def __init__(self, data):
		self.data = data

# 函数类的基类
class Function:
    # __call__方法是一个特殊的Python方法。
    # 定义了这个方法后,当f = Function()时,就可以通过编写f(...)来调用__call__方法了
	def __call__(self, input):
		x = input.data
		y = self.forward(x)  # 具体的计算在forward方法中进行
		output = Variable(y)
		return output

	def forward(self, x):
		raise NotImplementedError()  # 告诉使用了Function类forward方法的人这个方法应该通过继承来实现

# 函数类的具体实现类
class Square(Function):
	def forward(self, x):
		return x ** 2


if __name__ == "__main__":
	x = Variable(10)
	f = Square()
	y = f(x)
	print(type(y))
	print(y.data)

step4 数值微分

利用中心差分近似来计算导数:

\[f'(x) \approx \frac{f(x+ \epsilon)-f(x- \epsilon)}{2 \epsilon} \]

设计numerical_diff函数:

class Variable: 
	def __init__(self, data):
		self.data = data


class Function:
	def __call__(self, input):
		x = input.data
		y = self.forward(x)  # 具体的计算在forward方法中进行
		output = Variable(y)
		return output

	def forward(self, x):
		raise NotImplementedError()  # 告诉使用了Function类forward方法的人这个方法应该通过继承来实现


class Square(Function):
	def forward(self, x):
		return x ** 2


def numerical_diff(f, x, eps=1e-4):
	x0 = Variable(x.data - eps)
	x1 = Variable(x.data + eps)
	y0 = f(x0)
	y1 = f(x1)
	return (y1.data - y0.data) / (2 * eps)


if __name__ == "__main__":
	f = Square()
	x = Variable(2.0)
	dy = numerical_diff(f, x)
	print(dy)

复合函数的导数

def f(x):
    A = Square()
    B = Exp()
    C = Square()
    return C(B(A(x)))


if __name__ == "__main__":
	x = Variable(np.array(0.5))
	dy = numerical_diff(f, x)
	print(dy)

step6 手动进行反向传播

用反向传播计算导数

import numpy as np


class Variable: 
	def __init__(self, data):
		self.data = data
		self.grad = None  # gradient梯度的缩写

class Function:
	def __call__(self, input):
		x = input.data
		y = self.forward(x)  # 具体的计算在forward方法中进行
		output = Variable(y)
		self.input = input  # 保存输入的变量
		# 将input设置为实例变量。
		# 这样一来,当调用backward方法时,向函数输入的Variable实例就可以作为self.input使用

		return output

	def forward(self, x):
		raise NotImplementedError()  # 告诉使用了Function类forward方法的人这个方法应该通过继承来实现

	def backward(self, gy):
		raise NotImplementedError()


class Square(Function):
	def forward(self, x):
		y = x ** 2
		return y

	def backward(self, gy):
		x = self.input.data
		gx = 2 * x * gy
		return gx


class Exp(Function):
	def forward(self, x):
		return np.exp(x)

	def backward(self, gy):
		x = self.input.data
		gx = np.exp(x) * gy
		return gx


if __name__ == "__main__":
	A = Square()
	B = Exp()
	C = Square()

	x = Variable(np.array(0.5))
	a = A(x)
	b = B(a)
	y = C(b)

	y.grad = np.array(1.0)  # dy/dy = 1
	b.grad = C.backward(y.grad)
	a.grad = B.backward(b.grad)
	x.grad = A.backward(a.grad)

	print(x.grad)

step7 反向传播的自动化

import numpy as np


class Variable: 
	def __init__(self, data):
		self.data = data
		self.grad = None  # gradient梯度的缩写
		self.creator = None

	def set_creator(self, func):
		self.creator = func

	def backward(self):
		f = self.creator  # 1. 获取函数
		if f is not None:
			x = f.input  # 2. 获取函数的输入
			x.grad = f.backward(self.grad)  # 3. 调用函数的backward方法
			x.backward()  # 调用自己前面那个变量的backward方法(递归)


class Function:
	def __call__(self, input):
		x = input.data
		y = self.forward(x)  # 具体的计算在forward方法中进行
		output = Variable(y)
		output.set_creator(self)  # 让输出变量保存创造者信息
		self.input = input  # 保存输入的变量
		# 将input设置为实例变量。
		# 这样一来,当调用backward方法时,向函数输入的Variable实例就可以作为self.input使用

		self.output = output  # 也保存输出变量
		return output

	def forward(self, x):
		raise NotImplementedError()  # 告诉使用了Function类forward方法的人这个方法应该通过继承来实现

	def backward(self, gy):
		raise NotImplementedError()


class Square(Function):
	def forward(self, x):
		y = x ** 2
		return y

	def backward(self, gy):
		x = self.input.data
		gx = 2 * x * gy
		return gx


class Exp(Function):
	def forward(self, x):
		return np.exp(x)

	def backward(self, gy):
		x = self.input.data
		gx = np.exp(x) * gy
		return gx


if __name__ == "__main__":
	A = Square()
	B = Exp()
	C = Square()

	x = Variable(np.array(0.5))
	a = A(x)
	b = B(a)
	y = C(b)

	y.grad = np.array(1.0)  # dy/dy = 1
	y.backward()

	print(x.grad)

标签:__,入门,读书笔记,self,forward,input,data,自制,def
From: https://www.cnblogs.com/code-pigeon/p/17870682.html

相关文章

  • Docker极简入门
    Ubuntu安装Dockersudoaptinstalldocker.io开启Docker服务sudosystemctlenabledockersudosystemctlstartdocker为当前用户赋予Docker用户组权限sudogroupadddockersudousermod-aGdocker${USER}newgrpdocker使用ps命令,该命令的功能是列出所有容,检查Docke......
  • 黑客玩具入门——9、Burp Suite
    BurpSuite是一款集成化的渗透测试工具,包含了很多功能,可以帮助我们快速完成对web应用程序的渗透测试和攻击。BurpSuite是由Java语言编写,因为Java是可以跨平台的,所以BurpSuite也是跨平台的,支持windows、linux、mac。1、代理和浏览器设置BurpSuite代理工具是以拦截代理的方式,拦......
  • LLM 入门笔记-Tokenizer
    以下笔记参考huggingface官方tutorial:https://huggingface.co/learn/nlp-course/chapter6下图展示了完整的tokenization流程,接下来会对每个步骤做进一步的介绍。1.Normalizationnormalize其实就是根据不同的需要对文本数据做一下清洗工作,以英文文本为例可以包括删除......
  • XmlRPC入门_基于组合类型的客户端、服务端
    1、客户端#include<stdlib.h>#include<stdio.h>#include<xmlrpc-c/base.h>#include<xmlrpc-c/client.h>#include"config.h"/*informationaboutthisbuildenvironment*/#defineNAME"Xmlrpc-cTestClient"#d......
  • 8.4 Windows驱动开发:文件微过滤驱动入门
    MiniFilter微过滤驱动是相对于SFilter传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数IRP操作都由过滤管理器(FilterManager或Fltmgr)所接管,因为有了兼容层,所以在......
  • 黑客玩具入门——8、其他攻击手段
    1、拒绝服务攻击使用某些手段故意占用某一系统对外服务的有限资源,从而导致其无法正常工作的行为就是拒绝服务攻击。实际上拒绝服务攻击并不是一个攻击方式,它是一类具有相似特征的攻击方式的集合。拒绝服务攻击有以下分类:1.数据链路层的拒绝服务攻击攻击目标:交换机集线器:以前......
  • XmlRPC入门_基于C的服务端、客户端
    以下客户端与服务端的代码内容为官网给出的示例,此处拷贝记录,了解基础使用方式。1、服务端#include<iostream>#include<winsock2.h>#include<windows.h>#include"xmlrpc-c/base.h"#include"xmlrpc-c/server.h"#include"xmlrpc-c/server_abyss.h"#incl......
  • Jmeter接口自动化测试 —— Jmeter下载安装及入门
    jmeter简介ApacheJMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。下载下载地址:ApacheJMeter-DownloadApacheJMeter安装由于Jmeter是基于Java的程序,所以我们要使用Jmeter就必须先安装Ja......
  • 3-1 MySQL 入门-安装配置篇
    ​ 概要以前,在开发程序时,我们会把很多的数据和信息存储到某个文件夹中的文件中,例如:user.txt、db.xlsx等。现在,有那么一个叫:数据库管理系统(DBMS,DatabaseManagementSystem)的软件,可以帮助我们实现对文件夹中的文件进行操作,而我们只要学习DBMS能识别的指令,就能控制它去帮助我......
  • postgresql从入门到精通教程 - 第36讲:postgresql逻辑备份
       PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。 第36讲:PostgreSQL逻辑备份 第36讲:12月02日(周六)19......