CNN 模型压缩与加速算法综述

CNN 模型压缩与加速算法综述

姜媚 2017-08-21 5760标签: CNN , 神经网络

导语:卷积神经网络日益增长的深度和尺寸为深度学习在移动端的部署带来了巨大的挑战,CNN模型压缩与加速成为了学术界和工业界都重点关注的研究领域之一。

前言

自从AlexNet一举夺得ILSVRC 2012 ImageNet图像分类竞赛的冠军后,卷积神经网络(CNN)的热潮便席卷了整个计算机视觉领域。CNN模型火速替代了传统人工设计(hand-crafted)特征和分类器,不仅提供了一种端到端的处理方法,还大幅度地刷新了各个图像竞赛任务的精度,更甚者超越了人眼的精度(LFW人脸识别任务)。CNN模型在不断逼近计算机视觉任务的精度极限的同时,其深度和尺寸也在成倍增长。

表1 几种经典模型的尺寸,计算量和参数数量对比

Model Model Size(MB) Million
Mult-Adds
Million
Parameters
AlexNet[1] >200 720 60
VGG16[2] >500 15300 138
GoogleNet[3] ~50 1550 6.8
Inception-v3[4] 90-100 5000 23.2

随之而来的是一个很尴尬的场景:如此巨大的模型只能在有限的平台下使用,根本无法移植到移动端和嵌入式芯片当中。就算想通过网络传输,但较高的带宽占用也让很多用户望而生畏。另一方面,大尺寸的模型也对设备功耗和运行速度带来了巨大的挑战。因此这样的模型距离实用还有一段距离。

在这样的情形下,模型小型化与加速成了亟待解决的问题。其实早期就有学者提出了一系列CNN模型压缩方法,包括权值剪值(prunning)和矩阵SVD分解等,但压缩率和效率还远不能令人满意。

近年来,关于模型小型化的算法从压缩角度上可以大致分为两类:从模型权重数值角度压缩和从网络架构角度压缩。另一方面,从兼顾计算速度方面,又可以划分为:仅压缩尺寸和压缩尺寸的同时提升速度。

本文主要讨论如下几篇代表性的文章和方法,包括SqueezeNet[5]、Deep Compression[6]、XNorNet[7]、Distilling[8]、MobileNet[9]和ShuffleNet[10],也可按照上述方法进行大致分类:

表2 几种经典压缩方法及对比

Method Compression Approach Speed Consideration
SqueezeNet architecture No
Deep Compression weights No
XNorNet weights Yes
Distilling architecture No
MobileNet architecture Yes
ShuffleNet architecture Yes

继续阅读CNN 模型压缩与加速算法综述

WD MyCloud拆硬盘恢复系统后容量部分显示0KB

捣鼓挂掉WD MyCloud之后,在参照 拯救死翘翘了的 WD My Cloud 恢复系统后,首页中的容量部分显示0KB,如下图:

解决方法为,进行一次"仅系统"的"系统出厂还原",如下图:

参考链接


MyCloud showing 0kb available, data and files cannot be accessed

让WordPress 4.9支持上传更多文件类型

WordPress对上传的文件类型是有限制的,在这里,我们以在子主题twentyfifteen-child中增加扩展名为.bz2的文件类型为例子。

首先编辑子主题的functions.php文件

$ sudo vim /var/www/wordpress/wp-content/themes/twentyfifteen-child/functions.php

在文件尾部增加如下内容:

<?php
	/*BUG Fix for after wordpress https://core.trac.wordpress.org/ticket/21299*/
	add_filter( 'wp_check_filetype_and_ext', 'upload_mimes_fix_after_47', 10, 4 );
	function upload_mimes_fix_after_47($data, $file, $filename, $mimes) {
		global $wp_version;
		if( $wp_version == '4.7' || ( (float) $wp_version < 4.7 ) ) { return $data; }
		$filetype = wp_check_filetype( $filename, $mimes );
		return [ 'ext' => $filetype['ext'], 'type' => $filetype['type'], 'proper_filename' => $data['proper_filename'] ];
	}

	/*add upload file type*/
	add_filter('upload_mimes', 'custom_upload_mimes');
	function custom_upload_mimes ( $existing_mimes=array() ) {
		$existing_mimes['bz2'] = 'application/octet-stream';
		return $existing_mimes;
	}
?>

参考链接


Ubuntu 16.04下用Python显示YUV格式的图片

YUV420p to RGB & view

from PIL import Image
import sys
from struct import *
import array

if len(sys.argv) != 4:
        print "***** Usage syntax Error!!!! *****\n"
        print "Usage:"
        print "python <script> <.yuv file yuv420p> <width&gt> <height> "
        sys.exit(1) # exit
else:
        pass

image_name = sys.argv[1]
width = int(sys.argv[2])
height = int(sys.argv[3])

y = array.array('B')
u = array.array('B')
v = array.array('B')

f_y = open(image_name, "rb")
f_uv = open(image_name, "rb")
f_uv.seek(width*height, 1)

image_out = Image.new("RGB", (width, height))
pix = image_out.load()

print "width=", width, "height=", height

for i in range(0, height/2):
    for j in range(0, width/2):
        u.append(ord(f_uv.read(1)));

for i in range(0, height/2):
    for j in range(0, width/2):
        v.append(ord(f_uv.read(1)));
for i in range(0,height):
    for j in range(0, width):
        y.append(ord(f_y.read(1)));
        #print "i=", i, "j=", j , (i*width), ((i*width) +j)
        #pix[j, i] = y[(i*width) +j], y[(i*width) +j], y[(i*width) +j]
        Y_val = y[(i*width)+j]
        U_val = u[((i/2)*(width/2))+(j/2)]
        V_val = v[((i/2)*(width/2))+(j/2)]
        B = 1.164 * (Y_val-16) + 2.018 * (U_val - 128)
        G = 1.164 * (Y_val-16) - 0.813 * (V_val - 128) - 0.391 * (U_val - 128)
        R = 1.164 * (Y_val-16) + 1.596*(V_val - 128)
        pix[j, i] = int(R), int(G), int(B)

######################################################
# B = 1.164(Y - 16)                   + 2.018(U - 128)
# G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
# R = 1.164(Y - 16) + 1.596(V - 128)
######################################################

#image_out.save("out.bmp")
image_out.show()

UYVY/YUV422 to RGB and view:

from PIL import Image
import sys
from struct import *
import array
 
if len(sys.argv) != 4:
        print "***** Usage syntax Error!!!! *****\n"
        print "Usage:"
        print "python <script> <.yuv file uyvy422> <width&gt> <height> "
        sys.exit(1) # exit
else:
        pass
 
image_name = sys.argv[1]
width = int(sys.argv[2])
height = int(sys.argv[3])
 
y = array.array('B')
u = array.array('B')
v = array.array('B')
 
f_uyvy = open(image_name, "rb")
f_uv = open(image_name, "rb")
f_uv.seek(width*height, 1)
 
image_out = Image.new("RGB", (width, height))
pix = image_out.load()
 
print "width=", width, "height=", height
 
for i in range(0,height):
    for j in range(0, width/2):
        u  = ord(f_uyvy.read(1));
        y1 = ord(f_uyvy.read(1));
        v  = ord(f_uyvy.read(1));
        y2 = ord(f_uyvy.read(1));
 
        B = 1.164 * (y1-16) + 2.018 * (u - 128)
        G = 1.164 * (y1-16) - 0.813 * (v - 128) - 0.391 * (u - 128)
        R = 1.164 * (y1-16) + 1.596*(v - 128)
        pix[j*2, i] = int(R), int(G), int(B)
 
        B = 1.164 * (y2-16) + 2.018 * (u - 128)
        G = 1.164 * (y2-16) - 0.813 * (v - 128) - 0.391 * (u - 128)
        R = 1.164 * (y2-16) + 1.596*(v - 128)
        pix[j*2+1, i] = int(R), int(G), int(B)
 
######################################################
# B = 1.164(Y - 16)                   + 2.018(U - 128)
# G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
# R = 1.164(Y - 16) + 1.596(V - 128)
######################################################
 
#image_out.save("out.bmp")
image_out.show()

原始链接


YUV to RGB : Python Imaging Library

Ubuntu14.04安装和配置ROS Indigo

安装ROS

配置Ubuntu的软件源

配置Ubuntu要求允许接受restricted、universe和multiverse的软件源,可以根据下面的链接配置:
https://help.ubuntu.com/community/Repositories/Ubuntu

配置成如下图所示即可,一般情况下,这些配置都是默认的。

添加软件源到sources.list

设置软件源的代码如下:

$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'

一旦添加了正确的软件源,操作系统就知道去哪里下载程序,并根据命令自动安装软件。

设置密钥

$ wget http://packages.ros.org/ros.key -O - | sudo apt-key add -

安装

首先确认你的Debian的软件包索引是最新的。Debian计划是一个致力于创建一个自由操作系统的合作组织。我们所创建的这个操作系统名为 Debian。Debian系统目前采用Linux内核或者FreeBSD内核。

$ sudo apt-get update

在ROS中有许多不同的函数库和工具,建议是完全安装,也可以根据自己的要求分别安装。完全安装时的工具包括ROS、rqt、可视化环境rviz、通用机器人库robot-generic libraries、2D(如stage)和3D(如Gazebo)仿真环境2D/3D simulators、导航功能包集navigation and 2D/3D(移动、定位、地图绘制、机械臂控制)、感知库perception(如视觉、激光雷达、RGB-D摄像头等)。

$ sudo apt-get install ros-indigo-desktop-full

初始化rosdep

rosdep不仅能够使你更方便的安装一些系统依赖程序包,而且ROS的一些主要部件的运行也需要rosdep。

$ sudo rosdep init
$ rosdep update

安装rosinstall

rosinstall命令是一个使用的非常频繁的命令,使用这个命令可以轻松的下载许多ROS软件包。

$ sudo apt-get install python-rosinstall

设置环境

添加ROS的环境变量,这样,当你打开你新的shell时,你的bash会话中会自动添加环境变量。

$ echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
# 使环境变量设置立即生效
$ source ~/.bashrc

配置你的ROS环境

注意:当你用像apt这样的软件包安装管理器安装ROS,那么这些软件包用户是没有权利的去编辑的,当创建一个ROS package和处理一个ROS package时,你应该始终选择一个你有权限工作的目录作为工作目录。

管理你的环境

在安装ROS的时候,你会看到提示:source(命令)几个setup.*sh文件,或者甚至添加sourcing到你的shell启动脚本中。这是必须的,因为ROS依赖于结合使用shell环境的概念上。这使得开发依赖不同版本的ROS或者不同系列的package更加容易。

如果你在寻找或者使用你的ROS package上有问题,请确定的你的ROS环境变量设置好了,检查是否有ROS_ROOT和ROS_PACKAGE_PATH这些环境变量。

$ export | grep ROS

如果没有,你需要source一些setup.*sh文件。

环境设置文件是为你产生的,但是可以来自不同的地方:

  • 使用package管理器安装的ROS package提供setup.*sh文件;
  • rosbuild workspace使用像rosws这样的工具提供setup.*sh文件;
  • setup.*sh文件在编译和安装catkin package时作为副产品创建。

注意:rosbuild和catkin是两种组织和编译ROS代码的方式,前者简单易用,后者更加复杂但是提供更多灵活性尤其是对那些需要去集成外部代码或者想发布自己软件的人。

如果你在Ubuntu 14.04上使用apt工具安装ROS,那么你会在'/opt/ros/indigo/'目录中有setup.*sh文件,你可以这样source它们:

$ source /opt/ros/indigo/setup.bash

你每次打开新的shell都需要运行这个命令,如果你把source /opt/ros/indigo/setup.bash添加进.bashrc文件就不必要每次打开一个新的shell都运行这条命令才能使用ROS的命令了。

创建ROS工作环境

对于ROS Groovy和之后的版本可以参考以下方式建立catkin工作环境。在shell中运行:

$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace

可以看到在src文件夹中可以看到一个CMakeLists.txt的链接文件,即使这个工作空间是空的(在src中没有package),任然可以建立一个工作空间。

$ cd ~/catkin_ws/
$ catkin_make

catkin_make命令可以非常方便的建立一个catkin工作空间,在你的当前目录中可以看到有build和devel两个文件夹,在devel文件夹中可以看到许多个setup.*sh文件。启用这些文件都会覆盖你现在的环境变量,想了解更多,可以查看文档catkin。在继续下一步之前先启动你的新的setup.*sh 文件。

$ source devel/setup.bash

为了确认你的环境变量是否被setup脚本覆盖了,可以运行一下命令确认你的当前目录是否在环境变量中:

$ echo $ROS_PACKAGE_PATH

输出:

/home/youruser/catkin_ws/src:/opt/ros/indigo/share:
/opt/ros/indigo/stacks

至此,你的环境已经建立好了,可以继续学习ROS文件系统了!

参考链接


Ubuntu14.04安装和配置ROS Indigo

ubuntu 16.04/ubuntu 17.10下解决wireshark权限问题

ubuntu 16.04/ubuntu 17.10下使用wireshark可能会遇到如下权限问题:

Couldn’t run /usr/bin/dumpcap in child process: Permission denied

也有可能列表中找不到我们抓包的网卡。

可以使用如下方法解决:

1.添加wireshark用户组

$ sudo groupadd wireshark

2.将dumpcap更改为wireshark用户组

$ sudo chgrp wireshark /usr/bin/dumpcap

3.让wireshark用户组有root权限使用dumpcap

$ sudo chmod 4755 /usr/bin/dumpcap

4.将需要使用的用户名(一般都是当前登陆用户)加入wireshark用户组

$ sudo gpasswd -a `whoami` wireshark

参考链接


ubuntu下解决wireshark权限问题

macOS Sierra升级到macOS High Sierra后执行cc,git命令报错

macOS Sierra升级到macOS High Sierra后执行cc,git等命令报错,错误信息如下:

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

解决方法如下:

$ xcode-select --install

参考链接


mac更新系统后Git不能用,提示missing xcrun at

Windows 7系统上安装CentOS 7后通过修改grub2添加Windows 7启动引导项

按照以往的经验,先安装Windows 7之后,再装CentOS 7,那么CentOS 7应该会自动添加Windows 7启动项。但是安装完成后,发现启动项里没有Windows 7

我们需要手动添加Windows 7的启动项。

我们需要修改grub2的模版文件,然后执行grub2-mkconfig自动重建grub2引导列表。

$ sudo cp /etc/grub.d/40_custom /etc/grub.d/41_win7_custom

$ sudo vi /etc/grub.d/41_win7_custom

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry 'Windows 7'{
set root=(hd0,1)
chainloader +1
}

$ grub2-mkconfig -o /boot/grub2/grub.cfg
$ reboot

至于set root=(hd0,1),还是set root=(hd0,msdos1),或者set root=(hd0,msdosX),请在启动列表中按下e键,进入grub rescue模式,执行ls命令列出分区,如果第一个启动不了,请逐个分区都试试。

参考链接


Centos7 + Windows7 双系统,通过修改grub2,重新添加 Win7 启动引导项