需求描述:最近在做数据清洗的工作,从ods层到dwd层对数据进行标准化。有多张表需要汇入主题表,因为表中的字段比较多,况且也不统一,需要从指定字段拿数据,并且清洗,最后汇入主题表。
insert into # 使用insert into时,属于是追加行为,如果指定字段,那么查询的字段要出插入列数一致 示例: insert into table personnel(id,name,age,gender) select id,name,age,gender from people; # 由于我是分区表,还需要指定分区,这块当时给我困惑了好长时间 insert into table personnel partition(ptr='day')(id,name,age,gender) select id,name,age,gender from people; 说明:一定要注意partition的顺序,本人就是在这里踩了坑,谨记。 insert overwrite # 使用overwrite时,是覆盖数据,into是追加数据,但是需要注意的是,overwrite后面的table不能省略而且不能指定字段名 insert overwrite table partition(ptr='day') select id,name,age,gender from people; PS:又结束了一天忙碌的工作,祝愿大家开心生活每一天。
近日,阿里发布了Animate Anyone,只需一张人物照片,结合骨骼动画,就能生成人体动画视频。
项目地址:https://humanaigc.github.io/animate-anyone/
论文地址:https://arxiv.org/pdf/2311.17117.pdf
Github:https://github.com/HumanAIGC/AnimateAnyone
在图像生成领域视频,尤其是在角色动画(通过驱动信号从静态图像中生成角色视频)生成中,其中角色详细信息的一致性仍然是一个艰巨的问题。为了确保可控性和连续性,引入了一个有效的姿势指导器来指导角色的动作,并采用了一种有效的时间建模方法来确保视频帧之间的平滑过渡。本方法可以通过数据驱动的方式对任意角色进行动画制作,相比其他图像到视频的方法,其在角色动画方面表现更优。此外,本方法在时尚视频和人类舞蹈合成的基准测试中取得了最先进的结果。
一、Animate Anyone介绍 模型架构,如下图所示:
网络的初始输入由多帧噪声组成。去噪UNet基于SD的设计进行配置,采用相同的框架和块单元,并继承SD的训练权重。该方法包含三个关键组件:1)ReferenceNet:编码参考图像中字符的外观特征;2)Pose Guider:编码运动控制信号,实现角色的可控动作;3)Temporal Layer:编码时间关系,保证角色运动的连续性。
1.1 ReferenceNet 在文本生成视频的任务中,文本Prompt包含高级语义,只需要语义与生成的视觉内容相关性即可。然而,在图像生成视频任务,图像特征更详细一些,要求生成的结果更精确匹配。在之前的研究中,重点关注图像驱动生成,大多数方法都采用CLIP图像编码器作为交叉注意中的文本编码器,然而,这种设计未能解决与细节一致性相关的问题。一个原因由于这种限制,CLIP图像编码器的输入包括低分辨率(224×224)图像,导致丢失重要的细粒度细节信息。另一个因素是CLIP经过预训练以匹配语义强调高级特征匹配的文本特征,从而导致在特征编码内的详细特征的不足。
作者设计了一种参考图像特征提取网络ReferenceNet。对于ReferenceNet,采用了与去噪UNet相同的框架,不包括时间层。与去噪的UNet类似,ReferenceNet从原始SD继承了权重,并且对每个SD的权重更新都是独立进行的。如上图2所示,将self-attention层替换为space-attention层,然后执行self-attention,并提取特征图的前半部分作为输出。这种设计有两个优点:首先,ReferenceNet可以利用原始SD的预训练图像特征建模能力,从而得到良好的初始化特征。其次,由于ReferenceNet和去噪UNet本质上相同的网络结构和共享的初始化权值,去噪UNet可以选择性地从ReferenceNet中学习相同特征空间中相关的特征。利用与文本编码器共享的特征空间,提供参考图像的语义特征,作为有益的初始化,加快整个网络训练过程。
ControlNet也采用类似的设计,它在去噪UNet中引入了额外的控制特征使用零卷积。然而,控制信息(例如深度或者边缘信息)在空间上与目标图像是对齐的,而参考图像和目标图像在空间上相关但不对齐。因此,ControlNet不是适合直接应用。后续的实验会有具体的分析。
虽然ReferenceNet引入了与去噪UNet相当数量的参数,但在基于扩散的视频生成中,所有视频帧都要进行多次去噪,而ReferenceNet在整个过程中只需要提取一次特征。因此,在推理过程中,它不会导致计算开销的大幅增加。
1.2 Pose Guider ControlNet表现出超出文本Prompt之外且具有高度鲁棒性的条件生成功能。由于去噪的UNet需要微调,本文选择不纳入额外的ControlNet,以防止计算复杂度的显著增加。相反,作者采用了一个轻量级的姿势引导器。这个姿态引导器利用四个卷积层(4×4核,2×2步,使用16,32,64128通道,类似于ControlNet中的条件编码器)以与噪声潜分辨率相同的姿态图像对齐。然后,将处理后的姿态图像与噪声潜层相加,再输入到去噪的UNet中。姿态引导器使用高斯权重进行初始化,并且在最终的投影层中采用零卷积。
1.3 Temporal Layer 许多研究表明将时间层加入文本生成图像(T2I)的模型中可以捕获视频帧的时间依赖关系,这种设计有助于从预训练好的T2I模型迁移图像生成能力。我们的时间层在Res-Trans块内的空间注意力和交叉注意力组件之后进行集成。temporal层的设计灵感来自AnimateDiff。通过残差连接将来自时间层的特征纳入原始特征。时间层只应用于去噪UNet的Res-Trans块内。对于ReferenceNet,它计算单个参考图像的特征,不参与时间建模。由于姿态引导器实现了角色连续运动的可控性,实验表明,时间层确保了外观细节的时间平滑和连续性,避免了复杂的运动建模。
二、Animate Anyone训练策略 训练总共分为两个阶段:第一阶段使用单个视频帧进行训练,在去噪UNet中排除了时间层,模型以单帧噪声作为输入,同时训练ReferenceNet和Pose Guider。参考图像从整个视频剪辑中随机选择。Denoising UNet和ReferenceNet的模型使用SD的预训练权重进行初始化,而Pose Guider使用高斯权重进行初始化,最后的投影层使用零卷积。VAE的编码器和解码器以及CLIP图像编码器的权重都保持不变。这个阶段的优化目标是在给定参考图像和目标姿势的条件下生成高质量的动画图像。第二阶段将时间层引入先前预训练好的模型,并使用AnimateDiff的预训练权重进行初始化。模型的输入是一个24帧的视频剪辑。在这个阶段,只训练时间层,固定网络的其他权重。
三、Animate Anyone实验效果分析 3.1 实验设置 从互联网收集了5K个角色视频片段(2-10s时长)进行训练,并采用DWPose提取角色的姿势序列(包括身体和手),并使用OpenPose对其进行渲染为姿势骨架图像。训练硬件为4个NVIDIA A100 GPU。在训练过程中,使用了两个阶段的训练,在第一个训练阶段,采样单个视频帧,并调整大小和中心裁剪到768×768的分辨率,batch size设置为64,训练30000步;在第二个训练阶段,使用24帧视频序列,并设置batch size为4,训练10000步。两种学习率都设置为1e-5。在推理过程中,重新调整姿势轮廓的长度来匹配角色参考图像中的特征轮廓,并使用DDIM采样器进行20步去噪。作者采用了时间聚合中的方法,将不同批次的结果连接到生成长视频。为了与其他图像进行公平比较动画方法,作者还在两个特定的基准(UBC时尚视频数据集和TikTok数据集)上训练模型。
3.2 定性分析 Animate Anyone可以动画化任意角色,包括全身人物、半身肖像、卡通角色和人形角色。它能够生成高清晰度和逼真的角色细节,并在大幅度运动下保持与参考图像的时间一致性,同时在帧之间展现时间连续性。更多视频结果可在补充材料中查看。
3.3 对比分析 Animate Anyone在时尚视频合成和人类舞蹈生成两个基准测试中进行了评估。使用SSIM、PSNR和LPIPS等指标进行图像质量的定量评估,使用FVD指标进行视频质量的评估。
时尚视频合成
人类舞蹈生成
图像到视频通用方法
3.4 消融实验 四、Animate Anyone不足之处 1.与许多视觉生成模型类似,模型可能难以为手部运动生成高度稳定的结果,有时会导致失真以及运动模糊;
2.由于图像只提供了一个视角,生成角色移动时未见部分的问题是不确定的,可能会导致不稳定性;
3.由于使用了DDPM,该模型的生成效率较低。
参考文献: [1] https://arxiv.org/pdf/2311.17117.pdf
一、点击运行,运行到手机或模拟器,没有安装插件到话会显示,安装真机运行插件。
二、安装好之后显示界面会更新。 三、
3.1、数据线连接手机
3.2、安卓手机 开启开发者模式
备注:第一次开启需要,在设置中找到自己的版本号(可以在设置里搜索版本号,找到自己手机的版本,通常是第一个。或者设置,我的设备-全部参数-xx版本。例小米手机:MIUI 版本),连续点击直到提示-已经处于开发者模式。
第二次开启,搜索开发者就会有提示。 可以直接在安卓机设置里-搜索(开发者)--选择开启开发者选项按钮
3.2、手机上同一个页面,下拉开启usb调试模式
回到编辑器,刷新之后选择对应选项,点击运行,手机上就会安装对应基座。
四、安卓云打包
4.1、登录Dcloud账号/注册Dcloud账号
4.2、获取Dcloud AppID (manifest.json-基础配置uni-app应用标识,重新获取)
设置应用名称-设置应用图标(浏览,上传图片,自动生成所有图标并替换)
4.3、发行app云打包
1、输入安卓包名
安卓包名一般以域名命名,反过来写
2、选择证书类型
三种证书:
自有证书需要自己生成,可以自己研究一下。
公共证书:不安全,所有人都可以用的公共证书。
云端证书:推荐(生成方式:点击云端证书边上的-详情-登录Dcloud开发者中心-找到对应的应用名称)
点击应用名称-点击安卓云端证书-创建证书(生成之后系统会自动进行关联)
3、勾选打正式打包
4、选择打包方式
传统打包、
快速安心打包、
(区别在于是否上传代码跟证书-都可以)
5、云打包如提示需安装插件点击安装即可(没有安装需要安装一下)
6、打包之后,控制台会输出生成的,安装包所在文件夹的位置。
7、进入文件夹,右键apk文件,选择安装到手机
备注:
其他选项可根据需要自行调整。
五、上架应用市场
自行研究。。。
关于: 编译器版本跟sdk版本不一致的问题
修改成自己需要的版本号 ,例如上面:3.8.12
关于aab包:
上架安卓的google商店的话,需要打aab包。
挂个详细链接给:
Google Play上传应用要求Android App Bundle (AAB) 格式的相关说明 - DCloud问答
目录
一.异常的概念
二.异常的体系结构
三.异常的处理
异常处理思路
LBYL:Look Before You Leap
EAFP: It's Easier to Ask Forgiveness than Permission
异常抛出throw
异常的捕获
提醒声明throws
try-catch捕获处理
finally的作用
四.自定义异常类
一.异常的概念 有一句话说的很好 ”程序员不是在写BUG就是在改BUG” ,在日常开发中,程序员绞尽脑汁的去写出完美的代码,但是在程序运行过程中难免回遇见一些奇奇怪怪的问题。而这些问题与BUG总是很难去控制,用人类的思维去看明明是很完美的一个逻辑处理,但是交给编译器就产生的结果总会与我们的预期大相径庭,在Java中,我们将程序执行过程中发生的不正常的行为称为异常,比如什么算数异常啊,数组越界异常啊,空指针异常啊这都属于异常的范围,我们统称为异常
System.out.println(10 / 0); // 执行结果Exception in thread "main" java.lang.ArithmeticException int[] arr1 = {1, 2, 3}; System.out.println(arr1[100]); // 执行结果Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException int[] arr2 = null; System.out.println(arr2.length); // 执行结果Exception in thread "main" java.lang.NullPointerException 并且我们可以看见在Java中对于不同的异常,都有对应的类来描述
二.异常的体系结构 实际上异常的种类是很多的,为了应对不同的异常或者错误,Java提供了一个非常庞大的异常体系机构供程序员来更好的维护代码的安全性,如下图所示
异常可能发生在编译阶段,可能发生在运行阶段,因此我们可以按照异常发生的时间段将其进行分类:
编译时异常,也叫做受查异常运行时异常,也叫做非受查异常 但是诸如将单词拼写错误导致的问题我们程序出现问题的情况不属于异常
三.异常的处理 代码中存在异常并不是什么奇怪的事情,但是在出现异常后,我们需要及时通知程序员去修改,对于异常的处理,我们分为俩种思路
异常处理思路 LBYL:Look Before You Leap 也就是说我们在操作之前就对异常做出充分的检查,也就是事先防御型,比如我们在设计一款游戏的时候,我们就需要对其中可能发生的每一个错误做出处理机制和避免机制
1、首次适应算法 概念:首次适应算法从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。
实验要求:已知作业名、作业大小、作业提交时间、内存容量、碎片大小,要求使用分区大小不等的内存分区方法和首次适应分配算法给每次到来的作业分配内存。输出内存分区情况和分配情况。
#include <iostream> using namespace std; #define FREE 0 #define BUSY 1 #define MAX_length 300 const double debri = 20; //设置碎片大小 // FREE代表空闲 BUSY代表已分配 typedef struct free_area //首先定义空闲区分表结构 { int flag; int size; int number; int begin_address; }Elemtype; typedef struct Free_Node { Elemtype date; struct Free_Node *prior; struct Free_Node *next; }Free_Node,*pNod; pNod headNode; pNod initNode; int m_allocation();//作业分配 int free(int number);//作业回收 bool ff(int number,int size);//首次适应算法 void show();//查看分配 void init();//初始化 int main() { int tag=0; int number; init(); while(tag!
1.Java获取两日期之间的所有日期集合 废话不多说直接上代码
注意事项:如果要获取到结束日期的当天,两日期间隔相减的值要加上1,否则结束日期只会到前一天
第一种方式 //开始 LocalDate startDate = LocalDate.parse("2023-06-01", DateTimeFormatter.ofPattern("yyyy-MM-dd")); //结束 LocalDate endDate = LocalDate.parse("2023-06-07", DateTimeFormatter.ofPattern("yyyy-MM-dd")); //间隔 包含当天需要加1 long numOfDays = ChronoUnit.DAYS.between(startDate, endDate) + 1L; List<LocalDate> listOfDates1 = LongStream.range(0, numOfDays) .mapToObj(startDate::plusDays)//映射 .collect(Collectors.toList());//收集 listOfDates1.forEach(System.out::println); 第二种方式 //开始 LocalDate startDate = LocalDate.parse("2023-06-01", DateTimeFormatter.ofPattern("yyyy-MM-dd")); //结束 LocalDate endDate = LocalDate.parse("2023-06-07", DateTimeFormatter.ofPattern("yyyy-MM-dd")); //间隔 long numOfDays = ChronoUnit.DAYS.between(startDate, endDate); List<LocalDate> listOfDates2 = Stream.iterate(startDate, date -> date.plusDays(1)) .limit(numOfDays + 1) //+1包含当天,输出结果只到2023-06-06 .collect(Collectors.toList()); listOfDates2.forEach(System.out::println); 输出
2.String转localDate,Date转localDate String 类型转localDate
系列文章目录(Intellij IDEA2023年10月 最新教程)
Java学习之IDEA的安装教程和使用 以下是第一章的内容:IntelliJ IDEA安装教程
文章目录 前言准备工作步骤(敲详细!!!) 前言 IDEA的安装是Java课程的入门,本人台式机于2023年7月份进行了系统重装,恰巧最近需要重新安装IDEA进行使用,借此机会给同学们分享我的安装过程(昔日的安装过程依稀记得,这次是边安装边截图),我把我鼠标和键盘的每一步每一个动作都记录了下来,保证同学们都能理解并且成功安装;希望同学们按照我的步骤一步一步操作,最后一定能少走那些年我踩过的坑。
一、kdk的安装 解释一下:JDK 是 Java Development ToolKit 的简称,也就是 Java 开发工具包。JDK 是整个 Java 的核心,包括 Java 运行环境(Java Runtime Envirnment,简称 JRE),Java 工具(比如 javac、java、javap 等等),以及 Java 基础类库(比如 rt.jar)。
————————————————
版权声明:本文为CSDN博主「沉默王二」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qing_gee/article/details/102792349
总之别人说啥就是啥,我个人理解就是:jdk是IDEA运行的Java环境,没有jdk的话IDEA只能写代码却不能debug,就是不能运行你写的代码,安装了JDK就能跑起来,所以第一步是先给电脑安装好JDK
1、JDK的下载 官网链接:
https://www.oracle.com/java/technologies/downloads/ 找对位置,download 她!
2、jdk的安装 下载好之后(双击):
这里一定要注意!!!!:切换安装地址,不要使用默认地址!!!!
在D盘(不要选C盘系统盘,尤其是♀们!!!),尽量跟我的一样,里面新建一个Java文件夹
安装好之后,关掉安装页面,准备下一步。
3、jdk的系统配置(这一步很重要) 打开“我的电脑”or文件管理页面→计算机→系统属性
在系统设置里面也能找到
找到”关于”→高级系统设置
高级→环境变量
系统变量→新建
变量名为
JAVA_HOME 变量值为当时JDK安装所在的文件夹,比如我的(选预览目录去找比较快)
D:\Program Files\java 添加好后是这样的:
紧接着再点击新建:
变量名
CLASSPATH 变量值
.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar 然后在系统变量(S)中找到 Path,单击一下它,紧接着点击 编辑
Django提示mysql版本过低:django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.26).
因为mysql5.7及以下是免费的数据库,8.0之后是收费的。使用免费的数据库更放心,使用上没有什么区别。这个提示只是Django的版本检测提示,把它注释掉就好了。
全局搜索函数:
check_database_version_supported()
文件路径是:
D:\Python\web_project\dj01\venv\Lib\site-packages\django\db\backends\base\base.py
找到第二个,就是就是使用的那个,把它注释了:
def init_connection_state(self): """Initialize the database connection settings.""" global RAN_DB_VERSION_CHECK if self.alias not in RAN_DB_VERSION_CHECK: # self.check_database_version_supported() RAN_DB_VERSION_CHECK.add(self.alias) 先执行生成数据库迁移文件命令:
python .\manage.py makemigrations
然后写好数据实体类: from django.db import models # Create your models here. """轮播图模型""" class Banner(models.Model): # 模型字段 image_url = models.CharField(max_length=255, verbose_name="广告图片") link = models.CharField(max_length=500, verbose_name="广告链接") remark = models.TextField(verbose_name="备注") is_show = models.BooleanField(verbose_name="是否显示", default=False) orders = models.IntegerField(default=1, verbose_name="
简介
Android Studio 构建系统以 Gradle 为基础,并且 Android Gradle 插件添加了几项专用于构建 Android 应用的功能。虽然 Android 插件通常会与 Android Studio 的更新步调保持一致,但插件(以及 Gradle 系统的其余部分)可独立于 Android Studio 运行并单独更新。
插件版本和gradle版本对应
gradle插件版本gradle版本1.0.0 - 1.1.32.2.1 - 2.31.2.0 - 1.3.12.2.1 - 2.91.5.02.2.1 - 2.132.0.0 - 2.1.22.10 - 2.132.1.3 - 2.2.32.14.1 - 3.52.3.0+3.3+3.0.0+4.1+3.1.0+4.4+3.2.0 - 3.2.14.6+3.3.0 - 3.3.34.10.1+3.4.0 - 3.4.35.1.1+3.5.0 - 3.5.45.4.1+3.6.0 - 3.6.45.6.4+4.0.0+6.1.1+4.1.0+6.5+4.2.0+6.7.1+7.07.0+7.17.2+7.27.3.3+7.47.3+7.57.4+8.08.0 Android Studio 对应的Gradle 插件版本 Android Studio 版本所需插件版本As 2.2.22.0.0 - 2.2.3As 3.63.0 - 6.7.1Arctic Fox | 2020.3.13.1-7.0Bumblebee | 2021.1.13.2-7.1Chipmunk | 2021.
一. 前言 以下代码只可用于私服,不可商用,代码完全开源,因为自己的研究方向也是深度学习方向,而且平时闲的时候还喜欢玩会cf火线等枪战,就想着找一个大模型做一个对游戏敌人的识别的功能,一切实现之后就想把自己的心得写出来,我打算分俩个教程分别细述整个学习以及操作的过程,教程一主要包括了yolov5的基本使用,制作并训练自己的数据集,第二个教程包括对yolov5添加或修改部分代码以达到实现完整功能的目的
提示:看这篇文章需要会一些虚拟环境的基础操作以及python的基本操作,如果对虚拟环境不了解,对cudnn和cuda不了解可以看下面这篇文章 ==》https://blog.csdn.net/calmdownn/article/details/130609866
二. 制作数据集 2.1 下载labelImg 和 所需配置库 进入aconda虚拟环境中之后下载下面三个库文件
pip install PyQt5 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install pyqt5-tools -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install lxml -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
labelImg : 到github上将labelImg压缩包下载下来,我用的是1.8.1的版本 ==》labelImg下载地址
2.2 进入虚拟环境编译resources.py文件之后启动labelImg 进入虚拟环境之后切换到(cd)下载之后的labelImg文件夹目录,执行以下命令将qt文件转化为.py
pyrcc5 -o resources.py resources.qrc
(我的python版本是3.8),最后运行labelImg.py的python文件,打开labelImg
python labelImg.py
注意:可能会爆出以下错误,提示在libs文件中找不到resources文件
解决方法:将resources.py文件转移到libs文件夹中
打开之后如下:
点击PascalVoc按钮,将其切换成yolo格式,open就是打开你原始图片的文件夹,open dir 就是打开你的目标图片文件夹(推荐这个),change save Dir就是改变你的保存路径
下面是它的快捷键:
2.3 使用labelImg 添加原图片,按w进行拉框,拉框之后为其命名即可
我这里是画了一个头和一个身子
全部画完之后按住 ctrl + s 进行保存,你就能在原先设置的存储路径中看见一个.txt的文件了
打开txt文件之后如下,0和1分别代表头部类和身体类,四个数值分别代表你画框的左上角坐标和右下角坐标
到这制作数据集的步骤就结束了,下面开始下载并使用yolov5模型
三. yolov5的下载与使用 3.
原地址:https://cycloctane.github.io/posts/8/index.html
之前写flask应用练手的时候接触到了这个框架的用法。学习的时候发现各种博客参差不齐,大多只是搬了一套用法,没有特别能讲清楚的那种。官方文档很完善,但其中有些东西写得比较抽象,也有很多事项还是自己钻研过之后才理解的。在这里按自己的思路简单记录一下。
这些大部分都是咱自己的理解,大概会有一些不准确的地方,只用来参考一下。目前也并不完善,之后会逐步更新内容。
0x00 SQLAlchemy是python中常用的ORM层框架。它的位置处于DBAPI和web应用之间,自身并不包含连接数据库的功能,需要配合数据库驱动(DBAPI)使用。
对于一般的python的DBAPI,进行数据库操作需要建立一个连接,再从连接中获取一个游标(cursor),再用游标执行SQL语句并从游标中获取结果。整个流程很直观。
而对于一个SQLAlchemy实例,通常需要:
engine: 通过DBAPI获取数据库连接(实际上是一个连接池)。即让SQLAlchemy知道如何连接到我们的数据库。Metadata: 保存数据库中schema信息的集合。Table: 数据库的表的对象。可以自己定义,或者通过engine从数据库中已经存在的表中反射。当然同时也有Column作为列的对象。Mapped Class: 映射类。把数据库表映射成类。Session: 构建一个绑定到engine的session,是最终用来进行各种数据库操作的接口。 最终使用SQLAlchemy具体方法其实多种多样。新旧版本之间也有些区别,有些方法是旧版的常规使用方法但新版已经不推荐使用了(但还在兼容),有些非常规的方法在简单的情况下也可以正常使用(比如直接用Table实例在Session中进行数据库操作而不进行类映射)。看别的博客和说明的时候会发现怎么用的都有,很容易就绕晕了。但其实提到的方法在目前版本下基本上都可以正常使用,但用不用得明白又是另外一回事了。
不管怎样,我们只要分别理解以上几个部分的用法和作用,即可理解这些使用方法分别是怎么回事。
0x01 安装 这个不用多说,直接用pip安装。
pip install SQLAlchemy 当然上面提到过需要和DBAPI一起使用,所以DBAPI当然也得安装。咱用mysql多一点,使用的是mysql官方的mysql-connector。并不是SQLAlchemy推荐的mysql驱动,但咱用着好像也没什么问题
pip install mysql-connector-python 0x02 连接数据库 在SQLAlchemy中建立数据库连接需要用engine。首先安装数据库对应的DBAPI,然后用create_engine()函数创建一个连接engine。不同于python驱动,SQLAlchemy中engine连接参数的指定使用的是类似于JDBC的一种Database URL。总结一下就像这样:
<dialect>+<DBAPI>://<user>:<password>@<ip>:<port>/<schema>?<arg_key>=<value>&<arg_key>=<value>.. 不同的数据库的差别被称为dialect(方言)。SQLAlchemy即是通过区分不同的dialect和DBAPI来同时兼容众多不同的数据库的。因此DATABASE URL最开头首先需要指定数据库dialect和使用的DBAPI。//后的内容会解析成python的DBAPI所识别的kwargs参数,原样传给DBAPI中建立连接池的方法,获取的当然也是一个连接池(并非单个连接)。DBAPI所支持的其他的参数,包括SSL连接相关的参数直接作为URL的参数加在?后即可。
顺便Database URL也是支持URL Encode的,特殊字符像网站URL一样escape一下就可以正常传了。
from sqlalchemy import create_engine engine=create_engine("mysql+mysqlconnector://user:password@octanepi:3306/test?ssl_verify_cert=True&ssl_cert=client.crt&ssl_key=client_key.pem&ssl_ca=ca-chain.crt&pool_size=10") 如此就能得到一个使用mysql数据库和mysql-connector-python的DBAPI通过SSL连接到octanepi的mysql数据库服务的一个名为"test"的schema的engine实例,对应的就是DBAPI中的mysql.pooling.MySQLConnectionPool()方法。之后对数据库的操作都建立在这个engine实例的基础上即可。3306端口号可以省略。pool_size是DBAPI中的方法中指定连接池的连接数的参数,当然也可以直接在Database URL中指定,影响的就是engine对应的连接池大小。
0x03 Raw SQL 除了ORM查询方法外,SQLAlchemy也预留了直接使用SQL语句的接口。有了数据库的连接,我们就可以用raw sql方法直接进行操作了。其实就是相当于隔了一层SQLAlchemy core让DBAPI运行我们自己构建的SQL语句,没有涉及到SQLAlchemy的ORM功能,也就当然不用进行表和类的声明了。
from sqlalchemy.sql import text conn = engine.connect() print(conn.execute(text("SELECT * FROM information LIMIT 1")).fetchall()) print(conn.execute(text("SELECT * FROM information WHERE id=:id LIMIT 1"
Android Termux 安装Kali Linux 或 kali Nethunter史诗级详细教程 一、Termux配置1、下载安装2、配置存储和换源3、基本工具安装 二、Kali Linux安装1、下载安装脚本2、更换apt源3、图形化安装 三、Kali Nethunter安装1、下载安装脚本2、更换apt源3、图形化连接 四、报错汇总1、Kali Linux的VNC连接失败或灰屏2、Kali Nethunter未配置DNS报错3、Kali Nethunter的VNC连接失败4、Kali Linux更新upgrade时postgresql报错5、Kali未正确关闭VNC session报错6、Kali的自带Firefox报错7、Termux的Kali默认没有Systemctl8、Kali自带的apache2报错 五、资源汇总1、本文资源获取地址2、终端间的VNC连接3、Termux后台进程被杀死优化4、Termux开启Apache25、Termux开启SSH 一、Termux配置 1、下载安装 1️⃣ 下载F-Droid
https://f-droid.org/zh_Hans/packages/com.termux/
2️⃣在F-Droid内查询Termux并安装
F-Droid正常网络可访问,如果遇到网路慢可考虑上梯子,F-Droid更新完数据进行下面Termux安装
3️⃣开启Termux的后台运行,最好悬浮窗等都打开
2、配置存储和换源 1️⃣ 开启Termux的系统存储权限
termux-setup-storage 2️⃣Termux换源
sed -i 's@^\(deb.*stable main\)$@#\1\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/apt/termux-main stable main@' $PREFIX/etc/apt/sources.list 3、基本工具安装 pkg update pkg upgrade pkg install proot pkg install git pkg install wget pkg install vim # 建议单条执行,避免出错不好定位,过程提示的选择一直Y下去,会有很多个 二、Kali Linux安装 1、下载安装脚本 此版本安装建议完成之前的基本安装再安装 pkg install python pkg install python2 避免出现问题,有很多坑,详细解决方案见报错解决
动态分区分配算法 一、实验环境 编译软件:pycharm
程序语言:python
二、问题描述: 设计程序模拟四种动态分区分配算法:首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法的工作过程。假设内存中空闲分区个数为n,空闲分区大小分别为P1, … ,Pn,在动态分区分配过程中需要分配的进程个数为m(m≤n),它们需要的分区大小分别为S1, … ,Sm,分别利用四种动态分区分配算法将m个进程放入n个空闲分区,给出进程在空闲分区中的分配情况。
三、程序要求: 1)利用首次适应算法、循环首次适应算法、最佳适应算法和最坏适应算法四种动态分区分配算法模拟分区分配过程。
2)模拟四种算法的分区分配过程,给出每种算法进程在空闲分区中的分配情况。
3)输入:空闲分区个数n,空闲分区大小P1, … ,Pn,进程个数m,进程需要的分区大小S1, … ,Sm,算法选择1-首次适应算法,2-循环首次适应算法,3-最佳适应算法,4-最坏适应算法。
4)输出:最终内存空闲分区的分配情况。
四、实现提示: 页面置换的实现过程如下:
变量初始化;空闲分区个数n,空闲分区大小P1, … ,Pn,进程个数m,进程需要的分区大小S1, … ,Sm,算法选择1-首次适应算法,2-循环首次适应算法,3-最佳适应算法,4-最坏适应算法;根据用户选择的算法进行动态分区分配;输出所有进程分配后的空闲分区分配情况。 五、代码设计与实现 (一)程序设计 (1)首次适应算法 设计思想:
首先,对n个空闲分区按地址递增的次序排列;在分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;按照作业的大小,从该分区中划出一块内存空间,分配给请求者,余下的空闲分区仍留在空闲链中;若从链首直至链尾都不能找到一个能满足要求的分区,则表明系统中已没有足够大的内存分配给该进程,内存分配失败,返回。 部分代码:
def first_fit_algorithm(n, free_partitions, m, processes): allocated_partitions = [-1] * m#初始化m个作业未分配状态 # 对空闲分区按照大小由小到大排序 sorted_partitions = sorted(enumerate(free_partitions), key=lambda x: x[1]) #排序后将空闲分区按顺序重新编号 modified_list = [(i, size) for i, (old_idx, size) in enumerate(sorted_partitions)] for i in range(m): for j, partition_size in modified_list: if partition_size >= processes[i]:#当空闲分区的大小大于等于作业大小时,可分配 allocated_partitions[i] = j modified_list[j]=list(modified_list[j]) modified_list[j][1]-=processes[i] break return allocated_partitions (2)循环首次适应算法 设计思想:
Kafka这个服务在启动时会依赖于Zookeeper,Kafka相关的部分数据也会存储在Zookeeper中。如果kafka或者Zookeeper中存在脏数据的话(即错误数据),这个时候虽然生产者可以正常生产消息,但是消费者会出现无法正常消费消息的情况。
所以在进行下述这个案例进行测试时,为了避免一些错误,可以将两个镜像服务全部进行重装,重装的镜像服务由于未设定数据存储方式(即采用非持久化的匿名数据卷),所以在重装以后会采用新的匿名数据卷,是一个全新的配置信息。
PS:同样是MQ,相比较而言,RabbitMQ针对异常情况的兼容处理比Kafka要好很多,使用Kafka需要有很丰富的经验,生产环境非必要不建议使用这个。
1、earliest Windosw环境下面使用下述两个命令重装Zookeeper和Kafka:
docker run -d --name zookeeper -p 2181:2181 -t zookeeper:latest docker run -d --name kafka -p 9092:9092 -e KAFKA_ZOOKEEPER_CONNECT=192.168.1.15:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.1.15:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -e TZ="Asia/Shanghai" wurstmeister/kafka:latest 假设前面的环境准备我已经完成了,现在正式进入案例测试流程。当前kafka的版本为2.8.11,Spring Boot的版本为2.7.6,在pom.xml中引入下述依赖:
<dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>2.8.11</version> </dependency> 然后在yml配置文件进行如下配置:
spring: kafka: bootstrap-servers: 127.0.0.1:9092 consumer: group-id: 0 key-deserializer: org.apache.kafka.common.serialization.StringDeserializer value-deserializer: org.apache.kafka.common.serialization.StringDeserializer auto-offset-reset: earliest producer: key-serializer: org.apache.kafka.common.serialization.StringSerializer value-serializer: org.apache.kafka.common.serialization.StringSerializer 在项目中创建一个生产者用于往主题topic0中投递消息,如下所示:
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.support.SendResult; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureCallback; import org.
监控一个 TRC20 代币的钱包地址余额,以下是您可以遵循的步骤:
1. 安装 TronWeb: TronWeb 是一个允许您与波场区块链交互的 JavaScript 库。
首先,您需要在您的项目中安装它。使用 NPM 安装 TronWeb:
npm install tronweb 2. 初始化 TronWeb 实例:
创建一个 TronWeb 实例并连接到波场网络。您可以选择连接到主网或测试网。 const TronWeb = require('tronweb'); const tronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io', // 主网地址 // fullHost: 'https://api.shasta.trongrid.io', // 测试网地址 privateKey: '' // 这里不需要私钥,因为我们只是查询余额 }); 3. 查询 TRC20 代币余额: 您需要知道您想要查询的 TRC20 代币的智能合约地址。
然后,您可以调用合约的 balanceOf 方法来查询特定地址的余额。
async function getTRC20TokenBalance(tokenAddress, walletAddress) { try { // 创建合约实例 const contract = await tronWeb.
Ⅰ- 壹 - 使用需求 前端 的方式 点击这个按钮,直接让打印机打印我想要的东西
github地址: https://github.com/whqgo/nodeWebPrint
Ⅱ - 贰 - 小票打印 目前比较好的方式就是直接用 TSPL 标签打印指令集, 基础环境就不多说了,这个功能的实现就是利用usb发送指令,现在缺少个来让我们能够和usb沟通的工具,下面这就是推荐的一个程序驱动,安装通用USB驱动程序.
注: TSPL是一套通用的标签打印指令集,很多主流标签打印机都支持。市面上标签打印机的通讯方式主要有:串口、USB、蓝牙和WIFI,通过上述方式发送相应的TSPL指令,标签打印机就可以依照指令进行打印。 usb 插件需要的 程序驱动(Zadig) https://zadig.akeo.ie/
下载完成后打开,依次操作
勾选这些
选择连接的usb 打印机usb, 一般是 打印机商品名字,我这使用的是佳博打印机
3.安装驱动
编写代码 目录结构
main入口文件
webPrintUtils文件夹 具体的实现
index : 功能实现的逻辑bitmap_nodejs : image转bitmap所用tspl.class : TSPL 指令二次封装一下usb.class: 用于连接 usb数据写入操作 列如我们想画一个条形码
在tspl.class.js文件中添加一个barcode方法, 具体的指令很容易在网上查到
/** * 条码,这里固定为code128 * 单位都为dot * * @param {Number} [x=0] - x * @param {Number} [y=0] - y * @param {Number} [height=80] - height * @param {String} [content="
SQL中 JOIN 的两种连接类型:内连接(自然连接、自连接、交叉连接)、外连接(左外连接、右外连接、全外连接)
1. 自然连接(natural join)(内连接) 学生表
mysql> select * from student; +----+--------+----------+ | id | name | code | +----+--------+----------+ | 1 | 张三 | 20181601 | | 2 | 尔四 | 20181602 | | 3 | 小红 | 20181603 | | 4 | 小明 | 20181604 | | 5 | 小青 | 20181605 | +----+--------+----------+ 5 rows in set (0.00 sec) CREATE TABLE `student` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, `code` int DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; INSERT INTO student (name, code) VALUES ('张三', 20181601), ('尔四', 20181602), ('小红', 20181603), ('小明', 20181604), ('小青', 20181605); 成绩表
h5微信jsapi支付 参考链接jsapi介绍准备工作第一步微信授权获取用户openid第二步调起微信支付常见错误 参考链接 微信支付jsapi官方文档
微信网页授权
jsapi介绍 准备工作 公众号商户号备案域名配置应用
先参考支付指引接入准备
基本步骤
1、在商户号关联公众号
2、在商户号配置支付授权目录(支付目录+回调目录)
3、在公众号配置网页授权域名 第一步微信授权获取用户openid 参考链接微信网页授权
进入页面后从缓存中判断是否已经拿到用户openid,或者地址栏上是否携带code,没有则调用下面代码进行申请用户授权
let protocol = window.location.protocol; let host = window.location.host; let local = protocol + '//' + host; let appId = '';公众号appid window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURIComponent(local)}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect` 用户同意授权后会在回调地址中携带code,下面提供获取地址栏上code参数方法
function getUrlParams(name) { const queryString = window.location.search; const params = new URLSearchParams(queryString); const value = params.get(name); return value ? decodeURIComponent(value) : null; } 然后把code传给后端,后端通过code获取access_token,再通过access_token获取用户信息并返回给前台
网页授权对于前端来说只需要拉起用户授权,并将code传给后台
只是测试网页授权可以使用测试公众号,需要先关注测试号并配置授权域名
测试公众号
第二步调起微信支付 安装依赖
论文地址:官方论文地址
代码地址:官方代码地址
一、本文介绍 本篇文章给大家带来的实战讲解是Crossformer模型,其是一个针对多变量时间序列预测的新型深度学习模型,发表ICLR 2023上并且排名前5%,所以这个模型的质量还是能够有一定保证的(但是我用官方的代码真的是Bug一堆改的让人头大)。Bug多是很多但是其效果还是可圈可点的,Crossformer的主要思想是:通过维度-段式嵌入技术将时间序列数据转换为二维向量数组,同时使用两阶段注意力层来高效地捕获这两种依赖关系。Crossformer采用分层编码器-解码器结构,在不同层次上利用信息进行预测。
专栏目录:时间序列预测目录:深度学习、机器学习、融合模型、创新模型实战案例
专栏订阅: 时间序列预测专栏:基础知识+数据分析+机器学习+深度学习+Transformer+创新模型
目录
一、本文介绍
二、网络结构讲解
2.1 Crossformer的主要思想
2.2、维度-段式(DSW)嵌入
2.3、两阶段注意力(TSA)层
2.4、分层编码器-解码器(HED)结构
2.5、模型代码
三、数据集
四、参数讲解 五、模型训练
六、配置代码 七、模型预测
八、训练个人数据集 8.1、修改一
8.2、修改二
九、全文总结 二、网络结构讲解 2.1 Crossformer的主要思想 这个模型是一种新的基于Transformer的模型,名为Crossformer,这个模型在今年的ICLR上提出,是一种专门为多变量时间序列(MTS)预测设计。 Crossformer的主要特点包括:
1. 维度-段式(DSW)嵌入:这种新颖的嵌入技术将多变量时间序列数据沿每个维度划分为段,将这些段嵌入到特征向量中。这种方法保持了时间和维度信息,有助于模型更好地捕捉MTS数据的固有结构。
2. 两阶段注意力(TSA)层:Crossformer使用TSA层来有效捕捉时间和不同维度之间的依赖性。对于MTS预测来说,这两个方面的依赖性都是重要的。
3. 分层编码器-解码器(HED)结构:模型使用HED来利用不同规模的信息进行预测。这种分层方法有助于更有效地理解和预测MTS数据。 论文表明,通过其独特的方法,Crossformer有效地捕捉了跨维度依赖性,这是现有基于Transformer的MTS预测模型中常常忽视的一个关键方面。通过在六个真实世界数据集上的广泛实验结果显示,Crossformer在性能上超越了以前的最先进模型,表明了其有效性和实际应用的潜力。 这项研究通过解决现有模型的局限性并引入创新技术以提高性能,对时间序列预测领域做出了重要贡献。
下面我分别来解释这个模型中的三种结构->
2.2、维度-段式(DSW)嵌入 DSW嵌入是Crossformer模型的一个关键特性,它的目的是更好地捕捉MTS(多变量时间序列)数据中的跨维度依赖关系。传统的基于Transformer的模型主要关注于捕捉时间跨度上的依赖(即跨时间依赖),而往往没有显式地捕捉不同变量间的依赖性(即跨维度依赖),这限制了它们的预测能力。
在DSW嵌入中,每个维度的时间序列数据点被分成一定长度的段。然后,每个段被嵌入到一个向量中,方法是使用线性投影加上位置嵌入。线性投影矩阵E和位置嵌入Epos都是可学习的。这样,每个嵌入后的向量hid表示一个时间序列的单变量段,最终得到一个二维向量数组H。在这个数组中,每个向量hid代表一段时间序列的一维切片。与其他针对MTS预测的Transformer模型不同,DSW嵌入显式地捕捉了跨维度依赖性。
上图展示了Crossformer模型中维度-段式(DSW)嵌入的概念:
a) 由在ETH1数据集上训练的双层Transformer模型得出的自注意力分数热图,展示了多变量时间序列(MTS)数据倾向于被分段。
b) 描述了之前Transformer基础模型的嵌入方法,这些模型将同一时间步的不同维度的数据点嵌入到一个向量中。
c) 展示了Crossformer的DSW嵌入:在每个维度中,相邻的时间点形成一个段进行嵌入。
总结:这个图解清晰地说明了Crossformer如何通过其DSW嵌入机制来处理MTS数据,这是该模型与以前的方法不同的地方,它保留了时间序列数据在不同时间步的维度信息,以便更好地捕捉跨维度的依赖性。
2.3、两阶段注意力(TSA)层 两阶段注意力(TSA)层是Crossformer模型的一个核心组成部分,用于捕捉嵌入数组中的跨时间和跨维度依赖性。具体来说,通过DSW嵌入,输入数据被嵌入到一个二维向量数组中,以保留时间和维度的信息。然后,TSA层被设计出来,用于捕捉这些嵌入数组的依赖性。
以下是TSA层的工作流程说明:
1. 跨时间阶段:
TSA层接收一个二维数组 Z 作为输入,这个数组可能是维度-段式(DSW)嵌入的输出或下层TSA层的输出。对于每个维度,直接应用多头自注意力(MSA)机制来捕捉同一维度内不同时间段之间的依赖关系。这一阶段的计算涉及到层归一化(LayerNorm)和多层感知机(MLP),这有助于处理自注意力机制的输出。此阶段的计算复杂度为 ,其中 L 是段的数量,D 是维度的数量。 2. 跨维度阶段:
为了避免直接在维度之间应用MSA所带来的的计算复杂度,提出了一种路由机制。为每个时间步设置了一小组可学习的向量,称为“路由器”,用于从所有维度聚集信息。这些路由器随后将聚合的信息分发到各个维度,有效地建立了维度之间的全连接,而没有高复杂度。路由机制显著降低了复杂度,从减少到,通过限制需要考虑的连接数量。与跨时间阶段类似,跨维度阶段也使用层归一化和MLP来处理路由机制的输出 这种两阶段的方法使Crossformer能够高效地处理多变量时间序列数据中的复杂依赖关系,通过区别对待时间轴和维度轴,尊重它们在数据结构中的独特作用。
上图显示了两阶段注意力(TSA)层的构造和功能:
a)TSA层的整体结构,包含了跨时间阶段(Cross-Time Stage)和跨维度阶段(Cross-Dimension Stage),用于处理 O(2cD)=O(D)。
在Android中设置网络代理:一文详解 引言 在移动设备上,特别是Android平台,设置网络代理是一种常见的需求,可以通过网络代理实现对网络请求和响应的拦截和修改。本文将详细介绍在Android设备上通过adb命令设置全局HTTP代理的方法,并解释这个操作的实际用途以及在开发和测试中的应用场景。
Android中设置全局HTTP代理的方法 在Android设备上,可以通过adb命令行工具来设置全局HTTP代理,这对于开发人员和测试人员来说是一种方便而强大的工具。以下是通过adb设置全局HTTP代理的示例命令:
adb shell settings put global http_proxy ip:port adb shell settings put global http_proxy :0 其中,ip:port代表你所要使用的HTTP代理服务器的IP地址和端口号。如果你想禁用代理,可以将:0作为参数传递。
实际用途 1. 网络调试和抓包 通过设置全局HTTP代理,开发人员可以使用抓包工具(如Charles、Fiddler等)捕获Android设备上的网络请求和响应。这对于调试应用程序的网络请求、查看接口返回数据以及检测潜在的网络问题非常有帮助。
2. 模拟网络状况 在开发和测试过程中,模拟不同的网络条件是至关重要的。通过设置全局HTTP代理,可以使用网络工具模拟不同的网络状况,如弱网络连接、高延迟或断网状态,以确保应用在各种网络条件下都能正常工作。
3. 安全性测试 网络代理还可以用于进行安全性测试,模拟中间人攻击等网络安全问题。通过捕获和修改网络流量,可以评估应用在面对潜在的安全风险时的表现,并采取必要的安全措施。
示例演示 以下是一个简单的Python示例,演示如何使用subprocess库通过Python脚本自动执行adb命令来设置全局HTTP代理:
import subprocess def set_global_proxy(ip, port): command = f'adb shell settings put global http_proxy {ip}:{port}' subprocess.run(command, shell=True) def disable_proxy(): command = 'adb shell settings put global http_proxy :0' subprocess.run(command, shell=True) # 示例:设置代理 set_global_proxy('192.168.1.100', '8888') # 示例:禁用代理 disable_proxy() 结论 在Android设备上设置全局HTTP代理是一项强大的操作,为开发人员和测试人员提供了在不同网络条件下调试和测试应用程序的能力。通过这种方式,可以更好地了解应用在各种网络环境中的性能和安全性。但需要注意的是,在实际使用中应谨慎使用代理,以免引起不必要的问题。