-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 60.7 KB
/
content.json
1
[{"title":"spring-boot使用@Aspect切面编程","date":"2018-05-09T07:29:25.000Z","path":"2018/05/09/spring使用@Aspect切面编程/","text":"我们遇到很多业务场景需要在做一项工作的时候,有跟这个工作相关联的工作一块执行,如在这项工作的前面执行一个事情,或者后面执行一个事情等等。 现在开发为了方便阅读代码,不影响当前代码结构,我们采取切面编程的方式,另外通过自定义注解的方式来进一步控制切面编程。 123456789//自定义注解@Target({ElementType.PARAMETER, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface pizerLog { /** 两个控制参数 **/ public String param_a() default \"\"; public String param_b() default \"\";} spring若要用@Aspect,需要在xml内配置,才能解析切面代码1<aop:aspectj-autoproxy/> 面向切面编程代码123456789101112131415161718192021222324252627282930313233343536@Component@Aspectpublic class PizerAspect { /**service层切面*/ private final String POINT_CUT = \"execution(* project.Service..*(..))\"; @Pointcut(POINT_CUT) private void pointcut(){} @Before(value = \"pointcut()\") public void doAfterAdvice(JoinPoint joinPoint) throws ClassNotFoundException { System.out.println(\"方法前面\"); String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); String param_a = \"\"; String param_b = \"\"; if (methods.length>0){ for (Method method : methods) { if (method.getName().equals(methodName)) { if (method.getAnnotation(pizerLog.class)!=null){ param_a = method.getAnnotation(pizerLog.class).param_a(); param_b = method.getAnnotation(pizerLog.class).param_b(); break; } } } } //拿到两个参数,再根据自己业务进行二次控制 System.out.println(\"param_a==\"+param_a); System.out.println(\"param_b==\"+param_b); }} spring-boot的service代码123456@RestControllerpublic interface RedissonTestService { @ResponseBody @RequestMapping(\"/aasd\") String getRedissonClient();} spring-boot的RedissonTestService实现代码1234567891011@Controllerpublic class RedissonTestServiceImpl implements RedissonTestService { @JournalLog(operationType = \"asdasd\",modularTypeName = \"1\") public String getRedissonClient() { System.out.println(\"方法中\"); return \"asd\"; }} 最后访问GET http://localhost:11111/aasd,可以查看切面信息在执行方法前边先执行,若要在后执行或者需要其他方式,请继续查阅@After等等注解。","tags":[{"name":"java","slug":"java","permalink":"https://pizerliu.github.io/tags/java/"}]},{"title":"mongodb复制集配置","date":"2018-05-01T02:03:25.000Z","path":"2018/05/01/mongodb复制集/","text":"本教程采用docker-compose搭建,在一台机器上搭建mongodb复制集配置。主机负责插入更新数据,从机负责查询数据。 首先是机器目录结构: 该目录下所有文件权限最好设置chmod 777,注意keyfileDir内的keyfile要设置chmod 600.(keyfile上一篇主从配置已经介绍) create_conf.sh为未打开auth时用来生成conf文件的脚本,代码为:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120rm -rf /root/top/mongodb_replicset/28017/conf/mongod.confrm -rf /root/top/mongodb_replicset/28018/conf/mongod.confrm -rf /root/top/mongodb_replicset/28019/conf/mongod.confrm -rf /root/top/mongodb_replicset/28020/conf/mongod.confcat >>/root/top/mongodb_replicset/28017/conf/mongod.conf<<'EOF'systemLog: destination: file path: \"/usr/mongodb_logs/mongodb.log\" logAppend: truestorage: journal: enabled: true dbPath: \"/usr/mongodb_data\" directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: # cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: true# security:# authorization: disabled# keyFile: \"/usr/mongodb_key/keyfile\"net: port: 28017replication: oplogSizeMB: 2048 replSetName: my_replEOFcat >>/root/top/mongodb_replicset/28018/conf/mongod.conf<<'EOF'systemLog: destination: file path: \"/usr/mongodb_logs/mongodb.log\" logAppend: truestorage: journal: enabled: true dbPath: \"/usr/mongodb_data\" directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: # cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: true# security:# authorization: disabled# keyFile: \"/usr/mongodb_key/keyfile\"net: port: 28018replication: oplogSizeMB: 2048 replSetName: my_replEOFcat >>/root/top/mongodb_replicset/28019/conf/mongod.conf<<'EOF'systemLog: destination: file path: \"/usr/mongodb_logs/mongodb.log\" logAppend: truestorage: journal: enabled: true dbPath: \"/usr/mongodb_data\" directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: # cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: true# security:# authorization: disabled# keyFile: \"/usr/mongodb_key/keyfile\"net: port: 28019replication: oplogSizeMB: 2048 replSetName: my_replEOFcat >>/root/top/mongodb_replicset/28020/conf/mongod.conf<<'EOF'systemLog: destination: file path: \"/usr/mongodb_logs/mongodb.log\" logAppend: truestorage: journal: enabled: true dbPath: \"/usr/mongodb_data\" directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: # cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: true# security:# authorization: disabled# keyFile: \"/usr/mongodb_key/keyfile\"net: port: 28020replication: oplogSizeMB: 2048 replSetName: my_replEOF create_conf_auth.sh为打开auth时用来生成conf文件的脚本,代码为:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120rm -rf /root/top/mongodb_replicset/28017/conf/mongod.confrm -rf /root/top/mongodb_replicset/28018/conf/mongod.confrm -rf /root/top/mongodb_replicset/28019/conf/mongod.confrm -rf /root/top/mongodb_replicset/28020/conf/mongod.confcat >>/root/top/mongodb_replicset/28017/conf/mongod.conf<<'EOF'systemLog: destination: file path: \"/usr/mongodb_logs/mongodb.log\" logAppend: truestorage: journal: enabled: true dbPath: \"/usr/mongodb_data\" directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: # cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: truesecurity: authorization: enable keyFile: \"/usr/mongodb_key/keyfile\"net: port: 28017replication: oplogSizeMB: 2048 replSetName: my_replEOFcat >>/root/top/mongodb_replicset/28018/conf/mongod.conf<<'EOF'systemLog: destination: file path: \"/usr/mongodb_logs/mongodb.log\" logAppend: truestorage: journal: enabled: true dbPath: \"/usr/mongodb_data\" directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: # cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: truesecurity: authorization: enable keyFile: \"/usr/mongodb_key/keyfile\"net: port: 28018replication: oplogSizeMB: 2048 replSetName: my_replEOFcat >>/root/top/mongodb_replicset/28019/conf/mongod.conf<<'EOF'systemLog: destination: file path: \"/usr/mongodb_logs/mongodb.log\" logAppend: truestorage: journal: enabled: true dbPath: \"/usr/mongodb_data\" directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: # cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: truesecurity: authorization: enable keyFile: \"/usr/mongodb_key/keyfile\"net: port: 28019replication: oplogSizeMB: 2048 replSetName: my_replEOFcat >>/root/top/mongodb_replicset/28020/conf/mongod.conf<<'EOF'systemLog: destination: file path: \"/usr/mongodb_logs/mongodb.log\" logAppend: truestorage: journal: enabled: true dbPath: \"/usr/mongodb_data\" directoryPerDB: true #engine: wiredTiger wiredTiger: engineConfig: # cacheSizeGB: 1 directoryForIndexes: true collectionConfig: blockCompressor: zlib indexConfig: prefixCompression: truesecurity: authorization: enable keyFile: \"/usr/mongodb_key/keyfile\"net: port: 28020replication: oplogSizeMB: 2048 replSetName: my_replEOF 注意:所有的mongodb.log文件还有keyfile文件,切记不能为root用户权限,需要修改,否则docker内环境读不到。例如下面代码修改:1chown polkitd keyfile 执行create_conf.sh,生成配置文件后,执行以下mongodb_replicset.yml代码,docker-compose -f mongodb_MS.yml up -d 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758version: \"2.1\"networks: default: external: name: pizer_local_networkservices: pizer_env_mongodb_28017: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_28017 hostname: pizer_env_mongodb_28017 ports: - 28017:28017 volumes: - /root/top/mongodb_replicset/28017/log:/usr/mongodb_logs - /root/top/mongodb_replicset/28017/data:/usr/mongodb_data - /root/top/mongodb_replicset/keyfileDir:/usr/mongodb_key - /root/top/mongodb_replicset/28017/conf:/usr/mongodb_conf command: ['--bind_ip_all','--config=/usr/mongodb_conf/mongod.conf'] pizer_env_mongodb_28018: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_28018 hostname: pizer_env_mongodb_28018 ports: - 28018:28018 volumes: - /root/top/mongodb_replicset/28018/log:/usr/mongodb_logs - /root/top/mongodb_replicset/28018/data:/usr/mongodb_data - /root/top/mongodb_replicset/keyfileDir:/usr/mongodb_key - /root/top/mongodb_replicset/28018/conf:/usr/mongodb_conf command: ['--bind_ip_all','--config=/usr/mongodb_conf/mongod.conf'] pizer_env_mongodb_28019: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_28019 hostname: pizer_env_mongodb_28019 ports: - 28019:28019 volumes: - /root/top/mongodb_replicset/28019/log:/usr/mongodb_logs - /root/top/mongodb_replicset/28019/data:/usr/mongodb_data - /root/top/mongodb_replicset/keyfileDir:/usr/mongodb_key - /root/top/mongodb_replicset/28019/conf:/usr/mongodb_conf command: ['--bind_ip_all','--config=/usr/mongodb_conf/mongod.conf'] pizer_env_mongodb_28020: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_28020 hostname: pizer_env_mongodb_28020 ports: - 28020:28020 volumes: - /root/top/mongodb_replicset/28020/log:/usr/mongodb_logs - /root/top/mongodb_replicset/28020/data:/usr/mongodb_data - /root/top/mongodb_replicset/keyfileDir:/usr/mongodb_key - /root/top/mongodb_replicset/28020/conf:/usr/mongodb_conf command: ['--bind_ip_all','--config=/usr/mongodb_conf/mongod.conf'] 无auth启动后,设置用户权限:123456789101112131415161718192021use admin#创建root用户db.createUser( { user: \"root\", pwd: \"zxc`12`12\", roles: [ { role: \"root\", db: \"admin\" } ] })#验证权限use admindb.auth('root','zxc`12`12')#创建登陆用户(允许读写)use testdb.createUser( { user: \"pizer\", pwd: \"zxc`12`12\", roles: [ { role: \"readWrite\", db: \"test\" } ] }) 然后执行create_conf_auth.sh,,生成配置文件后,再次执行mongodb_replicset.yml代码,docker-compose -f mongodb_MS.yml up -d,则mongodb复制集建立成功。","tags":[{"name":"mongodb","slug":"mongodb","permalink":"https://pizerliu.github.io/tags/mongodb/"}]},{"title":"mongodb主从配置","date":"2018-04-29T05:23:01.000Z","path":"2018/04/29/mongodb主从配置/","text":"本教程采用docker-compose搭建,在一台机器上搭建mongodb主从配置。主机负责插入更新数据,从机负责查询数据。 首先是机器目录结构: 该目录下所有文件权限最好设置chmod 777,注意keyfileDir内的keyfile要设置chmod 600.(keyfile后面讲是什么) data_master为主机mongodb存放数据目录,data_salve_1为从机1的mongodb存放数据目录,data_salve_2为从机2的mongodb存放数据目录.mongodb_master_log,mongodb_slave_1_log,mongodb_slave_2_log,为各主从机的log存放位置。mongodb_MS.yml(有两个不一样的,下面仔细看)为docker-compose搭建各容器的文件。keyfileDir内有一文件keyfile,主要是用来主从机握手的key文件,在linux系统中,生成代码为:1openssl rand -base64 741 >> keyfile 首先要建立没有登陆权限的mongodb主从,执行以下版本一mongodb_MS.yml代码,docker-compose -f mongodb_MS.yml up -d (注意把–source里的ip改成自己机器的ip):12345678910111213141516171819202122232425262728293031323334353637383940414243444546version: \"2.1\"networks: default: external: name: pizer_local_networkservices: pizer_env_mongodb_master: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_master hostname: pizer_env_mongodb_master ports: - 27008:27017 volumes: - /root/top/mongodb_MS_docker/mongodb_master_log:/usr/mongodb_logs - /root/top/mongodb_MS_docker/data_master:/usr/mongodb_data - /root/top/mongodb_MS_docker/keyfileDir:/usr/mongodb_key command: ['--master','--bind_ip_all','--dbpath=/usr/mongodb_data','--logpath=/usr/mongodb_logs/mongodb_master.log'] pizer_env_mongodb_slave_1: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_slave_1 hostname: pizer_env_mongodb_slave_1 ports: - 27009:27017 volumes: - /root/top/mongodb_MS_docker/mongodb_slave_1_log:/usr/mongodb_logs - /root/top/mongodb_MS_docker/data_slave_1:/usr/mongodb_data - /root/top/mongodb_MS_docker/keyfileDir:/usr/mongodb_key depends_on: - \"pizer_env_mongodb_master\" command: ['--slave','--source=47.100.22.11:27008','--bind_ip_all','--dbpath=/usr/mongodb_data','--logpath=/usr/mongodb_logs/mongodb_slave_1.log'] pizer_env_mongodb_slave_2: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_slave_2 hostname: pizer_env_mongodb_slave_2 ports: - 27010:27017 volumes: - /root/top/mongodb_MS_docker/mongodb_slave_2_log:/usr/mongodb_logs - /root/top/mongodb_MS_docker/data_slave_2:/usr/mongodb_data - /root/top/mongodb_MS_docker/keyfileDir:/usr/mongodb_key depends_on: - \"pizer_env_mongodb_master\" command: ['--slave','--source=47.100.22.11:27008','--bind_ip_all','--dbpath=/usr/mongodb_data','--logpath=/usr/mongodb_logs/mongodb_slave_2.log'] 此时,mongodb主从是没有登陆账户限制的,这是极不安全的,接下来我们需要设置登陆账户。 我们进入数据库master容器,在位置/usr/bin/处执行mongo,执行下面操作:123456789101112131415161718192021use admin#创建root用户db.createUser( { user: \"root\", pwd: \"zxc`12`12\", roles: [ { role: \"root\", db: \"admin\" } ] })#验证权限use admindb.auth('root','zxc`12`12')#创建登陆用户(允许读写)use testdb.createUser( { user: \"pizer\", pwd: \"zxc`12`12\", roles: [ { role: \"readWrite\", db: \"test\" } ] }) 登陆用户创建完毕,接下来设置数据库auth,然后重启,依然执行以下版本二mongodb_MS.yml代码,docker-compose -f mongodb_MS.yml up -d (注意把–source里的ip改成自己机器的ip): 12345678910111213141516171819202122232425262728293031323334353637383940414243444546version: \"2.1\"networks: default: external: name: pizer_local_networkservices: pizer_env_mongodb_master: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_master hostname: pizer_env_mongodb_master ports: - 27008:27017 volumes: - /root/top/mongodb_MS_docker/mongodb_master_log:/usr/mongodb_logs - /root/top/mongodb_MS_docker/data_master:/usr/mongodb_data - /root/top/mongodb_MS_docker/keyfileDir:/usr/mongodb_key command: ['--master','--bind_ip_all','--dbpath=/usr/mongodb_data','--logpath=/usr/mongodb_logs/mongodb_master.log','--auth','--keyFile=/usr/mongodb_key/keyfile'] pizer_env_mongodb_slave_1: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_slave_1 hostname: pizer_env_mongodb_slave_1 ports: - 27009:27017 volumes: - /root/top/mongodb_MS_docker/mongodb_slave_1_log:/usr/mongodb_logs - /root/top/mongodb_MS_docker/data_slave_1:/usr/mongodb_data - /root/top/mongodb_MS_docker/keyfileDir:/usr/mongodb_key depends_on: - \"pizer_env_mongodb_master\" command: ['--slave','--source=47.100.22.11:27008','--bind_ip_all','--dbpath=/usr/mongodb_data','--logpath=/usr/mongodb_logs/mongodb_slave_1.log','--auth','--keyFile=/usr/mongodb_key/keyfile'] pizer_env_mongodb_slave_2: image: 'docker.io/mongo:3.6-rc' container_name: pizer_env_mongodb_slave_2 hostname: pizer_env_mongodb_slave_2 ports: - 27010:27017 volumes: - /root/top/mongodb_MS_docker/mongodb_slave_2_log:/usr/mongodb_logs - /root/top/mongodb_MS_docker/data_slave_2:/usr/mongodb_data - /root/top/mongodb_MS_docker/keyfileDir:/usr/mongodb_key depends_on: - \"pizer_env_mongodb_master\" command: ['--slave','--source=47.100.22.11:27008','--bind_ip_all','--dbpath=/usr/mongodb_data','--logpath=/usr/mongodb_logs/mongodb_slave_2.log','--auth','--keyFile=/usr/mongodb_key/keyfile']","tags":[{"name":"mongodb","slug":"mongodb","permalink":"https://pizerliu.github.io/tags/mongodb/"}]},{"title":"目标检测SSD","date":"2018-03-07T07:21:21.000Z","path":"2018/03/07/目标检测SSD/","text":"目标检测域内,传统一点的框架会在feature map(或者原图)上进行region proposal提取出可能有物体的部分然后进行分类,这一步可能非常费时,所以SSD就放弃了region proposal,而选择直接生成一系列defaul box(或者叫prior box),然后将这些default box回归到正确的位置上去,整个过程通过网络的一次前向传播就可以完成,非常方便。 SSD 是基于一个前向传播 CNN 网络,产生一系列 固定大小(fixed-size) 的 bounding boxes,以及每一个 box 中包含物体实例的可能性,即 score。之后,进行一个 非极大值抑制(Non-maximum suppression) 得到最终的 predictions。SSD算是YOLO的多尺度版本,由于YOLO对小目标检测效果不好,所以SSD在不同的feature map上分割成grid然后采用类似RPN的方式做回归。 SSD在基础网络结构后,添加了额外的卷积层(没有用全链接层),使得这些卷积层的大小是逐层递减的,所以可以在多尺度下进行 predictions。 feature map cell 就是将 feature map 切分成 8×8 或者 4×4 之后的一个个的格子; default box 就是每一个格子上,一系列固定大小的 box,即图中虚线所形成的一系列 boxes。 每一个 box 相对于与其对应的 feature map cell 的位置是固定的。 在每一个 feature map cell 中,我们要 predict 得到的 box 与 default box 之间的 offsets,以及每一个 box 中包含物体的 score(每一个类别概率都要计算出)。 因此,对于一个位置上的 kk 个boxes 中的每一个 box,我们需要计算出 cc 个类,每一个类的 score,还有这个 box 相对于 它的默认 box 的 4 个偏移值(offsets)。于是,在 feature map 中的每一个 feature map cell 上,就需要有 (c+4)×k(c+4)×k 个 filters。对于一张 m×nm×n 大小的 feature map,即会产生 (c+4)×k×m×n(c+4)×k×m×n 个输出结果。 在生成一系列的 predictions 之后,会产生很多个符合 ground truth box 的 predictions boxes,但同时,不符合 ground truth boxes 也很多,而且这个 negative boxes,远多于 positive boxes。这会造成 negative boxes、positive boxes 之间的不均衡。训练时难以收敛。 因此,本文采取,先将每一个物体位置上对应 predictions(default boxes)是 negative 的 boxes 进行排序,按照 default boxes 的 confidence 的大小。 选择最高的几个,保证最后 negatives、positives 的比例在 3:1,这样的比例可以更快的优化,训练也更稳定。 源码里使用pycaffe定义网络:http://blog.csdn.net/u011762313/article/details/48213421 本文摘自互联网,是方便自己再次查阅回顾。若有侵权问题可联系邮箱[email protected]。","tags":[{"name":"机器学习","slug":"机器学习","permalink":"https://pizerliu.github.io/tags/机器学习/"},{"name":"目标检测SSD","slug":"目标检测SSD","permalink":"https://pizerliu.github.io/tags/目标检测SSD/"}]},{"title":"caffe环境配置","date":"2018-01-31T04:36:31.000Z","path":"2018/01/31/caffe环境配置/","text":"本来是打算直接windows系统用docker的caffe环境,怎奈docker技术吃得不够透彻,在调取摄像头资源的时候,docker容器调取不到本机摄像头资源,没办法,只能回归老办法,再装ubuntu系双统配置caffe环境,配置过程中也是万分纠结,因为之前没有直接配置过caffe(都是偷懒用的docker,咳咳),接下在首先总结一下我的caffe安装。 最开始第一反应是去搜索ubuntu怎么安装caffe,嘟嘟出来一大堆,然后一个个的试,发现不是出这个问题,就是出那个问题,折腾了两天(相信不少第一次装得孩子们都遇到这种草蛋的事情)。后来在看caffe项目的时候,突然想起来人家给的有dockerfile,按着dockerfile来装必定没问题啊,然后就按照dockerfile来安装,步骤如下: 零. 安装cuda,opencv就不做过多说明。一. 下载caffe代码,在caffe目录下写一个shell脚本,用来安装caffe所需要的依赖,有些包国内下载可能会不通畅,建议翻墙或者用别的源进行尝试,文件命名为install.sh,内容如下:1234567891011121314151617181920212223apt-get update && apt-get install -y --no-install-recommends \\ build-essential \\ cmake \\ git \\ wget \\ libatlas-base-dev \\ libboost-all-dev \\ libgflags-dev \\ libgoogle-glog-dev \\ libhdf5-serial-dev \\ libleveldb-dev \\ liblmdb-dev \\ libopencv-dev \\ libprotobuf-dev \\ libsnappy-dev \\ protobuf-compiler \\ python-dev \\ python-numpy \\ python-pip \\ python-scipy && \\for req in $(cat python/requirements.txt) pydot; do pip install $req; done 二. caffe编译安装123mkdir build && cd build && \\cmake .. && \\make -j8 三. 环境变量的配置( sudo gedit /etc/profile ,修改完毕重启电脑即可)1234export CAFFE_ROOT=/home/pizer/workspace/caffe (设置你自己的caffe目录)export PYCAFFE_ROOT=$CAFFE_ROOT/pythonexport PYTHONPATH=$PYCAFFE_ROOT:$PYTHONPATHexport PATH=/usr/local/cuda/bin:$CAFFE_ROOT/build/tools:$PYCAFFE_ROOT:$PATH (环境变量放入$PATH内)","tags":[{"name":"机器学习","slug":"机器学习","permalink":"https://pizerliu.github.io/tags/机器学习/"},{"name":"caffe","slug":"caffe","permalink":"https://pizerliu.github.io/tags/caffe/"}]},{"title":"机器学习之CNN","date":"2017-10-27T01:57:31.000Z","path":"2017/10/27/机器学习基础之CNN/","text":"—— step.1 数据集 首先根据自己想达到的目的,来建立正样本数据集和负样本数据集(ps:如果检测是否有人,正样本及有人的图片,负样本就是为你不想判定为有人的图片),当然如果有已经开源的数据集,我们当然直接拿来用就好。 接下来推荐几个学习时使用的不错数据集: 1. MNIST —— 一个手写数字的数据集 2. 搜狗实验室数据集 —— 搜狗收集了包括人物、动物、建筑、机械、风景、运动等类别 3. ImageNet —— 一个计算机视觉系统识别项目,是目前世界上图像识别最大的数据库 —— step.2 CNN介绍 卷积 神经网络判断一个图片是否包含“人”的过程,包括四个步骤: 图像输入(InputImage)→ 卷积(Convolution)→ 最大池化(MaxPooling)→ 全连接神经网络(Fully-ConnectedNeural Network)计算 → 步骤如下图: 了解传统的神经网络的就知道,作为神经元的感知机模型十分简单,如全连接层的网络结构,采用矩阵相乘然后进行非线性变换。 感知机模型: f(x) = sign( Wx + b ) 传统神经网络的劣势在于,当需要处理一个4004003的RGB图片时,一张图就需要处理较大的数据量,占用的内存空间会巨大,还必将导致收敛速度慢,使得需要更多训练数据以及更多的迭代。另一方面,全连接网络结构在处理每一个像素时,其相邻像素和距离很远像素都是无差别对待的,并没有考虑图像内容的空间结构。 通过认识到上面的不足,卷积神经网络产生了,卷积神经网络指的是至少有一层计算为卷积操作的神经网络。卷机操作是其中的核心,他充分利用了图片中相邻区域的信息,通过稀疏连接和共享权值的方式大大减少了参数矩阵的规模,从而减少计算量,也提高了收敛速度。 所谓的卷积核,其实就是一个权值矩阵,表示如何处理单个像素与邻域像素之间的关系。卷积核的各个元素相对差值较小,就相当于每个像素和周围像素取了个平均值,也就有了模糊降噪的效果。而卷积核的各个元素相对差值较大,就拉大了每个像素和周围像素的差距,也就可以提取边缘,达到锐化的效果。(卷积核元素累加为0时,图片输出亮度会很低,但不会全黑,大部分是黑色,有部分图案边缘存在,也就做到边缘提取了) 但是,我怎么才知道我们想要的卷积核参数那? 通过卷机操作和反向传播算法结合,通过大量图片让程序自己学习出卷积核参数即可。 传统神经网络,对于一张1000x1000像素的图来说,就会有多达10万个输入。而对于CNN来说,如果使用的10x10的卷积核,每个节点就只有100个输入,对应100个权值,数量级大大减小。 —— step.3 tensorflow对CNN的项目实现 实现CNN时会用到: 1. 池化 pooling: 一种是最大池化(max pooling),在定义窗口内取最大值。另一种是平均池化(average pooling).池化主要作用是降维。 2. 激活函数 Relu:将一个特征空间的向量通过非线性变换映射到另一个空间中才能实现线性可分。它的优点在于分类效果好,收敛速度快,计算速度快。 3. 多层卷积:将对前面提取的细节特征进行再次提取组合,相当于把视野放大,提取出更完整,更抽象的特征。 4. Dropout:过拟合是指训练结果在训练集和测试集上表现差别很大的情况。 代码实现:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179import tensorflow as tfimport numpy as npimport osfrom ssutils import *# 图像二值化# grayed_image = tf.image.rgb_to_grayscale(image0)true_path = 'F:/机器学习/目标检测/jiji_test/true_image/正/'false_path = 'F:/机器学习/目标检测/jiji_test/false_image/负/'# 函数声明部分def weight_variable(shape): # 正态分布,标准差为0.1,默认最大为1,最小为-1,均值为0 initial = tf.truncated_normal(shape, dtype=tf.float32, stddev=0.1) return tf.Variable(initial)def bias_variable(shape): # 创建一个结构为shape矩阵也可以说是数组shape声明其行列,初始化所有值为0.1 initial = tf.constant(0.1, dtype=tf.float32, shape=shape) return tf.Variable(initial)def conv2d(x, W): # 卷积遍历各方向步数为1,SAME:边缘外自动补0,遍历相乘 return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')def max_pool_2x2(x): # 池化卷积结果(conv2d)池化层采用kernel大小为2*2,步数也为2,周围补0,取最大值。数据量缩小了4倍 return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')# 读取数据def read_img(true_path,false_path): imgs = [] labels = [] cate = [true_path + x for x in os.listdir(true_path)] # os.path.isdir(path + x) for idx, folder in enumerate(cate): img = imread(folder) # img = transform.resize(img, (w, h, c)) imgs.append(img) labels.append(np.array([0.,1.])) cate = [false_path + x for x in os.listdir(false_path)] # os.path.isdir(path + x) for idx, folder in enumerate(cate): img = imread(folder) # img = transform.resize(img, (w, h, c)) imgs.append(img) labels.append(np.array([1.,0.])) c = list(zip(imgs, labels)) random.shuffle(c) imgs[:], labels[:] = zip(*c) return np.asarray(imgs, np.float32)/255-0.5, np.asarray(labels, np.float32)# 声明一个占位符,None表示输入图片的数量不定,240*320*4图片分辨率xs = tf.placeholder(tf.float32, [None, 240,320,4])# 类别是0-1总共2个类别,对应输出分类结果ys = tf.placeholder(tf.float32, [None, 2])keep_prob = tf.placeholder(tf.float32)# x_image又把xs reshape成了240*320*4的形状.作为训练时的input,-1代表图片数量不定x_image = tf.reshape(xs, [-1, 240, 320, 4])## 第一层卷积操作 ### 第一二参数值得卷积核尺寸大小,即patch,第三个参数是图像通道数,第四个参数是卷积核的数目,代表会出现多少个卷积特征图像;W_conv1 = weight_variable([5, 5, 4, 32])# 对于每一个卷积核都有一个对应的偏置量。b_conv1 = bias_variable([32])# 图片乘以卷积核,并加上偏执量,卷积结果240x320x32h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)# 池化结果120x160x32 卷积结果乘以池化卷积核h_pool1 = max_pool_2x2(h_conv1)## 第二层卷积操作 ### 第一二参数值得卷积核尺寸大小,即patch,第三个参数是图像通道数,第四个参数是卷积核的数目,代表会出现多少个卷积特征图像;W_conv2 = weight_variable([5, 5, 32, 64])# 对于每一个卷积核都有一个对应的偏置量。b_conv2 = bias_variable([64])# 图片乘以卷积核,并加上偏执量,卷积结果120x160x64h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)# 池化结果60x80x64 卷积结果乘以池化卷积核h_pool2 = max_pool_2x2(h_conv2)## 第三层卷积操作 ### 第一二参数值得卷积核尺寸大小,即patch,第三个参数是图像通道数,第四个参数是卷积核的数目,代表会出现多少个卷积特征图像;W_conv3 = weight_variable([5, 5, 64, 128])# 对于每一个卷积核都有一个对应的偏置量。b_conv3 = bias_variable([128])# 图片乘以卷积核,并加上偏执量,卷积结果60x80x128h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3)# 池化结果30x40x128 卷积结果乘以池化卷积核h_pool3 = max_pool_2x2(h_conv3)## 第四层卷积操作 ### 第一二参数值得卷积核尺寸大小,即patch,第三个参数是图像通道数,第四个参数是卷积核的数目,代表会出现多少个卷积特征图像;W_conv4 = weight_variable([5, 5, 128, 256])# 对于每一个卷积核都有一个对应的偏置量。b_conv4 = bias_variable([256])# 图片乘以卷积核,并加上偏执量,卷积结果30x40x256h_conv4 = tf.nn.relu(conv2d(h_pool3, W_conv4) + b_conv4)# 池化结果15x20x256 卷积结果乘以池化卷积核h_pool4 = max_pool_2x2(h_conv4)## 第五层全连接操作 ### 二维张量,第一个参数15x20x256的patch,也可以认为是只有一行7*7*64个数据的卷积,第二个参数代表卷积个数共1024个shape = int(np.prod(h_pool4.get_shape()[1:]))W_fc1 = weight_variable([shape, 1024])# 1024个偏执数据b_fc1 = bias_variable([1024])# 将第二层卷积池化结果reshape成只有一行15x20x256个数据# [n_samples, 15, 20, 256] ->> [n_samples, 15x20x256]h_pool2_flat = tf.reshape(h_pool4, [-1, shape])# 卷积操作,结果是1*1*1024,单行乘以单列等于1*1矩阵,matmul实现最基本的矩阵相乘,不同于tf.nn.conv2d的遍历相乘,自动认为是前行向量后列向量h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)# dropout操作,减少过拟合,其实就是降低上一层某些输入的权重scale,甚至置为0,升高某些输入的权值,甚至置为2,防止评测曲线出现震荡,个人觉得样本较少时很必要keep_prob = tf.placeholder(tf.float32)h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) # 对卷积结果执行dropout操作## 第六层输出操作 ### 二维张量,1*1024矩阵卷积,共2个卷积,对应我们开始的ys长度为2W_fc2 = weight_variable([1024, 2])b_fc2 = bias_variable([2])# 最后的分类,结果为1*1*2 softmax和sigmoid都是基于logistic分类算法,一个是多分类一个是二分类y_conv = tf.nn.sigmoid(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)# 定义loss(最小误差概率),选定优化优化loss,# cross_entropy = -tf.reduce_sum(ys * tf.log(y_conv)) # 定义交叉熵为loss函数cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(y_conv),reduction_indices=[1])) # loss# tensorboard losstf.summary.scalar('loss', cross_entropy)train_step = tf.train.GradientDescentOptimizer(0.2).minimize(cross_entropy) # 调用优化器优化,其实就是通过喂数据争取cross_entropy最小化# 五,开始数据训练以及评测correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(ys, 1))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))# tensorboard losstf.summary.scalar('accuracy', accuracy)init = tf.global_variables_initializer()imgsData, labelsData = read_img(true_path, false_path)num_example = imgsData.shape[0]ratio = 0.5s = np.int(num_example * ratio)imgs_train = imgsData[:s]labels_train = labelsData[:s]imgs_test = imgsData[s:]labels_test = labelsData[s:]with tf.Session() as sess: sess.run(init) merged = tf.summary.merge_all() writer = tf.summary.FileWriter(\"logs/\", sess.graph) for i in range(20000): # 大乱数据,取得训练数据和测试数据 imgsData, labelsData = read_img(true_path, false_path) num_example = imgsData.shape[0] ratio = 0.5 s = np.int(num_example * ratio) imgs_train = imgsData[:s] labels_train = labelsData[:s] if i % 100 == 0: train_accuracy = sess.run(accuracy, feed_dict={xs: imgs_train, ys: labels_train, keep_prob: 0.8}) print(\"step %d, training accuracy %g\" % (i, train_accuracy)) sess.run(train_step,feed_dict={xs: imgs_train, ys: labels_train, keep_prob: 0.5}) summary = sess.run(merged,feed_dict={xs: imgs_train, ys: labels_train, keep_prob: 0.5}) writer.add_summary(summary, i) print(\"test accuracy %g\" % sess.run(accuracy,feed_dict={xs: imgs_test, ys: labels_test, keep_prob: 1.0})) —— step.4 声明 部分图片和内容来自于网络,若有纠纷麻烦联系邮箱:[email protected]","tags":[{"name":"机器学习","slug":"机器学习","permalink":"https://pizerliu.github.io/tags/机器学习/"},{"name":"CNN","slug":"CNN","permalink":"https://pizerliu.github.io/tags/CNN/"}]},{"title":"阿里云栖大会行记","date":"2017-10-17T12:39:20.000Z","path":"2017/10/17/阿里云栖大会行记/","text":"初见 阿里巴巴于2017年10月11日到2017年10月14日在杭州举行了一年一度的科技盛会——云栖大会。出于对阿里的喜爱,我关注了阿里技术公众号 ( ps:应该算帮忙打广告了哈,可以联系我 ,哈哈哈),9月底在翻看阿里技术的文章时发现了一个令人惊喜的活动,就是可以填写自己信息报名作为阿里小记者参观云栖大会,反馈一篇参会感就可以获得一张参会门票,这个活动对于我们这些喜欢阿里的穷苦学僧来说是再好不过的啦 (大家多多关注阿里妹的福利 -。-)。 最后,抱着试试的心态填写了我的信息,没想到马上就得到了阿里妹的电话回复,我也就正式成为了一名阿里小记者 (我骄傲 ) 相识 由于实习工作原因导致我只能参加13号的云栖大会,其实还是蛮遗憾的。 10月13号早上6点多就早早的起床跟约好的一位同样喜欢阿里的小伙伴一块在南站集合前往阿里的基地 —— 杭州。 到达云栖小镇后经过身份识别拿到了自己的牌子入场,进入场馆,最大的一个感觉就是各个行业与数据结合的越来越紧密,后面的时代是数据的时代,而非互联网时代。数据已经渗透到农业,陆地运输交通业,海上运输交通,生物工程,虚拟技术,台风检测,医疗保健,金融等等。跟自己最为贴切的感触就是,阿里通过使用阿里系软件所得到的数据可以给个人生成一个健康图(咳咳,我的数据有点糟糕,-。-)。 当逛到每个展台的时候,展台的工作人员都会仔细耐心的跟我讲解他们的数据系统,以及企业的产品和现状,作为学生,我也会虚心听取的各个行业的大咖给我讲解他们的行业以及产品服务。聊的最久的是做海洋货轮大数据的公司,在展台的也是跟我年龄相仿的年轻人,我看到他们的整个地球拓扑图,显示海洋上航行所有货轮的航行路线,以及每个货轮都装有的AIS设备实时返回给基站船舶的数据,他们提供的远不仅仅这些,还有通过各个数据来预测最佳航线,来达到省燃料降低成本。我还是没有人家小哥讲的清楚,那位小哥太有耐心了。 自己也做了一年互联网方面的实习了,当然也不会忘记自己的老本行( -。- )。看到了几家自己也曾经用过的东西,APICloud,ping++,也发现了现在前端快速开发的趋势,直接在网站上通过可编辑的方式来达到自己想要的各种响应页面,快速的开发出静态页面。这方面还有不少人都比较感兴趣的了解。 到下午,到了阿里技术专场,我选择了一个自己比较感兴趣的自然语言处理方向的专场,自然语言处理作为机器学习中比较重要的应用之一,多了解了解也刚好是自己的兴趣所在。在专场静静的听了大概一两个小时,阿里的各位大牛给我们大家介绍了阿里使用自然语言处理在自己商业上的一些应用,以及应用的大致模型和架构,其中有阿里小蜜 Chit Chat,情感分析的应用,机器阅读理解技术和应用,蚂蚁金服NLP的进展与应用(李小龙给上的课),阿里智能翻译(期间大屏幕还出现了小许问题)。基本上都通过讲解阿里自己模型所优化的地方,整个模型从数据集到模型建立再到训练再到调参,然后对比当前其他解决方案和阿里解决方案的对比。(当然整个讲解的过程都是基于阿里的业务和服务上来的) 终章 最终,夜幕降临,即将闭馆,我也打包行李,叫了个滴滴(又给阿里帝打了个广告 -。- 生活处处有阿里啊)。","tags":[{"name":"生活","slug":"生活","permalink":"https://pizerliu.github.io/tags/生活/"},{"name":"热爱技术","slug":"热爱技术","permalink":"https://pizerliu.github.io/tags/热爱技术/"},{"name":"阿里","slug":"阿里","permalink":"https://pizerliu.github.io/tags/阿里/"}]},{"title":"vue学习","date":"2017-07-28T10:06:16.000Z","path":"2017/07/28/vue学习/","text":"vue学习1.vue组件化,组件内外通讯123456789101112131415161718192021222324252627282930313233//首先,vue外层给组件内层传参//外层代码<comm :width=\"300\" :height=\"300\" url=\"https://asd.org/post\" @close='close'></comm>//模块内代码,主要接收外层参数,内层直接用export default { props: { //携带几个参数加几个 url: { type: String, default: '' } }}//再者,vue内层给外层通讯//外层代码<comm url=\"https://asd.org/post\" @success=\"Success\" @close='close'></comm>export default { components: { comm }, //引入组件名 data() { }, methods: { Success(resData) { }, close() { } }}//内层代码this.$emit('Success', resData.data);this.$emit('close', resData.data); —待补充—","tags":[{"name":"前端","slug":"前端","permalink":"https://pizerliu.github.io/tags/前端/"},{"name":"vue","slug":"vue","permalink":"https://pizerliu.github.io/tags/vue/"}]},{"title":"初入java,一脸蒙蔽pizer是也","date":"2017-03-27T01:57:31.000Z","path":"2017/03/27/java基础函数整理/","text":"java基础函数整理 比较两个字符串 123两个字符串A和B,A.compareTo(B) //区分大小写比较A.compareToIgnoreCase(B) // 忽略大小写比较 查找字符串最后一次出现的位置 123字符串strOrig,lastIndex是查找字符串最后一次出现的位置(若为-1则不存在字符串内)String strOrig = \"Hello world ,Hello Runoob\";int lastIndex = strOrig.lastIndexOf(\"Hello\"); 删除字符串中的一个字符 12字符串str,removeCharAt(str, 3) 字符串替换 123字符串str,String str=\"Hello World\";str.replaceFirst(\"He\", \"Wa\") 字符串反转 12345String string=\"runoob\";String reverse = new StringBuffer(string).reverse().toString();System.out.println(\"字符串反转前:\"+string);System.out.println(\"字符串反转后:\"+reverse); 字符串搜索 1234567String strOrig = \"Google Runoob Taobao\";int intIndex = strOrig.indexOf(\"Runoob\");if(intIndex == - 1){ System.out.println(\"没有找到字符串 Runoob\");}else{ System.out.println(\"Runoob 字符串位置 \" + intIndex);} 字符串分割 12345678910111213141516171819String str = \"www-runoob-com\";String[] temp;String delimeter = \"-\"; // 指定分割字符temp = str.split(delimeter); // 分割字符串// 普通 for 循环for(int i =0; i < temp.length ; i++){ System.out.println(temp[i]); System.out.println(\"\");}System.out.println(\"------java for each循环输出的方法-----\");String str1 = \"www.runoob.com\";String[] temp1;String delimeter1 = \"\\\\.\"; // 指定分割字符, . 号需要转义temp1 = str1.split(delimeter1); // 分割字符串for(String x : temp1){ System.out.println(x); System.out.println(\"\");} 字符串小写转大写 1234String str = \"string runoob\";String strUpper = str.toUpperCase();System.out.println(\"原始字符串: \" + str);System.out.println(\"转换为大写: \" + strUpper); 数组排序及元素查找 12// binarySearch第一个参数为要查找的数组,第二个参数是要查找的值int index = Arrays.binarySearch(array, 2); 数组添加元素 12// insertElement第一个参数为要添加的数组,第二个参数是要插入的位置,第三个参数是要插入的值array = insertElement(array, 1, newIndex); 获取数组长度 1data.length 数组反转 12arrayList为要反转的数组Collections.reverse(arrayList); 数组获取最大和最小值 123numbers是一个数组,Arrays.asList()将一个数组转化为一个List对象(int) Collections.min(Arrays.asList(numbers));(int) Collections.max(Arrays.asList(numbers)); 数组合并 1234567String a[] = { \"A\", \"E\", \"I\" };String b[] = { \"O\", \"U\" };//a和b数组都转化为list然后合并再转为数组List list = new ArrayList(Arrays.asList(a));list.addAll(Arrays.asList(b));Object[] c = list.toArray();System.out.println(Arrays.toString(c)); 数组填充 12Array.fill(arrayname,value) 方法Array.fill(arrayname ,starting index ,ending index ,value) 方法 数组扩容 123456789String[] names = new String[] { \"A\", \"B\", \"C\" };String[] extended = new String[5];extended[3] = \"D\";extended[4] = \"E\";System.arraycopy(names, 0, extended, 0, names.length);//输出for (String str : extended){ System.out.println(str);} 删除数组元素 12345678//创建数组并添加元素ArrayList objArray = new ArrayList();objArray.clear();objArray.add(0,\"第 0 个元素\");objArray.add(1,\"第 1 个元素\");objArray.add(2,\"第 2 个元素\");//删除数组元素objArray.remove(1); 数组差集 12//数组objArray 减 数组objArray2objArray.removeAll(objArray2); 数组交集 12//数组objArray 交 数组objArray2objArray.retainAll(objArray2); 数组中查找指定元素 12//数组objArray是否有‘common1’这个元素objArray.contains(\"common1\"); 判断数组是否相等 12//数组ary和数组ary1是否相等Arrays.equals(ary, ary1); 数组并集 12//数组arr1和数组arr2的并集union(arr1, arr2); 格式化时间 1234Date date = new Date();// 获取当前时间String strDateFormat = \"yyyy-MM-dd HH:mm:ss\";SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);// 格式化时间System.out.println(sdf.format(date));// 输出已经格式化的现在时间 获取年份、月份等 123456789101112131415161718192021import java.util.Calendar; public class Main { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); int day = cal.get(Calendar.DATE); int month = cal.get(Calendar.MONTH) + 1; int year = cal.get(Calendar.YEAR); int dow = cal.get(Calendar.DAY_OF_WEEK); int dom = cal.get(Calendar.DAY_OF_MONTH); int doy = cal.get(Calendar.DAY_OF_YEAR); System.out.println(\"当期时间: \" + cal.getTime()); System.out.println(\"日期: \" + day); System.out.println(\"月份: \" + month); System.out.println(\"年份: \" + year); System.out.println(\"一周的第几天: \" + dow); // 星期日为一周的第一天输出为 1,星期一输出为 2,以此类推 System.out.println(\"一月中的第几天: \" + dom); System.out.println(\"一年的第几天: \" + doy); }} 时间戳转换成时间 123Long timeStamp = System.currentTimeMillis(); //获取当前时间戳SimpleDateFormat sdf = new SimpleDateFormat(\"yyyy-MM-dd\");String sd = sdf.format(new Date(Long.parseLong(String.valueOf(timeStamp)))); // 时间戳转换成时间","tags":[{"name":"java","slug":"java","permalink":"https://pizerliu.github.io/tags/java/"},{"name":"java基础函数整理","slug":"java基础函数整理","permalink":"https://pizerliu.github.io/tags/java基础函数整理/"}]},{"title":"前端工具使用","date":"2017-03-24T06:08:22.000Z","path":"2017/03/24/前端工具的使用/","text":"gulp使用: 123456789101112#node.js全局安装gulpnpm install --global gulp#作为项目的开发依赖(devDependencies)安装npm install --save-dev gulp#在项目根目录下创建一个名为 gulpfile.js 的文件:var gulp = require('gulp');gulp.task('default', function() { // 将你的默认的任务代码放在这});#运行 gulp:gulp (想要单独执行特定的任务(task),请输入 gulp <task> <othertask>)","tags":[{"name":"node.js","slug":"node-js","permalink":"https://pizerliu.github.io/tags/node-js/"},{"name":"gulp,webpack,brower","slug":"gulp,webpack,brower","permalink":"https://pizerliu.github.io/tags/gulp,webpack,brower/"},{"name":"koa","slug":"koa","permalink":"https://pizerliu.github.io/tags/koa/"},{"name":"angular","slug":"angular","permalink":"https://pizerliu.github.io/tags/angular/"}]},{"title":"主题加入背景特效并做了改进","date":"2017-03-24T06:08:22.000Z","path":"2017/03/24/主题加入背景特效并做了改进/","text":"yilia的背景特效的注入: 看到诗与远方的博客,感觉背景特效很赞,就借鉴过来用用,酷炫的东西大家都喜欢哈。由于他是对next主题的支持,而对yilia主题的支持还需要略微的修改,接下来就说明下要修改的地方。 主要修改的 ejs 在 themes\\hexo-theme-yilia-master\\layout.ejs :123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109#将<body>改为如下代码<body style=\"z-index: -2;\">#在layout文件底部,加入如下代码:<script type=\"text/javascript\" color=\"64,11,244\" opacity='1' zIndex=\"-1\" count=\"90\"> function browserRedirect() { var sUserAgent = navigator.userAgent.toLowerCase(); var bIsIpad = sUserAgent.match(/ipad/i) == \"ipad\"; var bIsIphoneOs = sUserAgent.match(/iphone os/i) == \"iphone os\"; var bIsMidp = sUserAgent.match(/midp/i) == \"midp\"; var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == \"rv:1.2.3.4\"; var bIsUc = sUserAgent.match(/ucweb/i) == \"ucweb\"; var bIsAndroid = sUserAgent.match(/android/i) == \"android\"; var bIsCE = sUserAgent.match(/windows ce/i) == \"windows ce\"; var bIsWM = sUserAgent.match(/windows mobile/i) == \"windows mobile\"; if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) { //document.getElementById('c_n11').style.display = 'none'; } else { ! function() { function o(w, v, i) { return w.getAttribute(v) || i } function j(i) { return document.getElementsByTagName(i) } function l() { var i = j(\"script\"), w = i.length, v = i[w - 1]; return { l: w, z: o(v, \"zIndex\", -1), o: o(v, \"opacity\", 1), c: o(v, \"color\", \"220,240,120\"), n: o(v, \"count\", 99) } } function k() { r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight } function b() { e.clearRect(0, 0, r, n); var w = [f].concat(t); var x, v, A, B, z, y; t.forEach(function(i) { i.x += i.xa, i.y += i.ya, i.xa *= i.x > r || i.x < 0 ? -1 : 1, i.ya *= i.y > n || i.y < 0 ? -1 : 1, e.fillRect(i.x - 0.5, i.y - 0.5, 1, 1); for(v = 0; v < w.length; v++) { x = w[v]; if(i !== x && null !== x.x && null !== x.y) { B = i.x - x.x, z = i.y - x.y, y = B * B + z * z; y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B, i.y -= 0.03 * z), A = (x.max - y) / x.max, e.beginPath(), e.lineWidth = A*2, e.strokeStyle = \"rgba(\" + s.c + \",\" + (A + 0.2) + \")\", e.moveTo(i.x, i.y), e.lineTo(x.x, x.y), e.stroke()) } } w.splice(w.indexOf(i), 1) }), m(b) } var u = document.createElement(\"canvas\"), s = l(), c = \"c_n11\", e = u.getContext(\"2d\"), r, n, m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(i) { window.setTimeout(i, 1000 / 45) }, a = Math.random, f = { x: null, y: null, max: 20000 }; u.id = c; u.style.cssText = \"display:black;position:absolute;top:10px;left:10px;z-index:\" + s.z + \";opacity:\" + s.o; j(\"body\")[0].appendChild(u); document.getElementById('c_n11').style.display = 'black'; k(), window.onresize = k; window.onmousemove = function(i) { i = i || window.event, f.x = i.clientX, f.y = i.clientY }, window.onmouseout = function() { f.x = null, f.y = null }; for(var t = [], p = 0; s.n > p; p++) { var h = a() * r, g = a() * n, q = 2 * a() - 1, d = 2 * a() - 1; t.push({ x: h, y: g, xa: q, ya: d, max: 6000 }) } setTimeout(function() { b() }, 100) }(); } } browserRedirect();</script> 以上代码实现,背景特效canvas层不会遮挡应用层,并适应pc端和手机端(手机端显示这个特效会巨丑,所以通过判断把手机端的特效给过滤掉了)。 国足的大宝: 下班与好友学长一块去吃羊蝎子看球赛,甚爽,昨日预选赛中国对韩国,时下政治情况下,可谓这场比赛吸引的全国人民的眼球,最后中国足球队顶住压力1:0战胜韩国,扬眉吐气!附小图几张:","tags":[{"name":"hexo","slug":"hexo","permalink":"https://pizerliu.github.io/tags/hexo/"},{"name":"国足大宝","slug":"国足大宝","permalink":"https://pizerliu.github.io/tags/国足大宝/"},{"name":"应用于yilia的背景特效,改进的背景特效","slug":"应用于yilia的背景特效-改进的背景特效","permalink":"https://pizerliu.github.io/tags/应用于yilia的背景特效-改进的背景特效/"}]},{"title":"node.js读取access数据库,绘制微桥智能视频设备数据图表","date":"2017-03-24T06:08:22.000Z","path":"2017/03/24/微桥智能设备应用(使用node-adodb组件)/","text":"node.js读access数据库mdb文件: 本项目使用electron打包桌面应用程序;支持微桥智能视频设备,设备自带软件显示方式单一,为了更直观的了解情况,故采用处理数据以图表形式显示的方式。 node-adodb组件支持node.js在windows读取access数据库mdb文件,并可进行sql操作。 12345678910111213#安装node-adodb组件npm install node-adodb#基本操作,dir_path为mdb文件路径,mdb为mdb文件名var ADODB = require('node-adodb');var connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+ dir_path +'\\\\' + mdb +';');//query操作的是有返回量的,比如查询//execute操作是没有返回量的connection .query('SELECT * FROM DATA_COUNTER WHERE DEVICE = 2;') .once('done', function(datas) { }) 下面是软件截图","tags":[{"name":"node.js","slug":"node-js","permalink":"https://pizerliu.github.io/tags/node-js/"},{"name":"读取access数据库","slug":"读取access数据库","permalink":"https://pizerliu.github.io/tags/读取access数据库/"},{"name":"绘制图表","slug":"绘制图表","permalink":"https://pizerliu.github.io/tags/绘制图表/"},{"name":"微桥智能视频设备","slug":"微桥智能视频设备","permalink":"https://pizerliu.github.io/tags/微桥智能视频设备/"}]},{"title":"小站接入友情链接头像","date":"2017-03-23T08:54:29.000Z","path":"2017/03/23/小站接入友情链接头像/","text":"ejs这小家伙不好用呀 前天在思考给木双鱼小站加些什么功能那,偶然在litten作者github的issue板块发现有人提出了友情链接图标的添加,网上看了下没有发现有网友添加这个功能,yilia主题的友情链接只有一个名字看着的确干巴巴的,决定自己来搞定这块. 基本想法比较简单,后面再进行拓展,有了友情链接的url,一般正规网站都会采用url/favicon.ico的方式存放图标,假如图标链接无效的话,采用备用头像。 最开始没有想到直接用img标签解决,而是想改写ejs代码实现,但是经过两天的挣扎,实现功能就卡在一步上(js参数传递给ejs参数),搞了两天没有解决这个问题,最后决定放弃这种方法,采用img标签的方法解决。不过还是介绍下自己学习ejs的学习。 友情链接这块的 ejs 在 themes\\hexo-theme-yilia-master\\layout\\tools.ejs。 ejs的大致语法为:12345678模板逻辑代码<% code %>输出变量值<%= code %>不做转义的输出变量值<%- code %>满足 if else、for in、foreach、对象数组的基本用法如push等 语法,ejs变量可以赋值给js变量,但是js变量没办法赋值给ejs变量。(ps:搞了两天没解决,如果我搞错了,希望大神指导) 最终采用img标签方式解决了问题,基本方法如下:12345678910111213141516171819202122#在tools.ejs文件里找到以下代码:<% for (var i in theme.friends){ %> <li class=\"search-li\"> <a href=\"<%- url_for(theme.friends[i]) %>\" target=\"_blank\" style=\"color:#969696\" class=\"search-title\"><i class=\"icon\"></i> <%if( url_for(theme.friends[i]) ){%> <%= i %></a> <% } %> </li><% } %>#将<%= i %>前面加上以下代码:<img class=\"imgUrl\" src=\"<%= url_for(theme.friends[i]) + 'favicon.ico' %>\" alt=\"icon\" height=\"40\" width=\"40\" />&nbsp&nbsp&nbsp#将tools.ejs文件尾部加上以下代码:<script type=\"text/javascript\"> t = document.getElementsByClassName(\"imgUrl\"); for(i = 0; i < t.length; i++){ t.item(i).onerror = function(){ this.src = \"https://pizerliu.github.io/earth.png\" } }</script> 最终,实现了友情链接的头像添加。","tags":[{"name":"hexo","slug":"hexo","permalink":"https://pizerliu.github.io/tags/hexo/"},{"name":"ejs更改","slug":"ejs更改","permalink":"https://pizerliu.github.io/tags/ejs更改/"},{"name":"添加友情链接头像","slug":"添加友情链接头像","permalink":"https://pizerliu.github.io/tags/添加友情链接头像/"}]},{"title":"hexo主题功能的注入","date":"2017-03-20T15:27:31.000Z","path":"2017/03/20/hexo主题功能的注入/","text":"一、多说评论功能的注入: 首先,在多说注册账号,获得账号名字,并在_config.yml里添加代码:12#是否开启多说duoshuo_shortname: pizer 并在主题目录下的 themes\\landscape\\layout_partial\\article.ejs 模板的源文件:1234567891011121314151617<% if (!index && post.comments && config.disqus_shortname){ %><section id=\"comments\"> <div id=\"disqus_thread\"></div> <script type=\"text/javascript\"> /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */ var disqus_shortname = '<%=config.disqus_shortname%>'; // required: replace example with your forum shortname /* * * DON'T EDIT BELOW THIS LINE * * */ (function() { var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); })(); </script> <noscript>Please enable JavaScript to view the <a href=\"https://disqus.com/?ref_noscript\">comments powered by Disqus.</a></noscript></section><% } %> 更改为:1234567891011121314151617181920<% if (!index && post.comments && config.duoshuo_shortname){ %> <section id=\"comments\"> <!-- 多说评论框 start --> <div class=\"ds-thread\" data-thread-key=\"<%= post.layout %>-<%= post.slug %>\" data-title=\"<%= post.title %>\" data-url=\"<%= page.permalink %>\"></div> <!-- 多说评论框 end --> <!-- 多说公共JS代码 start (一个网页只需插入一次) --> <script type=\"text/javascript\"> var duoshuoQuery = {short_name:'<%= config.duoshuo_shortname %>'}; (function() { var ds = document.createElement('script'); ds.type = 'text/javascript';ds.async = true; ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js'; ds.charset = 'UTF-8'; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ds); })(); </script> <!-- 多说公共JS代码 end --> </section><% } %> 二、最后更新时间和知识许可协议链接的注入: 这部分是参考Percy大兄弟的博客改写的: 将begin与end之间的内容添加到主题目录下 themes\\landscape\\layout_partial\\article.ejs文件。 123456789101112131415#<%- post.content %> 代码和 <% } else { %> 代码之间,代码如下:<div class=\"article-moreinfo\"> <div class=\"lastModifiedDate\"> <span>最后更新:</span> <time datetime=\"<%= date_xml(post.updated) %>\" itemprop=\"dateLastModified\"> <%= date(post.updated, null) %> </time> </div> <div class=\"copyright\"> <span>许可协议:</span> <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-nd/4.0/\">知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议</a> </div></div>","tags":[{"name":"hexo","slug":"hexo","permalink":"https://pizerliu.github.io/tags/hexo/"},{"name":"多说评论","slug":"多说评论","permalink":"https://pizerliu.github.io/tags/多说评论/"},{"name":"最后更新时间","slug":"最后更新时间","permalink":"https://pizerliu.github.io/tags/最后更新时间/"},{"name":"知识许可协议","slug":"知识许可协议","permalink":"https://pizerliu.github.io/tags/知识许可协议/"}]},{"title":"2017/3/20 木双鱼小站建立","date":"2017-03-20T01:25:20.000Z","path":"2017/03/20/木双鱼小站建立/","text":"惺惺松松 近日学习工作之余,突然有建立一个自己博客的想法,既可以记录下自己平时学习的过程,也可以平复自己这颗浮躁的心,记录下自己生活的点点滴滴也是很有意义的。 通过查看,发现了hexo,它是一个快速、简洁且高效的博客框架,可以帮助我快速搭建博客。通过查看,发现它的默认主题并不是我的菜,于是继续去google寻找我的最爱。通过翻阅发现了yilia主题,茫茫人海中看到了最爱的感觉,yilia简洁大方,重点突出,它就这么容易的get到我了。 搭建过程 安装node和git(google一抓一大把,就不细说啦,在git上要建立一个项目,github提供了一个免费空间,具体搭建请google) 下载yilia主题包 安装hexo 代码如下操作:1npm install -g hexo-cli 主要操作命令如下:1234567hexo init [项目名字]#编译hexo g#本地运行hexo s#根据配置上传到githexo d hexo d 命令需要先配置hexo根目录下的_config.yml文件(重点:hexo根目录) theme: hexo-theme-yilia-master #这里要填写你的主题名字,也就是文件夹名字 deploy: type: git repository: [这里填写你的git项目] branch: master 具体使用查看hexo文档 4.配置个人信息 切记个人头像和ico的配置都是在yilia主题根目录下的_config.yml文件(重点:yilia主题根目录),具体配置查看作者litten介绍","tags":[{"name":"hexo","slug":"hexo","permalink":"https://pizerliu.github.io/tags/hexo/"},{"name":"配置hexo","slug":"配置hexo","permalink":"https://pizerliu.github.io/tags/配置hexo/"}]}]