How to elaborate and train a Neural Network

March 31st, 2017 by JasonLe's Tech 392 views

Elaborate a Neural Network

First, pick a network architecture; choose the layout of your neural network, including how many hidden units in each layer and how many layers in total you want to have.

  • Number of input units = dimension of features x(i)

  • Number of output units = number of classes

  • Number of hidden units per layer = usually more the better (must balance with cost of computation as it increases with more hidden units)

  • Defaults: 1 hidden layer. If you have more than 1 hidden layer, then it is recommended that you have the same number of units in every hidden layer.

构建 Neural Network 首先要明确要创建几个隐藏层,每个隐藏层有多少个参数。

首先输入单元个数就是输入的特征数,输出的个数就是分类的个数,每个隐藏层中单元的个数是多少?

通常意义上,隐藏层中单元的个数越多,这个分类效果越好,但是需要权衡计算与特征数的关系。默认情况,一个神经网络会存在一个隐藏层,当多余一个隐藏层的情况下,每层拥有的单元个数相同。

Training a Neural Network

  • Randomly initialize the weights
  • Implement forward propagation to get hΘ(x(i)) for any x(i)
  • Implement the cost function
  • Implement backpropagation to compute partial derivatives
  • Use gradient checking to confirm that your backpropagation works. Then disable gradient checking.
  • Use gradient descent or a built-in optimization function to minimize the cost function with the weights in theta.

输入的特征的权重是随机指定的(如果全部输入的权重都为一个常数,那么输入到隐藏层的值就是相同的,那么导致hΘ(x(i))也是相同的,导致symmetry。不同的初始权重就是为了Symmetry Breaking)。

实现前馈传播算法,计算出每层的x(i),实现代价函数,通过反向传播算法计算每个Θ的偏导,然后通过梯度检查测试反向传播算法是否成功,然后将梯度检查disable掉(梯度检查计算复杂度太高)。

最后使用梯度下降找到最小的代价函数值和Θ。这个就是需要的特征集。

参考:

http://blog.csdn.net/jinlianjingd/article/details/50767743

https://www.coursera.org/learn/machine-learning/supplement/Uskwd/putting-it-together

Docker 编排工具简述

March 28th, 2017 by JasonLe's Tech 344 views

编排是一个新的词汇,经过阅读才明白编排指的是容器的集群化和调度。另一类含义指的是容器管理,负责管理容器化应用和组件任务。

典型的编排工具有:Docker swarm mode、Kuberbetes和Mesosphere DCOS,这三个工具都提供相同的特性,但同时三个工具所处于的地位又不尽相同。

  1. 这些工具在容器集群中提供或者调度容器,还可以启动容器。会根据需求,例如资源和部署位置,在最佳VM中启动容器。

       2. 脚本保证你把指定的配置加载到容器中。

       3. 容器管理工具跟踪和监控容器的健康,将容器维持在集群中。正常情况下,监视工具会在容器崩溃时启动一个新实例。如果服务器故障,工具会在另一台服务器上重启容器。这些工具还会运行系统健康检查、报告容器不规律行为以及VM或服务器的不正常情况。

       4.需要部署新版本的容器或者升级容器中应用时,容器管理工具自动在集群中更新你的容器或应用。如果出现问题,它们允许你回滚到正确配置的版本。

       5.容器使用服务发现来找到它们的资源。

       6.你希望容器运行在哪里?你希望每个容器分配多少CPU?所有这些需求都可以通过设置正确的容器部署策略实现。

        7.容器要能够和已有的IT管理工具兼容。

=================

Docker Swarm mode 和 Docker Swarm 

这是两款独立的编排工具,Docker Swarm是一种较旧的独立产品,曾经用于管理Docker集群。而Swarm mode是Docker内置的集群管理器。Docker 1.12后,Swarm mode引入Docker ,成为Docker Engine的一部分。

Docker swarm mode 支持滚动更新、节点间传输层安全加密、负载均衡和简单的服务抽象。可以在多个主机之间传播容器负载,它允许你在多个主机平台上设置swarm(即群集)。

Kubernetes

Kubernetes最初由有谷歌开发的开源容器管理工具。这个工具提供高度的互操作性,以及自我修复、自动升级回滚以及存储编排。目前负载均衡做的还不是很好,但是我们仍然需要在Kubernets基础上加入监控日志系统。

Marathon

Marathon是为Mesosphere DC/OS和Apache Mesos设计的容器编排平台。Marathon有很多特性,包括高可用、服务发现、负载均衡。

综上所述Mesos和Kubernetes主要用于运行集群应用程序。Mesos专注于通用调度,以插件的方式提供多个不同的调度器。而Kubernetes者用来构建容器的分布式环境。对于可以结合三个工具的优缺点,来构建容器云达到更好的管理效果。

 

https://docs.docker.com/engine/swarm/

https://kubernetes.io/

https://github.com/mesosphere/marathon

docker 初体验

February 21st, 2017 by JasonLe's Tech 392 views

Docker话说已经活了好几年了,业界开始逐步从热议到逐步落地使用,之前硕士搞过一年的LXC,虽然Docker这个技术新瓶装旧酒,但是由于加入了特有的hub机制,使其易于传播,易用性比LXC更具优势。

今天抽空使用了一下docker,准备将自己的 VPS 容器化,方便以后在不同主机中迁移。

Docker由三部分组成:一个运行docker命令的client, 一个包含images并以容器(container)形式运行image的主机,一个docker的images仓库。client与docker host上面的docker daemon通信。当然docker client和host可以运行于一台机器(我们做实验的时候是一台),默认的docker仓库是Docker Hub。

docker使用流程就是client pull 从hub上把image拉到docker host,然后通过run命令指挥image到host上面弄一个container来跑这个image。

或者就是client 通过build命令在host上面创建一个自己的image,然后通过push命令把image推到仓库。然后别人就可以使用自己构建的镜像。

刚开始使用对image容易搞混乱,按照我的理解:image就是一个文件系统镜像,用户无法直接修改这个镜像,类似于一种二进制文件形式(其实是一种特殊的文件系统)里面运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

我们使用docker run就可以将这个image运行起来,运行起来的image就是container。运行起来的container我们可以对其进行各种修改,每产生一个修改,就产生一个commition ID。后一个构建依赖前一个构建,因此和git版本管理很像!

image和container之间的关系类似程序与进程之间的关系!

Docker命令实例

  1. docker pull的格式是:
docker pull[选项] [Docker Registry地址] <仓库名>:<标签名>

2.docker images命令下载的images:

$docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu ml 14.04 b969ab9f929b 1 weeksago 210 MB

3.最最重要的就是docker run

$docker run -p 8080:80 -p 111:22 -i -t -name [docker-name] -d COMMAND

其中的-p指的是端口映射,-d 设置该容器以daemon模式运行,具体实例:

$ sudo docker run -i -t ubuntu:14.04 /bin/bash

docker run – 运行一个容器
-t – 分配一个(伪)tty (link is external)
-i – 交互模式 (so we can interact with it)
ubuntu:14.04 – 使用 ubuntu 基础镜像 14.04
/bin/bash – 运行命令 bash shell

4. docker start 其实就是docker run的缩写,创建好container之后就不用再输入很长的命令,而是由一个docker start代替。

$docker start [docker-name]

5. docker ps 可以显示出运行的所有容器

$ docker ps
CONTAINER ID       IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
e3a913872698       ubuntu:14.04       "bash"              11seconds ago      Up 10 seconds                           wizardly_elion
db1c25753e97       ubuntu:14.04       "bash"              21seconds ago      Up 21 seconds                           adoring_shannon

这几个命令在使用中使用频率最高。

Dockerfile是构建image的文件,类似于脚本命令。

# ubuntu 14.04 with vim and gcc
FROM ubuntu:14.04
MAINTAINER lzz<ldm5235@gmail.com>
RUN apt-get update && apt-getinstall –y vim gcc

其中FROM指定构建镜像的基础源镜像,如果本地没有指定的镜像,则会自动从 Docker 的公共库 pull 镜像下来。
FROM必须是 Dockerfile 中非注释行的第一个指令,即一个 Dockerfile 从FROM语句开始。FROM可以在一个 Dockerfile 中出现多次,如果有需求在一个 Dockerfile 中创建多个镜像。如果FROM语句没有指定镜像标签,则默认使用latest标签。
MAINTAINER <name> 指定创建镜像的用户

RUN 有两种使用方式
RUN “executable”, “param1”, “param2”
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像,后续的RUN都在之前RUN提交后的镜像为基础,镜像是分层的,可以通过一个镜像的任何一个历史提交点来创建,类似源码的版本控制。

exec 方式会被解析为一个 JSON 数组,所以必须使用双引号而不是单引号。exec 方式不会调用一个命令 shell,所以也就不会继承相应的变量,如:

RUN [ “echo”, “$HOME” ]
这种方式是不会达到输出 HOME 变量的,正确的方式应该是这样的

RUN [ “sh”, “-c”, “echo”, “$HOME” ]
RUN产生的缓存在下一次构建的时候是不会失效的,会被重用,可以使用–no-cache选项,即docker build –no-cache,如此便不会缓存。

 

http://www.cnblogs.com/hustcat/p/3980244.html

http://blog.csdn.net/u011537073/article/details/52719363

字符串乱码解决之道

January 5th, 2017 by JasonLe's Tech 395 views

最近工作压力太大,blog也逐渐荒废,怎么也得写点东西了,要不说不过去。。。。。

Qt为字节流和字符串分别提供了QByteArray和QString两个类(还有QLatin1String等其他类,但这两个是最主要的)。当我们涉及到I/O时,比如读写文件、读写网络socket、控制台输入输出、读写串口… 操作的都是字节流,如果我们此时需要操作的内容是字符串,则需要二者之间的相互转换。在C和C++中,我们一般都是将 “Hello World!” 这种称为字符串。但是就目前而言,当我们提字符串时,一般是指一个Unicode字符串,其由一个一个的Unicode字符构成;当我们提字节流时,是指一个一个的字节。或许我们可以说,ANSI C/C++截止目前只有字节流,而缺乏对字符串的支持。另外各个编译器对编码的支持又严重不一, Qt为解决这个问题提供了QTextCodec。

QTextCodec * textc = QTextCodec::codecForName("GBK");
1.QTextCodec::setCodecForCStrings(textc);
2.QTextCodec::setCodecForTr(textc); 
3.QTextCodec::setCodecForLocale(textc);

QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString。很简单的问题,”我是中文”这样写的时候,它是传统的char 类型的窄字符串,我们需要的只不过是通过某种方式告诉QString 这四个汉字采用的那种编码。而问题一般都出在很多用户对自己当前的编码没太多概念。另外文件是有编码的,但是这种纯文本文件却不会记录自己采用的编码,这个是问题的根源。真的是 QString 乱码了吗?其实很简单的一个问题,当你从窄字符串 char* 转成Unicode的QString字符串的时候,你需要告诉QString你的这串char* 中究竟用的是什么编码?GBK、BIG5还是Latin-1。理想情况就是:将char* 传给QString时,同时告诉QString自己的编码是什么;但是QString 提供的成员函数,远远满足不了大家的需求,于是只有采取语句1的办法。

tr(“中文”);与QString(“中文”);一样,你必须告诉tr这个窄字符串是何种编码?你不告诉它,它就用latin1。于是所谓的乱码问题就出来了。如何告诉tr你写的这几个汉字在磁盘中保存的是何种编码呢?这正是语句2所做的。如果你的编码采用的utf8,可以直接使用trUtf8而不必设置setCodecForTr()。

对于语句3应该没什么好说的,在绝大多数情况下,我们在代码中应该都用不到这个函数(默认的system应该比我们所能设置的要好)。
下面讲一下关于编码转换问题:
QT中的QString内容使用Unicode作为文本编码。但是实际系统中通常采用的是其他编码,例如GBK,utf8等。为了便于兼容这些格式,QT中还设置了两个字符串类型:
QCString类: C类型字符串,必须以\0结尾,也就是中间不能含有\0. 例如GBK编码的字符串
QByteArray类: 中间可以含有\0.例如utf8编码的字符串

在设置下面的代码基础上:

QTextCodec *gbk = QTextCodec::codecForName("gb18030"); 
QTextCodec *utg8 = QTextCodec::codecForName("utf-8");
QTextCodec::setCodecForTr(gbk);
QTextCodec::setCodecForLocale(gbk);
QTextCodec::setCodecForCStrings(gbk);

1. UTF-8 转换 GBK

QString U2G(QString utfStr)
{
   return gbk-&gt;toUnicode(utfStr.toLocal8Bit());
}

2 GBK 转换 UTF-8

QString U2G(QString gbkStr)
{
   return utg8-&gt;toUnicode(gbkStr.toUtf8());
}

代码示例:
———————————————————————————–

 QTextCodec *gbk = QTextCodec::codecForName("gb18030");
 QTextCodec *utf8 = QTextCodec::codecForName("utf-8");

 QTextCodec::setCodecForTr(gbk);
 QTextCodec::setCodecForLocale(gbk);
 QTextCodec::setCodecForCStrings(gbk);


 QFile file("../test.txt");
 file.open(QIODevice::ReadOnly);
 QByteArray readByte = file.readAll();
 QString readStr = utf8->toUnicode(readByte.data());
 file.close();
 QString utfStr = QObject::trUtf8(readByte); //utf-8
 QString gbkStr = QObject::tr("中文"); // gbk

 QString utf2gbk = gbk->toUnicode(readStr.toLocal8Bit()); // utf8 conver gbk
 QString gbk2utf1 = utf8->toUnicode(utf2gbk.toUtf8()); // gbk convert utf8
 QString g2u = gbk->toUnicode(gbk->fromUnicode(readStr)); // gbk convert utf8

 qDebug() << "gbk:" << gbkStr;
 qDebug() << "utf8:" << utfStr;
 qDebug() << "readStr:" << readStr;

 qDebug() << "read_size:" << readByte.length();
 qDebug() << "utf2gbk:" <<utf2gbk << "length:" << readStr.toLocal8Bit().length();
 qDebug() << "gbk2utf8-1:" << gbk2utf1 << " length: " << utf2gbk.toUtf8().length();
 qDebug() << "g2u" << g2u << "length:" << gbk->fromUnicode(utfStr).length();

 QLabel *label = new QLabel(utf2gbk);
 label->show();

参考:

【1】http://www.cnblogs.com/bingcaihuang/archive/2011/03/17/1986714.html

【2】http://knight4576.blog.51cto.com/2761974/703963

QT中.pro文件写法概述

December 15th, 2016 by JasonLe's Tech 473 views

最近在实现一个自动化编译qt工程的pro生成器,pro文件是组织qt项目的核心。

如果我们开始没有使用pro文件组织项目的话,可以先使用qmake -project生成一份pro文件,然后再着手对其进行修改。下面是我使用命令生成的一个pro文件:

######################################################################
# Automatically generated by qmake (2.01a) ?? 1? 5 19:54:06 2017
######################################################################

TEMPLATE = app
TARGET = 
DEPENDPATH += . include . src
INCLUDEPATH += .

# Input
HEADERS += include/ISCAS.h include/ISCASDef.h
SOURCES += src/ISCAS.cpp

TEMPLATE 参数指的是要编译出来什么东西,是独立运行的app还是dll文件或者是其他,
TEMPLATE = app

A> app -建立一个应用程序的makefile。这是默认值,所以如果模板没有被指定,这个将被使用。
B> lib – 建立一个库的makefile。
C> vcapp – 建立一个应用程序的VisualStudio项目文件。
D> vclib – 建立一个库的VisualStudio项目文件。
E> subdirs -这是一个特殊的模板,它可以创建一个能够进入特定目录并且为一个项目文件生成makefile并且为它调用make的makefile。

TARGET 指定生成的应用程序名,有时候我们将pro文件转换成为vcxproj文件(qmake -r -tp vc),我们想同时指定编译文件名字,比如release版本不带后缀d,而debug版本带d,程序员只需要切换编译模式就可以生成不同名字的文件。

TARGET = ProjectName
TARGET = $$qtLibraryTarget($$TARGET)

DEPENDPATH 指定程序编译时依赖的相关路径 DEPENDPATH += . forms include qrc sources

INCLUDEPATH 指的是头文件包含路径 INCLUDEPATH += .

后面的 HEADERS 和 SOURCES 就是指定 编译的头文件和源代码

下面来看另外一个pro文件模板:

PLATFORM_VERSION =  x86_32
ALLONE_DIR = E://

QT +=  xml quick sql xml network script webkit xmlpatterns testlib declarative

TEMPLATE = lib
TARGET = ISCAS
DEPENDPATH += .
INCLUDEPATH += ./include $$ALLONE_DIR/include
DEFINES += ISCAS_LIB
OBJECTS_DIR = ./tmp/obj
MOC_DIR = ./tmp/moc
DESTDIR = $$ALLONE_DIR/lib/component
CONFIG += qt warn_on debug_and_release console

# Input
HEADERS +=	./include/ISCAS.h	\
				./include/ISCASDef.h
SOURCES +=	./src/ISCAS.cpp

FORMS	+= ./forms/CSSC.ui
RCC_DIR = forms
UI_DIR = ./tmp
TRANSLATIONS = CSSC.ts
win32{
	CONFIG(release,release|debug){
	    LIBS += $$ALLONE_DIR/lib/win32/ComponentBase.lib
	    
	    LIBS += $$ALLONE_DIR/lib/win32/AllOneFoundation.lib
        
	    LIBS += $$ALLONE_DIR/lib/win32/EventNotification.lib
        
	    LIBS += $$ALLONE_DIR/lib/win32/DDSMsgHandle.lib
	}

	CONFIG(debug,release|debug) {
	    LIBS += $$ALLONE_DIR/lib/win32/ComponentBased.lib
	    
	    LIBS += $$ALLONE_DIR/lib/win32/AllOneFoundationd.lib
        
	    LIBS += $$ALLONE_DIR/lib/win32/EventNotificationd.lib
        
	    LIBS += $$ALLONE_DIR/lib/win32/DDSMsgHandled.lib  
	}
}

PLATFORM_VERSION 表示编译的程序版本是32位还是64位。

这个模板里ALLONE_DIR是一个变量,我们可以在下面的位置通过$$ALLONE_DIR使用该变量。

QT 就是Qt的各个lib库。

DEFINES += XX_XX_XXX //定义编译选项,在.h文件中就可以使用 :#ifdef xx_xx_xxx,例如:

#if defined ISCAS_LIB
#  define ISCAS_EXPORT Q_DECL_EXPORT
#else
#  define ISCAS_EXPORT Q_DECL_IMPORT
#endif

Q_DECL_EXPORT宏主要为了导出这个类,生成.dll的同时生成.lib文件。提供给外部接口供其他类使用。

OBJECTS_DIR 为存放中间文件的目录,一般我们在编译我们的工程的时候会生成许多的中间文件,如.o文件(linux下)或.obj(windows下),这样我们的工程就很乱,所以我们可以定义这个选择。

MOC_DIR指定moc命令将含Q_OBJECT的头文件转换成标准.h文件的存放目录。

DESTDIR指定生成的应用程序放置的目录。

CONFIG用来指定qmake关于应用程序的配置信息,在这里使用“+=”,是因为我们添加我们的配置选项到任何一个已经存在中。这样做比使用“=”那样替换已经指定的所有选项是更安全的。

A> qt部分告诉qmake这个应用程序是使用Qt来连编的。这也就是说qmake在连接和为编译添加所需的包含路径的时候会考虑到Qt库的。
B> warn_on部分告诉qmake要把编译器设置为输出警告信息的。
C> debug_and_release 部分告诉qmake应用程序生成debug版和release版的程序。
D> console指定该程序需要写控制台,包括cout cerr 等。

20170105220525

CONFIG(release,release|debug) 指定括号里里的LIBS+=是针对release版的,CONFIG(debug,release|debug)是针对 debug版的。

LIBS: 这里可以选择我们要包含的库,例如我们的工程要用到libz.so的一个压缩库,(如果是在Linux下,则去掉lib和后缀名,windows下去掉后缀名即可)在linux下我可以这样写:
LIBS += -lz  windows 下的libz.dll 为 LIBS += -llibz
或是用到image目录下的libimage.so库,那么可以这么写:
LIBS += -L../image/image

RESOURCES 定义工程资源描述文件,工程里需要很多图片,那么这些图片的定义都可以放在backup.qrc文件中进行描述,那么这里就可以指出我们的qrc文件。RESOURCES += backup.qrc

FORMS 指定工程中包含的.ui设计文件

UI_DIR 指定uic命令将.ui文件转化成ui_*.h文件的存放的目录,比如下面是存放到forms目录
UI_DIR += forms

RCC_DIR 指定rcc命令将.qrc文件转换成qrc_*.h文件的存放目录
RCC_DIR += ../tmp

TRANSLATIONS = CSSC.ts 就是使用lupdate -verbose CSSC.pro 生成ts文件。然后使用Qt linguist 翻译完毕以后,再使用lrelease -verbose CSSC.pro生成 .qm文件。

 

参考:

【1】http://blog.csdn.net/fjb2080/article/details/4833666

【2】http://blog.csdn.net/adriano119/article/details/5878169

【3】http://www.ithao123.cn/content-4528049.html