mask rcnn 数据基础介绍

[TOC]

概念理解

Mask R-CNN (Regional Convolutional Neural Network: 区域卷积神经网络)

ComputerVisionTasks

  • 图像分类 (Classification): 图片中有气球。

  • 语义分割 (Semantic Segmentation): 这些是图片中组成所有气球的像素。

  • 目标检测 (Object Detection): 这里是图片中7个气球的位置。我们需要识别被遮挡的物体。

  • 实例分割 (Instance Segmentation): 这是是图片中7个气球的位置,包括组成每一个气球的像素。

mAP: 均值平均精度(Mean Average Precision)

Backbone: 骨干网络

backbone feature map : 骨干特征图

Feature Pyramid Network (FPN): 特征金字塔网络

FPNFlowChart

Mask RCNN 的实现采用的是 ResNet101 + FPN 作为骨干网络

Region Proposal Network (RPN): 区域提议网络

Anchor: 锚点, RPN 通过扫描骨干特征图(backbone feature map ) 得到锚点的. SSD 中称为先验框Prior boxes

Non-max Suppression : 非最大抑制, 在 RPN 预测过程中,我们会选择最可能包含物体的锚点,然后去修正它们的位置以及尺寸。如果有些锚点重叠得太多,我们会保留前景得分最高的一个,而其他的锚点就丢弃掉(这种方式成为非最大抑制 Non-max Suppression )。

regions of interest (ROI): 最终的提议区域, 也就是我们感兴趣的区域

Ground Truth : 对于物体检测问题,Ground Truth包括图像,图像中的目标的类别以及图像中每个目标的边界框。

ROI Pooling: 感兴趣区域的池化

Batch Normalization : Batch Normalization可以提升模型收敛速度,而且可以起到一定正则化效果,降低模型的过拟合。

BA DA DS ML CS

BA: business analyst

DA: data analyst

DS: data science

ML: machine learning

CS: computer science

selective search: 选择性搜索

SSD: Single Shot MultiBox Detector

hard negative mining : 为了保证正负样本尽量平衡,SSD采用了hard negative mining

Locatization loss, loc: 位置误差

confidence loss, conf : 置信度误差

SSD loss : 损失函数定义为位置误差(locatization loss, loc)与置信度误差(confidence loss, conf)的加权和

Data Augmentation: 数据扩增

Randomly sample a patch: 随机采集块域

dilation converlutional : 扩张卷积

因果卷积: 因果卷积的理解可以认为是:不管是自然语言处理领域中的预测还是时序预测,都要求对时刻t 的预测yt只能通过t时刻之前的输入x1到xt-1来判别。这种思想有点类似于马尔科夫链。

残差卷积的跳层连接: 微软的残差网络 ResNet 就是经典的跳层连接(skip-connection),上一层的特征图 x 直接与卷积后的 F(x)对齐加和,变为 F(x)+x (特征图数量不够可用 0 特征补齐,特征图大小不一可用带步长卷积做下采样)。

Fully Convolutional Networks : 全卷积网络

mask rcnn 数据预处理解读

[TOC]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import os
import sys
import json
import skimage.draw
import skimage.io
import skimage.color
from imgaug import augmenters as iaa
import numpy as np
import random
import matplotlib.pyplot as plt
# plt.switch_backend('agg')

# Root directory of the project
ROOT_DIR = os.path.abspath("../../")
sys.path.append(ROOT_DIR)

# Import Mask RCNN
from mrcnn import visualize
from mrcnn.config import Config
from mrcnn import model as modellib, utils
from mrcnn.model import log
from samples.cells import run_via_json

COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
DEFAULT_LOGS_DIR = os.path.join(ROOT_DIR, "logs")
class_names = ['BG', 'cells1', 'cells2']
train_class_name = ['cells1', 'cells2']
show_class_name = ['cells2']

train_config = run_via_json.TrainConfig()
config = train_config
dataset = run_via_json.CellDataset()
dataset.load_data(train_config.dataset_dir, train_config.train_dir_name, class_names,
annotation=train_config.train_annotation_json)
dataset.prepare()

k8s学习笔记-03-Mater节点二进制部署

[TOC]

K8S Mater节点部署

1、部署Kubernetes API服务部署

  • apiserver提供集群管理的REST API接口,包括认证授权、数据校验以及集群状态变更等。
  • 只有API Server才能直接操作etcd;
  • 其他模块通过API Server查询或修改数据
  • 提供其他模块之间的数据交互和通信枢纽
(1)准备软件包
1
2
3
4
[root@linux-node1 ~]# cd /usr/local/src/kubernetes
[root@linux-node1 kubernetes]# cp server/bin/kube-apiserver /opt/kubernetes/bin/
[root@linux-node1 kubernetes]# cp server/bin/kube-controller-manager /opt/kubernetes/bin/
[root@linux-node1 kubernetes]# cp server/bin/kube-scheduler /opt/kubernetes/bin/只需要在linux-node1上拷贝
(2)创建生成CSR的 JSON 配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@linux-node1 ~]# cd /usr/local/src/ssl[root@linux-node1 ssl]# vim kubernetes-csr.json
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.56.110",  #Master的ip地址
"10.1.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
(3)生成 kubernetes 证书和私钥
1
2
3
4
5
6
7
[root@linux-node1 ssl]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem \
-ca-key=/opt/kubernetes/ssl/ca-key.pem \
-config=/opt/kubernetes/ssl/ca-config.json \
-profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
[root@linux-node1 ssl]# cp kubernetes*.pem /opt/kubernetes/ssl/
[root@linux-node1 ssl]# scp kubernetes*.pem 192.168.56.120:/opt/kubernetes/ssl/
[root@linux-node1 ssl]# scp kubernetes*.pem 192.168.56.130:/opt/kubernetes/ssl/
(4) 创建 kube-apiserver 使用的客户端 token 文件
1
2
3
4
[root@linux-node1 ~]#  head -c 16 /dev/urandom | od -An -t x | tr -d ' '
ad6d5bb607a186796d8861557df0d17f
[root@linux-node1 ~]# vim /opt/kubernetes/ssl/bootstrap-token.csv
ad6d5bb607a186796d8861557df0d17f,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
(5) 创建基础用户名/密码认证配置
1
2
3
[root@linux-node1 ~]# vim /opt/kubernetes/ssl/basic-auth.csv
admin,admin,1
readonly,readonly,2
(6) 部署Kubernetes API Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[root@linux-node1 ~]# vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target

[Service]
ExecStart=/opt/kubernetes/bin/kube-apiserver \
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota,NodeRestriction \
--bind-address=192.168.56.110 \
--insecure-bind-address=127.0.0.1 \
--authorization-mode=Node,RBAC \
--runtime-config=rbac.authorization.k8s.io/v1 \
--kubelet-https=true \
--anonymous-auth=false \
--basic-auth-file=/opt/kubernetes/ssl/basic-auth.csv \
--enable-bootstrap-token-auth \
--token-auth-file=/opt/kubernetes/ssl/bootstrap-token.csv \
--service-cluster-ip-range=10.1.0.0/16 \
--service-node-port-range=20000-40000 \
--tls-cert-file=/opt/kubernetes/ssl/kubernetes.pem \
--tls-private-key-file=/opt/kubernetes/ssl/kubernetes-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/opt/kubernetes/ssl/ca.pem \
--etcd-certfile=/opt/kubernetes/ssl/kubernetes.pem \
--etcd-keyfile=/opt/kubernetes/ssl/kubernetes-key.pem \
--etcd-servers=https://192.168.56.110:2379,https://192.168.56.120:2379,https://192.168.56.130:2379 \
--enable-swagger-ui=true \
--allow-privileged=true \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/opt/kubernetes/log/api-audit.log \
--event-ttl=1h \
--v=2 \
--logtostderr=false \
--log-dir=/opt/kubernetes/log
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
(7) 启动API Server服务
1
2
3
4
5
6
7
[root@linux-node1 ~]# systemctl daemon-reload
[root@linux-node1 ~]# systemctl enable kube-apiserver
[root@linux-node1 ~]# systemctl start kube-apiserver
[root@linux-node1 ~]# systemctl status kube-apiserver
[root@linux-node1 ssl]# netstat -tulnp |grep kube-apiserver
tcp 0 0 192.168.56.110:6443 0.0.0.0:* LISTEN 5052/kube-apiserver
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 5052/kube-apiserver

从监听端口可以看到api-server监听在6443端口,同时也监听了本地的8080端口,是提供kube-schduler和kube-controller使用。

2、部署Controller Manager服务

  • controller-manager由一系列的控制器组成,它通过apiserver监控整个集群的状态,并确保集群处于预期的工作状态。
(1)部署Controller Manager服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@linux-node1 ~]# vim /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes

[Service]
ExecStart=/opt/kubernetes/bin/kube-controller-manager \
--address=127.0.0.1 \
--master=http://127.0.0.1:8080 \
--allocate-node-cidrs=true \
--service-cluster-ip-range=10.1.0.0/16 \
--cluster-cidr=10.2.0.0/16 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \
--root-ca-file=/opt/kubernetes/ssl/ca.pem \
--leader-elect=true \
--v=2 \
--logtostderr=false \
--log-dir=/opt/kubernetes/log

Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
(2)启动Controller Manager
1
2
3
4
5
6
[root@linux-node1 ~]# systemctl daemon-reload
[root@linux-node1 scripts]# systemctl enable kube-controller-manager
[root@linux-node1 scripts]# systemctl start kube-controller-manager
[root@linux-node1 scripts]# systemctl status kube-controller-manager
[root@linux-node1 ssl]# netstat -tulnp |grep kube-controlle
tcp 0 0 127.0.0.1:10252 0.0.0.0:* LISTEN 5112/kube-controlle

从监听端口上,可以看到kube-controller监听在本地的10252端口,外部是无法直接访问kube-controller,需要通过api-server才能进行访问。

3、部署Kubernetes Scheduler

  • scheduler负责分配调度Pod到集群内的node节点
  • 监听kube-apiserver,查询还未分配的Node的Pod
  • 根据调度策略为这些Pod分配节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@linux-node1 ~]# vim /usr/lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes

[Service]
ExecStart=/opt/kubernetes/bin/kube-scheduler \
--address=127.0.0.1 \
--master=http://127.0.0.1:8080 \
--leader-elect=true \
--v=2 \
--logtostderr=false \
--log-dir=/opt/kubernetes/log

Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
[root@linux-node1 ~]# systemctl daemon-reload
[root@linux-node1 scripts]# systemctl enable kube-scheduler
[root@linux-node1 scripts]# systemctl start kube-scheduler
[root@linux-node1 scripts]# systemctl status kube-scheduler
[root@linux-node1 ssl]# netstat -tulnp |grep kube-scheduler
tcp 0 0 127.0.0.1:10251 0.0.0.0:* LISTEN 5172/kube-scheduler

从kube-scheduler的监听端口上,同样可以看到监听在本地的10251端口上,外部无法直接访问,同样是需要通过api-server进行访问。

4、部署kubectl 命令行工具

kubectl用于日常直接管理K8S集群,那么kubectl要进行管理k8s,就需要和k8s的组件进行通信,也就需要用到证书。此时kubectl需要单独部署,也是因为kubectl也是需要用到证书,而前面的kube-apiserver、kube-controller、kube-scheduler都是不需要用到证书,可以直接通过服务进行启动。

(1)准备二进制命令包
1
2
[root@linux-node1 ~]# cd /usr/local/src/kubernetes/client/bin
[root@linux-node1 bin]# cp kubectl /opt/kubernetes/bin/
(2)创建 admin 证书签名请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@linux-node1 ~]# cd /usr/local/src/ssl/
[root@linux-node1 ssl]# vim admin-csr.json
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "System"
}
]
}
(3)生成 admin 证书和私钥
1
2
3
4
5
6
7
8
9
10
11
[root@linux-node1 ssl]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem \
-ca-key=/opt/kubernetes/ssl/ca-key.pem \
-config=/opt/kubernetes/ssl/ca-config.json \
-profile=kubernetes admin-csr.json | cfssljson -bare admin
[root@linux-node1 ssl]# ls -l admin*
-rw-r--r-- 1 root root 1009 Mar 5 12:29 admin.csr
-rw-r--r-- 1 root root 229 Mar 5 12:28 admin-csr.json
-rw------- 1 root root 1675 Mar 5 12:29 admin-key.pem
-rw-r--r-- 1 root root 1399 Mar 5 12:29 admin.pem

[root@linux-node1 ssl]# cp admin*.pem /opt/kubernetes/ssl/
(4)设置集群参数
1
2
3
4
5
[root@linux-node1 ssl]# kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.56.110:6443
Cluster "kubernetes" set.
(5)设置客户端认证参数
1
2
3
4
5
[root@linux-node1 ssl]# kubectl config set-credentials admin \
--client-certificate=/opt/kubernetes/ssl/admin.pem \
--embed-certs=true \
--client-key=/opt/kubernetes/ssl/admin-key.pem
User "admin" set.
(6)设置上下文参数
1
2
3
4
[root@linux-node1 ssl]# kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin
Context "kubernetes" created.
(7)设置默认上下文
1
2
[root@linux-node1 src]# kubectl config use-context kubernetes
Switched to context "kubernetes".

上面(4)–>(7)的配置是为了在家目录下生成config文件,之后kubectl和api通信就需要用到该文件,这也就是说如果在其他节点上需要用到这个kubectl,就需要将该文件拷贝到其他节点。

1
2
3
4
5
6
[root@linux-node1 ~]# cat .kube/config 
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR2akNDQXFhZ0F3SUJBZ0lVUUszc2dUb0lrNlhmVDhFaUVvcXNNc2pQQUVzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1pURUxNQWtHQTFVRUJo
......
(8)使用kubectl工具
1
2
3
4
5
6
7
[root@linux-node1 ssl]# kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-2 Healthy {"health": "true"}
etcd-0 Healthy {"health": "true"}
etcd-1 Healthy {"health": "true"}

k8s学习笔记-02-ETCD集群二进制部署

[TOC]

ETCD集群部署

所有持久化的状态信息以KV的形式存储在ETCD中。类似zookeeper,提供分布式协调服务。之所以说kubenetes各个组件是无状态的,就是因为其中把数据都存放在ETCD中。由于ETCD支持集群,这里在三台主机上都部署上ETCD。

1349539-20180706111531842-16242459

(1)准备etcd软件包

1
2
3
4
5
6
wget https://github.com/coreos/etcd/releases/download/v3.2.18/etcd-v3.2.18-linux-amd64.tar.gz
[root@linux-node1 src]# tar zxf etcd-v3.2.18-linux-amd64.tar.gz  #解压etcd
[root@linux-node1 src]# cd etcd-v3.2.18-linux-amd64  #有2个文件,etcdctl是操作etcd的命令
[root@linux-node1 etcd-v3.2.18-linux-amd64]# cp etcd etcdctl /opt/kubernetes/bin/
[root@linux-node1 etcd-v3.2.18-linux-amd64]# scp etcd etcdctl 192.168.56.120:/opt/kubernetes/bin/
[root@linux-node1 etcd-v3.2.18-linux-amd64]# scp etcd etcdctl 192.168.56.130:/opt/kubernetes/bin/

(2)创建 etcd 证书签名请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@linux-node1 ~]# cd /usr/local/src/ssl
[root@linux-node1 ssl]# vim etcd-csr.json
{
"CN": "etcd",
"hosts": [  #此处的ip是etcd集群中各个节点的ip地址
"127.0.0.1",
"192.168.56.110",
"192.168.56.120",
"192.168.56.130"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}

(3)生成 etcd 证书和私钥

1
2
3
4
5
6
7
8
9
10
[root@linux-node1 ~]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem \
-ca-key=/opt/kubernetes/ssl/ca-key.pem \
-config=/opt/kubernetes/ssl/ca-config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
会生成以下证书文件
[root@linux-node1 ~]# ls -l etcd*
-rw-r--r-- 1 root root 1045 Mar 5 11:27 etcd.csr
-rw-r--r-- 1 root root 257 Mar 5 11:25 etcd-csr.json
-rw------- 1 root root 1679 Mar 5 11:27 etcd-key.pem
-rw-r--r-- 1 root root 1419 Mar 5 11:27 etcd.pem

(4)将证书拷贝到/opt/kubernetes/ssl目录下

1
2
3
[root@linux-node1 ~]# cp etcd*.pem /opt/kubernetes/ssl
[root@linux-node1 ~]# scp etcd*.pem 192.168.56.120:/opt/kubernetes/ssl
[root@linux-node1 ~]# scp etcd*.pem 192.168.56.130:/opt/kubernetes/ssl

(5)配置ETCD配置文件

2379端口用于外部通信,2380用于内部通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@linux-node1 ~]# vim /opt/kubernetes/cfg/etcd.conf
#[member]
ETCD_NAME="etcd-node1" #ETCD节点名称修改,这个ETCD_NAME每个节点必须不同
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"  #ETCD数据目录
#ETCD_SNAPSHOT_COUNTER="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
ETCD_LISTEN_PEER_URLS="https://192.168.56.110:2380" #ETCD监听的URL,每个节点不同需要修改
ETCD_LISTEN_CLIENT_URLS="https://192.168.56.110:2379,https://127.0.0.1:2379" #外部通信监听URL修改,每个节点不同需要修改
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.56.110:2380"
# if you use different ETCD_NAME (e.g. test),
# set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
ETCD_INITIAL_CLUSTER="etcd-node1=https://192.168.56.110:2380,etcd-node2=https://192.168.56.120:2380,etcd-node3=https://192.168.56.130:2380" #添加集群访问
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="k8s-etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.56.110:2379"
#[security]
CLIENT_CERT_AUTH="true"
ETCD_CA_FILE="/opt/kubernetes/ssl/ca.pem"
ETCD_CERT_FILE="/opt/kubernetes/ssl/etcd.pem"
ETCD_KEY_FILE="/opt/kubernetes/ssl/etcd-key.pem"
PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_CA_FILE="/opt/kubernetes/ssl/ca.pem"
ETCD_PEER_CERT_FILE="/opt/kubernetes/ssl/etcd.pem"
ETCD_PEER_KEY_FILE="/opt/kubernetes/ssl/etcd-key.pem"

(6)创建ETCD系统服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@linux-node1 ~]# vim /etc/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target

[Service]
Type=simple
WorkingDirectory=/var/lib/etcd
EnvironmentFile=-/opt/kubernetes/cfg/etcd.conf
# set GOMAXPROCS to number of processors
ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /opt/kubernetes/bin/etcd"
Type=notify

[Install]
WantedBy=multi-user.target

(7)重新加载系统服务并拷贝etcd.conf和etcd.service文件到其他2个节点

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@linux-node1 ~]# systemctl daemon-reload
[root@linux-node1 ~]# systemctl enable etcd
[root@linux-node1 ~]# scp /opt/kubernetes/cfg/etcd.conf 192.168.56.120:/opt/kubernetes/cfg/
[root@linux-node1 ~]# scp /etc/systemd/system/etcd.service 192.168.56.120:/etc/systemd/system/
[root@linux-node1 ~]# scp /opt/kubernetes/cfg/etcd.conf 192.168.56.130:/opt/kubernetes/cfg/
[root@linux-node1 ~]# scp /etc/systemd/system/etcd.service 192.168.56.130:/etc/systemd/system/

拷贝过去的etcd.conf在node2和node3需要进行修改4处的ip地址,举例修改node2如下:
[root@linux-node2 ~]# vim /opt/kubernetes/cfg/etcd.conf
ETCD_NAME="etcd-node2"
ETCD_LISTEN_PEER_URLS="https://192.168.56.120:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.56.120:2379,https://127.0.0.1:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.56.120:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.56.120:2379"

默认不会创建etcd的数据存储目录,这里在所有节点上创建etcd数据存储目录并启动etcd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@linux-node1 ~]# mkdir /var/lib/etcd
[root@linux-node1 ~]# systemctl start etcd
[root@linux-node1 ~]# systemctl status etcd

[root@linux-node2 ~]# mkdir /var/lib/etcd
[root@linux-node2 ~]# systemctl start etcd
[root@linux-node2 ~]# systemctl status etcd

[root@linux-node3 ~]# mkdir /var/lib/etcd
[root@linux-node3 ~]# systemctl start etcd
[root@linux-node3 ~]# systemctl status etcd

[root@linux-node1 ssl]# netstat -tulnp |grep etcd  #在各节点上查看是否监听了2379和2380端口
tcp 0 0 192.168.56.11:2379 0.0.0.0:* LISTEN 4916/etcd
tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 4916/etcd
tcp 0 0 192.168.56.11:2380 0.0.0.0:* LISTEN 4916/etcd

(8)验证ETCD集群

1
2
3
4
5
6
7
8
[root@linux-node1 ~]# etcdctl --endpoints=https://192.168.56.110:2379 \
--ca-file=/opt/kubernetes/ssl/ca.pem \
--cert-file=/opt/kubernetes/ssl/etcd.pem \
--key-file=/opt/kubernetes/ssl/etcd-key.pem cluster-health
member 435fb0a8da627a4c is healthy: got healthy result from https://192.168.56.120:2379
member 6566e06d7343e1bb is healthy: got healthy result from https://192.168.56.110:2379
member ce7b884e428b6c8c is healthy: got healthy result from https://192.168.56.130:2379
cluster is healthy #表明ETCD集群是正常的!!!

k8s学习笔记-01-概念和创建证书

[TOC]

1、Kubernetes的重要概念

  • Cluster

Cluster 是计算、存储和网络资源的集合,Kubernetes 利用这些资源运行各种基于容器的应用。

  • Master

Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。Master 运行 Linux 操作系统,可以是物理机或者虚拟机。为了实现高可用,可以运行多个 Master。

  • Node

Node 的职责是运行容器应用。Node 由 Master 管理,Node 负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。Node 运行在 Linux 操作系统,可以是物理机或者是虚拟机。

  • Pod

Pod 是 Kubernetes 的最小工作单元。每个 Pod 包含一个或多个容器。Pod 中的容器会作为一个整体被 Master 调度到一个 Node 上运行。

Kubernetes 引入 Pod 主要基于下面两个目的:

    1. 可管理性。
      有些容器天生就是需要紧密联系,一起工作。Pod 提供了比容器更高层次的抽象,将它们封装到一个部署单元中。Kubernetes 以 Pod 为最小单位进行调度、扩展、共享资源、管理生命周期。
    2. 通信和资源共享。
      Pod 中的所有容器使用同一个网络 namespace,即相同的 IP 地址和 Port 空间。它们可以直接用 localhost 通信。同样的,这些容器可以共享存储,当 Kubernetes 挂载 volume 到 Pod,本质上是将 volume 挂载到 Pod 中的每一个容器。

Pods 有两种使用方式:

    1. 运行单一容器。
      one-container-per-Pod 是 Kubernetes 最常见的模型,这种情况下,只是将单个容器简单封装成 Pod。即便是只有一个容器,Kubernetes 管理的也是 Pod 而不是直接管理容器。
    2. 运行多个容器。
      但问题在于:哪些容器应该放到一个 Pod 中?
      答案是:这些容器联系必须 非常紧密,而且需要 直接共享资源。

举个例子。

下面这个 Pod 包含两个容器:一个 File Puller,一个是 Web Server。

img

File Puller 会定期从外部的 Content Manager 中拉取最新的文件,将其存放在共享的 volume 中。Web Server 从 volume 读取文件,响应 Consumer 的请求。

这两个容器是紧密协作的,它们一起为 Consumer 提供最新的数据;同时它们也通过 volume 共享数据。所以放到一个 Pod 是合适的。

再来看一个反例:是否需要将 Tomcat 和 MySQL 放到一个 Pod 中?

Tomcat 从 MySQL 读取数据,它们之间需要协作,但还不至于需要放到一个 Pod 中一起部署,一起启动,一起停止。同时它们是之间通过 JDBC 交换数据,并不是直接共享存储,所以放到各自的 Pod 中更合适。

  • Controller

Kubernetes 通常不会直接创建 Pod,而是通过 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。为了满足不同的业务场景,Kubernetes 提供了多种 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等,我们逐一讨论。

Deployment 是最常用的 Controller,比如前面在线教程中就是通过创建 Deployment 来部署应用的。Deployment 可以管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。

ReplicaSet 实现了 Pod 的多副本管理。使用 Deployment 时会自动创建 ReplicaSet,也就是说 Deployment 是通过 ReplicaSet 来管理 Pod 的多个副本,我们通常不需要直接使用 ReplicaSet。

DaemonSet 用于每个 Node 最多只运行一个 Pod 副本的场景。正如其名称所揭示的,DaemonSet 通常用于运行 daemon。

StatefuleSet 能够保证 Pod 的每个副本在整个生命周期中名称是不变的。而其他 Controller 不提供这个功能,当某个 Pod 发生故障需要删除并重新启动时,Pod 的名称会发生变化。同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除。

Job 用于运行结束就删除的应用。而其他 Controller 中的 Pod 通常是长期持续运行。

  • Service

Deployment 可以部署多个副本,每个 Pod 都有自己的 IP,外界如何访问这些副本呢?

通过 Pod 的 IP 吗?
要知道 Pod 很可能会被频繁地销毁和重启,它们的 IP 会发生变化,用 IP 来访问不太现实。

答案是 Service。
Kubernetes Service 定义了外界访问一组特定 Pod 的方式。Service 有自己的 IP 和端口,Service 为 Pod 提供了负载均衡。

Kubernetes 运行容器(Pod)与访问容器(Pod)这两项任务分别由 Controller 和 Service 执行。

  • Namespace

如果有多个用户或项目组使用同一个 Kubernetes Cluster,如何将他们创建的 Controller、Pod 等资源分开呢?

答案就是 Namespace。
Namespace 可以将一个物理的 Cluster 逻辑上划分成多个虚拟 Cluster,每个 Cluster 就是一个 Namespace。不同 Namespace 里的资源是完全隔离的。

Kubernetes 默认创建了两个 Namespace。

1
2
3
4
[root@linux-node1 ~]# kubectl get namespace
NAME STATUS AGE
default Active 1d
kube-system Active 1d

default – 创建资源时如果不指定,将被放到这个 Namespace 中。

kube-system – Kubernetes 自己创建的系统资源将放到这个 Namespace 中。

2、Kubernetes架构和集群规划

(1)Kubernetes架构

img

(2)K8S架构拆解图

img

K8S Master节点

从上图可以看到,Master是K8S集群的核心部分,主要运行着以下的服务:kube-apiserver、kube-scheduler、kube-controller-manager、etcd和Pod网络(如:flannel)

1
2
3
4
5
6
7
API Server:K8S对外的唯一接口,提供HTTP/HTTPS RESTful API,即kubernetes API。所有的请求都需要经过这个接口进行通信。主要处理REST操作以及更新ETCD中的对象。是所有资源增删改查的唯一入口。 

Scheduler:资源调度,负责决定将Pod放到哪个Node上运行。Scheduler在调度时会对集群的结构进行分析,当前各个节点的负载,以及应用对高可用、性能等方面的需求。

Controller Manager:负责管理集群各种资源,保证资源处于预期的状态。Controller Manager由多种controller组成,包括replication controller、endpoints controller、namespace controller、serviceaccounts controller等

ETCD:负责保存k8s 集群的配置信息和各种资源的状态信息,当数据发生变化时,etcd会快速地通知k8s相关组件。Pod网络:Pod要能够相互间通信,K8S集群必须部署Pod网络,flannel是其中一种的可选方案。

K8S Node节点

Node是Pod运行的地方,Kubernetes支持Docker、rkt等容器Runtime。Node上运行的K8S组件包括kubelet、kube-proxy和Pod网络。

1
2
3
4
5
Kubelet:kubelet是node的agent,当Scheduler确定在某个Node上运行Pod后,会将Pod的具体配置信息(image、volume等)发送给该节点的kubelet,kubelet会根据这些信息创建和运行容器,并向master报告运行状态。

Kube-proxy:service在逻辑上代表了后端的多个Pod,外借通过service访问Pod。service接收到请求就需要kube-proxy完成转发到Pod的。每个Node都会运行kube-proxy服务,负责将访问的service的TCP/UDP数据流转发到后端的容器,如果有多个副本,kube-proxy会实现负载均衡,有2种方式:LVS或者Iptables

Docker Engine:负责节点的容器的管理工作

Kubernetes中pod创建流程

  Pod是Kubernetes中最基本的部署调度单元,可以包含container,逻辑上表示某种应用的一个实例。例如一个web站点应用由前端、后端及数据库构建而成,这三个组件将运行在各自的容器中,那么我们可以创建包含三个container的pod。

img

具体的创建步骤包括:

(1)客户端提交创建请求,可以通过API Server的Restful API,也可以使用kubectl命令行工具。支持的数据类型包括JSON和YAML。

(2)API Server处理用户请求,存储Pod数据到etcd。

(3)调度器通过API Server查看未绑定的Pod。尝试为Pod分配主机。

(4)过滤主机 (调度预选):调度器用一组规则过滤掉不符合要求的主机。比如Pod指定了所需要的资源量,那么可用资源比Pod需要的资源量少的主机会被过滤掉。

(5)主机打分(调度优选):对第一步筛选出的符合要求的主机进行打分,在主机打分阶段,调度器会考虑一些整体优化策略,比如把容一个Replication Controller的副本分布到不同的主机上,使用最低负载的主机等。

(6)选择主机:选择打分最高的主机,进行binding操作,结果存储到etcd中。

(7)kubelet根据调度结果执行Pod创建操作: 绑定成功后,scheduler会调用APIServer的API在etcd中创建一个boundpod对象,描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步boundpod信息,一旦发现应该在该工作节点上运行的boundpod对象没有更新,则调用Docker API创建并启动pod内的容器。

(3)实验环境准备:

1
2
3
4
主机名                   IP地址            描述
linux-node1.example.com eth0:192.168.56.110 K8S Master节点/ETCD节点
linux-node2.example.com eth0:192.168.56.120 K8S Node节点/ETCD节点
linux-node3.example.com eth0:192.168.56.130 K8S Node节点/ETCD节点

img

(4)系统环境初始化

1.安装Docker

第一步:使用国内Docker源

1
2
3
4
5
6
7
8
[root@linux-node1 ~]# cd /etc/yum.repos.d/
[root@linux-node1 yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

[root@linux-node2 ~]# cd /etc/yum.repos.d/
[root@linux-node2 yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

[root@linux-node3 ~]# cd /etc/yum.repos.d/
[root@linux-node3 yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

第二步:Docker安装:

1
2
3
[root@linux-node1 ~]# yum install -y docker-ce
[root@linux-node2 ~]# yum install -y docker-ce
[root@linux-node3 ~]# yum install -y docker-ce

第三步:启动后台进程:

1
2
3
[root@linux-node1 ~]# systemctl start docker
[root@linux-node2 ~]# systemctl start docker
[root@linux-node3 ~]# systemctl start docker

2.准备部署目录

1
2
3
[root@linux-node1 ~]# mkdir -p /opt/kubernetes/{cfg,bin,ssl,log}
[root@linux-node2 ~]# mkdir -p /opt/kubernetes/{cfg,bin,ssl,log}
[root@linux-node3 ~]# mkdir -p /opt/kubernetes/{cfg,bin,ssl,log}

3.准备软件包

github下载地址: https://github.com/kubernetes/kubernetes/releases

百度网盘下载地址:
https://pan.baidu.com/s/1zs8sCouDeCQJ9lghH1BPiw

4.解压软件包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@linux-node1 src]# tar zxf kubernetes.tar.gz 
[root@linux-node1 src]# tar zxf kubernetes-server-linux-amd64.tar.gz
[root@linux-node1 src]# tar zxf kubernetes-client-linux-amd64.tar.gz
[root@linux-node1 src]# tar zxf kubernetes-node-linux-amd64.tar.gz
[root@linux-node1 src]# cd kubernetes #解压的server、client、node都会解压到kubernetes目录下
[root@linux-node1 kubernetes]# ll
total 29536
drwxr-xr-x 2 root root 6 Apr 12 23:16 addons
drwxr-xr-x 3 root root 31 Apr 12 23:16 client
drwxr-xr-x 13 root root 4096 Apr 12 23:24 cluster
drwxr-xr-x 7 root root 131 Apr 12 23:25 docs
drwxr-xr-x 34 root root 4096 Apr 12 23:25 examples
drwxr-xr-x 3 root root 17 Apr 12 23:24 hack
-rw-r--r-- 1 root root 24710771 Apr 12 23:16 kubernetes-src.tar.gz
-rw-r--r-- 1 root root 5516760 Apr 12 23:16 LICENSES
drwxr-xr-x 3 root root 17 Apr 12 23:16 node
-rw-r--r-- 1 root root 3329 Apr 12 23:25 README.md
drwxr-xr-x 3 root root 66 Apr 12 23:16 server
drwxr-xr-x 3 root root 22 Apr 12 23:24 third_party
-rw-r--r-- 1 root root 8 Apr 12 23:25 version

各个节点增加kubernetes的环境变量

1
2
3
4
5
6
7
8
9
[root@linux-node1 ~]# vim .bash_profile
PATH=$PATH:$HOME/bin:/opt/kubernetes/bin
[root@linux-node1 ~]# source .bash_profile
[root@linux-node2 ~]# vim .bash_profile
PATH=$PATH:$HOME/bin:/opt/kubernetes/bin
[root@linux-node2 ~]# source .bash_profile
[root@linux-node3 ~]# vim .bash_profile
PATH=$PATH:$HOME/bin:/opt/kubernetes/bin
[root@linux-node3 ~]# source .bash_profile

5.CA证书创建和分发

  从k8s的1.8版本开始,K8S系统各组件需要使用TLS证书对通信进行加密。每一个K8S集群都需要独立的CA证书体系。CA证书有以下三种:easyrsa、openssl、cfssl。这里使用cfssl证书,也是目前使用最多的,相对来说配置简单一些,通过json的格式,把证书相关的东西配置进去即可。这里使用cfssl的版本为1.2版本。

(1)安装 CFSSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@linux-node1 ~]# cd /usr/local/src
[root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
[root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
[root@linux-node1 src]# chmod +x cfssl*  #增加执行权限
[root@linux-node1 src]# mv cfssl-certinfo_linux-amd64 /opt/kubernetes/bin/cfssl-certinfo
[root@linux-node1 src]# mv cfssljson_linux-amd64 /opt/kubernetes/bin/cfssljson
[root@linux-node1 src]# mv cfssl_linux-amd64 /opt/kubernetes/bin/cfssl
复制cfssl命令文件到k8s-node1和k8s-node2节点。如果实际中多个节点,就都需要同步复制。
[root@linux-node1 ~]# ssh-copy-id linux-node1
[root@linux-node1 ~]# ssh-copy-id linux-node2
[root@linux-node1 ~]# ssh-copy-id linux-node3
[root@linux-node1 ~]# scp /opt/kubernetes/bin/cfssl* 192.168.56.120:/opt/kubernetes/bin
cfssl 100% 10MB 18.1MB/s 00:00
cfssl-certinfo 100% 6441KB 21.3MB/s 00:00
cfssljson 100% 2224KB 13.3MB/s 00:00
[root@linux-node1 ~]# scp /opt/kubernetes/bin/cfssl* 192.168.56.130:/opt/kubernetes/bin
cfssl 100% 10MB 22.5MB/s 00:00
cfssl-certinfo 100% 6441KB 40.7MB/s 00:00
cfssljson 100% 2224KB 43.1MB/s 00:00

(2)创建用来生成 CA 文件的 JSON 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@linux-node1 src]# mkdir ssl && cd ssl    #创建临时证书存放目录
[root@linux-node1 ssl]# pwd
/usr/local/src/ssl

[root@linux-node1 ssl]# vim ca-config.json
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}

(3)创建用来生成 CA 证书签名请求(CSR)的 JSON 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@linux-node1 ssl]# vim ca-csr.json
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}

(4)生成CA证书(ca.pem)和密钥(ca-key.pem)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@linux-node1 ssl]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca  #生成证书和密钥
2018/05/30 14:11:02 [INFO] generating a new CA key and certificate from CSR
2018/05/30 14:11:02 [INFO] generate received request
2018/05/30 14:11:02 [INFO] received CSR
2018/05/30 14:11:02 [INFO] generating key: rsa-2048
2018/05/30 14:11:02 [INFO] encoded CSR
2018/05/30 14:11:02 [INFO] signed certificate with serial number 167714418220584190953978332616641264281080483250
[root@linux-node1 ssl]# ll
total 20
-rw-r--r-- 1 root root 290 May 30 14:09 ca-config.json
-rw-r--r-- 1 root root 1001 May 30 14:11 ca.csr
-rw-r--r-- 1 root root 208 May 30 14:10 ca-csr.json
-rw------- 1 root root 1675 May 30 14:11 ca-key.pem
-rw-r--r-- 1 root root 1359 May 30 14:11 ca.pem

(5)分发证书

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@linux-node1 ssl]# cp ca.csr ca.pem ca-key.pem ca-config.json /opt/kubernetes/ssl

SCP证书到k8s-node1和k8s-node2节点,以后增加节点也是需要将这些证书进行分发
[root@linux-node1 ssl]# scp ca.csr ca.pem ca-key.pem ca-config.json 192.168.56.120:/opt/kubernetes/ssl
ca.csr 100% 1001 350.2KB/s 00:00
ca.pem 100% 1359 891.4KB/s 00:00
ca-key.pem 100% 1675 1.0MB/s 00:00
ca-config.json 100% 290 180.7KB/s 00:00
[root@linux-node1 ssl]# scp ca.csr ca.pem ca-key.pem ca-config.json 192.168.56.130:/opt/kubernetes/ssl
ca.csr 100% 1001 350.2KB/s 00:00
ca.pem 100% 1359 891.4KB/s 00:00
ca-key.pem 100% 1675 1.0MB/s 00:00
ca-config.json 100% 290 180.7KB/s 00:00

tensorRT安装

[TOC]

tensorRT简介

深度学习的发展带动了一批深度学习框架,caffe、tensorflow、pytorch等,对于计算量庞大的CNN,效率一直是大家所关注的,接触过深度网络压缩的同学应该知道网络压缩最关键的两个思路,剪枝和量化。
TensorRT就是量化,将FP32位权值数据优化为 FP16 或者 INT8,而推理精度不发生明显的降低。
关于TensorRT首先要清楚以下几点:

  1. TensorRT是NVIDIA开发的深度学习推理工具,只支持推理,不支持训练;
    目前TensorRT4已经支持Caffe、Caffe2、TensorFlow、MxNet、Pytorch等主流深度学习库;

  2. TensorRT底层针对NVIDIA显卡做了多方面的优化,不仅仅是量化,可以和 CUDA CODEC SDK 结合使用,也就是另一个开发包DeepStream;

  3. TensorRT独立于深度学习框架,通过解析框架文件来实现,不需要额外安装DL库;

    参考示意图:

    tensorrt_01

tensorRT安装

1、安装tensorRT之前准备

Deep Learning Video Classification and Captioning

[TOC]

基本术语

  1. 视频分类(Video Classification):将基于视频的语义内容如人类行为和复杂事件等,将视频片段自动分类至单个或多个类别,视频分类的研究内容主要包括多标签的通用视频分类和人类行为识别等。
  2. 视频描述生成(Video Captioning):试图基于视频分类的标签,形成完整的自然语句,为视频生成包含最多动态信息的描述说明。
  3. 词袋模型(Bag of Words)
  4. 3D CNN
  5. Two-stream CNN
  6. TSN模型
  7. LSTM
  8. GRU-RNN

研究方法

一、 传统视频分类方法研究

在深度学习方法广泛应用之前,大多数的视频分类方法采用基于人工设计的特征和典型的机器学习方法研究行为识别和事件检测。

传统的视频分类研究专注于采用对局部时空区域的运动信息和表观(Appearance)信息编码的方式获取视频描述符,然后利用词袋模型(Bag of Words)等方式生成视频编码,最后利用视频编码来训练分类器(如SVM),区分视频类别。视频的描述符依赖人工设计的特征,如使用运动信息获取局部时空特征的梯度直方图(Histogram of Oriented Gradients,HOG),使用不同类型的轨迹的光流直方图(Histogram of Optical Flow, HOF)和运动边界直方图(Motion Boundary Histogram,MBH)。通过词袋模型或Fisher向量方法,这些特征可以生成视频编码。

当前,基于轨迹的方法(尤其是DT和IDT)是最高水平的人工设计特征算法的基础[2]。许多研究者正在尝试改进IDT,如通过增加字典的大小和融合多种编码方法,通过开发子采样方法生成DT特征的字典,在许多人体行为数据集上取得了不错的性能。

然而,随着深度神经网络的兴起,特别是CNN、LSTM、GRU等在视频分类中的成功应用,其分类性能逐渐超越了基于DT和IDT的传统方法,使得这些传统方法逐渐淡出了人们的视野。

二、 深度网络方法研究

**深度网络为解决大规模视频分类问题提供了新的思路和方法。**近年来得益于深度学习研究的巨大进展,特别是卷积神经网络(Convolutional Neural Networks, CNN)作为一种理解图像内容的有效模型,在图像识别、分割、检测和检索等方面取得了最高水平的研究成果。卷积神经网络CNN在静态图像识别问题中取得了空前的成功,其中包括MNIST、CIFAR和ImageNet大规模视觉识别挑战问题。CNN采用卷积与池化操作,可以自动学习图像中包含的复杂特征,在视觉对象识别任务中表现出很好的性能。基于CNN这些研究成果,国内外开始研究将CNN等深度网络应用到视频和行为分类任务中。

与图像识别相比,视频分类任务中视频比静态图像可以提供更多的信息,包括随时间演化的复杂运动信息等。视频(即使是短视频)中包含成百上千帧图像,但并不是所有图像都有用,处理这些帧图像需要大量的计算。最简单的方法是将这些视频帧视为一张张静态图像,应用CNN识别每一帧,然后对预测结果进行平均处理来作为该视频的最终结果。然而,这个方法使用了不完整的视频信息,因此使得分类器可能容易发生混乱。

(1) 监督学习方法

i. 基于图像的视频分类:将视频片段视为视频帧的集合,每个视频帧的特征通过ImageNet数据集上预先训练的最高水平的深度模型(如AlexNet,VGGNet,GoogLeNet,ResNet)进行获取*。最终,帧层特征汇聚为视频层特征,作为标准分类器(如SVM)识别的输入。*

ii. 端到端的CNN网络:关注于利用CNN模型学习视频隐含的时空模式,如3D CNN,Two-stream CNN,TSN模型等。

iii. 双流(Two-stream)法中的时间CNN只能获取很短时间窗口内的运动信息,难以处理长时间多种行为组成的复杂事件和行为。因此,引入RNN来建模长期时间动态过程,常用的模型有LSTM,GRU-RNN等。LSTM避免了梯度消失的问题,在许多图像和视频摘要、语音分析任务中非常有效。

iv. 视频中包含了很多帧,处理所有的视频帧计算代价很大,也会降低识别那些与类别相关的视频帧的性能。因此,引入视觉注意力机制来识别那些与目标语义直接相关的最有判别力的时空特征

(2) 非监督学习方法

采用非监督学习的方法,整合空间和时间上下文信息,是发现和描述视频结构的一种很有前途的方法。

datasets

近年来为推动视频分类的研究,也陆续发布了相关的视频数据集。小型标注良好的数据集如KTH,Hollywood2,Weizmann;中型的数据集如UCF101,Thumos’14和HMDB51,这些数据集超过了50类行为类别;大型数据集如Sports-1M,YFCC-100M,FCVID数据集,ActivityNet数据集,YouTube-8M等。

![Deep Learning Video Classification and Captioning](02-DeepLearning Video Classification and Captioning/Deep Learning Video Classification and Captioning.jpg)

其中比较有代表性的有YouTube-8M(2016)、ActivityNet(2015)、Sports-1M(2014)、**UCF-101(2012)、HMDB51(2011)**等。

YouTube-8M的提出标志着视频分类朝大规模通用多标签视频分类的方向发展。

当前的研究结果表明:

  • HMDB51数据集上,DOVF+MIFS方法最高水平的准确度为75%,在该数据集上还有较大的性能提升空间[3];
  • UCF101数据集上,TLE方法达到最高水平的准确率为95.6%[4]。

机器学习常用术语

[TOC]

概念理解

Mask R-CNN (Regional Convolutional Neural Network: 区域卷积神经网络)

ComputerVisionTasks

  • 图像分类 (Classification): 图片中有气球。

  • 语义分割 (Semantic Segmentation): 这些是图片中组成所有气球的像素。

  • 目标检测 (Object Detection): 这里是图片中7个气球的位置。我们需要识别被遮挡的物体。

  • 实例分割 (Instance Segmentation): 这是是图片中7个气球的位置,包括组成每一个气球的像素。

mAP: 均值平均精度(Mean Average Precision)

Backbone: 骨干网络

backbone feature map : 骨干特征图

Feature Pyramid Network (FPN): 特征金字塔网络

FPNFlowChart

Mask RCNN 的实现采用的是 ResNet101 + FPN 作为骨干网络

Region Proposal Network (RPN): 区域提议网络

Anchor: 锚点, RPN 通过扫描骨干特征图(backbone feature map ) 得到锚点的. SSD 中称为先验框Prior boxes

Non-max Suppression : 非最大抑制, 在 RPN 预测过程中,我们会选择最可能包含物体的锚点,然后去修正它们的位置以及尺寸。如果有些锚点重叠得太多,我们会保留前景得分最高的一个,而其他的锚点就丢弃掉(这种方式成为非最大抑制 Non-max Suppression )。

regions of interest (ROI): 最终的提议区域, 也就是我们感兴趣的区域

Ground Truth : 对于物体检测问题,Ground Truth包括图像,图像中的目标的类别以及图像中每个目标的边界框。

ROI Pooling: 感兴趣区域的池化

Batch Normalization : Batch Normalization可以提升模型收敛速度,而且可以起到一定正则化效果,降低模型的过拟合。

BA DA DS ML CS

BA: business analyst

DA: data analyst

DS: data science

ML: machine learning

CS: computer science

selective search: 选择性搜索

SSD: Single Shot MultiBox Detector

hard negative mining : 为了保证正负样本尽量平衡,SSD采用了hard negative mining

Locatization loss, loc: 位置误差

confidence loss, conf : 置信度误差

SSD loss : 损失函数定义为位置误差(locatization loss, loc)与置信度误差(confidence loss, conf)的加权和

Data Augmentation: 数据扩增

Randomly sample a patch: 随机采集块域

dilation converlutional : 扩张卷积

因果卷积: 因果卷积的理解可以认为是:不管是自然语言处理领域中的预测还是时序预测,都要求对时刻t 的预测yt只能通过t时刻之前的输入x1到xt-1来判别。这种思想有点类似于马尔科夫链。

残差卷积的跳层连接: 微软的残差网络 ResNet 就是经典的跳层连接(skip-connection),上一层的特征图 x 直接与卷积后的 F(x)对齐加和,变为 F(x)+x (特征图数量不够可用 0 特征补齐,特征图大小不一可用带步长卷积做下采样)。

Fully Convolutional Networks : 全卷积网络

Recurrent Neural Network : 循环神经网络

Recursive Neural Network: 递归神经网络

BPTT Back Propagation Through Time: 反向传播算法

BPTS (Back Propagation Through Structure)

Gated Recurrent Unit(GRU)

Long Short Term Memery LSTM: 长短时记忆

稀疏是指绝大部分元素的值都是0, 反义稠密

cross entropy : 交叉熵误差函数

Overfitting and Regularization

[TOC]

1. underfitting and overfitting

我们利用多项式回归获得更加准确的拟合曲线,实现了对训练数据更好的拟合。然而,我们也发现,过渡地对训练数据拟合也会丢失信息规律。看两个概念:

  • 欠拟合(underfitting):拟合程度不高,数据距离拟合曲线较远,如下左图所示。
  • 过拟合(overfitting):过度拟合,貌似拟合几乎每一个数据,但是丢失了信息规律,如下右图所示,房价随着房屋面积的增加反而降低了。

underfitting_and_overfitting

我们有如下策略来解决过拟合问题:

  1. 减少特征数,显然这只是权宜之计,因为特征意味着信息,放弃特征也就等同于丢弃信息,要知道,特征的获取往往也是艰苦卓绝的。
  2. 不放弃特征,而是拉伸曲线使之更加平滑以解决过拟合问题,为了拉伸曲线,也就要弱化一些高阶项(曲线曲折的罪魁祸首)。由于高阶项中的特征 x 无法更改,因此特征是无法弱化的,我们能弱化的只有高阶项中的系数 θi。我们把这种弱化称之为是对参数 θ 的惩罚(penalize)。**Regularization(正规化)**正是完成这样一种惩罚的“侩子手”。

如下例所示,我们将 θ3 及 θ4 减小(惩罚)到趋近于 0,原本过拟合的曲线就变得更加平滑,趋近于一条二次曲线(在本例中,二次曲线显然更能反映住房面积和房价的关系),也就能够更好的根据住房面积来预测房价。要知道,预测才是我们的最终目的,而非拟合。

regularization

2. Regularized Linear Regression

在线性回归中,我们的预测代价如下评估:

$$J(\theta)=\frac{1}{2m}\sum\limits_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2$$

为了在最小化 J(θ) 的过程中,也能尽可能使 $θ$ 变小,我们将上式更改为:

$$\begin{align*} J(\theta) &= \frac{1}{2m}\sum\limits_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2+\lambda\sum\limits_{i=1}^{n}\theta_j^2 \ &= \frac{1}{2m}(X\theta-y)^T(X\theta-y)+\lambda\sum\limits_{i=1}^{n}\theta_j^2 \end{align*}$$

其中,参数 λ 主要是完成以下两个任务:

  1. 保证对数据的拟合良好
  2. 保证 $θ$ 足够小,避免过拟合问题。

λ 越大,要使 $J(θ)$ 变小,惩罚力度就要变大,这样 θ 会被惩罚得越惨(越小),即要避免过拟合,我们显然应当增大 λλ 的值。

那么,梯度下降也发生相应变化:

$$\begin{align*} \theta_0 &=\theta_0-\alpha\frac{1}{m}\sum\limits_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})x_0^{(i)} \ \theta_j &=\theta_j-\alpha\big(\frac{1}{m}\sum\limits_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)}+\frac{\lambda}{m}\theta_j\big) \quad (1) \ \mbox {即:}& \ \theta &= \theta-\alpha*(\frac{1}{m} X^T(y-X\theta) + \frac{\lambda}{m}\theta_{j}) \quad j \neq 0 \end{align*}$$

其中,**(1)**式等价于:

$$\theta_j=\theta_j(1-\alpha\frac{\lambda}{m})-\alpha\frac{1}{m}\sum\limits_{i=1}^{m}[h_\theta(x^{(i)})-y^{(i)}]x_j^{(i)}$$

由于 $1-\alpha\frac{\lambda}{m}\lt1$ ,故而梯度下降中每次更新 θ,同时也会去减小 θ 值,达到了 Regularization 的目的。

如果使用正规方程,则使 J(θ) 最小化的 θ 值为:

$$\theta=(X^TX+\lambda\left[\begin{array}{ccccc}0 &\cdots &\cdots &\cdots &0 \ 0 &1 &\cdots &\cdots &0\ \vdots & \vdots & 1 &\cdots & 0\ \vdots &\vdots &\cdots &\ddots & \vdots \ 0 & 0 &\cdots &\cdots &1 \end{array}\right])^{-1}X^Ty$$

3. Regularized Logistic Regression

逻辑回归中的正规化,代价评估如下:

$$\begin{align*} J(\theta) &=\frac{1}{m}\sum\limits_{i=1}^{m}y^{(i)}logh_0(x^{(i)})+(1-y^{(i)})log(1-h_\theta(x^{(i)}))+\frac{\lambda}{2m}\sum\limits_{j=1}^{n}\theta_j^2 \ &= \frac{1}{m}\big((,log,(g(X\theta))^Ty+(,log,(1-g(X\theta))^T(1-y)\big) + \frac{\lambda}{2m}\sum_{j=1}^{n}\theta_{j}^{2} \end{align*}$$

梯度下降如下:

$$\begin{align*} \theta_0 &=\theta_0-\alpha\frac{1}{m}\sum\limits_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})x_0^{(i)} \ \theta_j &=\theta_j-\alpha\big(\frac{1}{m}\sum\limits_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)}+\frac{\lambda}{m}\theta_j\big) \ \mbox {即:}& \ \theta &= \theta - \alpha*(\frac{1}{m} X^T(y-g(X\theta)) + \frac{\lambda}{m}\theta_{j}) \quad j \neq 0 \end{align*}$$

Programming Exercise 2 Logistic Regression

[TOC]

1. Introduction

任务所要用到的文件
ex2.m - 运行主文件1
ex2 reg.m - 运行主文件1
ex2data1.txt - 主文件1训练数据
ex2data2.txt - 主文件2训练数据
submit.m - 提交任务函数文件
mapFeature.m - Function to generate polynomial features
plotDecisionBoundary.m - Function to plot classifier’s decision bound-
ary
[?] plotData.m - Function to plot 2D classification data
[?] sigmoid.m - Sigmoid Function
[?] costFunction.m - Logistic Regression Cost Function
[?] predict.m - Logistic Regression Prediction Function
[?] costFunctionReg.m - Regularized Logistic Regression Cost
? 表示完成任务所要修改的文件

2. Logistic Regression

该任务要求创建一个逻辑回归模型用来判断学生能否拿到大学录取通知书。

ex2data1.txt 文件中记录了之前的学生成绩(两门课的分数)和录取情况(1/0), 根据该数据判断新生的录取。

2.1 Visualizing the data

数据可视化

3. Regularized logistic regression