matplotlib画图

matplotlib基本使用 画板figure,画纸Sublpot画质,可多图绘画 画纸上最上方是标题title,用来给图形起名字 坐标轴Axis,横轴叫x坐标轴label,纵轴叫y坐标轴ylabel 图例Legend 代表图形里的内容 网格Grid,图形中的虚线,True显示网格 Markers:表示点的形状 常用图形 scatter:散点图 plot: 折线图 bar: 柱状图 heat:热力图 box:箱线图 hist:直方图 pie:饼图 area:面积图 基本步骤 def base_plot(): x = np.arange(-1000, 1000, 1) y = x * x # plt.plot(x, y, color='r', marker='o', linestyle='dashed') plt.plot(x, y, '.r', linestyle='dashed') # 使用format格式,与上面含义相同 plt.xlabel('X') plt.ylabel('y = x^2') plt.axis([-100, 100, 0, 100]) # 设置坐标轴范围 plt.show() 多图绘制 使用Python创建多个画板和画纸来绘制多幅图,如果事先不声明画板画板,默认是创建一个画板一个画纸 使用figure()方法创建画板1 使用subplot()方法创建画纸,并选择当前画纸并绘图 同样用subplot()方法选择画纸并绘图 def base_subplot(): fig = plt.figure(1) # 创建画板 ax1 = plt.subplot(2, 1, 1) # 创建画纸(子图), 三个数字,前两个表示创建1*1的画纸,第三个表示选择第一个画纸 plt....

十二月 19, 2021 · 1 分钟 · pan

关于变换

做图像处理或者数据增强的过程中,经常需要用得各种变换来处理图片。本文详细的说明了线性变换、仿射变换、透视变换的定义、几何意义、学习表达。重点给出透视变换的计算过程,并给出python实现代码。经验证和opencv的结果是一样的。 虽然opencv或者其他的库有现成的函数可供调用,但是我们还是需要明白这些函数输出的意义。比如opencv的getAffineTransform返回一个2*3的矩阵,这个2*3矩阵的意义是什么? 线性变换是仿射变换的特例,仿射变换是透视变换的特例 一、线性变换 1.1线性变换的定义 如果$f: V->W$满足如下两条性质,那么$f$就是线性变换 可加性(additivity):$f(x+y) = f(x)+f(y)$ 齐次性(homogeneity):$f(ax) = af(x)$ 当然也可以把这两个性质合并一下, 对任意的$a$下式总成立: $f(x+ay)=f(x)+af(y)$ 那么思考一下下面两个变换是不是线性变换 (1)$f(x,y) = x+2y$ (2)$f(x,y) = x+1$ 第一式子是线性变换,但是第二个式子是不满足齐次性的。因为$f(ax)=ax+1 ≠ a(x+1)$ 从齐次性可以看出,线性变换一定是过零点的 1.2线性变换的几何意义 满足如下几何性质 变换前是直线的,变换后依然是直线 直线比例保持不变 变换前是原点的,变换后依然是原点 二、仿射变换 2.1 仿射变换的几何意义 仿射变换从几何意义看不需要满足线性变换的第三点,即仿射变换满足如下两点即可 变换前是直线的,变换后依然是直线 直线比例保持不变 三、常见的变换 (Identity)恒等变换 (Translation)平移变换 (Rotation)旋转变换 (Scaling)尺度变换 (Reflection)反射变换 (Shear)错切 示意图如下 图片from 仿射变换及其变换矩阵的理解 在上面所有的变换中只有平移变换不是线性变换(不满足齐次性),其他的都是线性变换 所以仿射变换就是线性变换+平移 四、仿射变换和线性变换的数学表达 $Y = AX+b$ 其中A是一个m*n的矩阵,b是一个n维的向量。 其中 A表示线性变换,b表示平移 。A,b合在一起就可以表示一个仿射变换 上式可以写如下两个形式,用矩阵的方式方便计算 1、 $$Y = [A|b]*\left[\begin{matrix}X\\1 \end{matrix}\right]$$ 2、 $$ \left[\begin{matrix}Y\\1 \end{matrix}\right] = \left[\begin{matrix}A & b \\0 & 1 \end{matrix}\right] * \left[\begin{matrix}X\\1 \end{matrix}\right] $$...

十一月 29, 2021 · 2 分钟 · pan

梯度下降优化方法概述

Updated on 2023-06-24: add AdamW 梯度下降是优化神经网络和机器机器学习算法的首选优化方法。本文重度参考SEBASTIAN RUDER的文章。对于英文比较好的同学请直接阅读原文。本文只为个人的学习总结,难免有所欠缺和不足。 一、梯度下降变种 根据训练数据集的大小,梯度下降有三种变体,但是本质是一样的,不一样的是每次使用多少条样本。如果内存一次可以计算所有样本的梯度,称为:批梯度下降(Batch gradient descent);如果内存一次只允许一个样本,称为:随机梯度下降(Stochastic gradient descent);大部分时候,内存一次是可以计算部分样本的,称为:最小批梯度下降(Mini-batch gradient descent)。三种变体的数据表达如下: 1.1批梯度下降(Vanilla gradient descent,又称Batch gradient descent) $\theta = \theta - \eta \cdot \nabla_\theta J( \theta)$ 1.2随机梯度下降(Stochastic gradient descent) $\theta = \theta - \eta \cdot \nabla_\theta J( \theta; x^{(i)}; y^{(i)})$ 1.3最小批梯度下降(Mini-batch gradient descent) $\theta = \theta - \eta \cdot \nabla_\theta J( \theta; x^{(i:i+n)}; y^{(i:i+n)})$ 注意,在其他地方并没对上述三种变体做严格区别,统称为SGD(随机梯度下降),下文其余部分,我们也不加区分,统称为SGD 二、梯度下降的几种优化方法 传统的梯度下降法不能保证一个很好的收敛,而且有一些挑战需要被解决。 选择这个合适的学习率是比较困难的。特别是对一个新的模型和新数据集时候,我们是不知道选择什么样的学习率是合适的。只能不断的去尝试。 学习率调度算法可以在训练的过程中去调整模型的学习率。模型一开始的时候可以使用大一点的学习率,后面再使用小一点的学习率去微调模型。更好的方法是一开始也用一个小的学习率去warm-up训练,让参数先适应数据集。但是无论哪种学习率调度算法都需要预先定义调度算法,这种方法也是没有办法很好的适应模型的特征的、 对每一个参数都使用同样的学习率是不合适的。对于稀疏的数据或者特征非常不均衡的数据。最好是使用不同学习率学习不同频率的特征。 另外的挑战是对于高阶非凸的损失函数,往往会陷于局部极值点。还有一种鞍点的情况,模型也是很难学习的。此时损失函数在各个方向的梯度接近于0。SGD是很难逃脱与鞍点或者局部极值点的。 针对上面的一些问题,慢慢出现了一些针对梯度下降的优化方法。 在介绍SGD变种之前。先给出各个变种的一般范式。后天的各个变种优化方法都离不开这个范式。 (1)计算目标函数关于参数的梯度 $g_t = \nabla_\theta J( \theta)$...

十一月 28, 2021 · 1 分钟 · Pan

pytorch ddp

(1) 关键概念 world_size: 集群中所有GPU的数量 rank: 范围[0, world_size-1], 表示GPU的编号 local_rank: GPU在每台机器上的编号 比如,两台机器,每台机器4块卡,那么world_size= 2*4, rank 取值范围 [0,1,2,3,4,5,6,7], local_rank 取值范围[0,1,2,3] (2) torch.distributed.launch 启动集群参数 –nnodes: 一共多少台机器 –node_rank: 当前机器编号 –nproc_per_node: 每台机器多少个进程 –master_adderss: master节点ip地址 –master_port: master节点端口 master节点的node_rank必须为0 command example: python -m torch.distributed.launch --nnodes=2 --node_rank=0 --nproc_per_node 8 \ --master_adderss $my_address --master_port $my_port main.py (3) mp.spwan 启动 PyTorch引入了torch.multiprocessing.spawn,可以使得单卡、DDP下的外部调用一致,即不用使用torch.distributed.launch。 python xxxx.py一句话搞定DDP模式。 def demo_fn(rank, world_size): dist.init_process_group("nccl", rank=rank, world_size=world_size) # lots of code. ... def run_demo(demo_fn, world_size): mp.spawn(demo_fn, args=(world_size,), nprocs=world_size, join=True) (4) 集群训练步骤 import torch....

九月 15, 2021 · 2 分钟 · Pan

CompleableFuture原理和源码分析

CompleableFuture 使用场景 CompletableFuture的定义如下: public class CompletableFuture<T> implements Future<T>, CompletionStage<T> 我们看到CompletableFuture是实现了Future的接口的,在没有CompletableFuture之前,我们可以用FutureTask来实现一个Future的功能。那么有了FutureTask那么为什么还要有CompletableFuture呢? 我任务主要是CompletableFuture有两个优点 CompletableFuture可以实现完全的异步,而FutureTask必须通过get阻塞的方式获取结果 CompletableFuture .supplyAsync(()-> 1+2) .thenAccept((v)-> System.out.println(v*v)); 如上面的代码所示,我们完整的任务有两个阶段,一阶段是计算1+2,二阶段是计算一阶段返回结果的平方,在整个过程中,主线程完全不需要管这个任务的执行情况,也不会阻塞主线程。但是如果用FutureTask实现如上功能如下: FutureTask<Integer> futureTask1 = new FutureTask<Integer>(() -> { return 1 + 2; }); new Thread(futureTask1).start(); Integer periodOneResult = futureTask1.get(); FutureTask<Integer> futureTask2 = new FutureTask<Integer>(() -> { return periodOneResult * periodOneResult; }); new Thread(futureTask2).start(); Integer secondOneResult = futureTask2.get(); System.out.println(secondOneResult); 代码冗长不说,还需要get方法阻塞主线程去获取结果。以上代码只是说明CompletableFuture的异步优点,实际工作中你可以把两个任务看出两个api CompletableFuture可以实现复杂的任务编排,请思考下面代码的执行顺序是什么? CompletableFuture<String> base = new CompletableFuture<>(); CompletableFuture<String> completion0 = base.thenApply(s -> { System.out.println("completion 0"); return s + " 0"; }); CompletableFuture<String> completion1 = base....

4 分钟 · pan