微信搜索逆锋起笔关注后回复编程pdf
领取编程大佬们所推荐的 23 种编程资料!
安装好 Intellij idea 之后,进行如下的初始化操作,工作效率提升十倍。
1
插件
1. Codota 代码智能提示插件
只要打出首字母就能联想出一整条语句,这也太智能了,还显示了每条语句使用频率。
原因是它学习了我的项目代码,总结出了我的代码偏好。
如果让它再加上机器学习,人工智能写代码的时代还会远吗?
2. Key Promoter X 快捷键提示插件
每次都会在右下角弹窗提示,帮助我们快速熟悉快捷键。
3. CodeGlance 显示代码缩略图插件
当代码很多的时候,方便查看,很有用。
4. Lombok 简化臃肿代码插件
实体类中的get/set/构造/toString/hashCode等方法,都不需要我们再手动写了
5. Alibaba Java Coding Guidelines 阿里巴巴代码规范检查插件
会按照阿里Java开发手册上规范帮我们检查代码,然后对代码做不同颜色展示,鼠标放上去,会看到提示内容,帮助我们写出更规范的代码。
6. CamelCase 驼峰命名和下划线命名转换
这几种风格的命名方式,用快捷键 ⇧ + ⌥ + U / Shift + Alt + U可以进行快速转换,当我们需要修改大量变量名称的时候很方便。
7. MybatisX 高效操作Mybatis插件
8. SonarLint 代码质量检查插件
提示我不要用System.out输出,要用logger输出,诸如此类,帮助我们提升代码质量。
9. Save Actions 格式化代码插件
可以帮忙我们优化包导入,自动给没有修改的变量添加final修饰符,调用方法的时候自动添加this关键字等,使我们的代码更规范统一。
10. CheckStyle 代码风格检查插件
功能跟Alibaba Java Coding Guidelines类似
具体报错如下:
java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-java-8.0.18.jar:8.0.18] at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.18.jar:8.0.18] at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) ~[mysql-connector-java-8.0.18.jar:8.0.18] at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63) ~[mysql-connector-java-8.0.18.jar:8.0.18] at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73) ~[mysql-connector-java-8.0.18.jar:8.0.18] at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76) ~[mysql-connector-java-8.0.18.jar:8.0.18] at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836) ~[mysql-connector-java-8.0.18.jar:8.0.18] at com.
Tornado不仅仅是一个WEB框架,也可以是一个WEB服务器。
在Tornado中我们可以使用wsgi模块下的WSGIContainer类运行其他WSGI应用如:Fask, Bottle, Django。
首先我们写一个最小的Flask应用
# hello.py from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" 编写Tornado服务器
# run.py from tornado.wsgi import WSGIContainer from tornado.httpserver import HTTPServer from tornado.ioloop import IOLoop from hello import app http_server = HTTPServer(WSGIContainer(app)) http_server.listen(8008) IOLoop.instance().start() 我们创建了一个HTTP服务器实例http_server,因为服务器要服务于我们刚刚创建的WEB应用,将接收到的客户端请求通过WEB应用中的路由映射表引导到对应的handler中,所以在构建http_server对象的时候需要传入WEB应用对象app。可以使用自身的WEB框架,如果使用托管的应用,将要托管的应用以参数的形式传入到WSGIContainer类中。
http_server = HTTPServer(WSGIContainer(app)) 我们定义这个服务器监听的端口为8008
http_server.listen(8008) IOLoop是Tornado的核心I/O循环调度模块,也是tornado高性能的基石,封装了Linux的epoll和BSD的kqueue,用于处理socket相关的连接、响应、异步读写等网络事件。每个Tornado进程都会初始化一个全局唯一的IOLoop实例,在IOLoop中通过静态方式instance()进行封装,获取IOLoop实例直接调用此方法即可启动IOLoop实例,即启动事件循环机制,配合非阻塞的HTTP Server工作。
如果是tornado.ioloop.IOLoop.current().start()语句,IOLoop.current()返回当前线程的IOLoop实例。IOLoop.start()启动IOLoop实例的I/O循环,同时服务器监听被打开
IOLoop.instance().start() 完成之后直接允许即可
python run.py
this 深度解析 这是《你不知道的JavaScript》第三节,深入了解 this 的含义,以及如何判断 this 的指向。
this 是什么 首先我们要知道 this 到底是什么。我认为,this 更像是一个关键字,他最终可能会指向某个对象(也有可能指向undefined)。在函数中,this 只在函数调用的时候才确定其最终指向的对象,当我们在函数中对 this 进行操作的时候,实际是操作 this 指向的变量。
这里会有一些误区:
误区1:this 指向函数本身,这种想法是错的,虽然从 this 的字面含义的确有这层意思。
误区2:this 指函数的作用域,这是初学者比较容易弄混 this 和作用域的概念。诚然在某种情况下,this 可能会指向作用域,但这不代表 this 是函数的作用域。
用简单的示例你就能明白
function a() { let name = 'this' console.log(this.name) this.age = 20 console.log(a.age) } a() // log: // undefined // undefined 如果 this 指向函数,那么 this.age = 20 中 age 最终应该会挂载到 a.age 中。如果 this 指向函数作用域,那么 this.name 应该可以访问到作用域中定义的 name 值。但实际都无法获取到。
this 指向 那么 this 实际指向谁,只需遵循下面几个原则,你就能很快判断 this 指向谁
vue 中 key 值的作用可以分为两种情况来考虑。 第一种情况是 v-if 中使用 key 。由于 Vue 会尽可能高效地渲染元素,通常会复用已有元素而 不是从头开始渲染。因此当我们使用 v-if 来实现元素切换的时候,如果切换前后含有相同类 型的元素,那么这个元素就会被复用。如果是相同的 input 元素,那么切换前后用户的输入不 会被清除掉,这样是不符合需求的。因此我们可以通过使用 key 来唯一的标识一个元素,这个 情况下,使用 key 的元素不会被复用。这个时候 key 的作用是用来标识一个独立的元素。 第二种情况是 v-for 中使用 key 。用 v-for 更新已渲染过的元素列表时,它默认使用 “ 就地 复用 ” 的策略。如果数据项的顺序发生了改变, Vue 不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处的每个元素。因此通过为每个列表项提供一个 key 值,来以便 Vue 跟踪元 素的身份,从而高效的实现复用。这个时候 key 的作用是为了高效的更新渲染虚拟 DOM 。 扫码活着微信搜索《最新热门信息汇总》小程序给个支持,谢谢啊,扫码也可以奥
最近用到了SynchronousQueue,也在网上查阅了相关资料,总感觉有些话说得让人费解,下面结合自己的理解总结下。
1、一个不存储元素的阻塞队列。这句话就让我困惑了,不存储元素,那元素保存到哪里了?通过阅读源码,以非公平模式为例:
...
casHead(h, s = snode(s, e, h, mode))
...
static SNode snode(SNode s, Object e, SNode next, int mode) {
if (s == null) s = new SNode(e);
s.mode = mode;
s.next = next;
return s;
}
...
Thread w = Thread.currentThread();
...
else if (s.waiter == null)
s.waiter = w;
实际上元素还是保存下来了(不考虑take操作,可以暂时理解为链表),而且把调用put方法的线程也保存了。通过调试也可看到SynchronousQueue对象信息:
说明:启用了线程 put-t1放入整型数据1和线程put-t2放入整型数据2,put-t1先执行。通过阅读源码,发现其size()方法返回固定值0,为什么会这样呢?通过本文第3点分析,SynchronousQueue会存储放数据的节点和取数据的节点,这时候获取的长度是无效的,没有任何意义,所以返回了0,但“不存储元素”表述不准确。 2、SynchronousQueue吞吐量高于LinkedBlockingQueue和ArrayBlockingQueue。这种必然是有前提的,put(生产者)和take(消费者)效率一致。否则,生产者和消费者互相等待,吞吐量会手影响。
3、SynchronousQueue作为一个空集合,此队列不允许 null 元素。对于这句话我同样无法理解,为什么?看看源码,比较put和take操作:
put操作时,...transferer.transfer(e, false, 0)...;
take操作时,...E e = transferer.transfer(null, false, 0)...;
概述 先上一张JAVA集合继承关系图:
使用Map时,用得最多的是HashMap
Map<String, String> hashMap = new HashMap<String, String>(); 但是HashMap是无序的,既不保证元素按插入顺序性,也不保证元素按给定的排序方法按大小进行排序。
HashMap无序 HashMap的底层实现是哈希映射,所以表现为Hash的特点,不具有有序性
代码实例 public class Test { public static void main(String[] args) throws Exception { Map<String, String> hashMap = new TreeMap<>(); hashMap.put("a1", "6"); hashMap.put("b1", "9"); hashMap.put("d1", "8"); hashMap.put("c1", "7"); Iterator<Map.Entry<String , String >>iterator = hashMap.entrySet().iterator(); while (iterator.hasNext()){ Map.Entry<String, String> entry = iterator.next(); System.out.println("key " + entry.getKey() + " --- value " + entry.getValue()); } } } 输出结果
key a1 --- value 6 key b1 --- value 9 key c1 --- value 7 key d1 --- value 8 可以看出HashMap既没有插入顺序性,也不具有大小上的顺序性
6.pth2onnx.py import sys import onnx import os import argparse import numpy as np import cv2 import onnxruntime import torch from tool.utils import * from models import Yolov4 def detect(session, image_src): IN_IMAGE_H = session.get_inputs()[0].shape[2] IN_IMAGE_W = session.get_inputs()[0].shape[3] # Input resized = cv2.resize(image_src, (IN_IMAGE_W, IN_IMAGE_H), interpolation=cv2.INTER_LINEAR) img_in = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB) img_in = np.transpose(img_in, (2, 0, 1)).astype(np.float32) img_in = np.expand_dims(img_in, axis=0) img_in /= 255.0 print("Shape of the network input: ", img_in.shape) # Compute input_name = session.
参考链接:
https://github.com/Tianxiaomo/pytorch-YOLOv4
模型训练+推理步骤:
1. 下载代码和预训练模型,准备数据
2. 数据预处理:使用data_process的脚本进行自己标注的数据进行处理
3. 训练模型(需要修改train.py/cfg.py/dataset.py/以及tool中关于数据预处理的相关定义,请看代码去改)
4. 测试模型(修改test.py进行预测)
5. pytorch模型转onnx模型(修改pytorch2onnx.py)
6. onnx模型删减(修改dy_resize.py,删减不支持的算子)
7. onnx转om模型(atc命令如下)
8. 测试om模型(修改pyacl代码,本地代码没用等比例缩放,主要修改acl_dvpp.py的数据预处理)
9. 对比结果(把om模型的输出拿出来,放到test_onnx.py / test_om.py中测试,对比本地模型和atlas模型的检测结果)
一、数据处理 数据处理和数据样例请参考上一篇文章:
https://blog.csdn.net/gm_Ergou/article/details/118599118
二、模型训练 这里只贴出修改过的关键代码,其余代码可从参考链接下载:
https://github.com/Tianxiaomo/pytorch-YOLOv4
代码结构:
1.train.py # -*- coding: utf-8 -*- import time import logging import os, sys, math import argparse from collections import deque import datetime import copy import cv2 from tqdm import tqdm import numpy as np import torch import torch.nn as nn from torch.
1.CSPdarknet.py import math from collections import OrderedDict import torch import torch.nn as nn import torch.nn.functional as F #-------------------------------------------------# # MISH激活函数 #-------------------------------------------------# class Mish(nn.Module): def __init__(self): super(Mish, self).__init__() def forward(self, x): return x * torch.tanh(F.softplus(x)) #---------------------------------------------------# # 卷积块 -> 卷积 + 标准化 + 激活函数 # Conv2d + BatchNormalization + Mish #---------------------------------------------------# class BasicConv(nn.Module): def __init__(self, in_channels, out_channels, kernel_size, stride=1): super(BasicConv, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, kernel_size//2, bias=False) self.bn = nn.
概要 在大数据量高并发访问时,经常会出现服务或接口面对暴涨的请求而不可用的情况,甚至引发连锁反映导致整个系统崩溃。此时你需要使用的技术手段之一就是限流,当请求达到一定的并发数或速率,就进行等待、排队、降级、拒绝服务等。
对一般的限流场景来说它具有两个维度的信息:
时间:限流基于某段时间范围或者某个时间点,也就是我们常说的“时间窗口”,比如对每分钟、每秒钟的时间窗口做限定
资源:基于可用资源的限制,比如设定最大访问次数,或最高可用连接数
上面两个维度结合起来看,限流就是在某个时间窗口对资源访问做限制,比如设定每秒最多100个访问请求。但在真正的场景里,我们不止设置一种限流规则,而是会设置多个限流规则共同作用。
主要的几种限流规则如下:
QPS和连接数控制 对于图中连接数和QPS)限流来说,我们可设定IP维度的限流,也可以设置基于单个服务器的限流。
在真实环境中通常会设置多个维度的限流规则,比如设定同一个IP每秒访问频率小于10,连接数小于5,再设定每台机器QPS最高1000,连接数最大保持200。更进一步,我们可以把某个服务器组或整个机房的服务器当做一个整体,设置更high-level的限流规则,这些所有限流规则都会共同作用于流量控制。
传输速率 对于“传输速率”大家都不会陌生,比如资源的下载速度。有的网站在这方面的限流逻辑做的更细致,比如普通注册用户下载速度为100k/s,购买会员后是10M/s,这背后就是基于用户组或者用户标签的限流逻辑。
黑白名单 黑白名单是各个大型企业应用里很常见的限流和放行手段,而且黑白名单往往是动态变化的。举个例子,如果某个IP在一段时间的访问次数过于频繁,被系统识别为机器人用户或流量攻击,那么这个IP就会被加入到黑名单,从而限制其对系统资源的访问,这就是我们俗称的“封IP”。
我们平时见到的爬虫程序,比如说爬知乎上的美女图片,或者爬券商系统的股票分时信息,这类爬虫程序都必须实现更换IP的功能,以防被加入黑名单。有时我们还会发现公司的网络无法访问12306这类大型公共网站,这也是因为某些公司的出网IP是同一个地址,因此在访问量过高的情况下,这个IP地址就被对方系统识别,进而被添加到了黑名单。使用家庭宽带的同学们应该知道,大部分网络运营商都会将用户分配到不同出网IP段,或者时不时动态更换用户的IP地址。
白名单就更好理解了,相当于御赐金牌在身,可以自由穿梭在各种限流规则里,畅行无阻。比如某些电商公司会将超大卖家的账号加入白名单,因为这类卖家往往有自己的一套运维系统,需要对接公司的IT系统做大量的商品发布、补货等等操作。
分布式环境 分布式区别于单机限流的场景,它把整个分布式环境中所有服务器当做一个整体来考量。比如说针对IP的限流,我们限制了1个IP每秒最多10个访问,不管来自这个IP的请求落在了哪台机器上,只要是访问了集群中的服务节点,那么都会受到限流规则的制约。
从上面例子不难看出,我们最好将限流信息保存在一个“中心化”的组件上,这样它就可以获取到集群中所有机器的访问状态,目前有两个比较主流的限流方案:
网关层限流 将限流规则应用在所有流量的入口处
中间件限流 将限流信息存储在分布式环境中某个中间件里(比如Redis缓存),每个组件都可以从这里获取到当前时刻的流量统计,从而决定是拒绝服务还是放行流量
sentinel,springcloud生态圈为微服务量身打造的一款用于分布式限流、熔断降级等组件
限流方案常用算法介绍 说到限流,至少我们需要对限流的底层原理有个大致的了解,才好更深入的进行学习,下面我们挑选令牌桶算法、漏桶算法、滑动窗口和计数器算法来说一下
令牌桶算法 Token Bucket令牌桶算法是目前应用最为广泛的限流算法,顾名思义,它有以下两个关键角色:
令牌 获取到令牌的Request才会被处理,其他Requests要么排队要么被直接丢弃
桶 用来装令牌的地方,所有Request都从这个桶里面获取令牌
用图简单描述如下
主要涉及到2个过程:
令牌生成 这个流程涉及到令牌生成器和令牌桶,前面我们提到过令牌桶是一个装令牌的地方,既然是个桶那么必然有一个容量,也就是说令牌桶所能容纳的令牌数量是一个固定的数值。
对于令牌生成器来说,它会根据一个预定的速率向桶中添加令牌,比如我们可以配置让它以每秒100个请求的速率发放令牌,或者每分钟50个。注意这里的发放速度是匀速,也就是说这50个令牌并非是在每个时间窗口刚开始的时候一次性发放,而是会在这个时间窗口内匀速发放。
在令牌发放器就是一个水龙头,假如在下面接水的桶子满了,那么自然这个水(令牌)就流到了外面。在令牌发放过程中也一样,令牌桶的容量是有限的,如果当前已经放满了额定容量的令牌,那么新来的令牌就会被丢弃掉。
令牌获取 每个访问请求到来后,必须获取到一个令牌才能执行后面的逻辑。假如令牌的数量少,而访问请求较多的情况下,一部分请求自然无法获取到令牌,那么这个时候我们可以设置一个“缓冲队列”来暂存这些多余的令牌。
缓冲队列其实是一个可选的选项,并不是所有应用了令牌桶算法的程序都会实现队列。当有缓存队列存在的情况下,那些暂时没有获取到令牌的请求将被放到这个队列中排队,直到新的令牌产生后,再从队列头部拿出一个请求来匹配令牌。
当队列已满的情况下,这部分访问请求将被丢弃。在实际应用中我们还可以给这个队列加一系列的特效,比如设置队列中请求的存活时间,或者将队列改造为PriorityQueue,根据某种优先级排序,而不是先进先出。
漏桶算法 Leaky Bucket,又是个桶,限流算法是跟桶杠上了,那么漏桶和令牌桶有什么不同呢?我们来看图说话:
漏桶算法的前半段和令牌桶类似,但是操作的对象不同,令牌桶是将令牌放入桶里,而漏桶是将访问请求的数据包放到桶里。同样的是,如果桶满了,那么后面新来的数据包将被丢弃。
漏桶算法的后半程是有鲜明特色的,它永远只会以一个恒定的速率将数据包从桶内流出。打个比方,如果我设置了漏桶可以存放100个数据包,然后流出速度是1s一个,那么不管数据包以什么速率流入桶里,也不管桶里有多少数据包,漏桶能保证这些数据包永远以1s一个的恒定速度被处理。
漏桶 vs 令牌桶的区别
根据它们各自的特点不难看出来,这两种算法都有一个“恒定”的速率和“不定”的速率。令牌桶是以恒定速率创建令牌,但是访问请求获取令牌的速率“不定”,反正有多少令牌发多少,令牌没了就干等。而漏桶是以“恒定”的速率处理请求,但是这些请求流入桶的速率是“不定”的。
从这两个特点来说,漏桶的天然特性决定了它不会发生突发流量,就算每秒1000个请求到来,那么它对后台服务输出的访问速率永远恒定。而令牌桶则不同,其特性可以“预存”一定量的令牌,因此在应对突发流量的时候可以在短时间消耗所有令牌,其突发流量处理效率会比漏桶高,但是导向后台系统的压力也会相应增多。
滑动窗口 根据图示,我们将时间窗口的限流原理拆解描述一下其过程:
黑色的大框就是时间窗口,我们设定窗口时间为5秒,它会随着时间推移向后滑动。我们将窗口内的时间划分为五个小格子,每个格子代表1秒钟,同时这个格子还包含一个计数器,用来计算在当前时间内访问的请求数量。那么这个时间窗口内的总访问量就是所有格子计数器累加后的数值。
比如说,我们在每一秒内有5个用户访问,第5秒内有10个用户访问,那么在0到5秒这个时间窗口内访问量就是15。如果我们的接口设置了时间窗口内访问上限是20,那么当时间到第六秒的时候,这个时间窗口内的计数总和就变成了10,因为1秒的格子已经退出了时间窗口,因此在第六秒内可以接收的访问量就是20-10=10个。
滑动窗口其实也是一种计算器算法,它有一个显著特点,当时间窗口的跨度越长时,限流效果就越平滑。打个比方,如果当前时间窗口只有两秒,而访问请求全部集中在第一秒的时候,当时间向后滑动一秒后,当前窗口的计数量将发生较大的变化,拉长时间窗口可以降低这种情况的发生概率
那么有了上面的基础理论之后,我们来简单总结下目前常用的限流方案有哪些呢?
Guawa限流 说起Guava大家一定不陌生,它是Google出品的一款工具包,我们经常用它做一些集合操作比如Lists.newArrayList()等,它最早源于2007的"Google Collections Library"项目。Guava不甘于将自己平凡的一生都耗费在Collections上面,于是乎它开始了转型,慢慢扩展了自己在Java领域的影响力,从反射工具、函数式编程、安全验证、数学运算等等方面,都提供了响应的工具包
在限流领域中,Guava也贡献了一份绵薄之力,在其多线程模块下提供了以RateLimiter为首的几个限流支持类,但是作用范围仅限于“当前”这台服务器,也就是说Guawa的限流是单机的限流,跨了机器或者jvm进程就无能为力了
比如说,目前我有2台服务器[Server 1,Server 2],这两台服务器都部署了一个登陆服务,假如我希望对这两台机器的流量进行控制,比如将两台机器的访问量总和控制在每秒20以内,如果用Guava来做,只能独立控制每台机器的访问量<=10。
尽管Guava不是面对分布式系统的解决方案,但是其作为一个简单轻量级的客户端限流组件,非常适合来讲解限流算法
网关层限流 在整个分布式系统中,如果有这么一个“一夫当关,万夫莫开”的角色,非网关层莫属。服务网关,作为整个分布式链路中的第一道关卡,承接了所有用户来访请求,因此在网关层面进行限流是一个很好的切入点
4月15日,中国计算机学会(CCF)推荐的A类国际学术会议SIGIR 2021论文接收结果公布。 山东大学软件学院谢翌博士的长文“Learning Domain Semantics and Cross-Domain Correlations for Paper Recommendation”被录用。SIGIR是人工智能领域智能信息检索方向最权威的国际会议。第44届国际计算机学会信息检索大会(The 44th International ACM SIGIR Conference on Research and Development in Information Retrieval, SIGIR 2021)计划于2021年7月11日-7月15日以线上会议形式召开。这次会议共收到720篇长文投稿,仅有151篇长文被录用,录用率约21%。
附:论文介绍
论文题目:Learning Domain Semantics and Cross-Domain Correlations for Paper Recommendation
作者:谢翌,孙宇清,Elisa Bertino
论文概述:理解知识在不同学科之间的技术转移,对于促进学术创新非常重要。实现这一目标要面临两个挑战,即语义歧义和跨学科的不对称学术影响。本文研究了跨学科论文推荐中的知识传播和语义关联特征。我们采用生成模型将论文内容表示为在现有层次化学科分类上的概率关联,以降低语义的歧义。学科间的语义相关性通过影响函数、相关性度量和排序机制来表示。将用户兴趣表示为目标领域语义上的概率分布,并推荐相关论文。在真实数据集上的实验结果表明了该方法的有效性。我们基于可解释性实验讨论了结果的内在因素。与传统的基于词嵌入方法相比,本文方法支持领域语义的演化,从而支持语义关联的更新。本文方法的另一优点是它的灵活性和一致性,可以通过论文列表或关键字查询来支持用户兴趣表示,适用于实际应用场景。
多普勒模糊也称速度模糊,是在PD雷达中当发射脉冲信号频率为低或中脉冲重复频率时,由于采样频率较低而产生的不能准确测量目标多普勒频率的问题。具体原因如下:
多普勒维的采样为慢时间采样,采样频率为脉冲重复频率 f r f_r fr。由奈奎斯特采样定理可知,其采样频率 f r f_r fr应大于被检测目标的最大多普勒频率的两倍。如果采样频率小于运动目标产生的最大多普勒频率的两倍,则会出现对多普勒频率波形的采样率不够大,导致速度模糊,于是推出最大不模糊多普勒频率为 f d m a x = f r / 2 f_{dmax}=f_r/2 fdmax=fr/2,带入多普勒频率计算公式 f d = 2 v λ {{f}_{d}}=\frac{2v}{\lambda } fd=λ2v可得最大不模糊速度 v m a x v_{max} vmax为:
v m a x = λ f d m a x 2 = λ f r 4 v_{max}=\frac{\lambda f_{dmax}}{2}=\frac{\lambda f_{r}}{4} vmax=2λfdmax=4λfr
参考文献:崔宏宇. 脉冲多普勒雷达解模糊方法研究[D].杭州电子科技大学,2019.
web前端期末大作业 ~ 我的家乡-绿城之都html+css+javascript旅游网页设计实例 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大?HTML网页作业无从下手?网页要求的总数量太多?没有合适的模板?等等一系列问题。你想要解决的问题,在这篇博文中基本都能满足你的需求~
原始HTML+CSS+JS页面设计, web大学生网页设计作业源码,这是一个不错的网页制作,画面精明,非常适合初学者学习使用。
作品介绍 1.网页作品简介方面 :绿色简单旅游景点介绍网站,全套模板,包括首页、历史、风景、旅游、美食、动态、留言、团队介绍、联系我们等网站模板页面。
2.网页作品编辑方面:此作品为学生个人主页网页设计题材,代码为简单学生水平 html+css 布局制作,作品下载后可使用任意HTML编辑软件(例如:DW、HBuilder、NotePAD 、Vscode 、Sublime 、Webstorm 所有编辑器均可使用)
3.网页作品布局方面:网页布局整体为LOGO、导航、主体内容布局。子页面多种布局,兴趣爱好内容使用图片列表布局,成绩页面插入了表格,联系我们使用图片对齐方式设置了左对齐。
4.网页作品技术方面:使用CSS制作了网页背景图、鼠标经过及选中导航变色效果、下划线等。 首页制作了留言表单,同时简单使用JavaScript制作了表单判断(提交时表单不能为空)
文章目录 web前端期末大作业 ~ 我的家乡-绿城之都html+css+javascript旅游网页设计实例作品介绍一、作品演示1.首页2.历史3.旅游4.美食5. 留言 二、代码目录三、代码实现四、web前端入门到高级(视频+源码+资料+面试)一整套 (教程)五、源码获取六、更多HTML期末大作业作品文章七、更多表白源码 一、作品演示 1.首页 2.历史 3.旅游 4.美食 5. 留言 二、代码目录 三、代码实现 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>绿城之都-南宁</title> <meta content="绿城之都-南宁" name="keywords" /> <meta content="绿城之都-南宁" name="description" /> <link href="../css/base.css" rel="stylesheet" type="text/css"> <link href="../css/pagename.css" rel="stylesheet" type="text/css"> </head> <body> <!--header--> <div class="header"> <div class="w1000"> <p>你好,欢迎光临绿城之都南宁!</p> <div class="
数据集结构如第一篇文章(keras实现LeNet5)。
1.model.py 构造网络
# coding=utf-8 from keras.models import Model from keras.layers import Input, Dense, BatchNormalization, Conv2D, MaxPooling2D, AveragePooling2D, ZeroPadding2D from keras.layers import add, Flatten, Activation from keras.optimizers import SGD from keras.preprocessing.image import ImageDataGenerator import numpy as np from keras.callbacks import TensorBoard from keras.utils import plot_model seed = 7 np.random.seed(seed) def Conv2d_BN(x, nb_filter, kernel_size, strides=(1, 1), padding='same', name=None): if name is not None: bn_name = name + '_bn' conv_name = name + '_conv' else: bn_name = None conv_name = None x = Conv2D(nb_filter, kernel_size, padding=padding, strides=strides, name=conv_name)(x) x = BatchNormalization(axis=3, name=bn_name)(x) x = Activation('relu')(x) return x def Conv_Block(inpt, nb_filter, kernel_size, strides=(1, 1), with_conv_shortcut=False): x = Conv2d_BN(inpt, nb_filter=nb_filter[0], kernel_size=(1, 1), strides=strides, padding='same') x = Conv2d_BN(x, nb_filter=nb_filter[1], kernel_size=(3, 3), padding='same') x = Conv2d_BN(x, nb_filter=nb_filter[2], kernel_size=(1, 1), padding='same') if with_conv_shortcut: shortcut = Conv2d_BN(inpt, nb_filter=nb_filter[2], strides=strides, kernel_size=kernel_size) x = add([x, shortcut]) return x else: x = add([x, inpt]) return x def creatcnn(): inpt = Input(shape=(224, 224, 3)) x = ZeroPadding2D((3, 3))(inpt) x = Conv2d_BN(x, nb_filter=64, kernel_size=(7, 7), strides=(2, 2), padding='valid') x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x) x = Conv_Block(x, nb_filter=[64, 64, 256], kernel_size=(3, 3), strides=(1, 1), with_conv_shortcut=True) x = Conv_Block(x, nb_filter=[64, 64, 256], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[64, 64, 256], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[128, 128, 512], kernel_size=(3, 3), strides=(2, 2), with_conv_shortcut=True) x = Conv_Block(x, nb_filter=[128, 128, 512], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[128, 128, 512], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[128, 128, 512], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[256, 256, 1024], kernel_size=(3, 3), strides=(2, 2), with_conv_shortcut=True) x = Conv_Block(x, nb_filter=[256, 256, 1024], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[256, 256, 1024], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[256, 256, 1024], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[256, 256, 1024], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[256, 256, 1024], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[512, 512, 2048], kernel_size=(3, 3), strides=(2, 2), with_conv_shortcut=True) x = Conv_Block(x, nb_filter=[512, 512, 2048], kernel_size=(3, 3)) x = Conv_Block(x, nb_filter=[512, 512, 2048], kernel_size=(3, 3)) x = AveragePooling2D(pool_size=(7, 7))(x) x = Flatten()(x) x = Dense(2, activation='softmax')(x) model = Model(inputs=inpt, outputs=x) return model 2.
本章使用tensorflow训练resnet50,使用手写数字图片作为数据集。
数据集:
代码工程: 1.train.py import argparse import cv2 import tensorflow as tf # from create_model import resnet_v2_50 from create_model import resnet_v2_50 import numpy as np from data_loader import get_data, get_data_list from sklearn.metrics import accuracy_score def txt_save(data, output_file): file = open(output_file, 'a') for i in data: s = str(i) + '\n' file.write(s) file.close() def get_parms(): parser = argparse.ArgumentParser(description='') parser.add_argument('--train_data', type=str, default="dataset/train_data.txt") parser.add_argument('--test_data', type=str, default='data/test/') parser.add_argument('--checkpoint_dir', type=str, default='./model/') parser.add_argument('--epoch', type=int, default=5) parser.
web网页设计期末课程大作业~粉色的服装购物商城页面模板 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大?HTML网页作业无从下手?网页要求的总数量太多?没有合适的模板?等等一系列问题。你想要解决的问题,在这篇博文中基本都能满足你的需求~
原始HTML+CSS+JS页面设计, web大学生网页设计作业源码,~这是一个不错的网页制作,画面精明,非常适合初学者学习使用。
作品介绍 关于HTML网页设计期末课程大作业实现,大作业A+水平 ~,共有首页,登录页,瀑布流列表页,详情页带评价带晒单 等4个页面!
此作品为学生个人主页网页设计题材,代码为简单学生水平 html+css 布局制作,作品下载后可使用任意HTML编辑软件(例如:DW、HBuilder、NotePAD, Vscode 所有编辑器均可使用)
网页作品布局方面:网页布局整体为LOGO、导航、轮播图、主体内容布局。子页面多种布局,兴趣爱好内容使用图片列表布局,成绩页面插入了表格,联系我们使用图片对齐方式设置了左对齐。
网页作品技术方面:使用CSS制作了网页背景图、鼠标经过及选中导航变色效果、下划线等。 首页制作了留言表单,同时简单使用JavaScript制作了表单判断(提交时表单不能为空)
空)
文章目录 web网页设计期末课程大作业~粉色的服装购物商城页面模板作品介绍一、作品演示1.首页2. 分类3. 登录4.商品详情 二、代码目录三、代码实现四、前端 `零基础入门到高级 `(视频+源码+开发软件+学习资料+面试题) 一整套 (教程)六、更多HTML期末大作业文章七、更多表白源码 一、作品演示 1.首页 2. 分类 3. 登录 4.商品详情 二、代码目录 三、代码实现 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>登录页面</title> <meta name="keywords" content="[!--pagekey--]" /> <meta name="description" content="[!--pagedes--]" /> <link href="images/all.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="js/jquery.js"></script> <script type="
HTML网页设计结课作业~橙色时尚服装购物商城模板html源码 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大?HTML网页作业无从下手?网页要求的总数量太多?没有合适的模板?等等一系列问题。你想要解决的问题,在这篇博文中基本都能满足你的需求~
原始HTML+CSS+JS页面设计, web大学生网页设计作业源码,~这是一个不错的网页制作,画面精明,非常适合初学者学习使用。
作品介绍 这是一款仿蘑菇街商城网站,里面包括前后台设计,采用了懒加载技术,当用户往下浏览是,商品继续加载
此作品为学生个人主页网页设计题材,代码为简单学生水平 html+css 布局制作,作品下载后可使用任意HTML编辑软件(例如:DW、HBuilder、NotePAD, Vscode 所有编辑器均可使用)
网页作品布局方面:网页布局整体为LOGO、导航、轮播图、主体内容布局。子页面多种布局,兴趣爱好内容使用图片列表布局,成绩页面插入了表格,联系我们使用图片对齐方式设置了左对齐。
网页作品技术方面:使用CSS制作了网页背景图、鼠标经过及选中导航变色效果、下划线等。 首页制作了留言表单,同时简单使用JavaScript制作了表单判断(提交时表单不能为空)
空)
文章目录 HTML网页设计结课作业~橙色时尚服装购物商城模板html源码作品介绍一、作品演示二、代码目录三、代码实现四、前端 `零基础入门到高级 `(视频+源码+开发软件+学习资料+面试题) 一整套 (教程)六、更多HTML期末大作业文章七、更多表白源码 一、作品演示 二、代码目录 三、代码实现 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="renderer" content="webkit"> <meta http-equiv=X-UA-Compatible content=IE=8/> <title>蘑菇街</title> <link rel="stylesheet" href="./css/normalize.css" type="text/css" /> <link rel="stylesheet" href="./css/font-awesome.min.css" type="text/css" /> <link rel="stylesheet" href="./css/bootstrap.css" type="text/css" /> <!-- <link rel="stylesheet" href="./css/index.css" type="text/css" media="screen and (min-width:1000px)"/> --> <!-- <link rel="stylesheet" href="./css/ipa.css"type="text/css"media="screen and (min-width:700px) and (max-width:999px)"
文章目录 简介$refs$parent / \$children$provide / \$inject父传子父传孙子冲突问题 $attrs / \$listener$attrs$listener继承父传孙 总结 简介 这篇文章主要来聊聊,vue 中进行组件之间通信的几种方式。以及一些细节问题和优劣
$refs 通过在组件中绑定 ref=name 属性,我们可以在 this.$refs.name 获取到当前的组件实例。如果 ref 绑定的不是一个组件而是一个 html 元素,那获取到的是 dom 对象。
通过 ref 我们可以获取到子组件的实例,通过获取实例上的属性和方法来进行组件通信
<!-- 父组件 --> <template> <div> <!-- 若 ref 绑定的是普通 html 元素,那获取的对象就是 dom --> <div> <input type="text" ref="input"> <button @click="getDom">get</button> </div> <!-- 若 ref 绑定的是组件,那获取的就是当前的组件实例 --> <div> <child ref="child" /> <button @click="getChild">get</button> <button @click="setInfo">set</button> </div> </div> </template> <script> import child from './child.vue' export default { components: { child }, methods: { getDom() { // 获取 dom 元素,并调用 dom 元素上的成员方法 console.
1.计算图片逆光度
from matplotlib import pyplot as plt import cv2 import numpy as np import os import math def get_fm(file_name): image = cv2.imread(file_name,0) hist = cv2.calcHist([image],[0],None,[256],[0,256]) nums=image.shape[0]*image.shape[1] hist=hist/nums # 总体均值 u=0 for i in range(256): u+=hist[i]*i # print(u) # 总体方差 a=0 for i in range(256): a+=hist[i]*pow((i-u),2) # print(a) # 逆光度 dbl=np.sqrt(a) return dbl # file_name='data2/img/blur (8).jpg' # dbl=get_fm(file_name) # print(dbl) path='img/' for file in os.listdir(path): file_name=path+file dbl=get_fm(file_name) print(file, dbl) 2.图像傅里叶变换