介绍两款生成神经网络架构示意图的工具:NN-SVG和PlotNeuralNet
对于神经网络架构的可视化是很有意义的,可以在很大程度上帮助到我们清晰直观地了解到整个架构,我们在前面的 PyTorch的ONNX结合MNIST手写数字数据集的应用(.pth和.onnx的转换与onnx运行时)
有介绍,可以将模型架构文件(常见的格式都可以)在线上传到 https://netron.app/,将会生成架构示意图,比如将yolov5s.pt这个预训练模型,上传之后,将出现下面这样的图片(局部):
这种属于非常简单的层的连接展示,也能够直观知道整个架构是由哪些层组成,虽然每层可以查看一些属性,不过对于每层的具体细节并没有那么直观展现在图片当中。
接下来介绍的这两款都会生成漂亮的可视化神经网络图,可以用来绘制报告和演示使用,效果非常棒。
1、NN-SVG
NN-SVG生成神经网络架构的地址:http://alexlenail.me/NN-SVG/AlexNet.html
显示可能很慢,最好科学上网,进去之后,我们可以看到,有三种神经网络架构可以进行设置:FCNN、LeNet、AlexNet 我们分别来看下:
1.1、FCNN
第一种就是最基础的全连接神经网络FCNN,输入层-->隐藏层(若干)-->输出层,截图如下:
左侧边栏可以进行一些颜色、形状、透明度等设置,也可以很方便的增加和减少层。右边就会实时的显示出操作的效果。
1.2、LeNet
LeNet是一种经典的卷积神经网络,最初用来识别手写数字,我们来看下其结构:
可以看到架构主要是由卷积层组成,输入层-->卷积层-->最大池化层-->...-->全连接层-->输出层。
左边同样的都是可以设置颜色,透明度等,可以增减层数,在每层里可以设置数量、高宽以及卷积核大小,还可以指定是否显示层的名称,这样就更加清楚的知道架构是由哪些具体的层组成了。
1.3、AlexNet
AlexNet是辛顿和他的学生Alex Krizhevsky设计的CNN,在2012年ImageNet的竞赛中获得冠军,它是在LeNet的基础上应用了ReLU激活函数(取代Sigmoid)、Dropout层(避免过拟合)、LRN层(增强泛化能力)等的一种神经网络,截图如下:
同样的可以直观看到,每个层的数量、宽高、卷积核的大小,这些直观的神经网络示意图,尤其对于初学者来说可以很好的理解某个神经网络的整个计算过程。
最后的这些都是可以点击"Download SVG"将其下载成svg格式(一种XML格式)的文件。
2、PlotNeuralNet
2.1、安装
首先确认自己的操作系统,然后对应着进行安装,后面出现的示例是本人的Ubuntu 18.04版本上做的。
Ubuntu 16.04
sudo apt-get install texlive-latex-extra
Ubuntu 18.04.2
基于本网站,请安装以下软件包,包含一些字体包:
sudo apt-get install texlive-latex-base
sudo apt-get install texlive-fonts-recommended
sudo apt-get install texlive-fonts-extra
sudo apt-get install texlive-latex-extra
Windows或其他系统
下载安装MiKTeX:https://miktex.org/download
下载安装Git bash:https://git-scm.com/download/win
或者Cygwin:https://www.cygwin.com/
准备就绪之后运行即可:
cd pyexamples/
bash ../tikzmake.sh test_simple
2.2、克隆运行
上面的Latex安装好了之后,就克隆PlotNeuralNet:
git clone https://github.com/HarisIqbal88/PlotNeuralNet.git
我们先来执行自带的一个测试文件
cd pyexamples/
bash ../tikzmake.sh test_simple
将生成test_simple.pdf,截图如下:
2.3、test_simple.py
我们来看下自带的test_simple.py内容:
import sys
sys.path.append('../')
from pycore.tikzeng import *# defined your arch
arch = [to_head( '..' ),to_cor(),to_begin(),to_Conv("conv1", 512, 64, offset="(0,0,0)", to="(0,0,0)", height=64, depth=64, width=2 ),to_Pool("pool1", offset="(0,0,0)", to="(conv1-east)"),to_Conv("conv2", 128, 64, offset="(1,0,0)", to="(pool1-east)", height=32, depth=32, width=2 ),to_connection( "pool1", "conv2"), to_Pool("pool2", offset="(0,0,0)", to="(conv2-east)", height=28, depth=28, width=1),to_SoftMax("soft1", 10 ,"(3,0,0)", "(pool1-east)", caption="SOFT" ),to_connection("pool2", "soft1"), to_Sum("sum1", offset="(1.5,0,0)", to="(soft1-east)", radius=2.5, opacity=0.6),to_connection("soft1", "sum1"),to_end()]def main():namefile = str(sys.argv[0]).split('.')[0]to_generate(arch, namefile + '.tex' )if __name__ == '__main__':main()
代码比较简单,导入库之后就是定义架构,然后就自定义的每一层都写在arch这个列表中的 to_begin() 和 to_end() 之间,然后就通过函数 to_generate() 将arch列表生成.tex文件,最后就是通过bash自动转换成pdf文件,我们查看下bash文件内容:cat tikzmake.sh
#!/bin/bashpython $1.py
pdflatex $1.texrm *.aux *.log *.vscodeLog
rm *.texif [[ "$OSTYPE" == "darwin"* ]]; thenopen $1.pdf
elsexdg-open $1.pdf
fi
2.4、自定义网络架构
接下来我们自定义一个网络架构测试下,tony.py:
import sys
sys.path.append('../')
from pycore.tikzeng import *# defined your arch
arch = [to_head('..'),to_cor(),to_begin(),to_input('dog.png', width=18, height=14),to_Conv("conv1", 512, 64, offset="(1,0,0)", to="(0,0,0)", height=64, depth=64, width=10,caption="Conv1 Layer"),to_Pool("pool1", offset="(0,0,0)", to="(conv1-east)",caption="Pool1 Layer"),to_Conv("conv2", 128, 64, offset="(4,0,0)", to="(pool1-east)", height=32, depth=32, width=5,caption="Conv2 Layer"),to_connection("pool1", "conv2"),to_Pool("pool2", offset="(0,0,0)", to="(conv2-east)", height=28, depth=28, width=1,caption="Pool2 Layer"),to_SoftMax("soft1", 10 ,"(8,0,0)", "(pool1-east)", caption="Softmax Layer"),to_connection("pool2", "soft1"),to_skip(of="pool1",to="pool2",pos=1.25),to_end()]def main():namefile = str(sys.argv[0]).split('.')[0]to_generate(arch, namefile + '.tex' )if __name__ == '__main__':main()
其中一些代码的解释:
to_input:可以指定输入图片
to="(conv1-east)":表示当前层在conv1的东边(右边)
to_connection( "pool1", "conv2"):在两者之间画连接线
caption:标题
to_skip:做跳线,其中pos大于1表示向上进行画线,小于1就是向下,这个可以自己进行调试
如果对一些方法不明确其有哪些参数,可以使用帮助:helpto_input(pathfile, to='(-3,0,0)', width=8, height=8, name='temp')
to_SoftMax(name, s_filer=10, offset='(0,0,0)', to='(0,0,0)', width=1.5, height=3, depth=25, opacity=0.8, caption=' ')
当然这里的需要命令行进入到PlotNeuralNet目录,因为需要加载:from pycore.tikzeng import *
其他层需要加入,依葫芦画瓢即可,很简单,比如:
to_UnPool('Unpool', offset="(5,0,0)", to="(0,0,0)",height=64, width=2, depth=64, caption='Unpool'),
to_ConvRes("ConvRes", s_filer=512, n_filer=64, offset="(10,0,0)", to="(0,0,0)", height=64, width=2, depth=64, caption='ConvRes'),
to_ConvSoftMax("ConvSoftMax", s_filer=512, offset="(15,0,0)", to="(0,0,0)", height=64, width=2, depth=64, caption='ConvSoftMax'),
to_Sum("sum", offset="(5,0,0)", to="(ConvSoftMax-east)", radius=2.5, opacity=0.6),...
2.5、tikzeng.py
我们来查看下tikzeng.py代码:
import osdef to_head( projectpath ):pathlayers = os.path.join( projectpath, 'layers/' ).replace('\\', '/')return r"""
\documentclass[border=8pt, multi, tikz]{standalone}
\usepackage{import}
\subimport{"""+ pathlayers + r"""}{init}
\usetikzlibrary{positioning}
\usetikzlibrary{3d} %for including external image
"""def to_cor():return r"""
\def\ConvColor{rgb:yellow,5;red,2.5;white,5}
\def\ConvReluColor{rgb:yellow,5;red,5;white,5}
\def\PoolColor{rgb:red,1;black,0.3}
\def\UnpoolColor{rgb:blue,2;green,1;black,0.3}
\def\FcColor{rgb:blue,5;red,2.5;white,5}
\def\FcReluColor{rgb:blue,5;red,5;white,4}
\def\SoftmaxColor{rgb:magenta,5;black,7}
\def\SumColor{rgb:blue,5;green,15}
"""def to_begin():return r"""
\newcommand{\copymidarrow}{\tikz \draw[-Stealth,line width=0.8mm,draw={rgb:blue,4;red,1;green,1;black,3}] (-0.3,0) -- ++(0.3,0);}\begin{document}
\begin{tikzpicture}
\tikzstyle{connection}=[ultra thick,every node/.style={sloped,allow upside down},draw=\edgecolor,opacity=0.7]
\tikzstyle{copyconnection}=[ultra thick,every node/.style={sloped,allow upside down},draw={rgb:blue,4;red,1;green,1;black,3},opacity=0.7]
"""# layers definitiondef to_input( pathfile, to='(-3,0,0)', width=8, height=8, name="temp" ):return r"""
\node[canvas is zy plane at x=0] (""" + name + """) at """+ to +""" {\includegraphics[width="""+ str(width)+"cm"+""",height="""+ str(height)+"cm"+"""]{"""+ pathfile +"""}};
"""# Conv
def to_Conv( name, s_filer=256, n_filer=64, offset="(0,0,0)", to="(0,0,0)", width=1, height=40, depth=40, caption=" " ):return r"""
\pic[shift={"""+ offset +"""}] at """+ to +""" {Box={name=""" + name +""",caption="""+ caption +r""",xlabel={{"""+ str(n_filer) +""", }},zlabel="""+ str(s_filer) +""",fill=\ConvColor,height="""+ str(height) +""",width="""+ str(width) +""",depth="""+ str(depth) +"""}};
"""# Conv,Conv,relu
# Bottleneck
def to_ConvConvRelu( name, s_filer=256, n_filer=(64,64), offset="(0,0,0)", to="(0,0,0)", width=(2,2), height=40, depth=40, caption=" " ):return r"""
\pic[shift={ """+ offset +""" }] at """+ to +""" {RightBandedBox={name="""+ name +""",caption="""+ caption +""",xlabel={{ """+ str(n_filer[0]) +""", """+ str(n_filer[1]) +""" }},zlabel="""+ str(s_filer) +""",fill=\ConvColor,bandfill=\ConvReluColor,height="""+ str(height) +""",width={ """+ str(width[0]) +""" , """+ str(width[1]) +""" },depth="""+ str(depth) +"""}};
"""# Pool
def to_Pool(name, offset="(0,0,0)", to="(0,0,0)", width=1, height=32, depth=32, opacity=0.5, caption=" "):return r"""
\pic[shift={ """+ offset +""" }] at """+ to +""" {Box={name="""+name+""",caption="""+ caption +r""",fill=\PoolColor,opacity="""+ str(opacity) +""",height="""+ str(height) +""",width="""+ str(width) +""",depth="""+ str(depth) +"""}};
"""# unpool4,
def to_UnPool(name, offset="(0,0,0)", to="(0,0,0)", width=1, height=32, depth=32, opacity=0.5, caption=" "):return r"""
\pic[shift={ """+ offset +""" }] at """+ to +""" {Box={name="""+ name +r""",caption="""+ caption +r""",fill=\UnpoolColor,opacity="""+ str(opacity) +""",height="""+ str(height) +""",width="""+ str(width) +""",depth="""+ str(depth) +"""}};
"""def to_ConvRes( name, s_filer=256, n_filer=64, offset="(0,0,0)", to="(0,0,0)", width=6, height=40, depth=40, opacity=0.2, caption=" " ):return r"""
\pic[shift={ """+ offset +""" }] at """+ to +""" {RightBandedBox={name="""+ name + """,caption="""+ caption + """,xlabel={{ """+ str(n_filer) + """, }},zlabel="""+ str(s_filer) +r""",fill={rgb:white,1;black,3},bandfill={rgb:white,1;black,2},opacity="""+ str(opacity) +""",height="""+ str(height) +""",width="""+ str(width) +""",depth="""+ str(depth) +"""}};
"""# ConvSoftMax
def to_ConvSoftMax( name, s_filer=40, offset="(0,0,0)", to="(0,0,0)", width=1, height=40, depth=40, caption=" " ):return r"""
\pic[shift={"""+ offset +"""}] at """+ to +""" {Box={name=""" + name +""",caption="""+ caption +""",zlabel="""+ str(s_filer) +""",fill=\SoftmaxColor,height="""+ str(height) +""",width="""+ str(width) +""",depth="""+ str(depth) +"""}};
"""# SoftMax
def to_SoftMax( name, s_filer=10, offset="(0,0,0)", to="(0,0,0)", width=1.5, height=3, depth=25, opacity=0.8, caption=" " ):return r"""
\pic[shift={"""+ offset +"""}] at """+ to +""" {Box={name=""" + name +""",caption="""+ caption +""",xlabel={{" ","dummy"}},zlabel="""+ str(s_filer) +""",fill=\SoftmaxColor,opacity="""+ str(opacity) +""",height="""+ str(height) +""",width="""+ str(width) +""",depth="""+ str(depth) +"""}};
"""def to_Sum( name, offset="(0,0,0)", to="(0,0,0)", radius=2.5, opacity=0.6):return r"""
\pic[shift={"""+ offset +"""}] at """+ to +""" {Ball={name=""" + name +""",fill=\SumColor,opacity="""+ str(opacity) +""",radius="""+ str(radius) +""",logo=$+$}};
"""def to_connection( of, to):return r"""
\draw [connection] ("""+of+"""-east) -- node {\midarrow} ("""+to+"""-west);
"""def to_skip( of, to, pos=1.25):return r"""
\path ("""+ of +"""-southeast) -- ("""+ of +"""-northeast) coordinate[pos="""+ str(pos) +"""] ("""+ of +"""-top) ;
\path ("""+ to +"""-south) -- ("""+ to +"""-north) coordinate[pos="""+ str(pos) +"""] ("""+ to +"""-top) ;
\draw [copyconnection] ("""+of+"""-northeast)
-- node {\copymidarrow}("""+of+"""-top)
-- node {\copymidarrow}("""+to+"""-top)
-- node {\copymidarrow} ("""+to+"""-north);
"""def to_end():return r"""
\end{tikzpicture}
\end{document}
"""def to_generate( arch, pathname="file.tex" ):with open(pathname, "w") as f: for c in arch:print(c)f.write( c )
从这些代码也可以看出,通过这些方法,返回的是Latex代码来进行绘制的。
运行命令:bash ../tikzmake.sh tony 生成如图:
可以看到生成的可视化架构图,相比较于以前手工做图来说,真的大大提高了效率。更多详情可以去看具体源码。
github:PlotNeuralNet
相关文章:
介绍两款生成神经网络架构示意图的工具:NN-SVG和PlotNeuralNet
对于神经网络架构的可视化是很有意义的,可以在很大程度上帮助到我们清晰直观地了解到整个架构,我们在前面的 PyTorch的ONNX结合MNIST手写数字数据集的应用(.pth和.onnx的转换与onnx运行时) 有介绍,可以将模型架构文件(常见的格式都可以)在线上…...
iOS IdiotAVplayer实现视频分片缓存
文章目录 IdiotAVplayer 实现视频切片缓存一 iOS视频边下边播原理一 分片下载的实现1 分片下载的思路2 IdiotAVplayer 实现架构 三 IdiotAVplayer 代码解析IdiotPlayerIdiotResourceLoaderIdiotDownLoader IdiotAVplayer 实现视频切片缓存 一 iOS视频边下边播原理 初始化AVUR…...
SpringBootWeb请求-响应
HTTP请求 前后端分离 在这种模式下,前端技术人员基于"接口文档",开发前端程序;后端技术人员也基于"接口文档",开发后端程序。 由于前后端分离,对我们后端技术人员来讲,在开发过程中&a…...
List集合详解
目录 1、集合是什么? 1.1、集合与集合之间的关系 2、List集合的特点 3、遍历集合的三种方式 3.1、foreach(增强佛如循环遍历) 3.2、for循环遍历 3.3、迭代器遍历 4、LinkedList和ArrayList的区别 4.1、为什么ArrayList查询会快一些? 4.2、为什么LinkedLi…...
投稿指南【NO.12_8】【极易投中】核心期刊投稿(组合机床与自动化加工技术)
近期有不少同学咨询投稿期刊的问题,大部分院校的研究生都有发学术论文的要求,少部分要求高的甚至需要SCI或者多篇核心期刊论文才可以毕业,但是核心期刊要求论文质量高且审稿周期长,所以本博客梳理一些计算机特别是人工智能相关的期…...
解决git无法上传大文件(50MB)
解决方法 使用LFS解决GitHub无法上传大于50MB的文件 LFS简介 Git LFS(Large File Storage)是 Git 的一个扩展,用于管理大型文件,如二进制文件、图像、音频和视频文件等。它的主要目的是解决 Git 对大型二进制文件的版本控制和存…...
用递归实现字符串逆序(不使用库函数)
文章目录 前言一、题目要求二、解题步骤1.大概框架2.如何反向排列?3.模拟实现strlen4.实现反向排列5.递归实现反向排列 总结 前言 嗨,亲爱的读者们!我是艾老虎尤,今天,我们将探索一个题目,这个题目对新手非…...
初学python(一)
一、python的背景和前景 二、 python的一些小事项 1、在Java、C中,2 / 3 0,也就是整数 / 整数 整数,会把小数部分舍掉。而在python中2 / 3 0.66666.... 不会舍掉小数部分。 在编程语言中,浮点数遵循IEEE754标准,不…...
Excel VSTO开发8 -相关控件
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 8 相关控件 在VSTO开发中,Ribbon(或称为Ribbon UI)是指Office应用程序中的那个位于顶部的带有选…...
华为数据管理——《华为数据之道》
数据分析与开发 元数据是描述数据的数据,用于打破业务和IT之间的语言障碍,帮助业务更好地理解数据。 元数据是数据中台的重要的基础设施,元数据治理贯彻数据产生、加工、消费的全过程,沉淀了数据资产,搭建了技术和业务…...
Flink CDC 菜鸟教程 -环境篇
本教程将介绍如何使用 Flink CDC 来实现这个需求, 在 Flink SQL CLI 中进行,只涉及 SQL,无需一行 Java/Scala 代码,也无需安装 IDE。 系统的整体架构如下图所示: 环境篇 1、 准备一台Linux 2、准备教程所需要的组件 下载 flink-1.13.2 并将其解压至目录 flink-1.13.2 …...
【线上问题】linux部署docker应用docker-compose启动报端口占用问题(感觉上没有被占用)
目录 一、问题说明二、排查过程 一、问题说明 1.linux服务器使用的不是root用户权限 2.docker应用服务没有关闭的情况下,做了些重装docker,重启docker等操作 3.docker-compose up -d然后docker logs查看日志报端口被占用 4.netstat -ntpl | grep 端口 也…...
解决虚拟机克隆后IP和命名冲突问题
目录 解决IP冲突问题 解决命名冲突 解决IP冲突问题 克隆后的虚拟机和硬件地址和ip和我们原虚拟机的相同,我们需要重新生成硬件地址和定义ip,步骤如下: (1)进入 /etc/sysconfig/network-scripts/ifcfg-ens33 配置文件…...
分享一个python基于数据可视化的智慧社区服务平台源码
💕💕作者:计算机源码社 💕💕个人简介:本人七年开发经验,擅长Java、Python、PHP、.NET、Node.js、微信小程序、爬虫、大数据等,大家有这一块的问题可以一起交流! …...
[密码学入门]凯撒密码
单表代换 单表:英文26字母的顺序 代换:替换为别的字母并保证解密的唯一性 假如我们让加密方式为所有字母顺序移动3位 import stringstring.ascii_lowercase abcdefghijklmnopqrstuvwxyz b3 加密算法y(xb)mod26 解密算法为x(y-b)mod26 密钥空间26 …...
博客之QQ登录功能(一)
流程图 上图spring social 封装了1-8步需要的工作 1、新建包和书写配置文件 public class QQProperties {//App唯一标 识private String appId "100550231";private String appSecret "69b6ab57b22f3c2fe6a6149274e3295e";//QQ供应商private String…...
Redis多机数据库实现
Redis多机数据库实现 为《Redis设计与实现》笔记 复制 客户端可以使用SLAVEOF命令将指定服务器设置为该服务器的主服务器 127.0.0.1:12345> SLAVEOF 127.0.0.1 6379127.0.0.1:6379将被设置为127.0.0.1:123456的主服务器 旧版复制功能的实现 Redis的复制功能分为同步&a…...
Leangoo领歌 -敏捷任务管理软件,任务管理更轻松更透明
任务管理,简单易懂,就是对任务进行管理。那怎么可以更好进行任务管理呢?怎么样样可以让任务进度可视化,一目了然呢?有效的管理可以让我们事半功倍。 接下来我们看一下如何借助任务管理软件高效的做任务管理。 首先…...
go的iris框架进行本地资源映射到服务端
我这里使用的是HandleDirapi,有其他的请补充 package mainimport ("github.com/kataras/iris/v12" )type Hello struct{Status int json:"status"Message string json:"message" }func main(){app : iris.New()//第一个api:相当于首页app.Get(&q…...
代码随想录day46|139. 单词拆分
139. 单词拆分 class Solution:def wordBreak(self, s: str, wordDict: List[str]) -> bool:dp [False]*(len(s)1)dp[0]Truefor i in range(len(s)1):for j in wordDict:if i>len(j) and (s[i-len(j):i] in wordDict) and dp[i-len(j)]:dp[i] Truereturn dp[len(s)]多…...
MATLAB实现函数拟合
目录 一.理论知识 1.拟合与插值的区别 2.几何意义 3.误差分析 二.操作实现 1.数据准备 2.使用cftool——拟合工具箱 三.函数拟合典例 四.代码扩展 一.理论知识 1.拟合与插值的区别 通俗的说,插值的本质是根据现有离散点的信息创建出更多的离散点…...
vue优化首屏加载时间优化-cdn引入第三方包
前言 为什么要进行首屏加载优化,因为随着我们静态资源和第三方包和代码增加,压缩之后包会越来越大 随着网络的影响,在我们第一输入url请求资源时候,网络阻塞,加载时间长,用户体验不好 仔细观察后就会发现…...
lv4 嵌入式开发-3 标准IO的读写
目录 1 标准I/O – 读写流 2 标准I/O – 按字符输入 3 标准I/O – 按字符输出 4 标准I/O – 思考和练习 5 标准I/O – 按行输入 6 标准I/O – 按行输出 7 标准I/O – 思考和练习 1 标准I/O – 读写流 流支持不同的读写方式: 读写一个字符:fgetc()/fputc()一…...
iOS UIDevice设备信息
识别设备和操作系统 //获得共享设备实例 open class var current: UIDevice { get }//识别设备的名称 open var name: String { get } // e.g. "My iPhone"//设备类型 open var model: String { get } // e.g. "iPhone", "iPod touch"//本地化设…...
SLAM ORB-SLAM2(2)编译安装
SLAM ORB-SLAM2(2)编译安装 1. 软件包依赖安装2. 依赖安装2.1. Eigen2.2. Pangolin2.3. OpenCV3. ORB-SLAM23.1. 源码下载3.2. 文件修改3.3. 扩大交换空间3.4. 编译1. 软件包依赖安装 以一个纯净的ubuntu20.04桌面版为例 1.首先设置软件源为清华源 2.安装必要依赖 sudo ap…...
第11节-PhotoShop基础课程-索套工具
文章目录 前言1.索套工具 选中后按Ctrl 可以移动2.加,减,交叉 shift alt 2.多边形索套工具 手动首尾相连 或者双击空地1.单击绘制直线选区2.双击结束绘制3.加,减,交叉4. delete可以删除节点 3.磁性索套工具1.沿着边缘自动吸附2.可…...
Json字符串内容比较-超实用版
背景 之前有类似接口diff对比,数据对比的测试需求,涉及到json格式的数据对比,调研了几个大神们分享的代码,选了一个最符合自己需求的研究了下。 说明 这个对比方法,支持JsonObject和JsonArray类型的数据对比&#x…...
Redis系列之客户端Redisson
概述 官方推荐的客户端,支持Redis单实例、Redis哨兵、Redis Cluster、Redis master-slave等各种部署架构。 GitHub, 功能: 分布式锁 分布式锁 使用Redisson提供的分布式锁的一个最常见场景,应用部署为多个节点,然…...
centos 端口被占用的快速排查方式
问题笔记 centos 端口被占用的快速排查方式 centos 端口被占用的快速排查方式 这里说一个我刚刚遇到的问题,解决步骤用来记录,方便以后自己查询。 nginx配置完index.html测试文件,发现一直显示的404页面。 我跑到服务器上想重启一下nginx …...
Java“牵手”淘宝商品列表数据,关键词搜索淘宝商品数据接口,淘宝API申请指南
淘宝商城是一个网上购物平台,售卖各类商品,包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取淘宝商品列表和商品详情页面数据,您可以通过开放平台的接口或者直接访问淘宝商城的网页来获取商品详情信息。以下是两种常用方法的介绍&…...
可以盗链图片的网站/网站权重什么意思
原帖地址:http://community.csdn.net/Expert/topic/3298/3298074.xml?temp.6988336table1为初始化数据,table2为已用票据在table2上写触发器,table2每insert,update,or 批量delete时,实时体现tabel1的已用票号,已用票数, 结余票号,结余票数的值.-------…...
wordpress4.7.4伪静态/故事型软文广告
要是还没有安装Tomcat 服务器 可以点击此 http://tomcat.apache.org/download-60.cgi链接 在官网下载Tomcat服务器. 具体安装方法 这里不做介绍. 在安装好Tomcat之后 接着来就来配置 在桌面建立一个文件夹取名Test(也可以建立在其他的硬盘上)在Test文件下建立WEB-INF文件夹(这…...
左右布局的网站/外贸网站免费推广
iOS,Android原型图设计软件 –>Axure RP,UIDesigner,Pencil,iPhone Mockup,Justinmind<– #Axure RP AxureRP - 快速原型制作软件 – 线框图,原型,规格文档,由美国Axure Software Solutions, Inc.公司开发。 AxureRP也分商业版和免费…...
如何建立网站模板/网站建设开发外包公司
为了完成ListView分页操作,本文会封装一个负责“分页操作”的泛型类PageInfo,该泛型类不仅适用于WPF中ListView的分页,还适用于WPF及WinForms中其他需要分页操作的控件。 下面是PageInfo类的完整代码(包含枚举类型JumpOperation的…...
网站建设书 模板下载/黄山seo
做过测试可能对需求方面有所了解,但是如果要坐产品的话,产品方面的知识还是必须掌握的。比如说原型的设计,需求的分析,交互效果的设计等等。建议可以从产品助理做起。 产品经理的要求非常高 一个最硬性的标准就是表达能力…...
玻璃钢产品哪个网站做推广好/产品营销策略怎么写
1 案例1:配置并验证Split分离解析 1.1 问题 本例要求配置一台智能DNS服务器,针对同一个FQDN,当不同的客户机来查询时能够给出不 同的答案。需要完成下列任务: 从主机192.168.4.207查询时,结果为:www.tedu.…...