最近在处理一些音频数据,ffmpeg是一款非常好用处理音视频的工具包。那什么是ffmpeg呢?FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序,可以结合Java开发一些处理视频音频的功能。
1.ffmpeg下载 首先打开 ffmpeg官网下载
或者用 百度云 下载(https://pan.baidu.com/s/1dCK-TrOcUfC6pdKi2Y1e6g 提取码:2pdo)
然后点击 windows 对应的图标,再点击下面的 ”Windows EXE File” 随便选一个点进去选择一个版本下载。
2.下载后解压,配置环境变量 下载解压后就能在 bin 文件夹下能看到三个可执行程序:ffmpeg、ffplay、ffprobe,配置好环境变量后即可使用。
验证是否成功:
cmd窗口输入ffmpeg -version 。如下图则安装成功。
3.介绍 FFmpeg 组成 构成FFmpeg主要有三个部分
3.1第一部分是四个作用不同的工具软件,分别是:
ffmpeg.exe、ffplay.exe、 ffprobe.exe。
ffmpeg.exe:音视频转码、转换器ffplay.exe:简单的音视频播放器ffprobe.exe:简单的多媒体码流分析器 3.2第二部分是可以供开发者使用的 SDK,为各个不同平台编译完成的库。
如果说上面的四个工具软件都是完整成品形式的玩具,那么这些库就相当于乐高积木一样,我们可以根据自己的需求使用这些库开发自己的应用程序。这些库有:
libavcodec:包含音视频编码器和解码器
libavutil:包含多媒体应用常用的简化编程的工具,如随机数生成器、数据结构、数学函数等功能
libavformat:包含多种多媒体容器格式的封装、解封装工具
libavfilter:包含多媒体处理常用的滤镜功能
libavdevice:用于音视频数据采集和渲染等功能的设备相关
libswscale:用于图像缩放和色彩空间和像素格式转换功能
libswresample:用于音频重采样和格式转换等功能
3.3第三部分是整个工程的源代码,无论是编译出来的可执行程序还是SDK,都是由这些源代码编译出来的。
FFmpeg 的源代码由C语言实现,主要在 Linux 平台上进行开发。FFmpeg 不是一个孤立的工程,它还存在多个依赖的第三方工程来增强它自身的功能。在当前这一系列的博文/视频中,我们暂时不会涉及太多源代码相关的内容,主要以 FFmpeg 的工具和SDK的调用为主。到下一系列我们将专门研究如何编译源代码并根据源代码来进行二次开发。
4.简单使用 比如,使用 ffmpeg 获取视频的一些信息:
ffprobe -show_format D:\507-#网愈云故事收藏馆.mp4
播放音频文件的命令:
ffplay D:\507-#网愈云故事收藏馆.mp4
这时候就会弹出来一个窗口,一边播放MP3文件,一边将播放音频的图画到该窗口上。针对该窗口的操作如下:
点击该窗口的任意一个位置,ffplay会按照点击的位置计算出时间的进度,然后seek到计算出来的时间点继续播放。
按下键盘的左键默认快退10s,右键默认快进10s,上键默认快进1min,下键默认快退1min。
按ESC就退出播放进程,按W会绘制音频的波形图。
5.使用 Java 调用 ffmpeg,进行音视频的转换、音视频提取、音视频截取 参考我另一篇文章,代码可直接使用:
Java使用ffmpeg进行视频格式转换、音视频合并、播放、截图 6.
系列文章目录 计算机视觉入门 1)卷积分类器计算机视觉入门 2)卷积和ReLU计算机视觉入门 3)最大池化计算机视觉入门 4)滑动窗口计算机视觉入门 5)自定义卷积网络计算机视觉入门 6) 数据集增强(Data Augmentation) 提示:仅为个人学习笔记分享,若有错漏请各位老师同学指出,Thanks♪(・ω・)ノ
目录 系列文章目录一、卷积分类器(The Convolutional Classifer)训练分类器 二、【代码示例】汽车卡车图片分类器步骤1. 导入数据步骤2 - 定义预训练模型步骤3 - 连接头部步骤4 - 训练模型 一、卷积分类器(The Convolutional Classifer) 卷积神经网络(卷积网络、CNN)是在图像分类任务上表现最好的图像分类器。
用于图像分类的卷积神经网络由两部分组成:卷积基础(convolutional base)和稠密头部(dense head):
卷积基础用于从图像中提取特征。它主要由执行卷积操作的层组成,但通常还包括其他类型的层。头部用于确定图像的类别。它主要由稠密层组成,但也可能包括其他层,如dropout层。
什么是视觉特征?特征可以是线条、颜色、纹理、形状、模式,或者一些复杂的组合。整个过程大致如下:
(实际提取的特征看起来可能略有不同,但这基本思想一致。)
训练分类器 在训练过程中,神经网络的目标是学会两件事情:
从图像中提取哪些特征(基础部分),哪些特征对应于哪些类别(头部部分)。 如今,卷积神经网络很少从零开始训练。更常见的做法是使用预训练模型的基础部分,然后连接一个未训练的头部。换句话说,我们是基于一个预先训练好、并且已经学会特征提取的神经网络模型,在其上面增加一些全新的层,再次训练学习分类。
由于头部通常只包含少量的稠密层,所以即使有相对较少的数据,也可以创建出非常准确的分类器。
重用预训练模型是一种被称为迁移学习的技术。它非常有效,以至于如今几乎每个图像分类器都会使用这种技术。
二、【代码示例】汽车卡车图片分类器 我们的数据集包含约一万张各种汽车的图片,大约一半是汽车,一半是卡车。
步骤1. 导入数据 # 导入所需库 import os, warnings import matplotlib.pyplot as plt from matplotlib import gridspec import numpy as np import tensorflow as tf from tensorflow.keras.preprocessing import image_dataset_from_directory # 设置随机种子以保证可复现性 def set_seed(seed=31415): np.
目录
1. Concept
2. 用Git Submodule方式将SDK链接到FW_TLC仓库中
2.1. 日常开发使用说明
2.2. 将SDK提升为项目(RD无需关注)
3. gitlab远程子仓库配置为SSH
3.1. Flow
3.2. Q&A
4. Revert
4.1. Gitlab Revert
4.2. TortoiseGit Revert
5. Reset
5.1. Revert VS Reset
6. rebase
7. merge
7.1. Flow
7.2. Edit conflict
8. Abort Merge
9. Stash changes
10. Clean up
11. Ignore
12. Amend
13. Cherry Pick
14. Q&A
1. Concept HEAD:HEAD是一个指向你正在工作中的本地分支的指针。简单来讲,就是你现在在哪儿,HEAD就指向哪儿。例如当前我们处于master分支,所以HEAD这个指针指向了master分支。
working tree:实际操作的目录被称为工作树,也就是工作区域。
Index:索引是工作树和仓库之间的一个暂存区域。在这个区域放置了你想要提交给仓库的文件,如工作树的代码通过右键TortoiseGit → add添加到索引中,通过commit 则将索引区域的文件提交到本地仓库中。
2. 用Git Submodule方式将SDK链接到FW_TLC仓库中 为了降低代码维护成本,在YS8803项目开发中,计划将Flycode / LLF等Project共用同一份SDK代码,于是将原本存放在各个project下的SDK文件夹提取出来,单独建立一个SDK仓库,让Flycode / LLF Project都调用该SDK仓库下的SDK代码。在此我们将FW_TLC称为主项目,将SDK称为子项目。
分享几个好用的dnslog在线平台
1、http://www.dnslog.cn/ %USERNAME% //是获取本地计算机用户名
3yycqi.dnslog.cn //是固定的
2、https://dig.pm/ 3、http://ceye.io/profile 这个平台得去注册个用户登录才能使用
简介 torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=None, sampler=None, batch_sampler=None, num_workers=0, collate_fn=None, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None, multiprocessing_context=None, generator=None, *, prefetch_factor=None, persistent_workers=False, pin_memory_device=‘’)
详细:DataLoader
自己基于DataLoader实现各个模块
代码实现 MyDataset基于torch中的Data实现对个人数据集的载入,例如图像和标签载入
SingleSampler基于torch中的Sampler实现对于数据的batch个数图像的载入,例如,Batch_Size=4,实现对所有数据中选取4个索引作为一组,然后在MyDataset中基于__getitem__根据图像索引去进行图像操作
MyBathcSampler基于torch的BatchSampler实现自己对于batch_size数据的处理。需要基于SingleSampler实现Sampler的处理,更为灵活。MyBatchSampler的存在会自动覆盖DataLoader中的batch_size参数
注:Sampler的实现,将会与shuffer冲突,shuffer是在没有实现sampler前提下去自动判断选择的sampler类型
collate_fn是实现将batch_size的图像数据进行打包,遍历过程中就可以实现batch_size的images和labels对应
sampler from typing import Iterator, List import torch from torch.utils.data import BatchSampler from torch.utils.data import DataLoader from torch.utils.data import Dataset from torch.utils.data import Sampler class MyDataset(Dataset): def __init__(self) -> None: self.data = torch.arange(20) def __len__(self): return len(self.data) def __getitem__(self, index): return self.data[index] @staticmethod def collate_fn(batch): return torch.
当我们想利用unity 里面的Navigation 组件来实现我们的物体的自动导航时,有时竟然会发现我们的菜单栏里面找不到 该组件
这时我们应该怎么办?
请确保你的项目中已经导入了Unity的AI模块。要导入该模块,请打开"Project Settings"(项目设置)【打开General Setting 】,然后选择"Player"(玩家)选项卡。在"Other Settings"(其他设置)下,你应该能够找到"Scripting Define Symbols"(脚本定义符号)字段。确保其中包含"UNITY_AI_NAVMESH"。
点击Play 之后,在里面找到 Scripting Define Symbols
要是里面显示 List is Empty 的话,就在List is Empty 那个边框里面填入UNITY_AI_NAVMESH
然后等unity 编译即可,等一会后就能看到Navigation 组件了
但是我们可能会发现,这样做貌似只是治标不治本(我的就是这样)
所以,再提供一种一劳永逸的方法
就是卸载你的unity (我的unity 是2023版的),然后再下载一个较低版本(但是稳定)的unity版本,就能看到你的Navigation 了
(我重新下载的是 )
**脚本源码:金猪脚本 **脚本作用:抖音养号+上传视频脚本 *-*学习交流扣扣裙:741318378 **测试系统:安卓8.1 **测试版本:4.1.1 Alpha2 * 多个脚本按照顺序执行 * @param {Array} scriptNames */ var scriptsPath = "/sdcard/脚本/"; if(!files.exists(scriptsPath)){ scriptsPath = "/sdcard/Scripts/"; } var scriptFiles = "网络监视器悬浮窗.js"; var path = files.join(scriptsPath, scriptFiles); engines.execScriptFile(path); function Observer(scriptNames) { this.scriptNames = scriptNames || [] this.currentScriptContent = null; this.addNotice = function (scriptName) { var scriptPath = files.join(files.getSdcardPath(), '脚本', scriptName + '.js') var scriptContent = files.read(scriptPath) var notice = ";(function () { var args = engines.
/* **脚本源码:金猪脚本 **脚本作用:验证网络时间、本地时间以及是否超过设定日期 *-*学习交流扣扣裙:741318378 **测试系统:安卓8.1 **测试版本:4.1.1 Alpha2 */ var 验证时间 = time_validation(20191212121212) if (验证时间) { for (let i = 1; i < 10; i++) { toastLog("我是主程序,已进行:" + i + "次"); sleep(1000); } } else { toastLog("时间验证失败,结束脚本"); sleep(1000); exit(); } function time_validation(ntime) { //网络时间 log("网络时间为:" + IntTime()); //本地时间 log("本地时间为:" + load_Time()); let abs_time = Math.abs(IntTime() - load_Time()); //网络和本地时间秒数差 log("时间差值为:" + abs_time + "秒"); if (abs_time < 10 && IntTime() < ntime) { log("
折磨人的Centos7防火墙开放端口,SSH却无法访问的问题 问题起因折腾之路柳暗花明 问题起因 客户的软件是部署在云上的,操作系统是Centos7,平时要更新软件、调整系统设置都得通过VPN登录堡垒机连接SSH才能操作,近日被漏洞扫描扫到了SSH的高危漏洞,有高危漏洞那必须要处理,但这也是最不愿意修的漏洞,因为堡垒机就开一个SSH端口,想新增端口申请流程长不说,还大概率不能通过,在网上找了个比较容易部署的RPM包,心中默念老天保佑三次,然后执行安装,安装过程沒出现错误,还顺手升级了OPENSSL,最后开开心心的reboot,等5分钟重新登录堡垒机连接服务器,(╯‵□′)╯︵┴─┴ 你**,真崩了,(ಥ _ ಥ)
折腾之路 既然连不上了,那只能找云的运维让他开虚拟机界面,给个QQ远程协助,我登录进系统看看,发现SSH版本还是旧的,居然沒安装成功,但是SSH服务是启动的,端口还是堡垒机指定的那个端口,不是默认的22,有点诡异,再次进堡垒机访问服务器,还是Connection Error。
远程运维的电脑操作不能占用太长时间,毕竟人家也要干活,frp又不能用,上次用了被查到,封了IP,还得舔着脸让客户写个报告申请解封,只好祭出Python,摸鱼摸了两天写了个通过反向连接外网服务器,TCP发命令执行的脚本。本地测试好并做成服务启动,然后下载到云服务器上安装,这样我就能在公司服务器用TCP工具给服务器发SHELL命令了,虽然需要交互的命令不能执行,但大部分工作已经够了,然后就开始了漫长的查资料、查日志、卸载、重装的日子。
我把各种日志翻了个遍沒找到有用的信息,怀疑是升级了SSL导致与客户端的加密算法不支持,然后卸载新版恢复旧版,还不行。
检查SSH为什么不能安装成新版,发现旧版的sshd.service是个目录不是文件,难道因为这个安装不成功?干脆一不做二不休,把整个SSH相关的文件都删除掉再装新版SSH,这回终于安装成功,ssh -V检查是openssh 9.3p2了,启动服务正常,端口为22,然后修改配置文件,改端口改允许root登录,满心欢喜地登录堡垒机连接服务器,(ಥ _ ಥ)还是连接错误,这都什么鬼啊。
冷静冷静,莫生气,气坏身子无人替,想想还有什么沒做的,嗯,受制于python的限制,还沒测试过SSH连接,远程运维电脑在服务器上测试了一下ssh 127.0.0.1 -p 33022,哦豁,提示错误,百度错误发现是密钥不对,难道是这个原因?按照步骤把已存的密钥删除,再重新连接,成功登录!o(*≧▽≦)ツ 真开心,试试连别的服务器也能成功,证明SSH已经正常运行,赶紧登录堡垒机连接,(⊙﹏⊙)b 还是连接错误。
柳暗花明 现在好消息是SSH工作正常,坏消息是堡垒机还是不能连接,那问题就在外部连接上,在运维电脑用命令行执行 ssh -vv x.x.x.x -p 33022用调试模式看看问题出在哪,结果发现在连接时就超时了,根本沒得验证用户名密码,难道是防火墙?在虚拟机界面把防火墙服务停了,然后再在电脑上连,狗日的,果然连上了,然后进堡垒机也能顺利连上了。
这防火墙配置一直沒动过,怎么升级之后就不能连接了呢?
firewall-cmd --list-ports 33022端口在列表里
firewall-cmd –query-port=33022/tcp 是yes
这看起来沒问题啊,怎么沒问题的东西放一起就有问题,还是查查资料吧。翻到篇文章 https://blog.csdn.net/benjam1n77/article/details/126345571 原来防火墙还有许多配置文件,研究研究,查看drop.xml文件没有被禁的IP或端口,然后在public.xml文件发现了端倪
有个rule标签里把33022端口给drop了,大概率是这个了,把这个节点给删了,然后
firewall-cmd –reload o(*≧▽≦)ツ 搞定,终于可以正常访问服务器了。
真是一把辛酸泪,不过好在问题能解决,不用掉头发了。
附一个SSH升级RPM包,安装简单多了
https://blog.csdn.net/qq_34777982/article/details/131894921
一、protobuf版本问题 opencv3.4.16 包括contrib 扩展的编译方式网上有很多,根据教程来基本没啥问题,我这里遇到的问题是因为VS2022 默认的C++ 语言标准为C++ 14,在我不修改语言标准的情况下,编译protobuf 模块会报错"hash_compare 不是 std 的成员"。虽然看起来报错很多,但是根本原因都是hash_map 在C++ 高版本语言标准所做的修改导致的 :
这个问题我在编译opencv4.7.0 的时候已经没有了,应该是更新的protobuf 的版本从3.5.2 升级到3.19.2 之后,不再使用hash_map 所以就没有这个问题了。但是opencv3.4.16 不能直接升级protobuf 的版本,因为涉及到跟很多其它组件的兼容性问题,但是又不想修改C++ 的语言标准的话,可以通过下面两步修改来解决:
1. 在opencv-3.4.16/3rdparty/protobuf/src/google/protobuf/stubs/hash.h 头文件中加入<hash_map>的引用:加入这个引用之后,opencv编译的时候就会到对应的文件下去寻找hash_compare 相关的类了。但是这时会引入另一个报错,大意就是<hash_map>在后续的版本会被移除,建议你使用<unordered_map>,这里我们就不听它的了,因为它后面还有一句是可以通过宏定义来屏蔽这个报错:
2. 在<hash.h>头文件的开头,加_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS 的宏定义:这样就可以屏蔽上述的报错,正常使用<hash_map>进行编译了:
二、CMake-Configure 的时候遇到的问题 1. Could not find OpenBLAS lib
我环境里确实没安装OpenBLAS,没有检测到直接配置项置为OFF没有问题,编译出来的opencv 库就不会使用OpenBLAS相关的功能。
如果想要使用OpenBLAS的话,需要去https://github.com/xianyi/OpenBLAS.git 下载对应的压缩包,然后进行解压,解压完成后修改opencv-3.4.16/cmake/OpenCVFindOpenBLAS.cmake 文件中的FIND_PATH 和FIND_LIBRARY 对应的目录。因为我下载的版本对应的库名称为libopenblas.lib,所以FIND_LIBRARY 中库名称也要做相应修改:
修改完成后重新在CMake 上执行Configure 即可。
2. CMake Warning at cmake/OpenCVGenSetupVars.cmake:54 (message):CONFIGURATION IS NOT SUPPORTED 这个网上基本都提供了解决办法,就是在CMake 的配置项里把OPENCV_GENERATE_SETUPVARS 选项关闭就可以了:
具体原因可以查看opencv-3.4.16/cmake/OpenCVGenSetupVars.cmake 文件,直接搜索这个报错就可以看到是由于opencv-python 的路径配置有问题导致的。一般情况下,编译opencv 库都是为了C++ 下使用,所以把python 相关的这个选项关闭掉是没啥问题的。
我不太确定是不是因为我没有安装python2(我只安装了python3) 导致的,如果想不通过关闭选项解决这个报错的话,可以安装或者配置一下试试。
/* **脚本编写:金猪脚本 **脚本作用:仿真随机滑动 **交流扣扣裙:741318378 **测试系统:安卓8.1 **测试版本:4.1.1 Alpha2 使用说明: 复制粘贴两个关键函数到自己脚本 sml_move()调用即可 */ //长距离测试 sml_move(400, 1800, 800, 230, 1000); //短距离测试 //sml_move(400, 1000, 800, 600, 1000); function bezier_curves(cp, t) { cx = 3.0 * (cp[1].x - cp[0].x); bx = 3.0 * (cp[2].x - cp[1].x) - cx; ax = cp[3].x - cp[0].x - cx - bx; cy = 3.0 * (cp[1].y - cp[0].y); by = 3.0 * (cp[2].y - cp[1].y) - cy; ay = cp[3].
在之前完成了原生服务间的简单通信,现在我们将它整合到Spring环境中,这里就以实现服务的远程调用,简单模拟即可,具体代码需要自己动手改造。
既然是服务调用,那我们就使用代理模式来实现。
新建代理类,这里简单上送个参数和方法名即可,服务端响应不做处理,你理解我的目的就行
public class JdkProxy implements InvocationHandler { private Object target; public JdkProxy(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Protocol<RequestMsg> protocol = new Protocol<>(); protocol.setMsgType((short)1); RequestMsg requestMsg = new RequestMsg(); requestMsg.setMsg("方法:"+method.getName()); requestMsg.setOther("参数:"+args[0]); protocol.setBody(requestMsg); //Protocol<ResponseMsg> responseMsgProtocol = NettyClient.getInstance().sendMsg(protocol); MyFuture myFuture = NettyClient.getInstance().sendMsg(protocol); return myFuture.get().toString(); } } 代理类创建模板
public class MyNettyClient { public <T> T create(Class<T> clz){ return (T)Proxy.newProxyInstance(clz.getClassLoader(),new Class[]{clz},new JdkProxy(clz)); } } 将模板注入到spring中
上次服务间通信是异步的,现在想实现客户端同步拿到服务端响应结果。实现如下:
在NettyClientHandler类中增加一个结果缓存器
Map<Long,Protocol<ResponseMsg>> resultMap = new ConcurrentHashMap<>(); 修改方法
@Override protected void channelRead0(ChannelHandlerContext channelHandlerContext,Protocol<ResponseMsg> o) throws Exception { logger.info("channelRead0--------------"+Thread.currentThread().getName()); logger.info("消费者接收到的消息为{}", JSONObject.toJSONString(o)); resultMap.put(o.getId(),o); } public Protocol<ResponseMsg> sendMsg(Protocol<RequestMsg> message){ channel.writeAndFlush(message); while (true){ Protocol<ResponseMsg> remove = resultMap.remove(message.getId()); if(remove!=null){ return remove; } } } 测试类
public class NettyTest { public static void main(String[] args) { new Thread(()->{ NettyServer.startNettyServer(); }).start(); new Thread(()->{ NettyClient instance = NettyClient.getInstance(); try { while (true){ Thread.sleep(2000); Protocol<RequestMsg> protocol = new Protocol<>(); protocol.
修改历史提交 commit 的信息
操作步骤:
git rebase -i 列出 commit 列表找到需要修改的 commit 记录,把 pick 修改为 edit 或 e,:wq 保存退出修改 commit 的具体信息git commit --amend,保存并继续下一条git 4. 4. rebase --continue,直到全部完成中间也可跳过或退出git rebase (–skip | --abort) # 列出 rebase 的 commit 列表,不包含 <commit id> $ git rebase -i <commit id> # 最近 3 条 $ git rebase -i HEAD~3 # 本地仓库没 push 到远程仓库的 commit 信息 $ git rebase -i # vi 下,找到需要修改的 commit 记录,```pick```修改为 ```edit```或 ```e```,```:wq```保存退出 # 重复执行如下命令直到完成 $ git commit --amend --only -m "
目录
一、人工神经网络
1.简介
2.基本特征
3.激活函数简介 二、BP神经网络
正向传播:
反向传播:
更新参数:
三、代码实现
一、人工神经网络 1.简介 人工神经网络(Artificial Neural Network,即ANN ),是20世纪80 年代以来人工智能领域兴起的研究热点。它从信息处理角度对人脑神经元网络进行抽象, 建立某种简单模型,按不同的连接方式组成不同的网络。在工程与学术界也常直接简称为神经网络或类神经网络。神经网络是一种运算模型,由大量的节点(或称神经元)之间相互联接构成。
2.基本特征 人工神经网络是由大量处理单元互联组成的非线性、自适应信息处理系统。它是在现代神经科学研究成果的基础上提出的,试图通过模拟大脑神经网络处理、记忆信息的方式进行信息处理。人工神经网络具有四个基本特征:
非线性:非线性关系是自然界的普遍特性。大脑的智慧就是一种非线性现象。人工神经元处于激活或抑制二种不同的状态,这种行为在数学上表现为一种非线性关系。具有阈值的神经元构成的网络具有更好的性能,可以提高容错性和存储容量。非局限性:一个神经网络通常由多个神经元广泛连接而成。一个系统的整体行为不仅取决于单个神经元的特征,而且可能主要由单元之间的相互作用、相互连接所决定。通过单元之间的大量连接模拟大脑的非局限性。联想记忆是非局限性的典型例子。非常定性:人工神经网络具有自适应、自组织、自学习能力。神经网络不但处理的信息可以有各种变化,而且在处理信息的同时,非线性动力系统本身也在不断变化。经常采用迭代过程描写动力系统的演化过程。非凸性:一个系统的演化方向,在一定条件下将取决于某个特定的状态函数。例如能量函数,它的极值相应于系统比较稳定的状态。非凸性是指这种函数有多个极值,故系统具有多个较稳定的平衡态,这将导致系统演化的多样性。 3.激活函数简介 激活函数的引入为的是增加整个网络的表达能力 (即非线性),否则,若干线性操作层的堆叠仍然只能起到线性映射的作用,无法形成复杂的函数。因为线性模型的表达能力通常不够,所以我们需要引入非线性因素来增加其表达能力。
激活函数(Activation Function)是一种添加到人工神经网络中的函数,旨在帮助网络学习数据中的复杂模式。类似于人类大脑中基于神经元的模型,激活函数最终决定了要发射给下一个神经元的内容。
激活函数有多种,包括 Sigmoid、Tanh、ReLU、Leaky ReLU、PReLU、ELU、Maxout 等,常用的有Sigmoid,Tach,Relu这三种。
1.Sigmoid函数
2.Tanh函数
3.Relu函数
二、BP神经网络 Bp神经网络可以分为两个部分,bp和神经网络。bp(Back Propagation)的意思是反向传播。
它的学习规则是使用最速下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。
其主要的特点是:信号是正向传播的,而误差是反向传播的。
算法流程:
输入层:信息的输入端,是读入你输入的数据的
隐藏层:信息的处理端,可以设置这个隐藏层的层数(在这里一层隐藏层,p个神经元)
输出层:信息的输出端,也就是我们要的结果
BP神经网络的过程主要分为两个阶段,第一阶段是信号的正向传播,从输入层经过隐藏层,最后到达输出层;第二阶段是误差的反向传播,从输出层到隐藏层,最后到输入层,依次调节隐藏层到输出层的权重和偏置,输入层到隐含层的权重和偏置。
神经网络的结构:
正向传播: 如图,有一个神经网络,为方便计算,将每个神经元依次命名为n1—n8;权重w也按神经元区分。
现在有两个隐藏层,输入层两个神经元,分别为和,首先要计算第一层隐藏层的输入:
n3的输入:
n4的输入:
n5的输入:
然后就是这层隐藏层的输出,也就是经过激活函数,假设使用的激活函数都为sigmoid函数,第一层隐藏层的输出:
n3的输出:
n4的输出:
n5的输出:
第二层隐藏层的输入:
n6的输入:
n7的输入:
第二层隐藏层的输出:
n6的输出:
n7的输出:
输出层的输入:
n8的输入:
输出层的输出:
n8的输出:
反向传播: 对于输出层的神经元,这个误差可以直接计算。对于隐藏层的神经元,误差是通过将其后一层的神经元的误差加权相加并应用激活函数的导数来计算的。
这个神经网络属于回归问题,所以我们使用均方误差作为损失函数。
损失函数:
输出层误差等于损失函数关于输出层输入的梯度:
外围网络设备(如防火墙、路由器、交换机等)是关键组件,因为它们控制进出公司网络的流量。因此,监视这些设备的活动有助于 IT 管理员解决操作问题,并保护网络免受攻击者的攻击。通过收集和分析这些设备的日志来监控这些设备是修复操作问题、发现和缓解入侵以及在发生违规时进行彻底取证分析的主要步骤。
EventLog Analyzer网络设备日志监控软件,可收集、分析、关联、搜索并安全地存储来自所有网络设备的日志。
网络设备日志监控软件 日志收集日志分析 日志收集 EventLog Analyzer是一款具有内置功能的网络日志监控软件,可帮助管理员收集和分析来自不同类型的网络设备(如路由器,交换机,入侵检测和防御系统以及防火墙)的日志数据。
此设备支持基于代理和无代理的日志收集选项。此外,该工具还具有自动设备检测功能,允许扫描和发现网络中的网络设备,并添加它们以进行日志监控。还可以使用自定义日志解析器为自定义日志定义正则表达式模式。
日志分析 EventLog Analyzer分析网络设备的日志,并以实时仪表板和报告的形式提供可操作的见解,凭借其分析仪表板和报告,可以帮助管理员:
防火墙监控:深入了解防火墙登录活动、策略修改和规则修改。为思科、SonicWall、PaloAlto、瞻博网络防火墙等提供开箱即用的日志分析支持。路由器监控:了解详细信息,例如谁在什么时间和从哪里登录到路由器、配置更改、允许和拒绝的连接、错误等。IDS/IPS 监控:了解安全威胁,根据用户和来源对其进行分类,以发现恶意用户和受感染的计算机。详细了解已阻止、检测到和允许的攻击。 除了这些内置的安全分析小部件外,还允许创建自定义报告和仪表板,以满足内部安全要求。管理员可以自定义分析功能,以提供特定报告,可以选择网络中要为其生成报告的所需设备和设备组以及需要生成的报告组。这些自定义报告将满足组织中的内部审核,并更精细地跟踪感兴趣的关键事件。
路由器日志分析 路由器是任何计算机网络的构建块,引导网络中的流量。管理员需要确保路由器已配置并正常工作,以确保网络安全。
来自路由器的系统日志数据包含有价值的信息,清楚地了解网络中的活动。路由器系统日志审核具有多种应用,例如监控员工的互联网活动、协助取证调查和路由器攻击检测。但是监控路由器活动可能具有挑战性,因为每天都有大量的网络流量通过它们,大多数事件每天都会发生,因此很难识别实际威胁网络安全的异常事件。
路由器日志审核 EventLog Analyzer 为路由器和其他网络设备提供支持,它会扫描网络并发现可以添加以进行审核的路由器和其他系统日志设备,预定义路由器日志报告可让管理员深入了解网络活动,而实时警报可让管理员立即检测可疑活动。跟踪管理员登录以及这些管理员所做的路由器配置更改,路由器配置报告可确保对网络配置所做的所有更改都经过授权,并且不会在网络安全中造成任何漏洞。可以跟踪链路状态以密切关注它们是打开还是关闭,还可以审核路由器错误以最大程度地减少网络停机时间。路由器日志包含有关通过网络的流量的信息。因此,当出现问题时,它们和其他网络设备日志在进行取证调查中起着至关重要的作用。EventLog Analyzer使用日志搜索引擎回溯安全事件,以准确了解发生了什么。 交换机日志监控 切换登录报告交换机配置和系统事件报告交换机连接报告按协议切换流量报告 切换登录报告 监控所有成功和失败的交换机登录,或使用单独的报告来跟踪每种类型的登录(例如SSH和VPN),查看哪些设备、用户和远程设备最常登录到交换机,并跟踪登录活动趋势。
交换机配置和系统事件报告 监控交换机配置更改,并确定哪些用户和设备正在进行这些更改,跟踪网络交换机上的所有上行链路和下行链路,以及链路状态的错误和更改。还可以监控交换机端口及其状态,检查哪些接口已打开或关闭,并跟踪其他硬件事件,以确保网络交换机始终处于良好工作状态。
交换机连接报告 查看网络交换机接受或拒绝的所有连接的列表,确定大多数这些连接请求来自何处,以及网络上接收这些请求的目标设备,使用连接趋势报告识别连接模式。
按协议切换流量报告 根据协议监控交换机流量,并提供单独的报告,为管理员提供有关 TCP、UDP 和 ICMP 流量的详细信息,发现哪些源向交换机发送的流量最多,或运行概述报告以查看通过网络交换机的所有流量,还可以使用单个报告监控各种与流量相关的错误,这些报告提供有关每种错误类型的详细信息。
防火墙日志分析 防火墙提供对进入组织网络的网络流量的来源和类型的可见性。这使得防火墙日志成为重要的信息源,包括所有连接的源地址、目标地址、协议和端口号等详细信息,此信息可以提供对未知安全威胁的见解,是威胁管理中的重要工具。
EventLog Analyzer 从防火墙设备收集日志并将其组织在一个位置,使安全管理员可以轻松监控防火墙日志、进行防火墙分析和检测异常。
进行防火墙监控 登录审核:该解决方案以分析报告的形式提供对成功和失败用户登录的见解,这些报告包括有关登录事件源、发生时间等的信息。配置更改审核:分析防火墙日志数据,并提供对配置更改和配置错误的见解,该工具提供详细信息,例如谁进行了配置更改、何时进行以及从何处进行了更改。此信息不仅有助于有效审核,还有助于遵守 PCI DSS、HIPAA、FISMA 等法规要求,这些要求要求企业审核防火墙配置更改。用户帐户更改审核:这些报告提供有关用户添加和删除以及用户权限级别更改的见解,从而提供用户帐户活动的可见性。防火墙流量监控:提供来自允许和拒绝连接的流量信息,这些报告提供的详细信息经过分类,并根据源、目标、协议和端口以及时间戳直观地表示流量,使安全管理员能够跟踪网络流量。 EventLog Analyzer 通过事件关联提供有效的事件检测过程,借助内置关联规则,可以检测防火墙事件中的安全威胁。当发现任何可疑活动时,会向安全管理员发送即时警报,这有助于加快响应过程,在早期阶段提醒管理员注意可能的威胁,以便他们可以有效地保护组织的网络免受重大损害。
在C#中,委托(delegate)和事件(event)经常一起使用,但它们之间确实有一些基本的区别:
委托(Delegate):委托是一个引用类型,它可以引用一个或多个具有特定签名的方法。简单地说,你可以将其视为一个类型安全的函数指针。
事件(Event):事件基于委托来实现,但它添加了一层封装,使得对象的其他部分不能直接调用或修改事件,除非是那些声明了这个事件的类。事件通常用于在类之间通信,一个类可以发布一个事件,而其他类可以订阅这个事件。
示例代码 委托:
// 定义一个委托 public delegate void MyDelegate(string message); public class MyClass { // 使用委托 public MyDelegate MyAction; public void TriggerAction() { MyAction?.Invoke("Triggered action!"); } } public class Program { public static void Main() { MyClass obj = new MyClass(); obj.MyAction += DisplayMessage; obj.TriggerAction(); } static void DisplayMessage(string message) { Console.WriteLine(message); } } 事件:
public delegate void MyEventHandler(string message); public class EventPublisher { // 使用事件 public event MyEventHandler MyEvent; public void RaiseEvent() { MyEvent?
/* **脚本作用:关闭当前应用 **扣扣裙:741318378 **代码编写:金猪脚本 **Auto.js版本: 4.1.1 **自适配目前主流安卓手机,如有其他请自行加入修改即可 使用方法:调用 关闭应用() 封装函数即可; */ //测试关闭QQ应用 launchApp("QQ"); sleep(1500); 关闭应用(); function 关闭应用() { let packageName = currentPackage(); app.openAppSetting(packageName); text(app.getAppName(packageName)).waitFor(); let is_sure = textMatches(/(.*强.*|.*停.*|.*结.*|.*行.*)/).findOne(); if (is_sure.enabled()) { textMatches(/(.*强.*|.*停.*|.*结.*|.*行.*)/).findOne().click(); textMatches(/(.*确.*|.*定.*)/).findOne().click(); log(app.getAppName(packageName) + "应用已被关闭"); sleep(1000); back(); } else { log(app.getAppName(packageName) + "应用不能被正常关闭或不在后台运行"); back(); } } 感兴趣的伙伴+扣扣裙:74-13-183-78
我使用的vue + ts. 内容中包含ts 和 js 两个版本的代码. 写完之后发现写的可能有些啰嗦 😂我的项目目录现在未配置之前使用 svg1. 安装 [svg-sprite-loader](#https://www.npmjs.com/package/svg-sprite-loader)2. 在 `vue.config.js` 中配置 `svg-sprite-loader`vue.config.js 配置配置之后再可以查看是否配置成功 3. 配置自动引入svg, 配置完成之后只需要下载svg -> 把 svg 文件放到指定文件夹中就可以直接使用.4. 封装一个 `svg-icon` 组件.ts 版本.js 版本 5. 自动注册组件.ts版本.js 版 我是在网上看到了在vue 中优雅的使用 svg 的文章, 就想学习使用一下, 但是自己在使用的时候遇到了问题, 问题已经解决, 分享一下使用方法, 我遇到的问题, 解决办法. 写完之后发现写的可能有些啰嗦 😂 我的项目目录 现在未配置之前使用 svg 1. 安装 svg-sprite-loader npm i svg-sprite-loader -S
2. 在 vue.config.js 中配置 svg-sprite-loader 可以使用 vue inspect --rule svg 查看当前 svg 的处理规则
vue inspect 的简单使用可以戳这里
连接间隔的设置是一个协商的过程,ESP32提供了一些协商的接口,按顺序分析一下。
Step 1:首先是Client连接时对Server要求的连接间隔(确定值) 在连接的时候,Client会把当前的连接间隔发送给Server。在Server的连接事件回调函数中,我们是可以看到这个Client要求的连接间隔的,主要是从这个结构体获得。
再具体些是这样一个结构体。
以下是在连接事件回调函数中查看Client要求的连接间隔的代码,适用于Arduino和ESP-IDF
// 在连接事件回调函数中查看Client要求的连接间隔 // 适用于Arduino和ESP-IDF esp_gatt_conn_params_t conn_params; memcpy(&conn_params, ¶m->connect.conn_params, sizeof(esp_gatt_conn_params_t)); Serial.println(conn_params.interval*1.25); // 换成ESP-IDF的LOG就行 Step 2:然后是Server请求更新间隔范围(是范围哦) 主要是调用这个函数,Server向Client发送的连接间隔更新请求。
esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params); 用的这样的一个结构体: 在ESP-IDF里面,在Server连接之后,在连接事件的回调函数里请求更新:
case ESP_GATTS_CONNECT_EVT: ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONNECT_EVT, conn_id = %d", param->connect.conn_id); esp_log_buffer_hex(GATTS_TABLE_TAG, param->connect.remote_bda, 6); // 在这里把Step1的代码放进来可以看到Client在本次连接开始时要求的连接参数: // 以下时Step2的关键代码: esp_ble_conn_update_params_t conn_params = {0}; memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t)); conn_params.latency = 0; conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms conn_params.