看了很多的文章, 感觉写的都有点扯淡 ,误人子弟 。 源码中 : 默认是注释掉的,但是上面的备注写的是开启状态(没关系, 不管)。
所以这个 就有了三个状态:
1. 第一个 源码的 注释状态: # Disable cookies (enabled by default) # COOKIES_ENABLED = False 这个状态下, 其实可以理解成 cookie 是开启的状态, 但是他的获取值 是通过源码的方法,scrapy直接获取网页的上层的cookie ,然后带到下一层去的。 2. 第二种解开注释的情况下 : # Disable cookies (enabled by default) COOKIES_ENABLED = False 这个状态下的 cookie 是通过 headers 添加上去的,这个就是中间件里面的 包裹在头部里面
就是 setting源码中的 # Override the default request headers: #DEFAULT_REQUEST_HEADERS = { # 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', # 'Accept-Language': 'en', #} 要是只是个别需要增加头部的,可以直接传参进去。 setting 写入时传全局的;
机器学习笔记之生成模型综述——生成模型介绍 引言生成模型介绍 引言 从本节开始,将介绍生成模型的相关概念。
生成模型介绍 生成模型,单从名字角度,可以将其认识为:生成样本的模型。从流程的角度,它可以理解为:
给定一个数据集合,基于该数据集合进行建模,并通过数据集合学习出模型的参数信息;根据已学习出的参数信息,使用模型构建出新的数据。 但生成新的数据仅是生成模型的一个任务/目标,通过生成新数据的模型对生成模型进行判别可能是很片面的。
例如之前介绍的高斯混合模型( Gaussain Mixture Model,GMM \text{Gaussain Mixture Model,GMM} Gaussain Mixture Model,GMM),它的概率图结构可表示为:
其中 Z \mathcal Z Z是一个一维、离散型随机变量,对应的 X ∣ Z \mathcal X \mid \mathcal Z X∣Z服从高斯分布:
Z ∼ Discrete Distribution ( 1 , 2 , ⋯ , K ) X ∣ Z ∼ N ( μ k , Σ k ) k ∈ { 1 , 2 , ⋯ , K } \begin{aligned} \mathcal Z & \sim \text{Discrete Distribution}(1,2,\cdots,\mathcal K) \\ \mathcal X \mid \mathcal Z & \sim \mathcal N(\mu_{k},\Sigma_k) \quad k \in \{1,2,\cdots,\mathcal K\} \end{aligned} ZX∣Z∼Discrete Distribution(1,2,⋯,K)∼N(μk,Σk)k∈{1,2,⋯,K}
springboot环境
标题主要quartz依赖 <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <!--<version>${quartz.version}</version>--> </dependency> 实体类 package com.yuexiufinance.chatgtp.job; public class MyVo { private String id; private String name; private int age; public MyVo(String id, String name, int age) { this.id = id; this.name = name; this.age = age; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.
目录
1.创建相关配置目录
2.拉取镜像
3.查看 Network ports | ClickHouse Docs 中端口号配置 ,暂时只需要映射8123 9000 两个端口
4.创建临时容器,用以生成配置文件
5.将配置文件复制到 /data/clickhouse/conf 路径下
6.关闭临时容器
7.启动容器
8.连接clickhouse
clickhouse相关知识站点:
1.创建相关配置目录 mkdir -P /data/clickhouse/data mkdir -P /data/clickhouse/conf mkdir -P /data/clickhouse/log 2.拉取镜像 # 下载最新版本clickhouse docker pull clickhouse/clickhouse-server # 下载指定版本clickhouse docker pull clickhouse/clickhouse-server:23.1.3.5-alpine 3.查看 Network ports | ClickHouse Docs 中端口号配置 ,暂时只需要映射8123 9000 两个端口 4.创建临时容器,用以生成配置文件 # 容器关闭后会自动删除掉 docker run -d --rm --name clickhouse-server --ulimit nofile=262144:262144 clickhouse/clickhouse-server 5.将配置文件复制到 /data/clickhouse/conf 路径下 docker cp clickhouse-server:/etc/clickhouse-server/config.
信号处理,可以理解为对信号进行某种加工或变换来达到削弱信号中的多余内容、滤除混杂的噪声和干扰、将信号变换成容易分析与识别的形式,便于估计和选择它的特征参量等目的。
快速傅里叶变换(FFT)是信号处理的重要组成部分,是离散傅里叶变换(DFT)的快速算法,可以将离散信号从时域变换到频域,因为很多信号在时域上很难看出特征,但转换到频域上就可以很容易地看出其特征,方便进行频谱分析(感兴趣的同学可以去看看文末第一篇参考文献,通俗易懂地讲解了时域和频域的关系)。FFT可用于求信号的幅度、相位以及画频谱图等,下面分别进行介绍。
1.幅度计算:模拟信号经过AD采样后变成数字信号,N个采样点经过FFT后得到N个点的FFT结果(为方便进行FFT运算,通常N取2的整数次方),每一个点就对应着一个频率点,这个点的模值对应该频率值下的幅度,其中第一个点为直流分量,它的模值就是直流分量的N倍,即直流分量的幅度为FFT得到的第一个点的模值的N分之一;第二个点为基波分量(基频 = 采样频率/采样点数),第N+1个点为N次谐波分量(基频的N倍),基波分量和N次谐波分量的模值是该频率分量对应的幅度的N/2倍,即基波分量和N次谐波分量的幅度为FFT得到的第二个点和第N+1个点的模值的(N/2)分之一。
2.相位计算:每个点的相位对应该频率下的信号的相位。MATLAB中求相位可用angle函数。
3.画频谱图:FFT还可用于绘制信号的频谱图,从频谱图上可以很清晰地观察信号的频率分量,MATLAB代码如下: 子程序:
function [x,freq] = fft_plot(x,Fs)
%计算信号的双边幅度频谱和其横坐标、并调整使得横坐标中心频率为0Hz,输入:x为输入信号,Fs为采样频率,输出:x为输入信号的幅度频谱,freq为输入信号幅度频谱的横坐标
N = length(x);
%%计算频谱的横坐标,使得中心频率为0Hz
if mod(N,2)==0
k = -N/2:N/2-1;
else
k = -(N-1)/2:(N-1)/2;
end
T = N/Fs;
freq = k/T;
x= fft(x)/N;%fft并归一化
x= fftshift(x);
主程序:
[x1,freq] = fft_plot(x,Fs);
figure;
plot(freq,abs(x1));
xlabel('频率(Hz)');
ylabel('幅度');
title('信号频谱图');
参考文献:https://zhuanlan.zhihu.com/p/19763358
参考文献:https://blog.csdn.net/weixin_39536010/article/details/111682978
参考文献:https://www.cnblogs.com/gjblog/p/13494103.html
一.了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器。
锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写。
死锁:是数据库性能的重量级杀手之一,而死锁却是不同事务之间抢占数据资源造成的。
二.事务的概念 用华仔无间道中的一句来给你诠释下:去不了终点,回到原点。
事务有一个最显著的特征,就是它包含的所有 SQL 语句作为一个整体向数据库提交,只有所有的 SQL 语句都执行完成,整个事务才算成功,一旦某个 SQL 语句执行失败,整个事务就失败了。事务失败后需要回滚所有的 SQL 语句。
事务中的所有 SQL 语句是一个整体,共同进退,不可分割,要么全部执行成功,要么全部执行失败。
事务有很多实用的场景。例如对于电商网站,通常将用户订单存储在一张表中,将商品库存情况存储在另一张表中,当有用户下单时,需要执行两条 SQL 语句,一条负责更新订单表,一条负责更新库存表,这两条 SQL 语句必须同时执行成功。如果只有一条语句执行成功,另一条语句执行失败,将导致数据库出错,这种后果是无法接受的。
为了避免出现意外,可以将以上两条语句放到一个事务中,其中一条语句执行失败时,数据库将回滚到原来的状态。对于买家来说,数据库回滚会导致下单失败,但这很容易处理,让买家再次下单即可。数据库的正确性永远是最重要的。
其实我们平时使用数据库时,就已经在使用事务了,只不过这种事务只包含一条 SQL 语句,并且由数据库引擎自动封装和提交。这意味着,对于任何一条 SQL 语句,要么执行成功,要么执行失败,不能成功一部分,失败一部分。
三.事务的属性 一般来说,事务具有四个标准属性,分别是原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability),简称 ACID。具体说明如下:
1) 原子性
一个事务中的所有 SQL 语句,要么全部执行成功,要么全部执行失败,不会结束在中间的某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
2) 一致性
在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的数据必须完全符合所有的预设规则,其中包含数据的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
3) 隔离性
数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
4) 持久性
事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
四.分类 自动提交事务:是SQL Server默认的一种事务模式,每条Sql语句都被看成一个事务进行处理,你应该没有见过,一条Update 修改2个字段的语句,只修该了1个字段而另外一个字段没有修改。。
显式事务:T-sql标明,由Begin Transaction开启事务开始,由Commit Transaction 提交事务、Rollback Transaction 回滚事务结束。
隐式事务:使用Set IMPLICIT_TRANSACTIONS ON 将将隐式事务模式打开,不用Begin Transaction开启事务,当一个事务结束,这个模式会自动启用下一个事务,只用Commit Transaction 提交事务、Rollback Transaction 回滚事务即可。
五.显式事务的应用 常用语句就四个。
Linux 网络流量监控 Linux 网络流量监控是捕获和分析企业的 Linux 网络流量的过程。
为什么要监控 Linux 网络流量 深入了解网络流量对于测量和管理带宽使用情况非常重要。分析 Linux 网络流量有助于识别带宽瓶颈、最高用量者和其他可能影响网络性能的网络问题。
Linux 网络流量监视器如何工作 大多数 Linux 网络流量监控工具读取 /proc/net/dev 文件以获取流量统计信息,或使用 pcap 库进行数据包捕获,然后计算总大小以估计流量负载。Linux 网络流量监控工具通常是一个耗时的命令行工具,需要大量的预配置。尽管很复杂,但大多数 Linux 网络流量监视器都是简单的工具,支持一些基本指标、报告和报告筛选器。
Linux 网络监视工具需要的功能 能够在任何给定点监控网络中每个设备的状态对于维护网络基础设施的运行状况和效率至关重要。Linux 网络流量监控软件可帮助网络管理员:
确定网络中的顶级用量者和对话。监控网络流量,并预测流量趋势和使用模式。识别应用程序并对其进行分类以监控网络流量。设置基于阈值的实时警报,以减少响应时间并加快故障排除速度。根据部门和站点到站点流量监控带宽。实时检测和分类流量峰值、异常和网络安全威胁。以较低的成本生成带宽报告并预测带宽需求。 NetFlow Analyzer是一个全面的网络流量监控解决方案,提供广泛的带宽和网络流量监控功能。它是一种基于 Web 的网络流量监控工具,可在 Windows 和 Linux 系统上运行,并分析流数据以跟踪网络流量。NetFlow 分析器通过提供流量、速度、数据包、最高用量者、带宽利用率、网络异常等指标,让您深入了解网络的带宽使用情况。
NetFlow Analyzer 如何监控您的 Linux 设备 NetFlow Analyzer的NetFlow Generator工具被动捕获原始网络数据包并将其转换为NetFlow数据包,以帮助您监控不支持流量的设备。借助此功能,您现在可以像监控基于流的设备一样轻松地监控和分析来自 Windows 和 Linux 设备的网络流量。
使用 NetFlow Analyzer 监控 Linux 网络流量的优势 使用免费的NetFlow生成器工具,您只需单击几下即可添加和监控设备,而无需花费数小时进行配置。该工具附带大量报告和自定义选项,可帮助您监控 Linux 网络流量并分析数据,让您全面了解您的网络。
NetFlow Analyzer 如何作为 Linux 网络流量监控软件工作 NetFlow Analyzer 的关键实时 Linux 网络流量监控功能包括:
作者:王磊
更多精彩分享,欢迎访问和关注:https://www.zhihu.com/people/wldandan
MindSpore的GPU版本以前的安装指南,只写清楚了安装依赖,但没有明确指出安装具体执行的命令,缺乏实操性,比较依赖开发者自身的能力去完成安装,导致开发者在安装过程中会出现一些影响安装效率的问题。在新版本中,安装方面进行了优化,提供了自动化的脚本以及step by step的安装指南来帮助开发者完成Ubuntu+GPU版本的安装。
基于自动化脚本完成Ubuntu18.04 + GPU版本的安装 新的安装指南给出了自动化以及step by step安装方式,包括pip方式、Conda方式和源码编译方式。如果环境是全新的,可以使用自动化脚本安装,如果已经安装了一部分软件,也可以考虑跟随指南中后面的step by step的安装方式来完成安装。
在安装前,用户需要先执行nvidia-smi 来查看是否安装驱动,或者驱动是否匹配CUDA10.1/11.1。没有安装或者没有达到最低要求的驱动,需要按照指南先把驱动安装好。
sudo apt-get update sudo apt-get install ubuntu-drivers-common sudo ubuntu-drivers autoinstall 接下来只需要执行自动化脚本即可,假设我们需要用安装Python 3.9并使用pip完成1.6.1 的MindSpore版本安装,那么可以运行以下的脚本:
wget https://gitee.com/mindspore/mindspore/raw/master/scripts/install/ubuntu-gpu-pip.sh # 安装MindSpore 1.6.1,Python 3.9和CUDA 11.1。 PYTHON_VERSION=3.9 MINDSPORE_VERSION=1.6.1 bash -i ./ubuntu-gpu-pip.sh 如果你的网络条件比较好,那么在10-15分钟就能完成安装,自动化脚本在执行的结尾还会自动做run check检查以及运行简单的代码验证,最终你看到的结果应该是这样的:
MindSpore version: 1.6.1 The result of multiplication calculation is correct, MindSpore has been installed successfully! [[[[2. 2. 2. 2.] [2. 2. 2. 2.] [2. 2. 2. 2.]] [[2.
修改方法一 export PATH=/home/monk/anaconda3/bin:$PATH
配置完后可以通过echo $PATH查看配置结果。
生效方法:立即生效
有效期限:临时改变,只能在当前的终端窗口中有效,当前窗口关闭后就会恢复原有的path配置
用户局限:仅对当前用户
修改方法二 修改.bashrc文件:
vim ~/.bashrc
在最后一行添上:
export PATH=/home/monk/anaconda3/bin:$PATH
生效方法:(有以下两种)
1、关闭当前终端窗口,重新打开一个新终端窗口就能生效
2、输入“source ~/.bashrc”命令,立即生效
有效期限:永久有效
用户局限:仅对当前用户
修改方法三 修改profile文件:
vim /etc/profile
//找到设置PATH的行,添加
export PATH=/home/monk/anaconda3/bin:$PATH
生效方法:系统重启
有效期限:永久有效
用户局限:对所有用户
修改方法四 修改environment文件:
vim /etc/environment
在PATH=”/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games”中加入“:/home/monk/anaconda3/bin”
生效方法:系统重启
有效期限:永久有效
用户局限:对所有用户
新建utils\http.ts
import { hash } from 'ohash' // 后端返回的数据类型 export interface ResOptions<T> { data?: T code?: number msg?: string } /** * api请求封装 * @param { String } url 请求地址 * @param { Object } options useFtech第二个参数 * @param { Object } headers 自定义header头, 单独设置headers区分请求参数,也好设置类型 */ const fetch = (url: string, options?: any, headers?: any): Promise<any> => { const { public: { VITE_API_HOST } } = useRuntimeConfig() // 3.0正式版环境变量要从useRuntimeConfig里的public拿 const reqUrl = VITE_API_HOST + url // 你的接口地址 // console.
1.说明 QQ邮箱登录很可能需要拖动滑块进行验证,这里当做练习selenium,实现模拟拖动滑块
2.思路 1.使用selenium打开邮箱登录页面,判断是否,尝试登录,看是否需要验证码;
2.若需要图片验证码,那就获取验证码图片的url,验证码图片分为滑块小图片和背景图片,分别都下载;
3.使用OpenCV把图片高斯处理,然后边缘检测,匹配模板,得到最优匹配结果;
4.得到滑块与缺口之间的像素值,根据实际缩放比例以及偏移量得到最终要滑动的距离;
5.使用加速度公式模拟出比较类似人工操作的像素数组;
6.使用selenium分步拖动滑块完成验证
3.参考代码 测试环境Python版本:Python 3.9.2
Python库版本:
pip install selenium==4.8.0 pip install requests==2.28.0 pip install numpy==1.23.3 pip install Pillow==9.2.0 pip install opencv-python==4.6.0.66 import sys import time from io import BytesIO import cv2 import os import requests import random import numpy as np from PIL import Image as Im from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By wait_time_short = 1 wait_time1_long = 2 class QQEmail(object): def __init__(self, user, pwd, executable_path): self.
最近在参与一个煤矿井下移动机器人视觉导航的课题,需要考虑井下图像去尘去雾技术。复杂的煤矿井下尘雾环境不同于常规的室外和室内环境,空间狭长,光照较低,尘雾分布较密,比普通的去尘去雾要求更加严格和困难。对于昏暗有尘雾的煤矿场景,通常包含多个光源,光源区域和非光源区域表现出不同的颜色特征,因此环境照明通常不是全局各向同性的;此外,常用的局部最大像素法容易高估全局大气光照,以上两点导致输出图像中光源区域周围的颜色失真和光晕伪影,因而需要重新考察各种去雾方法在煤矿巷道图像的应用。本文主要用于记录和总结自己课题过程中所使用和参考的技术方法。
Single Image Haze Removal Using Dark Channel Prior(何恺明)
论文:https://ieeexplore.ieee.org/document/5567108
论文解读:
https://blog.csdn.net/s12244315/article/details/50292049/
https://blog.csdn.net/leviopku/article/details/83898619
https://www.cnblogs.com/Imageshop/p/3281703.html
https://kaiminghe.github.io/
参考网站:
https://zhuanlan.zhihu.com/p/420879222
https://blog.csdn.net/weixin_51154479/article/details/128446083
https://www.zhihu.com/question/361679585/answer/2281812125
https://www.cnblogs.com/Imageshop/p/3515871.html
前言: 当需要将一台机器(源机器)上的一个数据库完全复制到另一台机器(目标机器)上时,
可以选择先在源机器上备份该数据库,然后在目标机器上还原该备份的方法。
在项目搬移到另一个服务器上的时候,可以使用这种方法。我之前搬了个50多G的数据,我就先生成备份,然后将这个文件进行压缩包,通过腾讯云盘转到服务器中,本来是用ftp的,可那个太慢了。
第一步:连接数据库 打开SQL server management studio, 连接到服务器,
在“服务器名称”上填写本机名称,
可以在计算机-右键-属性中查看“计算机名”,然后点击“连接”,
如下图所示
第二步:选择备份 选中你要复制的数据库,右键-任务-备份,
如下图所示:
第三步:生成备份文件 选择你要复制的目标位置。一般情况下会有一个默认位置,请只备份到一个位置上,
最好不要再添加一个位置,不然还原的时候容易出错,(或者删除后再添加)
可以在备份完之后去默认位置拷贝出备份文件,
如下图所示:
第四步:拷贝备份文件 点击“确定”就会开始备份了。等备份完成,会得到一个xxx.bak文件,该文件就是备份文件,
去目标位置拷出该备份文件,拷到目标机器上即可。
第五步:点击“还原文件和文件组” 在目标机器上按第1步连接数据库,然后右键点击“数据库”,
点击“还原文件和文件组”,而不是点击“还原数据库”,不然容易出错,
如下图所示:
第六步: 在 “还原的目标” 下的 “目标数据库” 右侧的栏中填写目标机器上新数据库的名字(可以和原数据库名不同)。
在 “还原的源” 下点击 “源设备” 右侧的 “...” ,在点击 “添加” 选择拷到本机的数据库备份文件xxx.bak,然后点击确定就可以了,
如下图所示:
到此数据库复制完毕,刷新即可看到新添加的数据库
还原数据库错误一: 对于下面这种报错的解释很牵强,不能每次还原数据库都要创建一个数据库吧!我也是看到别人说的原因,和自己试用了一下!
数据库还原出现报错:服务器“DESKTOP-BNNIISU”失败。(Microsoft.SqlServer.SmoExtended)
System.Data.SqlClient.SqlError: 备份集中的数据库备份与现有的 'wwt' 数据库不同。 (Microsoft.SqlServer.Smo)
很多人在还原时想着新建一个空白的数据库,正好在还原数据库时是用下拉框选择的。
所以一般人不会怀疑这件事,就是在还原对象时,数据库已经有了这个名叫wwt的数据库冲突了。
所以只有手动输入没有过的数据库名称才会成功。
(这个设计真的是很狗血,感觉微软也是不知道怎么想的。) 作者有话说 该文档希望能解决你的问题,不能解决你的问题的话,请问“度娘”,走上编程这条路,“度娘”永远是你的法宝。
有些废话的东西你懂的话,完全可以不看;我其实也不喜欢理论上的知识;看看也是涨涨见识,可以在面试的时候,装那什么。
当然很多的理论知识也是借鉴了各位大神的,或者去官网找的。如有冒犯,还请见谅。
坚持日拱一卒、相信复利效应、不断践行践修,让我们活在成长中
一、什么是GUID GUID是16字节的二进制SQL Server数据类型,在表,数据库和服务器之间全局唯一。 GUID代表全局唯一标识符,可与UNIQUEIDENTIFIER互换使用。
二、GUID的使用 要在SQL Server中创建GUID,将使用NEWID()函数,如下所示:
SELECT NEWID() 多次执行上面SQL行,您每次都会看到一个不同的值。 这是因为NEWID()函数每执行一次都会生成一个唯一值。
要声明类型为GUID的变量,使用的关键字是UNIQUEIDENTIFIER,如以下脚本中所述:
DECLARE @UNI UNIQUEIDENTIFIER SET @UNI = NEWID() SELECT @UNI 如前所述,GUID值在表,数据库和服务器之间是唯一的。 GUID可以视为全局主键。 本地主键用于唯一标识表中的记录。 另一方面,GUID可用于唯一地标识跨表,数据库和服务器的记录。
三、GUID解决了什么问题 让我们看看如果我们在不同数据库的表中有冗余记录会遇到什么问题,以及GUID如何解决这些问题。
执行以下脚本:
CREATE DATABASE EngDB GO USE EngDB GO CREATE TABLE EnglishStudents ( Id INT PRIMARY KEY IDENTITY, StudentName VARCHAR (50) ) GO INSERT INTO EnglishStudents VALUES ('谢恩') INSERT INTO EnglishStudents VALUES ('强尼') 在上面的脚本中,我们创建一个名为“ EngDB”的数据库。
然后,我们在此数据库中创建一个表“ EnglishStudents”。
该表有两列:Id和StudentName。 Id列是主键列,我们使用Identity作为约束将其设置为自动递增。
最后,我们将两个名为“ Shane”和“ Jonny”的学生记录插入“ EnglishStudents”表中。
前言 之前在公司的一个项目中,有个同事需要对一个数据进行分库处理,本来是打算用备份,然后在分库的。但是那种方法麻烦,而且遇到数据表比较大的话就很慢,还有就是会备份一些没必要的表,清理起来也是费时费力。他问到我后,我写了这个文档给他,用生成脚本的方法的话,可以选择你需要生成脚本的表,最后再执行脚本就行了。
第一步: 双击“数据库”选项,打开数据库列表。然后选中要生成脚本的数据库,单击右键,选择“任务”-“生成脚本”选项。弹出“生成脚本”窗口。
第二步: 在生成脚本”窗口中,点击“下一步”,选中需要生成脚本的数据库,在点击“ 下一步”,选择脚本选项,在点击“下一步”。
注:这些可以先选择整个数据库去生成,“为整个数据库及所以数据库对象编写脚本”,就是说整个数据库生成脚本,包括存储过程还有视图。“选择具体的数据库对象"是:可以选择对应的表,视图,存储过程等去生成脚本。
第三步: 这里我们先生成的文件路径先改一下,改到你要生成的路径。然后点击“高级”这里。
注:
第四步: 这里需要注意下,高级里面有个选项—要编写脚本的数据库类型,这个选项默认是 仅限架构,
架构和数据:就是数据库框架和数据都会生成。
仅限架构:只生成数据库框架, 在复制数据库,但是不想复制他数据库中的数据时,用的到。
仅限数据:只生成数据库数据,我用过,就是测试和正式的数据库中数据不一致,导致我测试中有bug。我把测试中的数据删除掉,然后去正式哪里生成数据后,再进行添加到测试的数据库中的表里。
第五步: 这里就是让你检查一下,看一下需要生成的数据库,还有所选的对象,还有生成文件的路径。正确的话下一步就好了
第六步: 等待脚本生成就行了,数据库越大生成的话就越久。最后点击完成就行了,很简单的操作
作者有话说 该文档希望能解决你的问题,不能解决你的问题的话,请问“度娘”,走上编程这条路,“度娘”永远是你的法宝。
有些废话的东西你懂的话,完全可以不看;我其实也不喜欢理论上的知识;看看也是涨涨见识,可以在面试的时候,装那什么。
当然很多的理论知识也是借鉴了各位大神的,或者去官网找的。如有冒犯,还请见谅。
坚持日拱一卒、相信复利效应、不断践行践修,让我们活在成长中
转载:https://www.jianshu.com/p/03fd1e22bcfe
一、简介
(1)Anaconda
Anaconda3下载地址:https://www.anaconda.com/distribution/#download-section
Anaconda是目前最流行的数据科学平台以及现代机器学习的基础。同时Anaconda 也是一个Python的发行版,专注于人工智能,天然适合科学计算,数据分析和机器学习,其包管理器是conda。
Anaconda distribution 是世界上最流行的Python/R数据科学平台,是在一台机器上开发、测试、训练的工业标准。Anaconda distribution能够使每个数据科学家快速的下载1500+Python/R数据科学包,能够使用Conda管理库和依赖项以及环境,能够用scikitlearn/Tensorflow/Theano开发和训练机器学习和深度学习模型,能够用Dask/Numpy/Pandas/Numba分析可伸缩性和性能的数据,能够用Matplotlib/Bokeh/Datashader/Holoviews可视化结果。
(2) Pytorch
Pytorch官网
Pythorch是一个开源的机器学习框架,它加速了从原型到产品的过程。
(3)Pycharm
Pycharm下载地址
二、Anaconda
(1)安装Anaconda
下载Anaconda3后运行出现下图:
点击“next”,进入下一步:
点击“I Agree”,进入下一步选择安装路径:
点击“Next”,进入下一步高级选项然后勾选第二项:
点击“Install”,进入安装界面:
点击“Next”,进入下面提示界面:
点击“Next”,进入下一步点击“Finish”即可。
(2)验证Anaconda是否安装成功
在开始菜单找到Anaconda Prompt输入:“conda list”出现下图即安装成功。
(3)创建Python环境
在Anaconda Prompt中输入:“conda create -n pytorch python=3.7”。如下图:
-n:即name表示环境名称,本次命名为pytorch。
python:选择Python的版本号,本次为3.7版本。
按回车后出现下图:
输入“y”按回车,出现下图说明安装成功。
激活创建的环境,输入:“conda activate pytorch”回车。如下图:
三、Pytorch
(1)复制安装命令
进入Pytorch官网,进入下面界面:
Pytorch Build:选择稳定版本
系统选择:根据自己电脑系统选择
Package:选择Conda安装
语言选择:Python3.7(根据自己实际情况选择)
Cuda:根据显卡是否为Nvidia显卡以及是否支持cuda加速及显卡驱动的版本选择,我的笔记本不支持cuda所以选择“None”
Run this Command:复制该条目的内容
(2)在Anaconda Prompt执行安装命令
在Anaconda Prompt中选择创建的python环境,然后粘贴上一步复制的内容。如下图:
回车后出现下图:
输入“y”,按回车,出现下图:
上图显示有一个包没有下载完整,重复上一步的粘贴命令,直到全部包安装成功。如下图:
(3)验证安装是否成功
在Anaconda Prompt中选择创建的python环境,输入:“python”,然后回车。接着输入:“torch”,然后回车。最后输入:“torch.cuda.is_available()”出现下图表明安装成功。
(4) 激活环境
activate pytorch 四、Pycharm
面向连接的运输:TCP TCP连接 定义:两个应用进程通信之前必须建立“握手”连接,初始化TCP连接参数。逻辑连接,其连接的共同状态只保留在两个通信端系统的TCP程序中,即TCP协议只运行在端系统中,对底层透明。特点: 面向字节流:TCP将数据看成无结构的、有序的字节流流水线机制:TCP拥塞控制、流量控制、设置窗口大小·全双工服务(full-duplex service):A、B具有TCP连接,则数据可在A、B间双向传递点对点(point-to-point):只能在单个发送方、单个接收方之间连接,所以不能实现“多播”三次握手(three-way handshake):客户首先发出特殊的TCP报文段,服务器反馈一个TCP报文段,客户再使用第三个TCP报文段作为响应。(前两个不包含数据,第三个可以包含数据。)最大报文段长度(Maximum Segment Size,MSS): TCP从发送缓存中取出并放入报文段中的应用层数据的最大长度。最大传输单元(Maximum Transmission Unit,MTU): MSS受限于链路层的帧长度。在以太网和PPP链路层协议中,MTU 为1500B,TCP/IP首部长度为40B,因此MSS长度为1460B。路径MTU,是指从源到目的地的所有链路中的发送的最大链路层帧。 组成:发送方主机缓存、变量、与进程连接的套接字,接收方主机缓存、变量、与进程连接的套接字。TCP只运行在端系统中,所以主机之间的其他网络设备都不包含缓存、变量。
TCP报文段结构 源端口号/目的端口号:2B,实现多路复用与分解,端口是传输层和应用层的服务接口。
检验和:2B,实现差错检测,检验范围包括首部和数据,为计算方便,可添加12B的伪首部。
序号:4B,实现可靠数据传输。序号是建立在传送的字节流之上,不是报文段的序列,即序号是指该报文段首字节的字节流编号。
例1:数据流为500000B的文件,MSS为1000B,则TCP将该数据分为500个报文段。第一个报文段序号为0,第二个报文段序号为1000,第三个为2000。
例2:TCP传输时,初始序列号总是从0开始吗?如果不是,为什么?
答:不是,连接双方都可以随机产生的初始序列号,防止攻击者对TCP序列进行预测攻击!
确认号:4B,实现可靠数据传输。确认号建立在全双工服务上,主机A的确认号是主机A期望从主机B接收到的下一字节的序号。
例1:A已经收到B的0~535的所有字节,正常情况。此时A打算向B发送一个报文段,则该报文段中的确认号为536
例2:A收到B的0~535和900 ~1000的所有字节,但还没有收到536 ~ 899的报文段,报文丢失。TCP采用累积确认,所以仍将等待字节536(和其后的所有字节),故A打算发送给B的报文段的确认号为536
例3:主机A先后收到0~535,900 ~ 1000,536 ~899字节的报文段,失序到达。RFC文档中并未明确规定处理原则,交给编程人员处理。①接收方立即丢弃失序报文段,操作简单但是无意义②接收方缓冲失序的字节,等待缺少的字节以填补该间隔,更有效,符合实践要求
接收窗口:2B,实现流量控制,指示接收方期望接收的字节数量。
数据偏移:1B,指示该TCP首部的长度,以32bit的字位单位。由于选项字段可变,所以TCP首部长度是可变的。
选项:可选并且可变长,实现协商MSS或调节窗口大小。
标志字段:6bit。
URG:紧急,当URG=1时,表明本报文段的数据中的紧急数据占多少字节,紧急数据放在数据的最前面,由紧急指针指出。当紧急数据存在并给出了指向紧急数据尾指针的时候,TCP通知接收方的应用层(在实践中,URG和紧急指针并不使用);ACK:确认,当ACK=1时,表明对已被成功接收报文段的确认。PSH:立即推送,当PSH=1时,表明接收方应立即将数据交给上层。RST:复位,当RST=1时,表明TCP连接中出现严重差错,必须释放连接,再重新连接。SYN:建立连接,当SYN=1时,表明该报文段是连接请求或连接接收报文。FIN:终止连接,当FIN=1时,表明该报文段的数据已发送完毕,并要求释放连接。 填充:使首部长度为4B的整数倍。
TCP抓取:
往返时间的估计与超时 估计往返时间: 样本RTT(SampleRTT):报文段发出到收到确认之间的时间量,只做一次SampleRTT测量,忽略重传的报文段;会随路由器的拥塞和端系统的负载的变化,而随之波动变化;典型RTT(EstimatedRTT):平滑处理,使用样本RTT的加权均值,该方法在统计学中称为指数加权移动平均(EWMA)
计算公式: E s t i m a t e d R T T = ( 1 − α ) ∗ E s t i m a t e d R T T + α ∗ S a m p l e R T T EstimatedRTT =(1-α)*EstimatedRTT+α*SampleRTT EstimatedRTT=(1−α)∗EstimatedRTT+α∗SampleRTT,α的推荐值为0.
uniapp接入蓝牙设备(踩坑记录) APP开启notify失败uni.notifyBLECharacteristicValueChangeAPP写入数据失败uni.writeBLECharacteristicValueios监听特征值失败uni.notifyBLECharacteristicValueChangeuni.getBluetoothDevices获取到的广播包数据不更新安卓手机搜索不到设备 APP开启notify失败uni.notifyBLECharacteristicValueChange APP
调用uni.createBLEConnection之后
需要延时2秒
再调用uni.notifyBLECharacteristicValueChange
APP写入数据失败uni.writeBLECharacteristicValue 同上
延迟1秒
再调用uni.writeBLECharacteristicValue
ios监听特征值失败uni.notifyBLECharacteristicValueChange ios连接设备后,需要把全流程跑完,不能直接监听特征值
1.获取蓝牙设备所有服务
2.链接服务
3.获取服务特征值
4.监听特征值
uni.getBluetoothDevices获取到的广播包数据不更新 需要持续开启扫描蓝牙设备,才能通过uni.getBluetoothDevices获取到最新的广播包数据
安卓手机搜索不到设备 安卓不仅要开启蓝牙,还需要开启定位
链路层 概述 相关概念: 结点(nodes):运行链路层协议的所有设备,包括主机、路由器、交换机节点、WIFI接入点链路(link) :连接相邻节点的通信信道,包括有线链路、无线链路数据帧(frame):在第二层的链路层进行传输时,必须将IP数据报封装成数据帧 数据链路层:将数据报从一个节点传送到该节点直接由物理链路相连的另一个节点 链路层提供的服务 封装成帧:IP数据报作为“数据”字段 和 若干首部字段封装成链路层帧
链路接入:媒体访问控制协议(Medium Access Control,MAC)规定了帧在链路上传输的规则。
可靠数据传输:提供了可靠交付服务,保证在链路层无差错地传输网络层数据报。通过确认和重传机制实现。
注意:链路层的可靠数据传输通常用于高比特错误率的无线链路,目的是在本地进行纠错一个差错,而不是进行重传。
链路层的可靠数据传输一般不用于低比特差错的有线链路,如:光纤、同轴电缆、双绞线。
差错检测和纠正:
当链路中因为信号衰减、电磁噪声而出现比特差错,所以链路层需要进行差错检测;
差错检测通过让发送节点在帧中包括差错检测比特,让接收节点进行差错检测实现,通知发送方重传或丢弃数据帧
纠正错误是指接收方能够直接标识和纠正比特错误,而不需要请求重传。
问:为什么要在链路层和端到端都实现可靠传输?
答:①数据传输出错的地方:物理信道因为信号衰减、噪声干扰等导致数据比特出错。网络层中的路由器因为缓存有线,导致分组丢失。
②链路层可靠保证了节点间链路进行无比特差错,对象是链路层,目标是网络层
③传输层可靠保证了网络路由无差错,对象是网络层。目标是应用层
④必须在链路层实现可靠,因为在较低层就可以提前发现物理层的错误,而不用等到传输层才发现错误。
⑤也必须在传输层实现可靠,因为这是可靠数据传输的最后一道防线,必须保证数据报正确交付给应用程序。
流量控制:用于控制发送节点向直接相连的接收节点发送数据帧的频率
半双工和全双工:在半双工模式中,两个节点都可发送数据,但是不能同时发送
链路层实现的位置 设备:在主机和路由器上都要实现网络适配器(网卡):在主机上,链路层的主体部分是在网络适配器上实现的。网络适配器的核心是链路层控制器,该控制器通常是一个实现了许多链路层服务的专用芯片。例如:Intel的710控制器实现了以太网协议;AR5006控制器实现了802.11WIFI协议。 差错检测和纠错技术 比特级差错检测和纠错 定义:是指对一个节点发送到另一个物理上相邻节点的帧,检测是否出现比特差错,并纠正。差错检测和纠正比特(Error-Detection and Correction,EDC):在发送节点上为保护比特,为数据报添加EDC增强数据。发送节点: 保护范围:数据报,链路层帧首部中的寻址信息、序号和其他字段。数据:将保护范围内所有字段作为数据进行传送EDC:在数据后添加EDC 接收节点: 接收比特序列 D’ 和 EDC’ ,若EDC’与EDC相同,则无错误;反之,则有错误。 - 缺点:差错检测和纠正技术不能保证接收方检测到所有的比特差错。所以,要选择一个好的差错检测算法保证这种情况发生的概率很小。 奇偶校验-最基本的方法 一比特奇偶校验 发送方: 在要发送的数据D(d位)后面附加一个奇偶校验位使“1”的个数是奇数(奇校验)和偶数(偶校验)一起传输发送(d+1)位 接收方: 检测收到的信息(d+1)位中“1”的个数偶校验:出现奇数个“1”,至少出现一个比特差错(奇数个比特差错)奇校验:出现偶数个“1”,至少出现一个比特差错(奇数个比特差错) 注意: 奇偶校验可以检查出是否出现奇数个bit错误,但不能发现偶数bit错误 假设出现偶数位bit错误:00->11等价于不变;11->00等价于不变; 10->01等价于不变;01->10等价于不变;
假设不成立,矛盾。
假设比特差错概率很小并且假设差错是独立发生的时,那么在一个分组中同时出现多个bit错误的概率很小,所以此时一比特奇偶校验足够适合。若差错集中在一起“突发”,则一帧中未检测到的差错的概率达到50%。 二维奇偶校验 基本思想:将数据D(d位)划分位 i 行 j 列的矩阵,对每行、每列都分别计算奇偶值;最后将产生的 i+j+1奇偶比特构成链路层帧的差错检测。当某bit出现差错时,可以检测出器所在行、所在列,从而定位检测并纠正bit。示例 检查和-常用于运输层 检验和(checksum):网络层中的IPv4首部、传输层数据报首部都有检验和字段。(因特网IPv4中只对首部计算;TCP/UDP中对所有计算;还有其他的将首部和数据分别计算得到两个检验和)发送方: 按照16bit将数据划分求所有16位的整数和,高位要“回卷”(进位补加到最低位再计算)将得到的和取反码,作为检验和放在首部,发送报文 接收方: 对收到的信息做相同的求和,并取反码若全为"1",则收到的数据无差错只要含有“0”,则收到的数据出现差错 特点: 分组开销小,检查和位数较少。如:16bit差错检测能力弱,但方法简单、速度快,适用于传输层的软件实现。链路层的差错检测由硬件实现,可以执行更复杂,更强大的CRC循环冗余检测 循环冗余检测-常用于链路层 循环冗余检测(Cyclic Redundancy Check,CRC):现在被广泛使用的差错检测技术
项目简介
本项目根据个人需求进行北京二手房信息的数据分析,通过数据分析观察住房特征规律,利用机器学习模型进行简单的预测。
数据源
通过爬虫爬取第三方房屋中间商网站(链家和安居客)获取数据源,仅供学习使用。
目的
北京房价是最受关注的话题。因此,本项目以研究北京二手房房价为目的,对二手房房价进行数据分析。
统计北京各区域二手房房价情况
统计北京各区域二手房数量
统计西城区、东城区和海淀区各地方二手房房价
统计房价与房屋面积区段的房屋数量
技术和工具
本项目以Python语言编程完成数据分析。
数据分析:pandas,numpy,matplolib
1、 数据导入和清洗 import pandas as pd import numpy as np import matplotlib.pyplot as plt # 导入链家二手房数据 lianjia_df = pd.read_csv('./lianjia.csv') print(lianjia_df.head()) print('\n') # 删除没用的列 ['Id', 'Direction', 'Elevator', 'Renovation'],为了与安居客数据合并 drop = ['Id', 'Direction', 'Elevator', 'Renovation'] lianjia_df_clean = lianjia_df.drop(drop, axis=1) # 重新摆放列位置 ['Region', 'District', 'Garden', 'Layout', 'Floor', 'Year', 'Size', 'Price'] columns = ['Region', 'District', 'Garden', 'Layout', 'Floor', 'Year', 'Size', 'Price'] lianjia_df_clean = pd.
文章目录 摘要0 引言1 协同过滤算法2 实时推荐服务3 电影推荐系统设计部署3.1 架构设计3.2 系统功能设计3.3 数据库设计 4 系统运行效果5 结语参考文献 摘要 摘要:随着社会逐渐进入信息过载时代,人们对电影个性化推荐服务的要求与日俱增。本文以协同过滤算法为基础进而发掘用户与用户之间的隐含关联,不同电影之间的隐性信息,采集并分析用户对电影的操作记录对用户进行个性化的模型构建,并利用Flume与Kafka建立数据管道,通过Spark系统进行快速计算,从而完成对用户的实时个性化电影推荐。
关键词:个性化推荐;协同过滤;实时推荐;电影推荐;Spark;
0 引言 随着当代互联网技术的飞速发展,日益普及的个人电脑,移动终端等设备,极大的丰富了人们的生活,如多种多样的网站门户、APP等提供数以万计的电影视频,但用户面对海量的数据 [ 1 ] ^{[1]} [1],难以从中提取有效信息,有时并不能在庞杂的电影种类中挑选到自己喜欢的电影,导致用户体验很差。那么个性化的电影推荐系统作为一种信息过滤系统,对电影评分、类别、热度等进行数学统计,利用用户对电影的标签评价,进行个性化离线推荐服务;通过挖掘用户潜在的兴趣爱好,分析电影之间的隐藏关联性,进行协同过滤推荐;基于电影相似度矩阵,利用用户对电影的历史评分记录,通过Flume的实时采集,利用Spark平台高速计算的特点 [ 3 ] ^{[3]} [3],按权重推荐优先级实现实时电影推荐 [ 2 ] ^{[2]} [2]。这样一种基于协同过滤的个性化实时电影推荐系统,实现多方共赢,通过准确的预测用户的行为,对用户进行合理化的实时推荐,省去了用户在挑选影片上所花费的时间,并拓宽用户视野,将“冷门”但喜爱的影片进行推荐,提高用户惊喜度,提升用户体验。利用个性化电影推荐系统,提高了影片利用率,增加用户对网站的粘度 [ 5 ] ^{[5]} [5],提高网站收入。
1 协同过滤算法 协同过滤算法核心思想是通过用户历史行为数据发掘用户潜在的偏好,并将与用户兴趣爱好相似的其他用户划分群组进行个性化预测与推荐,进而实现将用户感兴趣的电影进行推荐。协同过滤算法分为两类:一类是基于用户的协同过滤算法,另一类是基于物品的协同过滤。
基于用户 ( U s e r − b a s e d ) (User-based) (User−based)的协同过滤通过用户的历史浏览记录以及打分评价记录,对数据进行清洗分类和数学统计。并根据不同的用户对相同的电影的偏好程度计算不同用户之间的潜在关系,对相似群组的用户进行划分,此时处于同一群组的用户可以根据邻居对电影评分以及评价的加权平均值来预测目标用户的可能评分,进而生成目标用户的个性化推荐电影。
基于物品 ( I t e m − b a s e d ) (Item-based) (Item−based)的协同过滤依赖于不同电影之间的分类标签以及不同用户对其评价的关联度,计算不同用户对不同电影的平均偏好值差异,得到电影相似度矩阵。对已打标签或已评分电影进行对相似电影的推荐预测,依据不同电影间的相似程度,基于电影间的关系对用户进行相似电影的预测推荐,最终根据以上信息对目标用户形成推荐。
一句话结论:本文归纳CMake构建c++工程的基本用法,实现多依赖、多工程、多文件格式的工程编译构建。
1.简介 CMake(cross-platform make)是一个跨平台编译工具,它不能直接生成最终可执行程序,而是构建各平台标准的构建文档(如Linux的Makefile、Windows的sln)。
使用时,用户不再需要直接编写底层Makefile文件,而是编写语法简单的CMakeLists.txt文件,CMake在执行目录下查找CMakeLists.txt来生成Makefile、构建工程,大幅降低工程构建和编译的难度。
2.简单工程 - output - build - tests - test0 - main.cc - CMakeLists.txt cmake_minimum_required(VERSION 3.10) # set c++11 set(CMAKE_CXX_FLAGS "$GUN_FLAGS -std=c++11") # set output dir set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../output) # based on current CMakeLists.txt set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../output) # .exe set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../output) # .a # build test0 aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/test0 SRC_TEST0) # collect all cxx files in $test0 add_executabel(test0 ${SRC_TEST0}) 在项目构建和编译过程中会生成大量中间文件,为保持源代码目录纯净,一般在其他目录新建一个build目
mkdir build cd build cmake ../tests/ make 3.生成并使用链接库 目的:在A工程下,生成动态链接库,在B工程下调用。
由于工作关系,经常需要访问不同地点计算机里的资料,原来的解决方案为云盘同步,但由于众多云盘歇菜,存活的又限速,还有隐私风险等因素,不得不放弃这种免费方案。于是还有一种自己搭建私有云的方案(在路由器、NAS、小主机等设备上通过开源软件搭建——不是本文讨论主题,略过),或者远程控制方案(teamviewer却总是提示商用,无法安心的使用不得不放弃;还有anydesk、logmein等等也提供免费远程控制),但由于需要通过其设在国外的服务器中转,速度是个无法忍受的问题。于是寻找替代解决方案,终于让我找到了一个可以充分发挥想象优势,享受无限折腾乐趣的内网穿透服务——ZeroTier,下面就简要介绍一下它的基本功能:
一、主要功能:将安装ZeroTier软件的所有设备统一到一个虚拟局域网,用虚拟局域网ip和内网ip均可以无缝访问虚拟局域网中的任一台设备,并且拥有如下优势:
①. 节点之间属于 P2P UDP 直连,无需服务器中转流量,互联速度仅仅取决于你的和其他节点的直连上传带宽(当然握手之初是需要经过中心服务器来当媒婆的,之后就是UDP直连了!);
②. 节点之间的流量是加密和压缩的,所以有带宽放大的功能;
③. 配置简单,只需要填入一个 Network ID ,然后管理员在 Zerotier 官网管理页面允许通过一次,以后就直接允许连上了。
④.连上后各个虚拟网卡相当于同一局域网内,无应用的限制了——至于有哪些应用场景就需要读者你自己脑洞大开了。
⑤.关键的一点,只要你想要的连接的节点在100以内,所有功能都是免费的!
【二、详细安装步骤和注意事项请跳转到我的博客。】 还是搬到这里来方便大家吧!
二、简易设置:首先到官网ZeroTier.com去注册账号(ZeroTier Central),并新建你的Network ID(官网自动生成ID,你可以为它设置一个好记的名字并添加说明以便于记忆)。然后在你需要组建成局域网的设备上安装ZeroTier客户端(官网下载和安装指南地址),填入之前生成的Network ID,并到官网管理中心将设备对应的【Auth】选项进行勾选以将其并入该Network ID的局域网。
三、扩展应用:前述设置需要在每一个组网的设备上安装ZeroTier客户端并在官网管理中心添加许可,虽然已经够简单了,但万一某个设备的客户端被禁止了或更新系统后不能正常运行的话,就不能相互连通了。于是有一种想法,在需要组网的设备端上级路由器上安装ZeroTier客户端并在官网管理中心添加许可、设置路由表,这样安装了ZeroTier客户端的所有路由器下的所有设备都处在同一局域网下啰。
1、官网注册并新建Network ID,同前。
2、在路由器上安装并激活ZeroTier(以openwrt软路由为例,其它的可自行搜索):
(1) ssh进入路由器shell,运行opkg update && opkg install zerotier进行安装。(我用的是koolshare的openwrt固件,虽然已经在酷软中心集成了ZeroTier插件,但不推荐在酷软安装,有时会出一些莫名其妙的错误,还是如前述手动安装为好)
(2) ssh中运行zerotier-cli join ID(即你在官网建立的Network ID),或者直接修改/etc/config/zerotier配置文件(若ssh中运行zerotier-cli join ID出错也按此方法修改并保存此配置文件),将option enabled ‘0’的0改为1,list join ‘**********’改为你自己的Network ID。
(3) 重启路由器。
(4) 到官网管理中心勾选对应路由器的【Auth】项
(5) 添加路由表:
(6) 路由器防火墙设置,在【网络】→【防火墙】→【自定义规则】中添加如下规则,【重启防火墙】:
如果是在旁路由中还需添加这一条:iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
iptables -I FORWARD -i ztyqbub6jp -j ACCEPT
前言 之前在整理 selete 和 epoll 原理时,看到了两篇关于epoll ET模式的不错的文章。因此,借用此文章来加深对epoll ET模式的理解。(文末标注原文链接)
在进行ET模式的正式分析之前,我们来举个例子简单地了解下ET和LT:
假设我们通过 fork函数创建了父子两个进程,并通过 匿名管道来通信,在子进程中,我们一次向管道写入10个字符数据,为"aaaa\nbbbb\n";每隔5s写入10个字符数据;在父进程中,我们从管道中一次读取5个字符数据: 若我们采用的是 LT模式,则在5s的周期内,会先读取5个字符数据,读完之后,因为文件描述符中仍然有数据,epoll_wait会立即返回,会继续读取接下来的5个数据,之后在5s周期以内的剩余时间内,管道中的数据都为空,如下图1。 若我们采用的是 ET模式,则当父进程先读完管道中的5个字符后,由于子进程没有立即向管道中写入字符(间隔5s后才会第二次写入),所以此时父进程会先读到5个字符"aaaa\n",隔5s之后,再读到5个字符"bbbb\n",如下图2,可以看到ET模式下,随时间推移,管道中数据会越来越多。 图1:
图2:
epoll工作流程 想要了解ET模式和LT模式的区别,首先需要熟悉epoll的工作流程:
【注:】上图的poll不要理解成和select相似那个poll,这是通过epoll_ctl调用的,进行回调函数注册。
下面简要分析一下epoll的工作过程:
1)epoll_wait调用ep_poll, 当rdlist为空(无就绪fd)时挂起当前进程,直到rdlist不空时进程才被唤醒。 2)****文件fd状态改变(buffer由不可读变为可读或由不可写变为可写),导致相应fd上的回调函数ep_poll_callback()被调用。 ep_poll_callback将相应fd对应epitem加入rdlist,导致rdlist不空,进程被唤醒,epoll_wait得以继续执行。 3)ep_events_transfer函数 将rdlist中的epitem拷贝到txlist中,并将rdlist清空。 4)ep_send_events函数(很关键),它扫描txlist中的每个epitem,调用其关联fd对应的poll方法(图中蓝线)。 此时对poll的调用仅仅是取得fd上较新的events(防止之前events被更新),之后将取得的events和相应的fd发送到用户空间(封装在struct epoll_event,从epoll_wait返回)。 5)之后如果这个epitem对应的fd是LT模式监听且取得的events是用户所关心的, 则将其重新加入回rdlist(图中蓝线),否则(ET模式)不在加入rdlist。 ET模式 vs LT模式 区别 通过上图epoll的工作流程描述,可以看出ET模式和LT模式的区别主要发生在第5步:是否将文件描述符fd放回rdlist中,而rdlist的是否为空决定了epoll_wait函数的阻塞和非阻塞。因此,总结下二者的区别:
ET 如果是ET, epitem是不会再进入到readly list;除非fd再次发生了状态改变, ep_poll_callback被调用。 【因此,ET模式可减少epoll_wait函数的调用,从而减少系统开销,提高效率。】 LT 如果是非ET, 不管你还有没有有效的事件或者数据,都会被重新插入到ready list, 再下一次epoll_wait时, 会立即返回, 并通知给用户空间。当然如果这个被监听的fds确实没事件也没数据了, epoll_wait会返回一个0,空转一次。 加入rdlist途径分析 红线:fd状态改变才会触发,那什么情况会导致fd状态的改变呢?
对于读取操作: 1)当buffer由不可读状态变为可读的时候,即由空变为不空的时候。 2)当有新数据到达时,即buffer中的待读内容变多的时候。 对于写操作: 1)当buffer由不可写变为可写的时候,即由满状态变为不满状态的时候。 2)当有旧数据被发送走时,即buffer中待写的内容变少得时候。 蓝线:fd的events中有相应的时间(位置1)即会触发。那什么情况下会改变events的相应位呢?
对于读操作: 1)buffer中有数据可读的时候,即buffer不空的时候,fd的events的可读为就置1。 对于写操作: 2) buffer中有空间可写的时候,即buffer不满的时候fd的events的可写位就置1。 【说明:】
红线是时间驱动被动触发(fd状态改变);
蓝线是函数查询主动触发(LT和ET判断是否加入rdlist)。
1.kmalloc函数 static __always_inline void *kmalloc(size_t size, gfp_t flags) { if (__builtin_constant_p(size)) { #ifndef CONFIG_SLOB unsigned int index; #endif if (size > KMALLOC_MAX_CACHE_SIZE) return kmalloc_large(size, flags); #ifndef CONFIG_SLOB index = kmalloc_index(size); ///查找使用的哪个slab缓冲区 if (!index) return ZERO_SIZE_PTR; return kmem_cache_alloc_trace( ///从slab分配内存 kmalloc_caches[kmalloc_type(flags)][index], flags, size); #endif } return __kmalloc(size, flags); } kmem_cache_alloc_trace分配函数
void * kmem_cache_alloc_trace(struct kmem_cache *cachep, gfp_t flags, size_t size) { void *ret; ret = slab_alloc(cachep, flags, size, _RET_IP_); ///分配slab缓存 ret = kasan_kmalloc(cachep, ret, size, flags); trace_kmalloc(_RET_IP_, ret, size, cachep->size, flags); return ret; } 可见,kmalloc()基于slab分配器实现,因此分配的内存,物理上都是连续的。
【ybtoj】【线性基】k小异或和 题目 传送门
解题思路 线性基小知识
三大性质:1.原集合里的任何数都可以用线性基中某些数的异或和表示
2.线性基中任意数的异或和不等于0
3.线性基的大小只与原集合有关,大小固定且最小
用数组d存储线性基
逐一枚举集合中的元素,并尝试加入线性基
从高到低枚举二进制数x的每一位
如果x的第i位是1且d[i]位为空,x成功加入线性基
否则x异或上d[i](保证d[i]第i位为1,且是最高位)
对于本题,还需对线性基做处理
具体为,枚举d[i],若第j位为1,则异或上d[j]
最后还是原集合的线性基
求解过程:假如二进制数k的第i位为1,ans就异或上线性基中第i大的元素,ans即为所求
代码 #include<iostream> #include<cstring> #include<cstdio> using namespace std; int q,n,m,k,t,p; long long x,d[100]; void add(long long x) { for (int i=60;i>=0;i--) if (x&(1ll<<i)) if (d[i]) x=x^d[i]; else { d[i]=x; break; } } long long ask(int k) { if (k==1&&p<n) return 0; if (p<n) k--; if (k>=(1ll<<p)) return -1; long long ans=0; for (int i=0;i<=60;i++) if (d[i]) { if (k%2==1) ans^=d[i]; k/=2; } return ans; } int main() { scanf("
文章目录 目的GPIO(通用输入输出接口)基础说明初始化输出输入与电平读取锁定机制 EXTI(外部中断)基础说明使用演示 总结 目的 GPIO是单片机最基础的功能,EXTI最常用的场景就是GPIO用于输入时使用。这篇文章将对CH32V307中相关内容进行说明。
本文使用沁恒官方的开发板 (CH32V307-EVT-R1沁恒RISC-V模块MCU赤兔评估板) 进行演示。
本文演示中需要用到开发板上的KEY和LED,默认只是引入接口到排针,并没有和芯片GPIO口相连,下文使用中需要手动用杜邦线连接。
GPIO(通用输入输出接口) 基础说明 CH32V307的GPIO和大部分单片机一样支持多种工作模式: 浮空输入 上拉输入 下拉输入 模拟输入 开漏输出 推挽输出 复用功能的输入和输出 。
复位后 ,GPIO口运行在初始状态,这时大多数IO口都是运行在浮空输入状态 ,但也有HSE等外设相关的引脚是运行在外设复用的功能上。
沁恒官方提供了库函数用于操作GPIO口,主要是 ch32v30x_gpio.h 和 ch32v30x_gpio.c 两个文件,前者中声明了提供给用户调用的函数以及相关的枚举和宏定义类型等。
下面只介绍些GPIO的基础使用,剩余的功能大多数是结合外设复用或是中断等进行的,会在包含在那些内中中进行介绍。需要详细了解也可以直接查看上面的库函数文件。
初始化 初始化GPIO只要配置需要使用的GPIO口和工作模式及其附加参数等,比如下面方式:
// 下面函数将初始化 PA0 为推挽输出模式 void GPIO_Toggle_INIT(void) { GPIO_InitTypeDef GPIO_InitStructure = {0}; // GPIO后初始化结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //初始化GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 使用 Pin0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出切换频率 // 这个通常在满足需求的情况下越低越好,比如使用 GPIO_Speed_2MHz GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIO口 } 上面代码中出现的 GPIOA GPIO_Pin_0 GPIO_Mode_Out_PP 等枚举和宏定义类型都可以在 ch32v30x_gpio.
文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。
笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者:Aliven888
问题描述: 使用旧API编译器有诸如下面的提醒,有点编译器会报warning,有的编译器会报error,
warning: 'Reader' is deprecated: Use CharReader and CharReaderBuilder instead [-Wdeprecated-declarations] warning: 'FastWriter' is deprecated: Use StreamWriterBuilder instead [-Wdeprecated-declarations] 问题分析: Json::Reader 是旧版本的api,兼容性存在问题。
解决方案: 方案一 :兼容旧版本 坚持使用旧API可以在文件头部加入这段代码:
#if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #elif defined(_MSC_VER) #pragma warning(disable : 4996) 方案二 :使用新版本接口 // Parse config file std::string conf_path{"./conf/test.json"}; std::ifstream cfg_file(conf_path, std::ios::binary); if ((conf_path.empty()) || (!cfg_file.is_open())) { printf("Open config file [%s] failed.
查询服务器系统: 查看系统版本 cat /etc/redhat-release 查看linux 内核 uname -a 整体查看CPU相关信息 lscpu 结果:
[root@localhost ~]# lscpu Architecture: x86_64 #cpu架构 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 32 #逻辑CPU核数 On-line CPU(s) list: 0-31 Thread(s) per core: 2 #每核超线程数 Core(s) per socket: 8 #每个cpu核数 Socket(s): 2 #物理cpu个数 NUMA node(s): 2 Vendor ID: GenuineIntel #cpu产商 intel CPU family: 6 Model: 62 Model name: Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz Stepping: 4 CPU MHz: 1200.
1、Controller
@RequestMapping(value = "/importBlackCatLadingBill", method = RequestMethod.POST, produces = "multipart/form-data; charset=utf-8") @ApiOperation(httpMethod = "POST", value = "导入") public String importLadingbillData(@RequestParam("file") MultipartFile file, HttpServletRequest request) { return service.importCatData(request.getHeader("accountId"), file); } 2、Service层, 控制能够导入的类型,将导入时的信息存入对应的表中(可有可无,根据业务来写),最后解析Excel,将数据封装到对象并且保存导数据库中
public String importCatData(String accountId, MultipartFile file) { ApiOutParamsInfo<Boolean> result = new ApiOutParamsInfo<Boolean>(); LoginAccount loginAccount = (LoginAccount) redisUtil.hget("ACCOUNTINFO", accountId + "_login"); TImportManagement tImportManagement = new TImportManagement(); Map<String, Object> excelMap = new HashMap<>(); // List<Object> list = null; // 将导入文件的信息记录下来(可有可无,根据具体业务来写) tImportManagement.
文章目录 前言一、准备工作1、下载hadoop-3.3.12、修改环境变量配置文件3、服务器免密登录4、脚本文件在文件夹信息 二、安装创建/修改配置文件1、创建`core-site.xml`文件2、创建`hdfs-site.xml`文件3、创建运行脚本文件`install_shell.sh`4、上传并运行脚本5、访问`NameNode`的网页界面 前言 本文只是对hadoop进行单机版简单安装使用,并使用脚本快速安装hadoop单机版,有一些配置如yarn配置没有修改,但是会进行简单说明。全程使用root用户。
一、准备工作 1、下载hadoop-3.3.1 阿里镜像hadoop3.3.1
下载安装jdk:略
2、修改环境变量配置文件 vim /etc/profile 移动到文件末尾,按小写字母i进入插入模式,添加或修改下面的内容:
export HADOOP_HOME=/root/soft/hadoop-3.3.1 export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin 注意:PATH是修改之前配置JDK的那个,仅较之前添加了:$HADOOP_HOME/bin!
修改完大概是这样的:
使环境变量生效
source /etc/profile 3、服务器免密登录 ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 0600 ~/.ssh/authorized_keys 4、脚本文件在文件夹信息 文件内容(需上传到服务器或虚拟机上)
二、安装 创建/修改配置文件 在要上传的文件夹下操作
1、创建core-site.xml文件 <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
一直以为C#不存在内存泄漏的问题,直到遇到一个程序运行一段时间后出现卡顿情况,才发现程序出现了内存泄漏问题。在网上看到了几篇文章,整理下C#内存泄露可能的原因,提醒自己以后开发时注意下,后续遇到其他情况再补充完善。
1.非托管资源(内存、控件等)
因为非托管资源所占的内存不能自动回收,所以使用后必须手动回收,否则程序运行多次很容易造成内存泄露。
// 完成托管平台到win32平台的转换 IntPtr lpInBuffer = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(param, lpInBuffer, false); …… // 释放win32平台的内存资源 Marshal.FreeHGlobal(lpInBuffer); 在使用的函数开头写下using 就可以不用担心内存泄漏问题,简化复杂管理问题,异常,多return,continue,break,goto之类的跳转等。
using var xxx = new XXX();
如可以在 using 语句中声明对象:
using (Font font1 = new Font("Arial", 10.0f)) { // use font1 } 2.静态变量
静态变量中的成员所占的内存,如果不手动处理是不会释放内存的,单态模式的对象也是静态的,所以需要特别注意。因为静态对象中的成员所占的内存不会释放,如果此成员是以个对象,同时此对象中的成员所占的内存也不会释放,以此类推,如果此对象很复杂,而且是静态的就很容易造成内存泄露。
3.Dispose方法没被调用,或Dispose方法没有处理对象的释放。这样也会造成内存泄露
4.当一个查询语句查询出来的数据量很大,达到几百万条数据时存放到datatable 或dataset中也会造成内存溢出,这是可以采用分页查询等其他方法来解决。
5.未退订的事件
参考网页:
.NET资源泄露与处理方案
浅谈.net 内存泄露和内存溢出
8 Ways You can Cause Memory Leaks in .NET
目录
一、简介
1.题目:
2.时间:
3.来源:
4.简介:
二、相关名词
三、 文章总体架构
1.深度神经网络发展与分类
2.深度神经网络的主流硬件平台
3.FPGA开发流程
4.FPGA深度神经网络应用
5.FPGA深度神经网络加速
6.FPGA型号选择
7.基于FPGA的深度神经网络的性能衡量指标
8.影响FPGA应用于深度神经网络的因素
一、简介 1.题目: 深度神经网络 FPGA 设计进展、实现与展望
2.时间: 2022.03
3.来源: CHINESE JOURNAL OF COMPUTERS,计算机学报
4.简介: 论文从多个方面介绍了深度神经网络和FPGA以及二者结合的应用热点;
总结了基于FPGA的深度神经网络的设计思路与未来方向;
归纳了FPGA相关设计的评价指标;
分析了影响FPGA应用于深度神经网络的因素。
二、相关名词 ANN:Artificial Neural Network,人工神经网络
AutoML:Automatic Machine Learning,自动机器学习
SoC:System on chip,系统级芯片
brain-inspired chip:类脑芯片
RTL:Register Transfer Level,寄存器传输级
HLS:High Level Synthesis,高层次综合
三、 文章总体架构 1.深度神经网络发展与分类 目前主流的神经网络模型有:深度卷积神经网络、深度强化学习、轻量级神经网络、自动机器学习
2.深度神经网络的主流硬件平台 目前的硬件平台市场以通用性芯片(CPU、 GPU)、半制定化芯片(FPGA)、全制定化芯片 (ASIC)、集成电路芯片(SoC)和类脑芯片等为主。
综合计算能力强、灵活性高、设计简单、功耗低、设计成本低等多方面因素,FPGA更加适合应用于深度神经网络在普通领域的开发和使用。
3.FPGA开发流程 FPGA是一种半定制电路,目前开发有两种方式:寄存器传输级(RTL)描述和高层次综合(HLS)描述。
4.FPGA深度神经网络应用 图像检测与识别、目标跟踪、语音识别、文本处理、网络安全、智能控制
5.FPGA深度神经网络加速 ①FPGA加速器:比如DLAU、 Deep-Burning、 DeepX等等
1.Tomcat 阀 Tomcat阀(Valve)组件能对Catalina容器接收到的HTTP请求进行预处理。Tomcat阀是Tomcat专有,不能用于Tomcat以外的其它Servlet容器。而过滤器是在Java Servlet规范中提出了的,因此适用于所有的Servlet容器 。
1.1 Tomcat阀简介 Tomcat阀可以加入到3种Catalina容器中,它们是Engine、Host和Context。作用范围如下表:
容器描述Engine可以预处理该Engine接收到的所有HTTP请求Host可以预处理该Host接收到的所有HTTP请求Context可以预处理该Context接收到的所有HTTP请求 所有的Tomcat阀都实现了org.apache.Catalina.Valve接口或扩展了org.apache.Catalina.valves.ValveBase类。Tomcat阀包括以下几种:
客户访问日志阀(Access Log Valve)远程地址过滤阀(Remote Address Valve)远程主机过滤阀(Remote Host Valve)错误报告阀(Error Report Valve) Tomcat阀用<Valve>元素来配置,它的形式为:
<Valve className="实现这种阀的类的完整名字" ...其它属性.../> 如果把Tomcat阀加入到Context中,则需要在Tomcat的conf/server.xml文件的相应<Context>元素中加入<Valve>元素,或者在相应 Web应用的 META-INF/context.xml 文件的<Context>元素中加入<Valve>元素;但加入到Engine或Host中时,只能修改server.xml文件。
Tomcat中自带了关于Tomcat阀的参考文档:
<CATALINA_HOME>/webapps/docs/config/valve.html 1.2 客户访问日志阀 客户访问日志阀(Access Log Valve)能够将客户的请求信息写到日志文件中。这些日志可以记录网页的访问次数、访问时间、用户的会话活动和用户的安全验证信息等。
图1-1 客户访问日志阀的工作过程 客户访问日志阀的<Valve>元素的属性描述见下表:
属性描述className指定阀的实现类。如org.apache.Catalina.valves.AccessLogValvedirectory设定存放日志文件的绝对或相对于<CATALINA_HOME>的相对目录。该属性的默认值为<CATALINA_HOME>/logspattern设定日志的格式和内容。默认值为 common。prefix设定日志文件名前缀。默认为 access_logresolveHosts如果设为true,表示把远程IP地址解析为主机名,如果为false,表示直接记录远程IP地址。默认值为false。suffix设定日志文件的扩展名,默认值为""。 pattern 属性可以设置成common或者combined,这两个值集成了一些显示方式,也可以自己设置显示格式,支持如下的编码:
属性描述%a远程访问者IP地址%A本地服务器IP地址%b发送信息的字节数,不包括http header,如果为0显示为“-”%B发送信息的字节数,不包括http header%h这个就是服务器名称了,如果resolveHosts为false就是IP地址了%H访问者使用的协议%l远程逻辑用户名,目前总是返回“-”%m访问者请求使用的方法(GET、POST等)%p接受访问者请求的本地服务器端口%q请求中的查询字符串,即HTTP请求的第一行的URI部分的“?”后面的内容%r请求的第一行内容(包括请求方法、请求URI以及HTTP协议版本)%s服务器响应结果中的HTTP响应的状态码%S用户的session ID%t日期和时间,使用Common Log的格式%u经过安全认证的访问者,不存在时为"-"%U请求的URL路径%v本地服务器名%D处理请求花费的时间,以毫秒为单位%T处理请求花费的时间,以秒为单位 common的值:%h %l %u %t %r %s %b
combined的值:%h %l %u %t %r %s %b %{Referer}i %{User-Agent}I
例如在helloapp应用的context.xml文件的<Context>元素中加入如下<Valve>元素:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="helloapp_access_log." suffix=".txt" pattern="
FIND_IN_SET函数用于返回字符串str在字符串列表str_list中的位置,返回一个整数或一个NULL值
语法格式
FIND_IN_SET(str,str_list) str: 需要查询的字符串
str_list: 需要查询的字符串列表,参数以","分隔,形式如 (1,2,6,8,10,22)
提示Tips
① 如果在 str_list 中没有找到 str,FIND_IN_SET函数返回 0
② 如果 str 或 str_list 为 NULL,FIND_IN_SET函数返回 NULL
③ 如果 str_list 是一个空字符串(""),FIND_IN_SET函数函数返回 0
示例1
-- 1 SELECT FIND_IN_SET("a", "a"); -- 3 SELECT FIND_IN_SET("c", "a,b,c,c,d"); -- 0 SELECT FIND_IN_SET("a", "s,q,l"); -- 0 SELECT FIND_IN_SET("q", ""); -- 5 SELECT FIND_IN_SET("o", "h,e,l,l,o"); -- Null SELECT FIND_IN_SET("q", null); -- Null SELECT FIND_IN_SET(null, "s,q,l"); 示例2
导入数据
DROP TABLE IF EXISTS `divisions`; CREATE TABLE `divisions` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(25) NOT NULL, `belts` varchar(200) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4; INSERT INTO `divisions` VALUES ('1', 'O-1', 'white,yellow,orange'); INSERT INTO `divisions` VALUES ('2', 'O-2', 'purple,green,blue'); INSERT INTO `divisions` VALUES ('3', 'O-3', 'brown,red,black'); INSERT INTO `divisions` VALUES ('4', 'O-4', 'white,yellow,orange'); INSERT INTO `divisions` VALUES ('5', 'O-5', 'purple,green,blue'); INSERT INTO `divisions` VALUES ('6', 'O-6', 'brown,red'); INSERT INTO `divisions` VALUES ('7', 'O-7', 'black'); INSERT INTO `divisions` VALUES ('8', 'O-8', 'white,yellow,orange'); INSERT INTO `divisions` VALUES ('9', 'O-9', 'purple,green,blue'); INSERT INTO `divisions` VALUES ('10', 'O-10', 'brown,red'); divisions表 问题1: 查询生产皮带包含red belts的部门信息
文章目录 🥽 视频对应资料🥽 Tomcat服务器🌊 下载与安装🌊 关于Tomcat服务器的目录🌊 启动Tomcat🌊 实现一个最基本的web应用(这个web应用中没有java小程序) 🥽 静态资源与动态资源🥽 模拟Servlet本质🥽 Servlet规范🥽 开发一个带有Servlet(Java小程序)的webapp(重点)🥽 关于JavaEE的版本🥽 解决Tomcat服务器在DOS命令窗口中的乱码问题(控制台乱码)🥽 向客户端相应内容🥽 在Servlet中连接数据库🥽 在集成开发环境当中开发Servlet程序🥽 Servlet对象的生命周期🥽 适配器设计模式Adapter实现Servlet接口🥽 ServletConfig🥽 ServletContext🥽 缓存机制🥽 HTTP协议🥽 模板方法设计模式🥽 HttpServlet源码分析🥽 关于一个web站点的欢迎页面🥽 关于WEB-INF目录🥽 HttpServletRequest接口详解🥽 使用纯Servlet做一个单表的CRUD操作🥽 在一个web应用中应该如何完成资源的跳转🥽 将oa项目中的资源跳转修改为合适的跳转方式🥽 Servlet注解,简化配置🥽 通过反射获取注解🥽 使用模板方法设计模式优化oa项目🥽 分析使用纯粹Servlet开发web应用的缺陷🥽 JSP🌊 我的第一个JSP程序🌊 JSP概述🌊 JSP的基础语法💦 JSP中直接编写文字💦 JSP的page指令💦 JSP中编写java程序💧 <% java语句; %>💧 <%! %>💧 JSP的输出语句 <%= %> 💦 JSP中的注释💦 JSP基础语法总结 🥽 使用Servlet + JSP完成oa项目的改造🥽 oa系统实现登录功能🥽 session🌊 web应用的session机制🌊 session的实现原理 🥽 域对象🥽 session改造oa项目🥽 Cookie🥽 cookie实现一下十天内免登录功能🥽 JSP的指令🥽 JSP的九大内置对象🥽 EL表达式🌊 EL表达式概述🌊 EL表达式语法🌊 EL表达式的使用 🥽 JSTL标签库🌊 JSTL标签库概述🌊 使用JSTL标签库的步骤🌊 JSTL标签的原理🌊 jstl中的核心标签库core当中常用的标签 🥽 使用EL与JSTL改造OA项目🥽 Filter过滤器🥽 使用过滤器改造OA项目。🥽 Listener监听器🥽 实现oa项目中当前登录在线的人数。🥽 MVC架构模式 🥽 视频对应资料 视频地址:动力节点最新JavaWeb视频教程,javaweb零基础入门到精通IDEA版https://www.
目录
2ASK调制解调系统:
OOK信号 OOK(On-and-Off Keying):一种最简单的2ASK信号:
OOK信号的功率密度谱:
2ASK信号的频带效率:
OOK信号的调制实现方法:
OOK信号的接收及其误比特率:
OOK信号的相干解调:
OOK信号相关解调:
OOK信号的包络检波法解调:
包络检波法和同步检测法的比较:
采用三种不同方法解调OOK信号的性能比较:
例:
2ASK调制解调系统: 二进制移幅键控调制:2ASK(Amplitude Shift Keying)
OOK信号 OOK(On-and-Off Keying):一种最简单的2ASK信号: OOK信号的功率密度谱: 2ASK信号的频带效率: OOK信号的调制实现方法: 优缺点:
容易受到突然增益变化的影响效率不高用于语音级传输,速率不超过1200 bps用于在光纤在传输数字数据 OOK信号的接收及其误比特率: OOK信号的相干解调: 在理想限带及加性白噪干扰信道条件下的最佳接收:频带信道的理想限带特性是指在信道频带内幅频特性是恒定的、相频特性是线性相移,但信道的频带
OOK信号相关解调: OOK信号的包络检波法解调: 包络检波法和同步检测法的比较: 在相同的大信噪比下,2ASK信号采用同步检测法的误码率总是低于采用包络检波法的误码率, 但两者的误码性能相差并不大。
在系统实现方面,包络检波法不需要在接收端产生稳定的本地相干载波,实际实现时其电路上要 比同步检测法简单得多。但是,包络检波法存在门限效应,同步检测法则无门限效应。实际挡着, 对2ASK系统而言,在大信噪比条件下通常使用包络检测法进行非相干解调,而在小信噪比条件 下,通常使用同步检测法进行相干解调。
采用三种不同方法解调OOK信号的性能比较: 例:
目录
一、前言
二、ffmpeg解码API介绍
三、ffmpeg解码示例
四、ffmpeg解码框架设计
《ffmpeg解码H264/H265为yuv代码实现》链接:
https://edu.csdn.net/learn/38258/606144?spm=1003.2001.3001.4157
一、前言 当下音视频开发中解码视频的方案有很多,比如GPU解码器、CPU解码等。其中CPU解码通常使用纯软件的方法对视频解码。ffmpeg是最受欢迎的一款开源解码库。ffmpeg不仅仅支持视频解码还支持视频的编码、以及音频的编解码、同时还支持图像滤波处理以及音视频文件的转封装等。 ffmpeg github路径:GitHub - FFmpeg/FFmpeg: Mirror of https://git.ffmpeg.org/ffmpeg.git在本文中重点介绍如何使用ffmpeg解码H264/H265视频,并输出YUV420的格式。
二、ffmpeg解码API介绍 1、AVCodec *avcodec_find_decoder(enum AVCodecID id);
该函数用于查找一个解码器,并返回解码器。输入参数id为解码器的枚举值,AVCodecID中定义了上百中编解码器ID。H264和H265的ID值如下。
enum AVCodecID { ...... AV_CODEC_ID_H264, ...... AV_CODEC_ID_HEVC, #define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC ...... }; 返回值为AVCodec 类型的指针。AVCodec为解码器属性的结构体,定义如下。
/** * AVCodec. */ typedef struct AVCodec { /** * Name of the codec implementation. * The name is globally unique among encoders and among decoders (but an * encoder and a decoder can share the same name).
遇到这种问题不要慌,双击Ps软件打开,然后趁软件还没反应过来的时候快速按住Shift+Ctrl+Alt,
就会弹出以下信息,我们确定就可以了。
然后
重新打开即可。
http://blog.csdn.net/pipisorry/article/details/39909057
本博客一直在同步更新中!
内容包含:pycharm学习技巧 Learning tips、PyCharm3.0默认快捷键(翻译的)、pycharm常用设置、pycharm环境和路径配置、Pycharm实用拓展功能:pycharm中清除已编译.pyc中间文件、python2转python3最快方式
[pycharm版本控制和数据库管理][PyCharm中的那些实用功能]
pycharm学习技巧 Learning tips /pythoncharm/help/tip of the day:
A special variant of the Code Completion feature invoked by pressing Ctrl+Space twice allows you to complete the name of any class no matter if it was imported in the current file or not. If the class is not imported yet, the import statement is generated automatically.
You can quickly find all places where a particular class, method or variable is used in the whole project by positioning the caret at the symbol's name or at its usage in code and pressing Alt+Shift+F7 (Find Usages in the popup menu).
排查bigkey 过大的 Value 会引发数据倾斜、热点Key、实例流量或 CPU 性能被占满等问题,这个时候就需要排查 Redis 的大key去优化业务了,下面提供一些排查方案总结。
多大的 key 算大呢?
一个STRING类型的Key,它的值为5MB(数据过大)一个LIST类型的Key,它的列表数量为20000个(列表数量过多)一个ZSET类型的Key,它的成员数量为10000个(成员数量过多)一个HASH格式的Key,它的成员数量虽然只有1000个但这些成员的value总大小为100MB(成员体积过大) 如何查询key大小?
MEMORY USAGE 命令给出一个 key 和它的值在 RAM 中所占用的字节数。
> memory usage testk 51 1.使用命令 --bigkeys –bigkeys 是 redis 自带的命令,对整个 Key 进行扫描,统计 string,list,set,zset,hash 这几个常见数据类型中每种类型里的最大的 key。
–bigkeys 是以 scan 延迟计算的方式扫描所有 key,因此执行过程中不会阻塞 redis,但实例存在大量的 keys 时,命令执行的时间会很长,这种情况建议在 slave 上扫描。
Linux:
redis-cli -h 127.0.0.1 -p 6379 -a "password" --bigkeys Windows:
./redis-cli.exe -h 127.0.0.1 -p 6379 -a "password" --bigkeys 2.使用 Rdbtools 工具包 Rdbtools 是 python写的 一个第三方开源工具,用来解析 Redis 快照文件。除了解析 rdb 文件,还提供了统计单个 key 大小的工具。
文中截图为16.6的软件截图,16.6与17.4的操作逻辑基本相同,大家无需担心。后续文章会使用17.4的截图。
1操作环境准备
1.1单位设置
可以将全局单位设置为mil,精度改为2位,也可以设置为mm,这时精度改为4位,这个根据习惯而定。 操作步骤为:setup-design parameters-design:
1.2画布面积设置
在这里设置Allegro软件的画图界面的大小,包括设置显示的长宽和显示画面的左下角的坐标。这里通常设置得比我们的板框更大一些,方便我们布局的时候摆器件。这里选择单位为mm会比较直观,如下将长宽设置为500mm x 500mm,左下角左边设置为(-150,-150)。 操作步骤为:setup-design parameters-design:
1.3软件显示设置
将需要软件显示的内容打开,通常在setup-design parameters-display界面,将所有项目都勾选。从上到下的含义依次为:显示金属化过孔(如果不勾选则看不到孔,只能看到表层的regular pad和mask)、显示非金属化过孔、显示无盘孔、显示连接点、焊盘填充、Connect line endcaps(如果不勾选则走线的拐角显示不连续,如下图例)、显示热风焊盘、显示总线飞线、显示忽略的DRC、显示过孔符号、显示原点、在3D viewer中使用第三方的step模型。
1.4布局显示设置
Allegro软件里面有很多层,显示了很多器件级、板级的内容,在布局布线时,为了使我们操作的时候界面更清晰,不需要打开这么多的内容,可以在颜色管理器里面进行关闭。
操作步骤为:
1、setup-colors,弹出如下界面,点击off关闭所有显示:
2、在board geometry里勾选outline,打开板框显示:
3、在package geometry里勾选silkscreen_top、silkscreen_bottom,打开元器件的丝印显示。
4、在component中勾选silkscreen_top、silkscreen_bottom的refdes,打开元器件位号丝印显示。通常情况下布局时使用原理图与PCB协同操作不需要打开位号显示。
5、在stack-up中勾选顶底层的pin、via、etch、drc。显示打开这些内容就可以进行布局操作了。
6、如上所有步骤中的显示内容中的颜色都可以更改,将不同内容设置为不同颜色更方便进行操作,这个依据个人喜好而定。
1.5格点设置
一般使用mil单位,在进行布局时,格点设置为25mil,在走线层将格点设置为5等份。
操作步骤为:setup-grid,勾选grid on打开格点显示。打开后若发现没有分5等份的小格点,只需要点击一下长度测量工具show measure即可显示,这个操作是需要将当前活动层切换到电气层,用其他能切换到电气层的操作也可以。
1.6大十字光标设置
在布局时使用大十字光标,可以方便进行器件对齐。
操作步骤为: setup-User Perferences-display-cursor,勾选infinite_cursor_bug_nt,pcb_cursor可选菜单,若选择cross,则是十字小光标,若选择infinite,则是十字大光标,若选择octal,则是米子大光标。
1.7快捷键设置
在软件中设置一些常用命令的快捷键可以加快设计效率,快捷键设置定义文件在如下位置:C:\Cadence\SPB_16.6\share\pcb\text 。记事本打开此目录下的env文件,修改此文本。添加快捷键的方法如下:
命令:alias/funckey 快捷键 操作命令
一般组合键使用alias,单键使用funckey。如常用的有:
funckey g move //g移动
funckey " " iangle 90 //空格旋转90度
funckey q rats net //q显示飞线
funckey a add connect //a添加走线
funckey s slide //s调整走线
Mybatis Plus 多表联查(包含分页关联查询,图文讲解) 更新时间 2023-01-03 21:41:38 大家好,我是小哈。
本小节中,我们将学习如何通过 Mybatis Plus 实现多表关联查询,以及分页关联查询。
表结构 本文以查询用户所下订单,来演示 Mybatis Plus 的关联查询,数据库表除了前面小节中已经定义好的用户表外,再额外创建一张订单表,然后插入一些测试数据,执行脚本如下:
DROP TABLE IF EXISTS user; CREATE TABLE `t_user` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(30) NOT NULL DEFAULT '' COMMENT '姓名', `age` int(11) NULL DEFAULT NULL COMMENT '年龄', `gender` tinyint(2) NOT NULL DEFAULT 0 COMMENT '性别,0:女 1:男', PRIMARY KEY (`id`) ) COMMENT = '用户表'; INSERT INTO `t_user` (`id`, `name`, `age`, `gender`) VALUES (1, '犬小哈', 30, 1); INSERT INTO `t_user` (`id`, `name`, `age`, `gender`) VALUES (2, '关羽', 46, 1); INSERT INTO `t_user` (`id`, `name`, `age`, `gender`) VALUES (3, '诸葛亮', 26, 1); CREATE TABLE `t_order` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID', `order_id` bigint(20) UNSIGNED NOT NULL COMMENT '订单ID', `user_id` bigint(20) UNSIGNED NOT NULL COMMENT '下单用户ID', `goods_name` varchar(30) NOT NULL COMMENT '商品名称', `goods_price` decimal(10,2) NOT NULL COMMENT '商品价格', PRIMARY KEY (`id`), INDEX idx_order_id(`order_id`) ) COMMENT = '订单表'; INSERT INTO `t_order` (`id`, `order_id`, `user_id`, `goods_name`, `goods_price`) VALUES (1, 805646264648356, 1, 'Switch 游戏机', 1400.
由于安装yarn 时出现报错如上图
试试
实在不行建议重新安装nodejs再安装yarn,建议使用nodejs老版本比较稳定。
文章目录 前言CUDA流在默认流中重叠主机与设备用非默认CUDA流重叠多个核函数的执行重叠多个核函数的例子 用非默认CUDA流重叠核函数的执行与数据传递不可分页主机内存与异步的数据传输函数 总结参考 前言 CUDA程序的并行层次主要有两个,一个是核函数内部的并行,一个是核函数外部的。合理使用CUDA流能实现核函数外部的并行。
CUDA流 核函数外部并行:
(1)核函数计算与数据传输之间的并行
(2)主机计算与数据传输之间的并行
(3)不同数据传输之间的并行
(4)核函数计算与主机计算之间的并行
(5)不同核函数之间的并行
CUDA流:一个CUDA流指的是由主机发出的在一个设备中执行的CUDA操作序列。CUDA流各个操作的次序是由主机控制的,按照主机发布的次序执行。两个不同的CUDA流中的操作不一定按照顺序执行,和线程一样,要么并发要么交错地执行。
任何CUDA操作都存在于某个CUDA流中,要么是默认流和空流,要么是指定地非空流。前面的CUDA程序没有指定的都是默认和空流中执行的。
非默认的CUDA流实在主机端产生与销毁的。
// 创建 cudaError_r cudaStreamCream_t(cudaStream_t*); // 在yolov5_trt中使用过 // 销毁 cudaError_r cudaStreamDestroy(cudaStream_t); 由创建的代码可知,输入参数是cudaStream_t类型指针,返回值类型是一个错误代码。
不同CUDA流之间的并发
主机向某个CUDA流中发布一系列命令后必须马上获得程序的控制权,不用等待该CUDA流中的命令在设备中执行完毕。这样,就可以通过主机生成多个独立的CUDA流。
同时,CUDA运行时API还提供了两个函数:
// 这两个函数和等待和守护线程有点像 // 会强制阻塞主机,知道cuda流stream中的所有操作都执行完毕。 cudaError_r cudaStreamSynchronize(cudaStream_t stream); // 不阻塞主机,只是检查CUDA流stream中的所有操作是否都执行完毕。 cudaError_r cudaStreamQuery(cudaStream_t stream); 在默认流中重叠主机与设备 合理利用主机与设备之间的执行次序。如前面的简单的数组求和的核函数:
// 将某些数据从主机复制到设备上 cudaMemcpy(d_x,h_x,M,cudaMemcpyHostToDevice); cudaMemcpy(d_y,h_y,M,cudaMemcpyHostToDevice); // 调用核函数在设备中进行计算,数组求和 const int block_size = 128; // 不同型号的GPU有线程限制,开普勒到图灵最大为1024 const int gride_size = N/block_size; add<<<gride_size,block_size>>>(d_x,d_y,d_z); // 将某些数据从设备复制到主机上,这个数据传输函数隐式的起到了同步主机与设备的作用,所以后面用不用cudaDeviceSynchronize都可以 cudaMemcpy(h_z,d_z,M,cudaMemcpyDeviceToHost); 从主机看,数据传输是同步的。在主机执行核函数之前的CUDA操作语句将在默认的CUDA流中按代码的顺序执行。在进行数据传输时,主机是闲置的,不能进行其他操作。
不同的是,在执行核函数时,核函数的启动是异步的。主机发出执行的命令,不会等核函数执行完毕,而会立刻的到程序的控制权,往下执行。执行到从设备到主机传输数据这条语句,该语句不会立即执行。因为这是默认流中的CUDA操作,必须等待前一个CUDA操作执行完毕才会开始执行。
从上面的分析可知,核函数启动异步,对默认流中CUDA的操作会阻塞,但是对主机中的程序不会进行阻塞。如果调用核函数下一句是主机中的某个计算任务,那么主机就会在设备执行核函数的同时去进行一些计算。这样主机和设备就可以同时进行计算。
目录
ASPP结构介绍
ASPP在代码中的构建
参考资料
ASPP结构介绍 ASPP:Atrous Spatial Pyramid Pooling,空洞空间卷积池化金字塔。
简单理解就是个至尊版池化层,其目的与普通的池化层一致,尽可能地去提取特征。
利用主干特征提取网络,会得到一个浅层特征和一个深层特征,这一篇主要以如何对较深层特征进行加强特征提取,也就是在Encoder中所看到的部分。
它就叫做ASPP,主要有5个部分:
1x1卷积膨胀率为6的3x3卷积膨胀率为12的3x3卷积膨胀率为18的3x3卷积对输入进去的特征层进行池化 接着会对这五个部分进行一个堆叠,再利用一个1x1卷积对通道数进行调整,获得上图中绿色的特征。
ASPP在代码中的构建 import torch import torch.nn as nn import torch.nn.functional as F class ASPP(nn.Module): def __init__(self, dim_in, dim_out, rate=1, bn_mom=0.1): super(ASPP, self).__init__() self.branch1 = nn.Sequential( nn.Conv2d(dim_in, dim_out, kernel_size=(1,1), stride=(1,1), padding=0, dilation=rate, bias=True), nn.BatchNorm2d(dim_out, momentum=bn_mom), nn.ReLU(inplace=True), ) self.branch2 = nn.Sequential( nn.Conv2d(dim_in, dim_out, kernel_size=(3,3), stride=(1,1), padding=6 * rate, dilation=6 * rate, bias=True), nn.BatchNorm2d(dim_out, momentum=bn_mom), nn.ReLU(inplace=True), ) self.branch3 = nn.
一维数组逻辑挑战—一个萝卜一个坑问题
从键盘输入0-9的五个数,然后输出0-9中那些没有出现过的数
一维数组初始化的两种方式:
1:
for (i = 0; i < 10; i++)
{
a[i] = 0;//初始化每一个小房间为0
}
2:
int a[10]={0};
顺序:
#include<stdio.h> int main() { int a[10], i,t; for (i = 0; i < 10; i++) { a[i] = 0;//初始化每一个小房间为0 } for (i = 1; i <= 5; i++) { scanf("%d", &t);//依次读入五个0-9的数 a[t] = 1;//把对应的小房间改为1 } for (i = 0; i < 10; i++) { if (a[i] == 0) { printf("
【论文速递】CVPR2021 - 通过解耦特征的目标检测知识蒸馏 【论文原文】:Distilling Object Detectors via Decoupled Features
获取地址:https://arxiv.org/abs/2103.14475 博主关键词: 目标检测,知识蒸馏
推荐相关论文:
无 摘要: 知识蒸馏是一种广泛使用的范式,用于将信息从复杂的教师网络继承到紧凑的学生网络并保持强劲的表现。与图像分类不同,目标检测器更加复杂,具有多个损失函数,其中语义信息所依赖的特征是混乱的。在本文中,我们指出,从排除目标的区域获得的特征信息对于提取学生检测器也是必不可少的,这在现有方法中通常被忽略。此外,我们阐明了在蒸馏过程中应为来自不同地区的特征分配不同的重要性。为此,我们提出了一种通过解耦特征(DeFeat)的新型蒸馏算法,用于学习更好的学生检测器。具体来说,处理两个级别的解耦特征,以便将有用的信息嵌入到学生中,也就是从颈部分离特征,从分类头分离建议。在具有不同骨干的各种检测器上进行的广泛实验表明,所提出的DeFeat能够超越最先进的蒸馏方法进行目标检测。例如DeFeat将基于ResNet50的Faster R-CNN从37.4%提高到40.9% mAP,并将基于ResNet50的RetinaNet从 COCO 基准测试的36.5%提高到39.7%。我们的工具可在 https://github.com/ggjy/DeFeat.pytorch 获得。
简介: 作为计算机视觉的基本任务之一,目标检测在包括自动驾驶和监控视频分析在内的各种实际应用中越来越受到关注。深度学习的最新进展引入了许多基于卷积神经网络的目标检测解决方案。检测器的骨干通常由繁重的卷积操作组成,以产生对检测精度至关重要的密集特征。但这样做不可避免地会导致计算资源成本急剧增加,检测速度明显下降。已经开发了诸如量化[19,58,31,57,62],剪枝[2,17,20],网络设计[55,49,15,18]和知识蒸馏[56,6]等技术来克服这一困境并实现对检测任务的有效推理。我们对知识蒸馏特别感兴趣[24],因为当有经过性能验证的教师网络可用时,它提供了一种优雅的方式来学习紧凑的学生网络。首先针对分类任务开发经典知识蒸馏方法,以确定图像属于哪个类别。来自软标签输出[24, 28, 38, 13]或优化良好的教师网络的中间特征[1,23,66]的信息已被很好地用于学习学生网络,但这些方法不能直接扩展到需要进一步找出对象位置的检测任务。
在对象检测任务中有一些研究知识蒸馏的尝试。例如,FGFI [56] 要求学生网络在近对象定位点位置上模仿教师网络。TADF [47] 通过颈部特征中的高斯掩蔽物体区域和检测头中的阳性样本来提炼学生。这些工作只是从对象区域提取知识,因为背景区域被认为在检测任务中不感兴趣。直观地说,在蒸馏过程中,背景区域可能会引入大量噪声,并且很少被探索。但是在进行蒸馏时缺乏对背景区域的彻底分析。因此,草率决定丢弃背景区域可能并不明智。最重要的是,背景信息已被证明有助于视觉识别[53,46,9,16]。与其猜测背景区域对蒸馏毫无用处甚至有害,不如对背景进行公平彻底的分析,让事实说话。
我们首先通过比较两种方法来研究目标和背景区域在知识蒸馏中的作用:(i)仅通过目标区域FPN特征进行蒸馏,(ii)仅通过背景区域FPN特征进行蒸馏。人们理所当然地认为,当通过教师检测器的背景区域蒸馏时,学生不会得到显着增强,因为背景信息量较小且嘈杂[56]。然而,在对各种模型和数据集进行大量实验后,我们观察到一个令人惊讶的结果,即仅通过背景区域特征蒸馏学生也可以显着提高学生的能力,甚至可以达到与通过对象区域蒸馏相当的结果(图4)。我们通过提炼背景功能进一步探索性能改进的来源。以COCO的两个类别为例(见图1),我们进行了误差分析[25],发现通过背景区域蒸馏有效地减少了背景误报的数量。
Fig. 1. Error analyses of different distillation methods on COCO minival. KD via background regions alleviates the false positiverate and achieves comparable result with KD via object regions. Cor: correct class (IoU > 0.5). Loc: correct class but misalignedbox (0.
神经网络(模型)量化介绍 - PTQ 和 QAT 1. 需求目的2. 量化简介3. 三种量化模式3.1 Dynamic Quantization - 动态量化3.2 Post-Training Static Quantization - 训练后静态量化3.3 Quantization Aware Training - 量化感知训练 4. PTQ 和 QAT 简介5. 设备和运算符支持6. 选择一种方法7. 性能结果8. 精度结果9. 结论参考资料 1. 需求目的 在开发机器学习应用程序时,有效利用服务器端和设备上的计算资源非常重要。为了支持在服务器和边缘设备上更高效的部署,对模型量化的支持将变的更加重要。
量化利用8位整数(int8)指令来减小模型大小并更快地运行推断(减少延迟),并且可以是实现服务质量目标或甚至适合移动设备上可用资源的模型之间的差异。即使在资源不太受限的情况下,它也可以使您部署更大、更准确的模型。
2. 量化简介 量化主要是一种加速推理的技术,量化运算符仅支持前向传递。量化是指使用精度较低的数据进行计算和内存访问的技术,与浮点实现相比,通常是 int8。这可以在几个重要领域实现性能提升:
模型尺寸缩小 4 倍;内存带宽减少 2-4 倍;由于内存带宽的节省和使用 int8 算法的更快计算,推理速度提高了 2-4 倍(确切的加速取决于硬件、运行时和模型)。 然而,量化并非没有额外代价。从根本上说,量化意味着引入近似值,由此产生的网络精度略低。这些技术试图最小化完整浮点精度和量化精度之间的差距。
3. 三种量化模式 3.1 Dynamic Quantization - 动态量化 PyTorch支持的最简单的量化方法称为动态量化。这不仅涉及将权重转换为int8(正如所有量化变量中所发生的那样),而且还涉及在执行计算之前将激活转换为int 8(因此为“动态”)。因此,将使用高效的int8矩阵乘法和卷积实现来执行计算,从而实现更快的计算。然而,激活是以浮点格式读取和写入内存的。
3.2 Post-Training Static Quantization - 训练后静态量化 通过将网络转换为同时使用整数算术和int8内存访问,可以进一步提高性能(延迟)。静态量化执行额外的步骤,首先通过网络输入数据批,并计算不同激活的结果分布(具体来说,这是通过在记录这些分布的不同点插入“观察者”模块来完成的)。该信息用于确定不同的激活应该在推断时量化的具体程度(一种简单的技术是将整个激活范围简单地划分为256个级别,但我们也支持更复杂的方法)。重要的是,这一附加步骤允许我们在操作之间传递量化值,而不是在每个操作之间将这些值转换为浮点值,然后再转换为整数,从而大大加快了速度。
在PyTorch中,支持几个允许用户优化静态量化的功能:
观察者:可以自定义观察者模块,指定如何在量化之前收集统计信息,以尝试更高级的方法来量化数据。运算符融合:可以将多个操作融合为一个操作,节省内存访问,同时提高操作的数值精度。每通道量化:我们可以在卷积/线性层中独立量化每个输出通道的权重,这可以以几乎相同的速度获得更高的精度。 3.
项目场景: 提示:这里简述项目相关背景:
java 项目在 idea 中可正常启动,但在启动时 日志信息中 ERROR 相关信息出现,日志打印中 有红色error 信息出现,并且有相关 名称出现
问题描述 提示:这里描述项目中遇到的问题:
java 项目在 idea 中可正常启动,但在启动时 日志信息中 ERROR 相关信息出现
报错信息如下:
MyBatisPlus启动时报 mapper[xxx] is ignored, because it’s exists, maybe from xml file
报错信息含义:
MyBatisPlus启动时报 映射器[xxx]被忽略,因为它存在,可能来自xml文件
错误信息:
根据日志信息,大致可以定位到具体是哪个文件相关的问题~~~
原因分析: 提示:这里填写问题的分析:
根据报错提示信息,我们大致可定位 到相关的 xml 文件中,
注:解决问题之前我们首先需要大体分析其执行过程。Mybatisplus 执行逻辑大体和mybatis一样,只是在启动过程中会生成一些默认的SQL下面研究其生成默认SQL的过程。
解决方案: 提示:这里填写该问题的具体解决方案:
解决方案:
进入数据库查询 dao层,把getSess ionInfoByWebChat这个方法名称换掉,换一个其它的名称,(不与该名称重复即可),问题就迎刃而解了!