-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 102 KB
/
content.json
1
{"meta":{"title":"Hexo","subtitle":null,"description":"keep hungry and practice more","author":"Jun Fu","url":"https://github.com/SunshineJunFu/JunFu.github.io"},"pages":[{"title":"categories","date":"2019-01-10T03:06:17.000Z","updated":"2019-02-17T07:18:54.708Z","comments":true,"path":"categories/index.html","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/categories/index.html","excerpt":"","text":""},{"title":"tags","date":"2019-01-09T03:43:57.000Z","updated":"2019-02-17T07:18:54.710Z","comments":false,"path":"tags/index.html","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/index.html","excerpt":"","text":""}],"posts":[{"title":"paper1","slug":"paper1","date":"2019-03-22T04:38:25.000Z","updated":"2019-03-22T04:39:23.787Z","comments":true,"path":"2019/03/22/paper1/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/03/22/paper1/","excerpt":"","text":"Spatial Temporal Graph Convolutional Networks for Skeleton-Based Action RecognitionAbstract人体骨骼点的变化对人体动作的识别提供了重要的信息。传统骨骼建模的方法通常依赖于手工或者遍历的方法,导致表达能力受限以及很难泛化。本文提出了一种对动态骨骼建模的新方法,该方法叫做时空域图卷积网络。该方法通过自动地从数据中学习时空域的模式,避免了前面方法的局限性。该方法不仅得到了更好的表达能力,而且具有更好的泛化性。在Kinetics和NTU-RGBD两个大数据集上,该方法相比于主流方法,在性能方面实现了大幅度的提升。 Current Research StatePipeline OVerviewSkeleton Graph ConstructionT帧骨骼序列,每帧包含N个连接点,其可以构成一个无向时空图G = (V, E),图中的节点集为 $V={v_{ti}|t=1,…,T, i=1,…,N}$, 每个节点的特征向量用$F(v_{ti})$来表示,$F(v_{ti})$ 表示第t帧第i个节点的特征向量,其由该点的坐标向量以及坐标向量的置信度组成。 时空域图的构成分成两部分: 帧内(intra): 由人体的结构来确定节点间是否相连 帧间(inter): 时序上,相同的节点相连 时空域图上的边: 帧内边, 记为 $E_{S} = {v_{ti}v_{tj}|(i,j) \\in H}$, H代表自然连接的人体节点。 帧间边, 记为 $E_{F} = {v_{ti}v_{(t+1)i}$, 代表了它随时间变化的轨迹。 Spatial Graph Convoluional Neural Network先介绍下二维图像的卷积。给定卷积核大小为 $K x K$, 操作对象为 宽为W, 高为H, 通道数为c的特征图。对于空间上的某点x, 其卷积后的值可以通过下式计算得到: $ f_{out} = \\sum_{h=1}^{K}\\sum_{w=1}^{K} f_in(p(x,h,w)) \\dot w(h,w) $ 其中,p(x,h,w)为采样函数:$$Z^{2} x Z^{2} \\rightarrow Z^{2} $$ 枚举了点x的邻域,在图像里,也可以简化为$$p(x,h,w)= x + p^{‘}(h,w) $$, $$f_in(p(x,h,w)) \\in R^{1x1xc} w(h,w) \\in R^{1x1xc} $$, $$w(h,w)$$与位置无关。 接着,基于二维图像卷积的认识,我们推导在图上的卷积。从上面可以发现,卷积的核心部分在于采样函数p,权重函数w以及特征图$$f_in$$的定义。 1: 对于t时刻的空域图$$V_{t}$$, 特征图为$$f_in^{t}: V_{t} \\rightarrow R^{Nxc}$$, 是N节点的c维特征集合。2: 采样函数p(x,h,w), 在图像中,采样函数p(h,w)定义为x的邻域, 数学上可以表达为: $$D_{8}(x) \\leq k $$, $$ k $$为街区距离。因此,类似地,我们定义采样函数为节点的邻域,例如,对于节点$$v_{ti}$$, 采样函数表示为$$B(v_{ti} = {v_{tj}|d(v_{tj}, v_{ti}) \\leq D}$$, D代表$$v_{ti}$$与$$v_{tj}$$的路径长度。论文中给出的D,取值为1。3: 权重函数w, 相比于图像而言,图的邻域没有明确空间的顺序。解决该问题的一种方式是对邻域进行标号。本文也采用的该思路,不同于对每一个邻域节点进行标号,文中将$$B(v_{ti})$$分成固定的$$K$$个子集,也就是有一个映射函数 $$l_{ti}: B(v_{ti}) \\rightarrow {0,…,K-1} $$。 那么基于此,权重函数$$w(v_{ti},v_{tj}):B(v_{ti}) \\rightarrow R^{c} $$,c是单个节点特征的维度,这个可以通过预先定义一个cxK维的张量,然后通过子集序号来索引,即:$$w(v_{ti},v_{tj})=w^{‘}(l_{ti}(v_{tj}))$$. 总结而言,图卷积仍然是在邻域内进行加权(特征图和权重内积),改变了采样函数p,权重函数w以及特征图$$f_in$$的定义方式。 Spatial Graph Convolution通过重定义采样函数p,权重函数w以及特征图$$f_in$$,则可以推出下式: $f_{out}(v_{ti}= \\sum\\limits_{v_{tj} \\in B(v_{ti})} \\frac{1}{Z_{ti}(v_{tj})}f_{in}(p(v_{ti},v_{tj}))w(v_{ti},v_{tj})$ 其中,$$Z_{ti}(v_{tj})} = |{v_{tk}|l_{ti}(v_{tk})= l_{ti}(v_{tj})|$$, 代表了对应子集的基数,这个是用于平衡不同自己对输出的贡献。最终的出下式: $f_{out}(v_{ti}= \\sum\\limits_{v_{tj} \\in B(v_{ti})} \\frac{1}{Z_{ti}(v_{tj})}f_{in}(v_{tj})w(v_{ti},v_{tj})$。 值得注意的是, 如果把图像当作一个规则的2D网格,上式类似于标准的2D卷积。以3x3的卷积操作为例,我们有9个pixels,邻域被分成9个子集,每个子集含有1个像素点。 Spatial Temporal Modeling了解完空域的图卷积,那么接下来将它扩展至时域图卷积。 定义邻域: $$ B(v_{ti}) = {v_{qj}|d(v_{tj},v_{ti}) \\leq K, |q-t| \\leq \\lfloor \\Gamma/2 \\rfloor}, 其中$$\\Gamma$$控制者考虑时域的范围,可以理解为时域的核大小。 定义权重函数:与空域类似,仍然采用标号的方式(类似于embedding),由于时域上顺序是确定的,因此,对于节点$v_{ti}$, 其$l_{ST}$用下式确定:$l_{ST}(v_{qj}) = l_{ti}(v_{tj}) + (q-t+ \\lfloor \\Gamma/2 \\rfloor) x K $其中$l_{ti}(v_{tj})$是t时刻, i节点的空域标号。理解: 参照图1, 就是时域的邻域为前后 $$\\lfloor \\Gamma/2 \\rfloor)$$ 帧, 每帧考虑K个节点(图1很好的解释了该公式)。Ps:之所以如此编号,是为了确定邻接矩阵的index Partition Strategies单一labeling邻域内所有节点有着相同的贡献。 缺点: 丢失局部信息。 距离划分根据距离中心节点的距离进行划分 空域配置划分自定义一些划分方式 可学习的边重要性尽管当人在执行动作时,骨骼点一起运动,但是一个骨骼点可能出现在多个身体部位。 但是,每个节点应该在不同的部分有不同的重要性。因此,我们在每一时空图卷积加了一个可学习的掩模(mask)。 实现ST-GCN输入Tensor: shape ( C, V, T) C : 单个节点上的feature维度V : 空域节点T : 时间帧数 该文章实现思路可以分为两步走: 对每个时间点t,进行空域图卷积,此时邻接矩阵是已知的 然后对不同时刻的相同节点进行2-D卷积,核大小为 $1x \\Gamma$, 即进行时域聚合,此时,邻接矩阵是用卷积核来替代的。 理解: 第一步,相当于把空域的邻接节点的信息考虑了进来 第二步,相当于把 时域上的相同节点的邻接节点考虑了进来 实现过程中,论文中采用了批归一化,主要类似于kipf的归一化邻接矩阵,起到防止梯度爆炸的作用。","categories":[],"tags":[{"name":"Spatial Temporal Graph Convolutional Networks for Skeleton-Based Action Recognition","slug":"Spatial-Temporal-Graph-Convolutional-Networks-for-Skeleton-Based-Action-Recognition","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/Spatial-Temporal-Graph-Convolutional-Networks-for-Skeleton-Based-Action-Recognition/"}]},{"title":"tensorboard_install","slug":"tensorboard-install","date":"2019-02-27T03:19:31.000Z","updated":"2019-02-27T03:29:04.924Z","comments":true,"path":"2019/02/27/tensorboard-install/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/27/tensorboard-install/","excerpt":"","text":"安装Tensorflow-gpu 查看cuda版本: cat /usr/local/cuda/version.txt 查看cudnn版本: cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2 在该网站上,根据cuda和cudnn版本选择合适的tensorflow-gpu版本 在该网站上下载对应版本的whl文件 执行pip install xxx.whl, 即可 验证安装成功: import tensorflow a tf tf.Session() 上述语句无报错,则表示安装无误","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"tensorflowtutorial11","slug":"tensorflowtutorial11","date":"2019-02-20T13:01:22.000Z","updated":"2019-02-20T13:48:08.444Z","comments":true,"path":"2019/02/20/tensorflowtutorial11/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/20/tensorflowtutorial11/","excerpt":"","text":"tf.estimator.RunConfig()函数: replace(**kwargs) 返回新的RunConfig 以下可以被修改: model_dir, tf_random_seed, save_summary_steps, save_checkpoints_steps, save_checkpoints_secs, session_config, keep_checkpoint_max, keep_checkpoint_every_n_hours, log_step_count_steps, train_distribute, device_fn, protocol. eval_distribute, experimental_distribute, 1234config = tf.estimator.RunConfig().replace( session_config=tf.ConfigProto(device_count={'CPU':self._num_threads}), log_step_count_steps=20) tf.ConfigProto() 配置seseion参数 … tf.estimator.Estimator创建Estimator 1234567__init__( model_fn, model_dir=None, config=None, params=None, warm_start_from=None) Args: model_fn: 模型函数 (features, labels, mode, params, config) or (features, labels, mode, params) features: This is the first item returned from the input_fn passed to train, evaluate, and predict. This should be a single tf.Tensor or dict of same. labels: This is the second item returned from the input_fn passed to train, evaluate, and predict. mode: Optional. Specifies if this training, evaluation or prediction. See tf.estimator.ModeKeys params: Optional dict of hyperparameters. Will receive what is passed to Estimator in params parameter. This allows to configure Estimators from hyper parameter tuning config: Optional estimator.RunConfig object. Will receive what is passed to Estimator as its config parameter, or a default value. Allows setting up things in your model_fn based on configuration such as num_ps_replicas, or model_dir return: tf.estimator.EstimatorSpec() model_dir: 保存模型的路径 config: estimator.RunConfig configuration object. params: dict of hyper parameters that will be passed into model_fn. Keys are names of parameters, values are basic python types. Returns: an Estimator instance tf.estimator.EstimatorSpec()new( cls, mode, predictions=None, loss=None, train_op=None, eval_metric_ops=None, export_outputs=None, training_chief_hooks=None, training_hooks=None, scaffold=None, evaluation_hooks=None, prediction_hooks=None) Depending on the value of mode, different arguments are required. Namely For mode == ModeKeys.TRAIN: required fields are loss and train_op. For mode == ModeKeys.EVAL: required field is loss. For mode == ModeKeys.PREDICT: required fields are predictions. tf.estimator.TrainSpec创建训练的TrainSpec实例 1234567@staticmethod__new__( cls, input_fn, max_steps=None, hooks=None) Args: input_fn: 提供minibatches的输入数据的函数。函数的返回值结构如下: a tf.data.Dataset 对象 (features, labels): features 是tensor或者dict{name: tensor} max_steps: int, 训练的最大步数,未设置,则永远训练 hooks: 钩子函数 Returns: TrainSpec实例 tf.estimator.EvalSpec创建验证的EvalSpec实例 1234567891011@staticmethod__new__( cls, input_fn, steps=100, name=None, hooks=None, exporters=None, start_delay_secs=120, throttle_secs=600) Args: input_fn: 提供minibatches的输入数据的函数。函数的返回值结构如下: a tf.data.Dataset 对象 (features, labels): features 是tensor或者dict{name: tensor} steps: None,则在整个验证集验证 Returns: EvalSpec实例 tf.estimator.train_and_evaluate函数: Train and evaluate the estimator 123456tf.estimator.train_and_evaluate( estimator, train_spec, eval_spec) Args: estimator: estimator实例 train_spec: train_spec实例 eval_spec: eval_spec实例 tf.nn.embedding_lookup","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"linuxweek2","slug":"linuxweek2","date":"2019-02-17T07:22:46.000Z","updated":"2019-02-17T08:16:09.724Z","comments":true,"path":"2019/02/17/linuxweek2/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/17/linuxweek2/","excerpt":"","text":"正则表达式功能:描述一个字符串模式,用于字符串匹配操作和替换操作,针对文本内容 字符类别 描述 元字符 .,*,[,\\,^,$ 其他字符 与自身匹配 元字符 描述 . 代表匹配任意单字符 * 表示该符号前一个字符出现0次或者任意多次 [ 表示集合,在集合中\\,*,.代表其本身 \\ 转移字符,将特殊字符转义为本身 - [a-z]两个字符之间表示区间,否则代表本身 ^ 集合中时表示取反,在正则表达式行首表示匹配行首的字符串 $ 在正则表达式行尾表示匹配行尾的字符串,其他位置代表本身 PCRE对BRE进行了改进: (),表示分组 | 表示逻辑运算 (pink | green) 表示1次或多次 ? 表示出现0次或1次 {m,n}, 出现m至n次 命名的预定义集合: [[:xdigit:]] 16进制数字,\\d $\\rightarrow$ 数字,\\D $\\rightarrow$ 非数字 文本编辑工具grep行筛选 用法: grep [option] 模式 文件名列表 选项: -n 显示时每行前面显示行号 -v 显示所有不包含模式的行 -i 字母比较时忽略字母的大小写 sed流编辑 用法: 单个命令: sed ‘cmd’ 文件列表 多个命令: sed -e ‘cmd’ -e ‘cmd1’ 文件列表 执行文件里的命令: sed -f 命令文件 文件列表 模式描述增加( 和 ), 不影响匹配, 用于分组, 与之配套用的是 \\0, \\1, \\2…表示第几个括号括起来的内容 替换: ‘s/xxx/xx/g’ awk复杂筛选和加工,朱行扫描进行文本处理的一门语言 用法: awk ‘程序’ 文件名列表 awk -f 程序文件名 文件名列表 程序: 条件 {动作}, awk自动对每行文本执行条件判断,满足则执行动作, 多段程序使用空格或分号隔开 变量 NR, 行号 每行以空格为域分隔符,$1 代表第1个空格间的内容, $0代表整行内容 条件 关系运算: <,>, ==, <=, >=, != 逻辑运算: || , &&, ! 正则表达式的模式匹配: /regexpr/ 包含该模式的行,执行动作 不指定任何条件,对对所有文本行执行动作 BEGIN 开始处理所有文本行之前执行动作,END 处理完所有文本行之后执行动作 动作 加减乘除 print 变量1,变量2 print(“格式串”,变量1,变量2) 流程控制: if 条件判断,for 循环控制","categories":[],"tags":[{"name":"linux","slug":"linux","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/linux/"}]},{"title":"linuxweek5","slug":"linuxweek5","date":"2019-02-15T13:39:14.000Z","updated":"2019-02-17T07:18:54.654Z","comments":true,"path":"2019/02/15/linuxweek5/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/15/linuxweek5/","excerpt":"","text":"week5文件系统 类别 描述 根文件系统 整个文件系统的基础,不能脱卸(unmount) 子文件系统 包含硬盘,软盘,…,以根根文件系统中某一目录的身份出现 注: 根文件系统和子文件系统都有其自己独立的文件存储结构,甚至文件系统的格式也不同。 创建与删除123456789101112131415161718191. 在块设备文件 /dev/sdb上创建文件系统mkfs /dev/sdb2. 安装子文件系统mount,/mnt为预先创建的空目录名mount /dev/sdb /mnt3. 列出当前已安装的所有的子文件系统mount 4. 卸载某个文件系统unmount /dev/sdb5. 显示文件系统空间df -h 文件系统的结构 hh 组成 描述 引导块 用于启动系统,仅根文件系统的引导块有效 专用块 存放文件系统的管理信息,例如文件系统的大小,i节点区的大小 i节点区 存放指向文件存储区数据块的一些索引指针,即逻辑地址与物理地址的映射,文件类型,不包含文件名 文件存储区 存放文件数据,包含目录表 i节点区 i节点区由若干块构成,在 mkfs 命令 创建 文件系统时 确定 每块 可容 若干 个i节点,每个 i节点的大小是固定(比如 64kB) i节点从0开始编号,根据编号可以索引到磁盘块 每个文件度对应1个i节点 i 节点包含的信息: 指向文件存储区数据块的一些索引 指向文件存储区数据块的一些索引指针 文件类型,属组,权限,link数,大小,时戳,不包含文件名注: 目录表包含:文件名和i节点号 ls命令列出的目录大小为目录表文件本身的长度 目录表和i节点两级结构主要是为了提高目录检索的效率 软,硬连接硬连接:目录表中的“文件名-i节点号”映射关系,可以在同一目录或者不同目录中的两个文件项有相同的i节点号。 硬连接数目:同一i节点被目录项引用次数 创建硬连接: ln chapt0 intro 注: chapt0与intro同时存在时,地位平等 删除chapt0文件,则intro仍存在但link数减1 硬连接,只限于同一文件系统的普通文件 符号连接:又叫做软连接 文件仅包含一个路径名 12ln -s users_on sym.link ls -l sym.link 符号连接中的相对路径: 若符号连接文件包含绝对路径名,引用绝对路径名 若包含相对路径名,是相对符号连接文件的位置,而非调用进程的当前工作目录 异同点: 软连接在算法实现,可以在目录和不同的文件系统中使用 文件的权限普通文件的权限: 读、写、可执行, 不可写文件也可能被删除 可执行文件: 程序文件: 可执行文件 脚本文件: 文本文件, 第一行#!执行解释器,脚本运行时,是由解释程序创建一个进程 目录的权限 读权限, 是说能否访问目录表文件 写权限,是说能否写目录表文件 修改文件会修改i节点,不需要修改目录文件 目录无写权限不是指目录下所有文件禁止写 创建文件和删除文件,文件改名会修改目录文件 无写权限,目录表文件不许写 执行权限: 意味着分析路径名过程中可检索该目录 修改权限chmod [ugoa][+-=][rwxst] 文件名表 u 文件主权限g 同组用户权限o 其他用户a 所有 chmod 644 文件列表 注: 只允许文件主和超级 用户修改文件权限 unmask: 控制文件/目录的初始权限 unmask 打印当前值 unmask 022 将mask值设置为8进制的022,000 010 010 取消新文件和新目录的其他用户的w权限","categories":[],"tags":[{"name":"linux","slug":"linux","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/linux/"}]},{"title":"linuxweek8","slug":"linuxweek8","date":"2019-02-14T15:06:53.000Z","updated":"2019-02-17T07:18:54.657Z","comments":true,"path":"2019/02/14/linuxweek8/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/14/linuxweek8/","excerpt":"","text":"shell 之变量内部变量之位置参数 变量 描述 $0 脚本文件本身的名字 $1,$2,…,$n n号命令行参数 $# 命令行参数的个数 “$*” 等同于”$1 $2 $3…” “$@” 等同于”$1”,”$2”,”$3”,… 内部的shift命令: 位置参数的移位操作,$#的值减一,旧的$2变为$1,…,也可以shift n 自定义变量 存储的内容:字符串,执行的过程中可以被修改。 变量名: 字母开头,其余字符可以是数字,字母,下划线 创建变量: name=1.12 等号两侧不能有空格 引用变量: $name 或者 ${name} 当变量未定义时,变量值为空 shell内部一些开关 描述 set -u 当引用一个未定义的变量时,产生一个错误 set +u 当引用一个未定义的变量时,认为是一个空串 set -x 执行命令时,打印执行的命令及参数,前面冠以+号 set +x 取消上述设置 环境变量和局部变量 创建的变量,默认为局部变量 局部变量$\\rightarrow$环境变量,使用export语句 export proto 局部变量: shell启动的子进程继承环境变量,不继承局部变量 子进程对环境变量的修改,不影响父进程的同名变量 几个环境变量 HOME: 用户主目录的路径名 PATH: 命令查找路径 TERM: 终端类型 另外: set命令列出当前所有变量及其值以及函数的定义, env累出环境变量及其值。 元字符 元字符 描述 空格,制表符 命令行参数的分隔符 回车 执行键入的命令 >,<, 重定向与管道 ; 用于一行内输入多个命令(;;) & 后台运行(&&) $ 应用shell变量 ` 反向单引号,用于命令替换 * [] ? 文件通配符 \\ 去向后继字符的特殊作用,转义 () 用于定义shell函数或在子shell中执行一组命令 注: ()><|;&除本身意义外还可以起到分隔符的作用 转义双引号 “” 除$和`外特殊字符的特殊含义被取消,即仍可以使用命令替换和变量替换 需要的转义: \\”, \\$, `, \\ 单引号 对所括起的任何字符,不作任何特殊解释 转义符代表斜杠本身,不许中间插入单引号 反撇号 \\ 代表反斜线吱声 `代表反撇号本身 转义符后跟非特殊字符 引号内,系统处理时尽量维持字面含义 引号外,属于未定义的情况,最好不跟非特殊字符 shell 替换 命令替换 name=cmd 或者name = $(cmd) , 代表着name=执行cmd的标准输出, 变量替换 $name ${name} 文件名替换 ls *.c 辅助的命令 命令 描述 read name 从标准输入读入一行内容赋值给变量 echo arg1 arg2 arg3 打印命令行参数,没两个间用1空格分开,最后打印换行符 echo -e arg1 arg2 arg3 除上面功能外,会打印转义符 printf ‘\\033[01;33mConnect to %s Network\\n’ $proto 打印 注: echo转义 描述 \\c 打印完毕,不换行 \\b 退格 \\n 换行 \\r 回车 \\t 水平制表 \\ 反斜线 \\nnn 八进制描述的字符ASCII码","categories":[],"tags":[{"name":"linux","slug":"linux","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/linux/"}]},{"title":"linuxweek7","slug":"linuxweek7","date":"2019-02-14T06:54:38.000Z","updated":"2019-02-17T07:18:54.656Z","comments":true,"path":"2019/02/14/linuxweek7/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/14/linuxweek7/","excerpt":"","text":"shell种类 种类 描述 B-shell /bin/sh Stephen R.Bourne 于贝尔实验室开发 C-shell /bin/csh, Bill Joy K-shell /bin/csh, korn shell, David Korn Bash /bin/bash, Bourne Again shell 功能 shell是命令解释器 文件名替换,命令替换,变量替换 历史替换,别名替换 流程控制的内部命令(内部命令和外部命令) 主要用途:批处理,执行效率比算法语言低 学习bash的目的: 交互方式下:熟习shell的替换机制、转义机制,掌握循环等流程控制,可以编写复合命令 非交互方式:编写shell脚本程序,把一系列的操作,编纂成一个脚本文件,批量处理 具体功能 重定向与管道 方便交互使用的功能:历史替换与别名替换 shell变量 shell的变量替换,命令替换,文件名替换 元字符,如:单引号,双引号 流程控制 子程序 启动交互式shell注册shell 和 交互式shell的区别? 启动方法 注册shell: 注册shell 键入bash 命令: 交互式shell 脚本解释器 自动执行一批命令(用户偏好): 注册shell时:自动执行用户主目录下的.bash_profile文件中的命令 bash作为注册shell退出时: 自动执行$HOME/.bash_logout bash作为注册shell启动时: 自动执行$HOME/.bashrc 自动执行一批命令(系统级): 当bashbash bash作为注册shell被启动时:自动执行 /etc/profile 文件中命令 当bash 作为交互式shell启动时: 自动执行 /etc/bash.bashrc 当bash作为注册shell退出时:自动执行/etc/bash.bash.bash_logout 历史与别名历史表查看历史表 history 设置历史表的大小: 修改变量HISTSIZE 历史替换: 人机交互时,直接使用上下箭头 !! 引用上一条命令 !str 以str开头的最近用过的命令 别名创建别名:alias h=”alias”, 注意等号两端无空格 查看别名表: alias 取消别名: unalias h Tab键补全 每行的首个单词: 全搜索$PATH下的命令 行中的其他单词: 当前目录下的文件名 重定向输入 命令 描述 <filename 从filename中获取stdin <<word 从shell脚本文件中获取数据直到再次遇到定界符word ???? <<<word 从命令行获取信息作为标准输入 输出 fd 描述 0 标准输入, stdin 1 标准输出,stdout 2 标准错误输出, stderr 命令 描述 >filename 将stdout重定向到文件 filename,文件已存在则先清空( 覆盖方式 >>filename 将stdout重定向 追加 到文件 filename尾 2> filename 将文件句柄2重定向到文件 filename 2>&1 将文件句柄 2重定向到文件描述符 1 cmd1 cmd2 将cmd1的标准输出作为cmd2的标准输入","categories":[],"tags":[{"name":"linux","slug":"linux","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/linux/"}]},{"title":"tensorflow-tutorial-11","slug":"tensorflow-tutorial-11","date":"2019-02-11T02:53:52.000Z","updated":"2019-02-17T07:18:54.696Z","comments":true,"path":"2019/02/11/tensorflow-tutorial-11/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/11/tensorflow-tutorial-11/","excerpt":"","text":"导入数据tf.data.Dataset属性 属性 描述 output_classes 返回数据集中每个元素的每个组成部分的类名 output_shapes 返回数据集中每个元素的每个组成部分的形状 output_types 返回数据集中每个元素的每个组成部分的数据类型 方法创建数据集 方法 描述 from_tensor_slices(tensors) 建立给定tensors的数据集,多个元素,该数据集嵌入在图中,适用于小数据集(小于1G),更大的数据集操作 from_tensors(tensors) 同上,但针对单个元素 基于数据集上的变换 方法 描述 map(map_func,num_parallel_calls=None) 对数据集中的每个元素执行map_func操作 shuffle(buffer_size,seed=None,reshuffle_each_iteration=None) 随机抽取元素 batch(batch_size,drop_remainder=False) 设置batch的大小 repeat(count=None) 将数据集重复几次,默认为无限循环 zip(datasets) datasets 元组,将多个数据集合并 创建迭代器 方法 描述 make_initializable_iterator(shared_name=None) 创建一个未初始化的iterator make_one_shot_iterator() 创建一个已经自动初始化的iterator, 每次只返回单个元素 tf.data.Iterator属性 属性 描述 initializer 返回初始化迭代器的操作 output_classes 返回数据集中每个元素的每个组成部分的类名 output_shapes 返回数据集中每个元素的每个组成部分的形状 output_types 返回数据集中每个元素的每个组成部分的数据类型 方法创建迭代器 方法 描述 from_string_handle(string_handle,output_types) 基于给定的句柄创建一个未初始化的迭代器 from_structure(output_types) 基于给定的结构创建一个未初始化的迭代器 注: from_structure可以不同的数据集进行复用(reusable,Iterator.make_initializer(dataset)重新初始化,from_string_handle “feedable” iterator 。 区别: 常用方法 方法 描述 get_next(name=None) 返回下一个数据集中的元素 make_initializer(dataset,name=None) 返回通过指定的dataset初始化iterator的操作 string_handle(name=None) 返回代表迭代器的string 注:make_initializer 与 from_structure 连用, string_handle与from_string_handle连用。get_next抵达数据集最后一个元素会有tf.errors.OutOfRangeError错误。 References tf.data.Dataset tf.data.Iterator","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"linuxweek4","slug":"linuxweek4","date":"2019-02-07T06:52:24.000Z","updated":"2019-02-17T07:18:54.653Z","comments":true,"path":"2019/02/07/linuxweek4/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/07/linuxweek4/","excerpt":"","text":"文件管理列出当前文件ls [optional] [file/dir] 命令 描述 ls 列出当前目录下所有文件和目录 ls file 列出文件项 ls dir 列出目录下的所有文件项 选项 描述 -F 列出的如果是目录则在名字后以斜线/表示,可执行文件*,符号连接文件@,普通文件无标记 -l 以长格式显示信息 -a 列出文件名首字符为圆点的文件,默认情况下不列出 -A 与-a类似,不列出.和.. -s 列出文件占用的磁盘空间 -i 列出文件的i节点号 -h 以便于人阅读的方式打印数值 -d 当ls参数是目录时,列出目录自身信息 长格式列表input: ls -l argoutput: -rwxr-x–x 1 liang stud 519 Jul 5 15:02 arg 第一列:文件属性: 文件类型+文件的访问权限(rwx)(用户,与用户同组的用户,与该用户不同组的用户) 符号 文件类型 - 普通文件 d 目录 l 符号连接文件 b 块设备文件 c 字符设备文件 p 命名管道文件 第二列: 文件link数,涉及到此文件的目录项数 第3,4列: 用户名,该用户所在的组 第5列 文件类别 描述 普通文件 列出文件大小 目录 列出目录表大小 符号连接文件 列出符号连接文件自身的长度 字符设备和块设备 列出主次设备号 管道文件 列出管道的数据长度 第6列: 文件最后一次被修改的日期和时间 第7列: 文件名,对于符号连接文件,附带列出符号连接文件的内容 文件的复制与删除拷贝文件cp file1 file2 或者 cp file1 file2… filen dir 第二种格式,dir必须存在并且是目录 第一种格式,file2不存在,则创建;file2存在且是文件,则覆盖,若是目录则按格式2处理。 移动文件mv file1 file2 or mv file1 file2…filen dir or mv dir1 dir2 使用mv命令可以将文件和目录改名 可以将文件和从子目录从一个目录移动到另一个目录 删除文件rm file1 file2…filen 选项 描述 -r recursive 递归地删除实参表中的目录 -i inform 没删除一个文件需要操作员确认 -f force 强迫删除,只读文件也被删除并且无提示 文件打包命令tar ctxv [f device] file-list 选项 描述 -c create 创建新磁带,以前创建的会被覆盖 -t table 磁带的文件名列表。当不指定文件名时,将列出所有文件 -x eXtract 从磁带中抽取指定的文件,当不指定文件名时,抽取所有文件 -v verbose 每处理一个文件,就打印出文件的文件名,并在该文件名前冠以功能字母 f File指定设备文件名 z gzip 采用gzip压缩格式 j 采用bzip2算法 e.g. tar cvf my.tar *.[ch] makefile e.g. tar czvf my.tar.gz *[ch] makefile e.g. tar cjvf my.tar.bz2 *[ch] makefile 其他压缩/解压命令: gzip/gunzip 执行速度快 bzip2/bunzip2 占用较多的cpu时间 目录操作打印/改变当前目录 命令 描述 pwd print work directory 打印当前工作目录 cd dir 切换至dir cd windows 打印当前目录,linux回到用户主目录 cd .. 回到上层目录 创建/删除目录mkdir sun/work.d -p 自动创建路径不存在的目录 mkdir -p database/2019/09/04/log rmdir sum/work.d 要求被删除的目录除.与..外无其他文件或目录 -r 递归的删除目录及其子目录? 复制目录cp -r dir1 dir2 dir2 不存在,新建目录dir2,把dir1下内容拷贝至dir2下 dir2已存在,在dir2目录下新建dir1,把dir1内容拷贝纸dir2/dir1下 -v 实时显示正在复制的文件的名字 -u 增量拷贝,便于备份目录, 根据文件的时间戳,不拷贝相同的或者过时的版本文件,以提高拷贝速度。 touch将文件最后一次修改时间设置为当前时间,但不改变文件。 touch *.[ch] 目录遍历 find 功能: 从指定的查找范围开始,递归地查找子目录,凡满足条件的文件或者目录,执行规定的动作。 动作 动作 描述 -print 打印查找的文件的路径名 -exec 对查找的目标执行某一命令 在-exec及随后的分号之间的内容作为一条命令,{}代表遍历道德目标文件的路径名 -ok 只是对查找到符合条件的目标执行前需要管理人员确认 xxx 自定义命令 条件 命令 描述 -name wildcard 文件名与wildcare匹配,必须引号,文件名指的是路径名的最后一部分,对通配符的解释由find完成 -regex pattern 整个路径名与正则表达式pattern匹配 -type f/d/l/c/b/p 文件类型 -size +, , - N 文件大小,+ 大于,- 小于, 单位b,k,M -mtime +, ,- ndays 文件最近修改时间 -newer file 文件修改时间比file的修改时间还晚 () -o ! 表示多条件的“与”,“或”,”非” 示例: find verl.d ver2.d -name ‘*.c’ -print 范围: 当前目录的子目录ver1.d和ver2.d 条件: 与名字.c匹配。注:.c应当用引号括起来 动作: 把查找的文件的路径打印出来","categories":[],"tags":[{"name":"linux","slug":"linux","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/linux/"}]},{"title":"linux之vi编辑器","slug":"linuxweek3","date":"2019-02-06T14:57:11.000Z","updated":"2019-02-17T07:18:54.650Z","comments":true,"path":"2019/02/06/linuxweek3/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/06/linuxweek3/","excerpt":"","text":"vi编辑器有两种状态: 命令状态:键盘输入解释为命令 vi 一启动就进入命令行模式 以冒号可以引入行编辑的命令和查找命令 编辑命令i(insert, 当前字符前),a(append,当前字符后),可以从命令状态转到文本状态 文本状态 键盘输入解释为输入的文本 可以输入多行 有回显 按Esc键,返回到命令状态 常见命令光标移动 命令 描述 h 左移1列 j 下移1行 k 上移1行 l 右移1列 数值n+h,j,k,l 对应操作执行n次 ctrl+b 向后翻页 ctrl+f 向前翻页 ^ 将光标移至行首 $ 将光标移至行尾 w 右移1个单词 b 左移1个单词 :476 移动至476行 :1 移动首行 :$ 移动至文件末尾 编辑 命令 描述 x 删除当前字符 dd 删除行 u 取消上一次编辑 . 重复上一次编辑操作 :n1,n2d 删除第n1-n2行 :1,.d 删除首行至当前行 :.,$d 删除当前行至文件尾 :10,50y 拷贝10-50行至剪贴板(yank) p 粘贴剪贴板信息 ra 将当前光标处字符替换为a 保存 命令 描述 :wq 写入并保存 :w 写入不退出 :q! 不存盘退出 块操作 命令 描述 :5,10co56 复制第5-10行至56行之下 :8,34m78 移动8-34行至第78行之下 J 当前行和下面行合并至当前行 ctrl + l 刷新屏幕显示 ctrl+g 状态显示 查找与替换 命令 描述 /pattern 查找匹配该模式的项 n 向下查找下一个 N 向上查找下一个 :n1,n2s/pattern/string/g 替换成string 几个问题死机 现象:vi 编辑结束后执行存盘操作,果导致屏幕 卡死,输入任何信息都不在有显示 原因: 编辑结束后按下 Ctrl-S,因为 WindowsWindows 编辑器一般设置 Ctrl-S热键的动作为Save ,但Linux 却进入流量控制状态。 解决方法: 按下Ctrl-Q键后流量控制解除 意外中止问题 现象: vi编辑结束后存盘,程序意外中止成果丢失文件内容未发生变化 原因: vi存盘命令Shift-ZZ,误操作为Ctrl-ZZ,而Ctrl-Z按键导致当前运行进程被挂起 (suspend ),暂停运行(但进程尚在,处于stopped状态) 解决方式: 调用bash的作业管理机制,恢复运行被stopped的进程 jobs 列表当前被Stopped的进程有哪些 fg %1 将1号作业恢复到前台运行 %1 将1号作业恢复到前台运行 屏幕显示乱码问题 现象: cat /bin/bash 或head -n 1 /bin/bash 导致屏幕乱码,键盘输入也只能看到画表用的框框符 原因:/bin/bash /bin/bash /bin/bash文件不是本,这些二进制内容逐字节送到终端,凑巧一个序列被理解 终端,凑巧一个序列被理解 终端,凑巧一个序列被理解 为一个转义序列,执行动作:修改了终端字符集 解决方式:断开连接,重新连接,注意不要把非文本信息在终端输出 文本文件格式问题 现象: Linux下的文本件在 Windows用notepad打开,所有内容粘在一行内 原因: Linux和Windows的文本文件的存储格式不同, windows行尾为回车和换行\\r\\n,linux为\\n 解决方式: 在linux完成格式转化后再用windows处理 dos2unix/unix2dos, todos/frodos 中文编码配置问题 现象: 从windows迁来的文件,只有在显示中文字符时是乱码。Linux本身的正常显示 原因: 中文GBK与UTF8不兼容 7比特 ASCII码,字节高位为0,后面7位是英文ASCII码 gbk , 两个字节表示一个汉字,字节的高位为1以区分ASCII码 解决方式: 检查系统设置: export LANG=en_US.UTF-8 iconv:中文字符编码的转化: iconv -f gbk -t utf8","categories":[],"tags":[{"name":"linux","slug":"linux","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/linux/"}]},{"title":"tensorflow_tutorial_10","slug":"tensorflow-tutorial-10","date":"2019-02-02T17:03:10.000Z","updated":"2019-02-17T07:18:54.694Z","comments":true,"path":"2019/02/03/tensorflow-tutorial-10/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/03/tensorflow-tutorial-10/","excerpt":"","text":"梯度下降损失函数$J(\\theta, x)$是一个关于网络参数$\\theta$和样本$x$二元函数,它是一个凸函数,表示了用网络参数$\\theta$来预测与真实结果的偏差大小。神经网络的目标是使得预测结果与真实结果尽可能一致,这句话可以等价于:找到一组网络参数$\\theta$使得loss function最小。求解这一组网络参数$\\theta$的方法之一是梯度下降法: $$\\theta=\\theta-\\alpha\\frac{\\partial J(\\theta, x)}{\\partial\\theta}$$ 其中,$\\alpha$, 术语叫做学习率,也就是说每一步参数$\\theta$更新步长的大小,$\\frac{\\partial J(\\theta, x)}{\\partial\\theta}$为$J(\\theta, x)$对参数$\\theta$的偏导,反映了最快变化量。另一方面,由于采用的下降法,所以是负号。 直观的理解:以图2为例: 对于P点,它的$\\frac{\\partial J(\\theta, x)}{\\partial\\theta}< 0$, 因为使得损失越小,所以$\\theta$应该增大,对应于$-\\frac{\\partial J(\\theta, x)}{\\partial\\theta}>0$。 对于Q点,它的$\\frac{\\partial J(\\theta, x)}{\\partial\\theta}>0$, 因为使得损失越小,所以$\\theta$应该减小,对应于$-\\frac{\\partial J(\\theta, x)}{\\partial\\theta}<0$。 关于学习率$\\alpha$, 设置过大,如图3中的红线部分,$\\alpha$ 比较大 \\Rightarrow$ 每一步走的比较多 \\Rightarrow$ 优点:容易走出极小值点 缺点:易出现震荡,可能无法收敛至最小值点。 设置过小,如图3中的蓝线部分,$\\alpha$ 比较小 \\Rightarrow$ 每一步走的比较小 \\Rightarrow$ 优点:比较细粒度 缺点:比较难走出极小值点。 总结来说,学习率$\\alpha$一般起初可设置的比较大,随着训练,逐步减小。 从链式法则看 batch normalization 以图4为例,该网络由3个子系统$h_1, h_2, h_3$组成, 假设$h_1, h_2, h_3$均为无激活函数全连接系统。 其框架为:x $\\rightarrow$ $h_1$ $\\rightarrow$ $h_2$ $\\rightarrow$ $h_3$ $\\rightarrow$ $\\hat{y}$. 由图4可以写出以下公式: $$y_1=w_1 \\cdot x+b$$ $$y_2=w_2 \\cdot y_1+b$$ $$y_3=w_3 \\cdot y_2+b$$ $$\\hat{y} = y_3$$ 采用$L_2$损失函数为: $$L = \\frac{1}{2}(\\hat{y}-y)^2$$ 每层的$w$参数的偏导是:\\begin{align}\\frac{\\partial L}{\\partial w_1} &= \\frac{\\partial L}{ \\partial \\hat{y}} \\cdot \\frac{\\partial \\hat{y}}{ \\partial y_3} \\cdot \\frac{\\partial y_3}{ \\partial y_2}\\cdot \\frac{\\partial y_2}{ \\partial y_1}\\cdot \\frac{\\partial y_1}{ \\partial w_1} \\\\&= (\\hat{y}-y) \\cdot 1 \\cdot w_3 \\cdot w_2 \\cdot x\\end{align} \\begin{align}\\frac{\\partial L}{ \\partial w_2} &= \\frac{\\partial L}{ \\partial \\hat{y}} \\cdot \\frac{\\partial \\hat{y}}{ \\partial y_3} \\cdot \\frac{\\partial y_3}{ \\partial y_2}\\cdot \\frac{\\partial y_2}{ \\partial w_2} \\\\&= (\\hat{y}-y) \\cdot 1 \\cdot w_3 \\cdot y_1\\end{align} \\begin{align}\\frac{\\partial L}{ \\partial w_2} &= \\frac{\\partial L}{ \\partial \\hat{y}} \\cdot \\frac{\\partial \\hat{y}}{ \\partial y_3} \\cdot \\frac{\\partial y_3}{ \\partial y_3}\\\\&= (\\hat{y}-y) \\cdot 1 \\cdot y_2\\end{align} 如果对于有n个子系统的神经网络(多层) 从1计数,每层的参数的偏导为: $$\\frac{\\partial L}{ \\partial w_i} = \\prod_{k=n}^{i+1} w_k \\cdot y_{i-1} $$ 从该表达式可以发现参数的偏导与$\\prod_{k=n}^{i+1} w_k$ 以及前一层的输出$y_{i-1}$有关。 梯度弥散: 梯度过小: 假设每个子系统为一个缩放器,即w<1。 那么,当网络比较深的时候,对于比较深的层来说,其$\\prod_{k=n}^{i+1} w_k$不会太小,但是$y_{i-1}$会由于输入经过多个缩放器,变得非常小,最终梯度也变得非常小。对于浅层网络,$y_{i-1}$缩放的程度不是很大,但是$\\prod_{k=n}^{i+1} w_k$非常小,最终梯度也变得非常小。 梯度过大: 假设每个子系统为一个放大器,即w>1。 那么,当网络比较深的时候,对于比较深的层来说,其$\\prod_{k=n}^{i+1} w_k$不会太大,但是$y_{i-1}$会由于输入经过多个放大器,变得非常大,最终梯度也变得非常大。对于浅层网络,$\\prod_{k=n}^{i+1} w_k$放大的程度不是很大,但是$\\prod_{k=n}^{i+1} w_k$非常大,最终梯度也变得非常大。 如何解决梯度弥散: 从上面可以知道梯度的影响是$\\prod_{k=n}^{i+1} w_k$和$\\prod_{k=n}^{i+1} w_k$。 所以解决方式从两方面考虑: w的初始化: 取值尽可能的适中 对每层的输出做归一化处理(batch normalization),去掉直流信号,仍然保留信息。另外, 归一化处理(batch normalization) 对深层求梯度是有帮助的,但对于浅层求梯度求梯度起到的作用比较小。","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"tensorflow_tutorial_9","slug":"tensorflow-tutorial-9","date":"2019-02-02T17:02:40.000Z","updated":"2019-02-17T07:18:54.707Z","comments":true,"path":"2019/02/03/tensorflow-tutorial-9/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/03/tensorflow-tutorial-9/","excerpt":"","text":"batch Normalization定义将均值为$\\mu$, 标准差$\\sigma$的数据集合$x$,转化为均值为$\\beta$, 标准差$\\gamma$的数据集合$x^{’}$: $$x^{’}=\\gamma\\frac{(x-\\mu)}{\\sigma}+\\beta$$ 作用解决梯度弥散的问题 padding的方式 实现步骤 计算数据集合$x$的均值为$\\mu$, 标准差$\\sigma$ 套用变化公式 问题: 为什么采用滑动平均的方式来求解均值和方差? 先说结论:并不是测试时的mean,var的计算方式与训练时不同,而是测试时的mean,var在训练完成整个网络中就全部固定了。由于在优化网络的时候,我们一般采用的是batch梯度下降。所以在训练过程中,只能计算当前batch样本上的mean和var。但是我们做的normalization是对于整个输入样本空间,因此需要对每个batch的mean, var做指数加权平均来将batch上的mean和var近似成整个样本空间上的mean和var.而在测试Inference过程中,一般不必要也不合适去计算测试时的batch的mean和var,比如测试仅对单样本输入进行测试时,这时去计算单样本输入的mean和var是完全没有意义的。因此会直接拿训练过程中对整个样本空间估算的mean和var直接来用。此时对于inference来说,BN就是一个线性变换。 起始值为什么是 0 1? 说白了就是,怎么去估计数据的真实分布? https://www.cnblogs.com/34fj/p/8805979.html Tensorflow 实现Note: when training, the moving_mean and moving_variance need to be updated. By default the update ops are placed in tf.GraphKeys.UPDATE_OPS, so they need to be added as a dependency to the train_op. Also, be sure to add any batch_normalization ops before getting the update_ops collection. Otherwise, update_ops will be empty, and training/inference will not work properly. For example: 12345678x_norm = tf.layers.batch_normalization(x, training=training)# ...update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)with tf.control_dependencies(update_ops): train_op = optimizer.minimize(loss) Preliminary计算均值和方差1234567tf.nn.moments( x, axes, shift=None, name=None, keep_dims=False) Args: x: 张量 axes: 列表。求均值和方差的方向 name: 操作的名字 keep_dims: true,均值和方差的shape与输入一致 Returns: mean,variance When using these moments for batch normalization (see tf.nn.batch_normalization): for so-called “global normalization”, used with convolutional filters with shape [batch, height, width, depth], pass axes=[0, 1, 2].即,对同一个channel的数据进行计算均值和方差。 for simple batch normalization pass axes=[0] (batch only). 12345678910tf.nn.batch_normalization( x, mean, variance, offset, scale, variance_epsilon, name=None) Args: x : 张量 mean: 均值 variance: 方差 offset: \\beta, default None scale: \\gamma, default None variance_epsilon: A small float number to avoid dividing by 0 name: 操作的名字 性质: 如果不提供scale,offset,则新的张量的均值和方差分别为0,1。 mean, variance, offset and scale are all expected to be of one of two shapes: In all generality, they can have the same number of dimensions as the input x, with identical sizes as x for the dimensions that are not normalized over (the ‘depth’ dimension(s)), and dimension 1 for the others which are being normalized over. mean and variance in this case would typically be the outputs of tf.nn.moments(…, keep_dims=True) during training, or running averages thereof during inference. In the common case where the ‘depth’ dimension is the last dimension in the input tensor x, they may be one dimensional tensors of the same size as the ‘depth’ dimension. This is the case for example for the common [batch, depth] layout of fully-connected layers, and [batch, height, width, depth] for convolutions. mean and variance in this case would typically be the outputs of tf.nn.moments(…, keep_dims=False) during training, or running averages thereof during inference.Args: 12345678tf.assign( ref, value, validate_shape=None, use_locking=None, name=None) Args: ref: A mutable Tensor. Should be from a Variable node. May be uninitialized. value: A Tensor. Must have the same type as ref. The value to be assigned to the variable. validate_shape: An optional bool. Defaults to True. If true, the operation will validate that the shape of ‘value’ matches the shape of the Tensor being assigned to. If false, ‘ref’ will take on the shape of ‘value’.use_locking: An optional bool. Defaults to True. If True, the assignment will be protected by a lock; otherwise the behavior is undefined, but may exhibit less contention. name: A name for the operation (optional).Returns: A Tensor that will hold the new value of ‘ref’ after the assignment has completed. 12345678910tf.cond( pred, true_fn=None, false_fn=None, strict=False, name=None, fn1=None, fn2=None) Args: pred: A scalar determining whether to return the result of true_fn or false_fn. true_fn: The callable to be performed if pred is true. false_fn: The callable to be performed if pred is false. strict: A boolean that enables/disables ‘strict’ mode; see above. name: Optional name prefix for the returned tensors.Returns: Tensors returned by the call to either true_fn or false_fn. If the callables return a singleton list, the element is extracted from the list. BN在神经网络进行training和testingExample123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283\"\"\"大多数情况下,您将能够使用高级功能,但有时您可能想要在较低的级别工作。例如,如果您想要实现一个新特性—一些新的内容,那么TensorFlow还没有包括它的高级实现,比如LSTM中的批处理规范化——那么您可能需要知道一些事情。这个版本的网络的几乎所有函数都使用tf.nn包进行编写,并且使用tf.nn.batch_normalization函数进行标准化操作'fully_connected'函数的实现比使用tf.layers包进行编写的要复杂得多。然而,如果你浏览了Batch_Normalization_Lesson笔记本,事情看起来应该很熟悉。为了增加批量标准化,我们做了如下工作:Added the is_training parameter to the function signature so we can pass that information to the batch normalization layer.1.在函数声明中添加'is_training'参数,以确保可以向Batch Normalization层中传递信息2.去除函数中bias偏置属性和激活函数3.添加gamma, beta, pop_mean, and pop_variance等变量4.使用tf.cond函数来解决训练和预测时的使用方法的差异5.训练时,我们使用tf.nn.moments函数来计算批数据的均值和方差,然后在迭代过程中更新均值和方差的分布,并且使用tf.nn.batch_normalization做标准化 注意:一定要使用with tf.control_dependencies...语句结构块来强迫Tensorflow先更新均值和方差的分布,再使用执行批标准化操作6.在前向传播推导时(特指只进行预测,而不对训练参数进行更新时),我们使用tf.nn.batch_normalization批标准化时其中的均值和方差分布来自于训练时我们 使用滑动平均算法估计的值。7.将标准化后的值通过RelU激活函数求得输出8.不懂请参见https://github.com/udacity/deep-learning/blob/master/batch-norm/Batch_Normalization_Lesson.ipynb 中关于使用tf.nn.batch_normalization实现'fully_connected'函数的操作\"\"\"import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_datamnist = input_data.read_data_sets(\"MNIST_data/\", one_hot=True, reshape=False)def fully_connected(prev_layer, num_units, is_training): \"\"\" num_units参数传递该层神经元的数量,根据prev_layer参数传入值作为该层输入创建全连接神经网络。 :param prev_layer: Tensor 该层神经元输入 :param num_units: int 该层神经元结点个数 :param is_training: bool or Tensor 表示该网络当前是否正在训练,告知Batch Normalization层是否应该更新或者使用均值或方差的分布信息 :returns Tensor 一个新的全连接神经网络层 \"\"\" layer = tf.layers.dense(prev_layer, num_units, use_bias=False, activation=None) gamma = tf.Variable(tf.ones([num_units])) beta = tf.Variable(tf.zeros([num_units])) pop_mean = tf.Variable(tf.zeros([num_units]), trainable=False) pop_variance = tf.Variable(tf.ones([num_units]), trainable=False) epsilon = 1e-3 def batch_norm_training(): batch_mean, batch_variance = tf.nn.moments(layer, [0]) decay = 0.99 # 为什么其实是0均值, 1方差# train_mean = tf.assign(pop_mean, pop_mean*decay + batch_mean*(1 - decay)) train_variance = tf.assign(pop_variance, pop_variance*decay + batch_variance*(1 - decay)) with tf.control_dependencies([train_mean, train_variance]): return tf.nn.batch_normalization(layer, batch_mean, batch_variance, beta, gamma, epsilon) def batch_norm_inference(): return tf.nn.batch_normalization(layer, pop_mean, pop_variance, beta, gamma, epsilon) batch_normalized_output = tf.cond(is_training, batch_norm_training, batch_norm_inference) return tf.nn.relu(batch_normalized_output)\"\"\"我们对conv_layer卷积层的改变和我们对fully_connected全连接层的改变几乎差不多。然而也有很大的区别,卷积层有多个特征图并且每个特征图在输入图层上共享权重所以我们需要确保应该针对每个特征图而不是卷积层上的每个节点进行Batch Normalization操作为了实现这一点,我们做了与fully_connected相同的事情,有两个例外:1.将gamma、beta、pop_mean和pop_方差的大小设置为feature map(输出通道)的数量,而不是输出节点的数量。2.我们改变传递给tf.nn的参数。时刻确保它计算正确维度的均值和方差。\"\"\"def conv_layer(prev_layer, layer_depth, is_training): \"\"\" 使用给定的参数作为输入创建卷积层 :param prev_layer: Tensor 传入该层神经元作为输入 :param layer_depth: int 我们将根据网络中图层的深度设置特征图的步长和数量。 这不是实践CNN的好方法,但它可以帮助我们用很少的代码创建这个示例。 :param is_training: bool or Tensor 表示该网络当前是否正在训练,告知Batch Normalization层是否应该更新或者使用均值或方差的分布信息 :returns Tensor 一个新的卷积层 \"\"\" strides = 2 if layer_depth%3 == 0 else 1 in_channels = prev_layer.get_shape().as_list()[3] out_channels = layer_depth*4 weights = tf.Variable( tf.truncated_normal([3, 3, in_channels, out_channels], stddev=0.05)) layer = tf.nn.conv2d(prev_layer, weights, strides=[1, strides, strides, 1], padding='SAME') gamma = tf.Variable(tf.ones([out_channels])) beta = tf.Variable(tf.zeros([out_channels])) pop_mean = tf.Variable(tf.zeros([out_channels]), trainable=False) pop_variance = tf.Variable(tf.ones([out_channels]), trainable=False) epsilon = 1e-3 def batch_norm_training(): # 一定要使用正确的维度确保计算的是每个特征图上的平均值和方差而不是整个网络节点上的统计分布值 batch_mean, batch_variance = tf.nn.moments(layer, [0, 1, 2], keep_dims=False) decay = 0.99 train_mean = tf.assign(pop_mean, pop_mean*decay + batch_mean*(1 - decay)) train_variance = tf.assign(pop_variance, pop_variance*decay + batch_variance*(1 - decay)) with tf.control_dependencies([train_mean, train_variance]): return tf.nn.batch_normalization(layer, batch_mean, batch_variance, beta, gamma, epsilon) def batch_norm_inference(): return tf.nn.batch_normalization(layer, pop_mean, pop_variance, beta, gamma, epsilon) batch_normalized_output = tf.cond(is_training, batch_norm_training, batch_norm_inference) return tf.nn.relu(batch_normalized_output)\"\"\"为了修改训练函数,我们需要做以下工作:1.Added is_training, a placeholder to store a boolean value indicating whether or not the network is training.添加is_training,一个用于存储布尔值的占位符,该值指示网络是否正在训练2.Each time we call run on the session, we added to feed_dict the appropriate value for is_training.每次调用sess.run函数时,我们都添加到feed_dict中is_training的适当值用以表示当前是正在训练还是预测3.We did not need to add the with tf.control_dependencies... statement that we added in the network that used tf.layers.batch_normalizationbecause we handled updating the population statistics ourselves in conv_layer and fully_connected.我们不需要将train_opt训练函数放进with tf.control_dependencies... 的函数结构体中,这是只有在使用tf.layers.batch_normalization才做的更新均值和方差的操作\"\"\"def train(num_batches, batch_size, learning_rate): # Build placeholders for the input samples and labels # 创建输入样本和标签的占位符 inputs = tf.placeholder(tf.float32, [None, 28, 28, 1]) labels = tf.placeholder(tf.float32, [None, 10]) # Add placeholder to indicate whether or not we're training the model # 创建占位符表明当前是否正在训练模型 is_training = tf.placeholder(tf.bool) # Feed the inputs into a series of 20 convolutional layers # 把输入数据填充到一系列20个卷积层的神经网络中 layer = inputs for layer_i in range(1, 20): layer = conv_layer(layer, layer_i, is_training) # Flatten the output from the convolutional layers # 将卷积层输出扁平化处理 orig_shape = layer.get_shape().as_list() layer = tf.reshape(layer, shape=[-1, orig_shape[1]*orig_shape[2]*orig_shape[3]]) # Add one fully connected layer # 添加一个具有100个神经元的全连接层 layer = fully_connected(layer, 100, is_training) # Create the output layer with 1 node for each # 为每一个类别添加一个输出节点 logits = tf.layers.dense(layer, 10) # Define loss and training operations # 定义loss 函数和训练操作 model_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=labels)) train_opt = tf.train.AdamOptimizer(learning_rate).minimize(model_loss) # Create operations to test accuracy # 创建计算准确度的操作 correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # Train and test the network # 训练并测试网络模型 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for batch_i in range(num_batches): batch_xs, batch_ys = mnist.train.next_batch(batch_size) # train this batch # 训练样本批次 sess.run(train_opt, {inputs: batch_xs, labels: batch_ys, is_training: True}) # Periodically check the validation or training loss and accuracy # 定期检查训练或验证集上的loss和精确度 if batch_i%100 == 0: loss, acc = sess.run([model_loss, accuracy], {inputs: mnist.validation.images, labels: mnist.validation.labels, is_training: False}) print( 'Batch: {:>2}: Validation loss: {:>3.5f}, Validation accuracy: {:>3.5f}'.format(batch_i, loss, acc)) elif batch_i%25 == 0: loss, acc = sess.run([model_loss, accuracy], {inputs: batch_xs, labels: batch_ys, is_training: False}) print('Batch: {:>2}: Training loss: {:>3.5f}, Training accuracy: {:>3.5f}'.format(batch_i, loss, acc)) # At the end, score the final accuracy for both the validation and test sets # 最后在验证集和测试集上对模型准确率进行评分 acc = sess.run(accuracy, {inputs: mnist.validation.images, labels: mnist.validation.labels, is_training: False}) print('Final validation accuracy: {:>3.5f}'.format(acc)) acc = sess.run(accuracy, {inputs: mnist.test.images, labels: mnist.test.labels, is_training: False}) print('Final test accuracy: {:>3.5f}'.format(acc)) # Score the first 100 test images individually, just to make sure batch normalization really worked # 对100个独立的测试图片进行评分,对比验证Batch Normalization的效果 correct = 0 for i in range(100): correct += sess.run(accuracy, feed_dict={inputs: [mnist.test.images[i]], labels: [mnist.test.labels[i]], is_training: False}) print(\"Accuracy on 100 samples:\", correct/100)num_batches = 800 # 迭代次数batch_size = 64 # 批处理数量learning_rate = 0.002 # 学习率tf.reset_default_graph()with tf.Graph().as_default(): train(num_batches, batch_size, learning_rate)\"\"\"再一次,批量标准化的模型很快达到了很高的精度。但是在我们的运行中,注意到它似乎并没有学习到前250个批次的任何东西,然后精度开始上升。这只是显示——即使是批处理标准化,给您的网络一些时间来学习是很重要的。PS:再100个单个数据的预测上达到了较高的精度,而这才是BN算法真正关注的!!\"\"\"# Extracting MNIST_data/train-images-idx3-ubyte.gz# Extracting MNIST_data/train-labels-idx1-ubyte.gz# Extracting MNIST_data/t10k-images-idx3-ubyte.gz# Extracting MNIST_data/t10k-labels-idx1-ubyte.gz# 2018-03-18 19:35:28.568404: I D:\\Build\\tensorflow\\tensorflow-r1.4\\tensorflow\\core\\platform\\cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX# Batch: 0: Validation loss: 0.69113, Validation accuracy: 0.10020# Batch: 25: Training loss: 0.57341, Training accuracy: 0.07812# Batch: 50: Training loss: 0.45526, Training accuracy: 0.04688# Batch: 75: Training loss: 0.37936, Training accuracy: 0.12500# Batch: 100: Validation loss: 0.34601, Validation accuracy: 0.10700# Batch: 125: Training loss: 0.34113, Training accuracy: 0.12500# Batch: 150: Training loss: 0.33075, Training accuracy: 0.12500# Batch: 175: Training loss: 0.34333, Training accuracy: 0.15625# Batch: 200: Validation loss: 0.37085, Validation accuracy: 0.09860# Batch: 225: Training loss: 0.40175, Training accuracy: 0.09375# Batch: 250: Training loss: 0.48562, Training accuracy: 0.06250# Batch: 275: Training loss: 0.67897, Training accuracy: 0.09375# Batch: 300: Validation loss: 0.48383, Validation accuracy: 0.09880# Batch: 325: Training loss: 0.43822, Training accuracy: 0.14062# Batch: 350: Training loss: 0.43227, Training accuracy: 0.18750# Batch: 375: Training loss: 0.39464, Training accuracy: 0.37500# Batch: 400: Validation loss: 0.50557, Validation accuracy: 0.25940# Batch: 425: Training loss: 0.32337, Training accuracy: 0.59375# Batch: 450: Training loss: 0.14016, Training accuracy: 0.75000# Batch: 475: Training loss: 0.11652, Training accuracy: 0.78125# Batch: 500: Validation loss: 0.06241, Validation accuracy: 0.91280# Batch: 525: Training loss: 0.01880, Training accuracy: 0.96875# Batch: 550: Training loss: 0.03640, Training accuracy: 0.93750# Batch: 575: Training loss: 0.07202, Training accuracy: 0.90625# Batch: 600: Validation loss: 0.03984, Validation accuracy: 0.93960# Batch: 625: Training loss: 0.00692, Training accuracy: 0.98438# Batch: 650: Training loss: 0.01251, Training accuracy: 0.96875# Batch: 675: Training loss: 0.01823, Training accuracy: 0.96875# Batch: 700: Validation loss: 0.03951, Validation accuracy: 0.94080# Batch: 725: Training loss: 0.02886, Training accuracy: 0.95312# Batch: 750: Training loss: 0.06396, Training accuracy: 0.87500# Batch: 775: Training loss: 0.02013, Training accuracy: 0.98438# Final validation accuracy: 0.95820# Final test accuracy: 0.95780# Accuracy on 100 samples: 0.98 Referencehttps://github.com/SunshineJunFu/deep-learning/blob/master/batch-norm/Batch_Normalization_Solutions.ipynb https://www.cnblogs.com/zhengmingli/p/8031690.html https://www.tensorflow.org/api_docs/python/tf/nn/batch_normalization?hl=zh-cn https://www.jianshu.com/p/615113382fac http://lamda.nju.edu.cn/weixs/project/CNNTricks/CNNTricks.html https://www.zhihu.com/question/38102762 http://www.cnblogs.com/cloud-ken/p/9314769.html https://www.cnblogs.com/wuliytTaotao/p/9479958.html https://www.zhihu.com/question/66873757/answer/405455697","categories":[],"tags":[]},{"title":"tensorflow_tutorial_8","slug":"tensorflow-tutorial-8","date":"2019-02-02T17:00:57.000Z","updated":"2019-02-17T07:18:54.706Z","comments":true,"path":"2019/02/03/tensorflow-tutorial-8/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/03/tensorflow-tutorial-8/","excerpt":"","text":"如何使用高低阶的API搭建网络全连接结构:flatten$\\rightarrow$ xw+b$\\rightarrow$ norm layer(optional)$\\rightarrow$activation function $\\rightarrow$dropout(optional) 12345678910111213141516def add_fc_layer(inputs, in_dim, out_dim, scope_name, activation_function=None): with tf.variable_scope(scope_name): w = tf.get_variable(shape=[in_dim, out_dim], initializer=tf.contrib.layers.xavier_initializer(), name='weights') b = tf.get_variable(shape=[1, out_dim], initializer=tf.contrib.layers.xavier_initializer(), name='biases') wx_plus_b = tf.matmul(inputs, w) + b # broadcast if activation_function: wx_plus_b = activation_function(wx_plus_b) return wx_plus_b 卷积结构: convolution $\\rightarrow$ norm layer(optional) $\\rightarrow$activation function $\\rightarrow$pooling(optional) 1234567891011121314151617181920def add_conv2d_layer(inputs, in_channel, out_channel, scope_name, activation_function, filter_h, filter_w,stride): with tf.variable_scope(scope_name): fliter_mask = tf.get_variable(shape=[filter_h, filter_w, in_channel, out_channel], dtype=inputs.dtype, initializer=tf.contrib.layers.xavier_initializer(),name='filter') # 'same' 输入输出的宽高一致, 'valid', out_width = xxxx # conv_inputs = tf.nn.conv2d(inputs, fliter_mask, [1,stride,stride,1], 'SAME') # batch normalization # if activation_function: conv_inputs = activation_function(conv_inputs) # pooling # conv_inputs = tf.nn.max_pool(conv_inputs,[1,2,2,1],[1,2,2,1],'SAME') return conv_inputs 反卷积结构: inverse-convolution $\\rightarrow$ norm layer(optional) $\\rightarrow$activation function","categories":[],"tags":[]},{"title":"tensorflow_tutorial_7","slug":"tensorflow-tutorial-7","date":"2019-02-02T16:59:00.000Z","updated":"2019-02-23T02:07:05.738Z","comments":true,"path":"2019/02/03/tensorflow-tutorial-7/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/03/tensorflow-tutorial-7/","excerpt":"","text":"分类任务里的衡量指标二分类混淆矩阵 predicted 1 predicted 0 label 1 TP FN label 0 FP TN TP:label为正例,预测为正例 FP:label为负例,预测为正例 TN:label为正例,预测为正例 FN:label为正例,预测为负例 精度(Accuracy):\\begin{align}Accuracy &=\\frac{预测正确样本个数}{总样本数} \\\\&=\\frac{TP+TN}{TP+FP+TN+FN}\\end{align} 查全率(Recall): 预测正确的正例个数与总的正例的比值。 $$Recall=\\frac{TP}{TP+FN}$$ 查准率(Precision):预测正确的正例个数与预测为正例个数的比值。 $$Precision=\\frac{TP}{TP+FP}$$ 性质: Recall 和 Precision 是一对矛盾的指标 证明: 假定Recall $\\uparrow$, 由于$TP+FP=数据集内的正样本数=常数$ $\\Rightarrow$ TP$\\uparrow$, 由于TP$\\uparrow$,为了提高TP,会同时增加FP且FP+TP的增量大于TP的增量(直觉上,为了提高TP,分类器会偏向于将分类为正类,这样也增加了FP),所以Precision$\\downarrow$。 假定Recall $\\downarrow$, 由于$TP+FP=数据集内的正样本数=常数$ $\\Rightarrow$ TP$\\downarrow$, 由于TP$\\downarrow$,为了减小TP,会同时减小FP且FP+TP的减小量大于TP的减小量(直觉上,为了减小TP,分类器会偏向于将分类为负类,这样也减小了FP),所以Precision$\\uparrow$。 所以: Recall $\\uparrow$ $\\Rightarrow$ TP$\\uparrow$,FP+TP$\\uparrow$ $\\Rightarrow$ Precision $\\downarrow$ Recall $\\downarrow$ $\\Rightarrow$ TP$\\downarrow$,FP+TP$\\downarrow$ $\\Rightarrow$ Precision $\\uparrow$ 有的模型是将预测结果与一个阈值进行比较,如果大于该阈值则预测为正例,否则为反例。所以这个阈值非常重要,直接决定了模型的泛化能力。同时根据这个阈值我们可以将样本进行排序,“最可能”是正例的排在最前面,“最不可能”是正例的排在最后面。因此,如果我们想让precision更高,可以将阈值设置在排序靠前的位置,相反如果想让recall更高,可以将阈值设置在排序靠后的位置。 F1 Measure/Score 为了更准确反映模型的性能,引入了F1 score, 该指标同时考虑了Recall和Precision, 能让我们表达出对查准率/查全率的不同偏好。 $$F_{\\alpha}=(1+\\alpha^{2})\\frac{Precision*Recall}{\\alpha^{2}*Precision+Recall}$$ 当\\alpha > 1 时查全率有更大影响,当\\alpha < 1 时查准率有更大影响。 当$\\alpha=1$, 即为F1-score,Recall和Precision的调和平均数。$$F_{1}=(2)\\frac{Precision*Recall}{Precision+Recall}$$ 多label二分类Macro-f1-score(宏观角度)先在每个confusion matrix上计算precision和recall,最后计算平均值。 $$ Precision_{macro} = \\frac{1}{N}\\sum_{i}Precision_{i} $$$$ Recall_{macro} = \\frac{1}{N}\\sum_{i}Recall_{i} $$$$ F1_{macro}=(2)\\frac{Precision_{macro}*Recall_{macro}}{Precision_{macro}+Recall_{macro}}$$ Micro-f1-score(微观角度)先将每个confusion matrix中各个对应位置上的元素平均,得到TP、FP、TN、FN的平均值,然后计算precision、recall和F1$$Recall_{micro}=\\frac{\\overline{TP}}{\\overline{TP}+\\overline{FN}}$$$$Precision_{micro}=\\frac{\\overline{TP}}{\\overline{TP}+\\overline{FP}}$$$$F1_{micro}=(2)\\frac{Precision_{micro}*Recall_{micro}}{Precision_{micro}+Recall_{micro}}$$ ROC和AUC(Area under curve)每次预测一个样本后计算当下的两个值,最后用这两个值作为坐标画曲线。这两个值分别是真正例率(True Positive Rate)和假正例率(False Positive Rate),定义如下:$$ TPR = \\frac{TP}{TP+FN}$$$$ FPR = \\frac{FP}{TN+FP}$$ AUC越大越好,考虑了所有阈值。 ROC曲线的横坐标为false positive rate(FPR)即负类样本中被判定为正类的比例,也就是传说中的误纳率 纵坐标为true positive rate(TPR)即正类样本中被判定为正类的样本,1-TPR也就是传说中的误拒率 接下来我们考虑ROC曲线图中的四个点和一条线。 第一个点,(0,1),即左上角的点,在这个点意味着FPR=0,TPR=1,稍微翻译一下就是误纳率为0,误拒率为0,再翻译成人话就是负类样本中被判断为正类的比例为0,说明负类样本都被判断为负类,判断正确,正类样本中被判断为正类的比例为1,说明正类样本都被判断正确,所以这是一个完美的分类器,它将所有的样本都正确分类。 第二个点,(1,0),即右下角的点,在这个点意味着FPR=1,TPR=0,类似地分析可以发现这是一个最糟糕的分类器,因为它成功避开了所有的正确分类。把该判断为正类的判断为负类,把该判断为负类的判断为正类 第三个点,(0,0),即左下角的点,在这个点意味着FPR=TPR=0,可以发现该分类器预测所有的样本都为负样本(negative),在后面我们可以看到这种情况说明阈值选得过高。 第四个点(1,1),即右下角的点,分类器实际上预测所有的样本都为正样本,在后面我们可以看到这种情况说明阈值选得过低。 对角线: 如果是随机分类,则有$Tp=Fp$,$Tn=Fn$,$\\Rightarrow$ $FPR=TPR$ 好的分类器:$Tp>Fp$,$Tn>Fn$,,$\\Rightarrow$ $TPR=\\frac{TP\\uparrow}{TP\\uparrow+FN\\downarrow}>TPR=\\frac{FP\\downarrow}{FP\\downarrow+TN\\uparrow}$,位于对角线右侧 差的分类器:$Tp<Fp$,$Tn<Fn$,,$\\Rightarrow$ $TPR=\\frac{TP\\downarrow}{TP\\downarrow+FN\\uparrow}>TPR=\\frac{FP\\uparrow}{FP\\uparrow+TN\\downarrow}$,位于对角线右侧 AUC = 0说明样本中没有正例 如何画ROC曲线由于每次从分类模型中只能得到一个用于判定分类结果的分数,要将这个分数与一个阈值进行比较,判定这个样本属于哪个类,所以我们可以更改阈值,得到不同的分类结果,也就是不同的TPR和FPR 之前说到当我们将threshold设置为1和0时,分别可以得到ROC曲线上的(0,0)和(1,1)两个点 将这些(FPR,TPR)对连接起来,就得到了ROC曲线。当threshold取值越多,ROC曲线越平滑。 既然有了ACC为什么要有ROC呢(既生瑜何生亮呢) 我们知道,我们常用ACC准确率来判断分类器分类结果的好坏,既然有了ACC为什么还需要ROC呢,很重要的一个因素是实际的样本数据集中经常会出现数据偏斜的情况,要么负类样本数大于正类样本数,要么正类样本数大于负类样本数。 比如说我负类样本数有9,000个,正类样本数有100个,如果阈值选得过高,正类样本都判断为负类,同样负类样本都判定为负类,那么准确率90%,看起来还不错,但是如果考虑ROC中的TPR和FPR的话就会知道,此时的TPR=0,FPR=0,也就是误纳率是0,但是误拒率是100%,是左下角的点,并不是很好的一个点,而原来的ACC就不具有代表性 既然有了ROC为什么要有AUC呢(既生瑜何生亮呢) 使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而相对于AUC是个数值而言,对应AUC更大的分类器效果更好,数值更好判断一些。 Referenceshttps://zhuanlan.zhihu.com/p/39957290 http://www.cnblogs.com/zle1992/p/6689136.html https://www.zhihu.com/question/39840928 http://www.cnblogs.com/keedor/p/4463988.html https://www.cnblogs.com/keedor/category/669162.html","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"tensorflow_tutorial_6","slug":"tensorflow-tutorial-6","date":"2019-02-02T14:43:55.000Z","updated":"2019-02-17T07:18:54.702Z","comments":true,"path":"2019/02/02/tensorflow-tutorial-6/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/02/02/tensorflow-tutorial-6/","excerpt":"","text":"机器学习中的Loss回归任务MAE,L1 Loss$ L_{MAE} = \\frac{1}{N}\\sum_i^{N-1}|pred_i - label_i|$ MSE,L2 Loss$ L_{MSE} = \\frac{1}{N}\\sum_i^{N-1}(pred_i - label_i)^{2}$ 分类任务CrossEntropy Loss$$ loss(x,class)= -log(\\frac{exp(x[class])}{\\sum_{j}exp(x[j])}) = -x[class]+log(\\sum_{j}exp(x[j])) $$ 推导CrossEntropy Lossone-hot定义:用N个二进制位来表示N个状态,对于任意一状态,其N个二进制位,只有1位非零。例如, 0,1,2 分别会表示为001,010,100。 为什么用one-hot? Iris 数据集 以Iris数据集为例,数据集中共有3种花:Versicolor,Setosa,Virginica。如果直接按顺序给这3种花编号,并将编号作为每种花的label,会存在以下问题: 欧式距离问题:如果将Versicolor,Setosa,Virginica的label采用编号的方式则是:1,2,3。则$L_{Ver,Setosa}=1$,$L_{Ver,Vir}=2$,$L_{vir,Setosa}=1$,可以发现这三者两两的距离不一致。如果将label编号为001,010,100,则两两之间的距离为$L_{Ver,Setosa}=2$。因而,这样做显得更加合理。 交叉熵(CrossEntropy)自信息量(Self-information) 定义: 变量x发生概率的对数取反,表明该变量x携带的信息量的多少。 $$ I(x) = - log(p(x))$$ 其中,$ p(x) = Pr(X=x) $ 代表了在信息空间X中x出现的的概率。 熵 定义: 表明X的不确定程度,熵越大,不确定程度越大,越多的信息量。 $$H(X) = E[I(X)]$$ 对于离散的X信息空间: $$H(X) = \\sum_{i} (-p(x_i)logp(x_i)) $$ 对于连续的X信息空间: \\begin{align}H(x) &= \\int_{-\\infty}^{+\\infty} (p(x)I(x)dx) \\\\ &= \\int_{-\\infty}^{+\\infty}(-p(x)logp(x)dx)\\end{align} KL 散度 又叫相对熵: 定义:D(P||Q)表示当用概率分布Q来拟合真实分布P时,产生的信息损耗,其中P表示真实分布,Q表示P的拟合分布。散度越小,意味着Q越接近于P。 Noted that:有人将KL散度称为KL距离,但事实上,KL散度并不满足距离的概念 KL散度不是对称的 KL散度不满足三角不等式。 $$ D(p||q) = E_{~p}[log{p(x)/q(x)}]$$ 对于离散的X信息空间: $$D(P||Q)=\\sum_{i} p(i)logp(i)/q(i)$$ 对于连续的X信息空间: $$D(P||Q)=\\int_{-\\infty}^{+\\infty} p(x)logp(x)/q(x)dx$$ 交叉熵: 定义:$ CEH(p,q) = Ep[-logq]$ 性质: 交叉熵 = 熵 + KL散度 证明: \\begin{align}CEH(p,q) &= E_{~p}[-logq] \\\\&= E_{~p}[-logq/p * p] \\\\&= E_{~p}[-logp-logq/p] \\\\&= E_{~p}[-logp] + E_{~p}[-logq/p] \\\\&= E_{~p}[-logp] + E_{~p}[logp/q] \\\\&= H(p) + D(p||q)\\end{align} 由此可以发现,当p为真实分布时,其熵$H(p)$是固定不变的。因此,最小化交叉熵,可以被认为是最小化KL散度。 交叉熵的损失公式推导\\begin{align}L_{CEH(p,q)} &= Dkl(p||q) \\\\&= \\sum_{i}p(i)log(\\frac{p(i)}{q(i)})\\end{align} 对于二分类问题: \\begin{align}L_{CEH(p,q)} &= Dkl(p||q) \\\\&= -p(0)logq(0) - p(1)log(q(1)) \\\\&= -p(0)logq(0) - [1-p(0)]log[1-q(0)]\\end{align} 对于n分类: 神经网络的输出层是n维的向量,x[i]为类别i的取值,那么类别为i的概率为: $$q(i)= \\frac{exp(x[i])}{\\sum_{j}exp(x[j])} $$ 这一过程叫做归一化,学名Softmax。 根据前面所述的one-hot可知,对于单个样本,真实分布p是只在类别正确处有值且为1,所以 \\begin{align}L_{CEH(p,q)} &= Dkl(p||q) \\\\&= \\sum_{i}p(i)log(\\frac{p(i)}{q(i)}) \\\\&= 0 + 1 * log(\\frac{1}{q(i)}) \\\\&= - log(q(i)) \\\\&= - log(\\frac{exp(x[class])}{\\sum_{j}exp(x[j]))} \\\\&= - x[class]+log(\\sum_{j}exp(x[j]))\\end{align} 推广至多label","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"tensorflow_tutorial_5","slug":"tensorflow-tutorial-5","date":"2019-01-31T08:25:52.000Z","updated":"2019-02-17T07:18:54.702Z","comments":true,"path":"2019/01/31/tensorflow-tutorial-5/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/01/31/tensorflow-tutorial-5/","excerpt":"","text":"Summaryclass tf.Summary.FileWriterinit创建一个writer 123456789__init__( logdir, graph=None, max_queue=10, flush_secs=120, graph_def=None, filename_suffix=None, session=None) add_summary将summary string添加至事件文件中 1234add_summary( summary, global_step=None) flush将事件文件写到磁盘1flush() close将事件文件写到磁盘并关闭FileWriter。 1close() visulization Functionscalar123456tf.summary.scalar( name, tensor, collections=None, family=None) Args: name: 显示的名字 family: 同一族 Return: 一个operation image1234567tf.summary.image( name, tensor, max_outputs=3, collections=None, family=None) Args: name: 显示的名字 tensor: shape [batch_size, height, width, channels], channels可以是1,3,4,分别对应于Grayscale,RGB,RGBA。 histogram1234567tf.summary.histogram( name, values, collections=None, family=None) name: 显示的名称 values: 处理的数据,可以是任意形状 text123456tf.summary.text( name, tensor, collections=None) tensor: a string-type Tensor to summarize. audio合并可视化操作目的: 使得1次forward propagation,获取多个summary tf.summary.merge123456tf.summary.merge( inputs, collections=None, name=None) inputs: A list of string Tensor objects containing serialized Summary protocol buffers. tf.summary.merge_all12345tf.summary.merge_all( key=tf.GraphKeys.SUMMARIES, scope=None, name=None) Merges all summaries collected in the default graph. Args: key: GraphKey used to collect the summaries. Defaults to GraphKeys.SUMMARIES. scope: Optional scope used to filter the summary ops, using re.match Return: 返回一个ops Conclusion可视化主要流程: 预定义Summary objects 合并Summary objects 启动Session 定义tf.summary.FileWriter 获取summary string : sess.run(summary_ops, feed_dict={}) 添加至事件文件 写入磁盘 For example 12345678910111213141516171819202122import tensorflow as tfvar = tf.Variable(tf.zeros([], name='var'))scalar_op = tf.Summary.scalar('var', var)merge_op = tf.Summary.merge_all()init_op = tf.global_variables_initializer()with tf.Session() as sess: writer = tf.Summary.FileWriter('./logs') sess.run(init_op) summary_string = sess.run(merge_op) writer.add_summary(summary_string, global_step=0) writer.flush()","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"tensorflow_tutorial_4","slug":"tensorflow-tutorial-4","date":"2019-01-31T08:25:48.000Z","updated":"2019-02-17T07:18:54.701Z","comments":true,"path":"2019/01/31/tensorflow-tutorial-4/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/01/31/tensorflow-tutorial-4/","excerpt":"","text":"class saver作用:用于保存和恢复网络的参数 FunctionInit123456789101112131415161718__init__( var_list=None, reshape=False, sharded=False, max_to_keep=5, keep_checkpoint_every_n_hours=10000.0, name=None, restore_sequentially=False, saver_def=None, builder=None, defer_build=False, allow_empty=False, write_version=tf.train.SaverDef.V2, pad_step_number=False, save_relative_paths=False, filename=None) Args: var_list: 指定保存的变量。可以使list或者dict max_to_keep: 最近可以保存ckeckpoints的最大数目 keep_checkpoint_every_n_hours: 多久保存一次ckeckpoints12345678910111213v1 = tf.Variable(..., name='v1')v2 = tf.Variable(..., name='v2')# Pass the variables as a dict:saver = tf.train.Saver({'v1': v1, 'v2': v2})# Or pass them as a list.saver = tf.train.Saver([v1, v2])# Passing a list is equivalent to passing a dict with the variable op names# as keys:saver = tf.train.Saver({v.op.name: v for v in [v1, v2]}) save12345678910save( sess, save_path, global_step=None, latest_filename=None, meta_graph_suffix='meta', write_meta_graph=True, write_state=True, strip_default_attrs=False) 作用:保存网络参数 Args:sess: 会话句柄save_path:保存路径global_step:步数 restore作用:恢复网络参数 1234restore( sess, save_path) Args:sess: 会话句柄save_path:保存路径 Example123456789# Create a saver.saver = tf.train.Saver(...variables...)# Launch the graph and train, saving the model every 1,000 steps.sess = tf.Session()for step in xrange(1000000): sess.run(..training_op..) if step % 1000 == 0: # Append the step number to the checkpoint name: saver.save(sess, 'my-model', global_step=step) 查看保存文件里的tensor123456789from tensorflow.python import pywrap_tensorflow# 从检查点文件中读取数据reader = pywrap_tensorflow.NewCheckpointReader(checkpoint_path)var_to_shape_map = reader.get_variable_to_shape_map()# 显示变量名及其值for key in var_to_shape_map: print(\"tensor_name: \", key) print(reader.get_tensor(key)) 保存文件: .meta文件保存了当前图结构 .index文件保存了当前参数名 .data文件保存了当前参数值 注:每调用一次save方法会产生新的文件 To do transfer learning 里如何恢复部分模型参数","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"tensorflow_tutorial_2","slug":"tensorflow-tutorial-2","date":"2019-01-31T03:31:24.000Z","updated":"2019-02-17T07:18:54.697Z","comments":true,"path":"2019/01/31/tensorflow-tutorial-2/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/01/31/tensorflow-tutorial-2/","excerpt":"","text":"Tensors注: 必须初始化,才能使用 eval() run() Variable作用:用于记录graph的状态,即,记录拟合函数$g(X)$的权重。 创建Variable操作具有以下作用: 将该Variable作为graph的一个节点并必须指定初始化器或者初值 将该Variable放到键值为tf.GraphKeys.GLOBAL_VARIABLES的collections集合中 若trainable为true,则将该Variable放到键值为tf.GraphKeys.TRAINABLE_VARIABLES的collections集合 注:trainable为true表明该变量会进行更新,collections可以认为是一个空间,用于存放变量。 变量创建方式1: 12var = tf.Variable(<initial-value>, name=<optional-name>, dtype=tf.float32, trainable=true) 以此种方式创建变量var, var与initial-value的数据和形状一致,若定义出现两个名字一致的变量,会在后面定义的变量名称加上后缀_1,_2,_3,…”。 tensorflow定义了如下函数可以用来指定初值: Function Description tf.zeros(shape, dtype=tf.float32,name=None) 产生全0的tensor tf.ones(shape, dtype=tf.float32,name=None) 产生全1的tensor tf.random.normal(shape, mean=0.0, stddev=1.0) 产生服从正态分布的tensor tf.random.uniform(shape, minval=0.0, maxval=NOne) 产生服从均匀分布的tensor tf.random.truncated_normal(shape, mean=0.0, stddev=1.0) 产生服从截断正态分布的tensor 注:shape参数用来指定产生随机数的维度 List Description [] 0维,标量 [d1] 1维 [d1,d2] 2维 [None,d2] 2维,第一维度数目可以是任意值 [d1,d2,d3] 3维 [d1,d2,d3,…] n维 变量创建方式2: 12var = tf.get_variable(name, shape=None, dtype=None, initializer=None, trainable=true) 创建名为name的变量,初始化器由initializer指定,形状由shape指定。 在不复用变量的情况下,若定义两个名字一样的变量,则会报错。 Tensorflow内的initializer有: class constructor tf.contrib.layers.xavier_initializer ~(uniform=True),uniform=False采用正态分布 tf.random_normal_initializer ~(mean=0.0, stddev=1.0) tf.random_uniform_initializer ~(minval=0, maxval=None) tf.truncated_normal_initializer ~(mean=0.0, stddev=1.0) tf.ones_initializer ~() tf.zeros_initializer ~() For Examples: 123456var = tf.Variable(tf.random.normal([1,2,3]),name=\"var\")# 等价于 #var = tf.getVariable(\"var\",shape=[1,2,3],initializer=tf.random_normal_initializer()) Constant常量,在图中值不改变,不能进行reshape操作。 1234567tf.constant( value, dtype=None, shape=None, name='Const', verify_shape=False) For Examples: 123456# Constant 1-D Tensor populated with value list.tensor = tf.constant([1, 2, 3, 4, 5, 6, 7]) => [1 2 3 4 5 6 7]# Constant 2-D tensor populated with scalar value -1.tensor = tf.constant(-1.0, shape=[2, 3]) => [[-1. -1. -1.] [-1. -1. -1.]] placeholderplaceholder用于graph的输入,一般指定shape和dtype,name。 12345tf.placeholder( dtype, shape=None, name=None) manager Tensors 如图所示,在Tensorflow中,采用层次的结构来管理operations:collection $\\leftarrow$ variable scope $\\leftarrow$ operations。 从该图还可以得到如下信息: tensorflow图自定义了多个集合,例如集合1,2。集合1,2分别存放所有的,只用于训练的操作和张量。 集合通过键值进行区分,例如集合1,2的键值分别为tf.GraphKeys.GLOBAL_VARIABLES,tf.GraphKeys.TRAINABLE_VARIABLES。 为了避免出现操作和张量同名,定义了次级空间variable scope。在同一scope下的操作和张量具有相同的前缀名。该scope类似于c++里的namespace。 同一scope可以同时在多个集合中,图中v1,v2都属于集合1,2。 也可以存放一些没有在variable scope内的张量和操作。 variable scope作用:定义一个子空间,存放操作和张量。定义: tf.variable_scope 123456with tf.variable_scope(name, reuse=false): # define your tensors # define your operations 注:当reuse=false时,利用tf.get_variable定义tensor时不能出现两个同名张量。如若为True,后定义的张量与前面定义的张量一致。此外,对Variable定义tensor无影响。 For example123456with tf.variable_scope(\"hello\"): var = tf.get_variable(\"var\", shape =[1,2], intializer=tf.zeros_initializer()) var1 = tf.get_variable(\"var\", shape =[1,2], intializer=tf.zeros_initializer()) ==> error 12345678with tf.variable_scope(\"hello\", reuse=True): var = tf.get_variable(\"var\", shape =[1,2], intializer=tf.zeros_initializer()) var1 = tf.get_variable(\"var\", shape =[1,2], intializer=tf.zeros_initializer()) assert var == var1 ==> True collection作用:存放操作和张量。 操作: 从某个collection获取某个scope的variable集合: 12345tf.get_collection( key, scope=None) 从某个collection获取所有的variable: 12tf.get_collection(key) 将variable 添加至自定义集合name 12345tf.add_to_collection( name, value)","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"tensorflow_tutorial_1","slug":"tensorflow-tutorial-1","date":"2019-01-30T07:50:15.000Z","updated":"2019-02-17T07:18:54.659Z","comments":true,"path":"2019/01/30/tensorflow-tutorial-1/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/01/30/tensorflow-tutorial-1/","excerpt":"","text":"Basic conceptsPreface机器学习中的大部分任务是去学习一个将输入$X$映射到标签$Y$的映射函数$f(X)$: $X \\rightarrow Y$,由于在实际中,我们很难通过解析式求得$f(X)$的具体表达形式。因而,我们希望通过数值迭代的方式去求得一个近似函数$g(X;\\theta)$并且使得$g(X)$尽可能地逼近$f(X)$: $g(X;\\theta) \\rightarrow f(X)$。 Graph 图1 graph的框架 Tensorflow将这一过程表征为graph的形式。graph的组成可以分成以下3部分: 参数化层: Input $\\rightarrow$ Reshape $\\rightarrow$ ReLu Layer $\\rightarrow$ReLu Layer $\\rightarrow$ softmax 逼近量化层: Input $\\rightarrow$ Class Labels$\\rightarrow$ Cross Entropy 参数更新层: Gradients $\\rightarrow$ Logit Layer $\\rightarrow$ ReLu Layer graph由节点和边组成,节点和边分别对应操作(operations)和张量(Tensors)。 操作(operations)包含: 定义Tensor 基于Tensor的运算($e.g.$ +-*/)。 从动态图可知,graph中的Tensors flow(流动)分为两步: forward propagation: Input $\\rightarrow$ Reshape $\\rightarrow$ ReLu Layer $\\rightarrow$ Logit Layer $\\rightarrow$ softmax backpropagation: Gradients $\\rightarrow$ Logit Layer $\\rightarrow$ ReLu Layer forward propagation 用于预测输入数据对应的label; backpropagation 用于更新网络参数$\\theta$,使得$g(X)$尽可能地逼近$f(X)$。此外,从图中可以看出,为了方便区分operations,定义了作用域(scope), $e.g.$ ReLu Layer, Logit Layer。 12345678910# 显示定义图:(默认是定义了一张图)g = tf.Graph()# 往图里添加operationswith g.as_default(): c = tf.constant(30.0) assert c.graph == g# 返回当前图g = tf.get_default_graph()# 查看当前图的operationsoperations = g.get_operations() #list Tensors张量是对矢量和矩阵向潜在的更高维度的泛化,TensorFlow 在内部将张量表示为基本数据类型的 n 维数。 Tensor的属性: 数据类型(dtype): $e.g.$ tf.float32, tf.int32, tf.string 形状(shape) 名称(name) Tensor的阶的定义 rank Description 0 标量 1 一维数组 2 二维数组 3 三维数组 n n维数组 注:rank = len(tensor.shape)=tf.rank(tensor) Tensor的分类 kind Description tf.Variable 用于存储graph的状态 tf.placeholder 用于graph的输入 tf.constant 用于存常量 tf.SparseTensor 用于稀疏张量 Tensor Auxiliary: 改变形状,使用tf.reshape(tensor, new_shape) 改变数据类型,使用tf.cast(tensor,new_dtype) 获取Tensor的值,在某个Session下使用tensor.eval() Session会话(Session)和图(graph)相互绑定的,graph只是定义了符号运算,但并未获得实际的物理运行环境,会话(Session)则为graph提供了可实际运行的上下文。因而,在一个会话下,才能进行数值运算。 123456789101112131415161718192021# create Sessiontf.Session(target='',graph=None,config=None) #graph默认指定为当前默认图# usage1:define some operationssess = tf.Session()sess.run(ops, feed_dict={a: xxx})sess.close()# usage2:define some operationswith tf.Session() as sess: sess.run(ops, feed_dict={a: xxx}) #feed_dict{xxx} 对应于该ops所需要的输入值","categories":[],"tags":[{"name":"tensorflow","slug":"tensorflow","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/tensorflow/"}]},{"title":"linuxweek1","slug":"linuxweek1","date":"2019-01-11T16:25:58.000Z","updated":"2019-02-17T07:18:54.649Z","comments":true,"path":"2019/01/12/linuxweek1/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/01/12/linuxweek1/","excerpt":"","text":"Linux基本的Linux命令 man man name or man section name or man -k regexp section: 1 ->命令, 2 -> 系统调用 3 -> 库函数 date 读取系统的时间和日期 定制输出格式: data ”+%Y-%m-%d %H:%M:%S Day %j” or data “+%s” ntpdate 0.pool.ntp.org 设置时间(only root) ntpdate -q 0.pool.ntp.org 查询时间 cal cal 当前月份日历 cal year cal month year bc bc 缺省精度为数点后0位 bc -l 缺省精度为数点后20位 passwd passwd 普通用户修改登陆密码 passwd 用户名 root 可重置用户的密码 了解系统状态的命令 who 确定谁在系统中 who 列出已登录系统的用户 who am i whoami uptime 已开机时间, CPU负载, 登陆用户数 top free vmstat ps e 所有进程 f full格式 l long格式 文本处理命令 more/less more filename 满屏后,空格翻页,换行,向下滚动一行, q 退出, /pattern, / 不支持回退 less is more, 可利用上下箭头,支持回退 cat/od 文本格式打印 cat filename or cat -n filename 带行号 od 逐字节打印 od -c/-t c(字符), -t x1(16进制), -t d1(10进制), -t u1(8进制) head/tail head -n number filename / tail -n number filename head -n -number filename 除末尾number行,均为头 tail -n +number filename 除首number行,均为尾 tail -f filename 实时打印文件尾部信息 tee tee filename 将stdin的数据送到stdout,并存入文件filename wc 列出文件一共多行,多少单词,多少字符 文件大于1,会有个合计 -l 只输出行 sort sort -n 按数值大小排顺序,不按字符比较规则 tr 翻译字符 tr string1 string2 翻译string1至string2 uniq uniq options inputfile -u 只保留没有重复的行(只打印一次) -d 只保留重复的行(只打印一次) -c 计数同样的行出现的次数","categories":[],"tags":[{"name":"linux","slug":"linux","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/linux/"}]},{"title":"hexo迁移和复用","slug":"setupBlog3","date":"2019-01-09T04:31:06.000Z","updated":"2019-02-17T07:18:54.658Z","comments":true,"path":"2019/01/09/setupBlog3/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/01/09/setupBlog3/","excerpt":"","text":"如何方便的迁移hexo博客解决方案是:在同一个Repositories,创建两个branch,master用于存放静态网页文件,hexo用于存放hexo代码。 创建远程分支hexo git clone url git brand -r, 若存在hexo分支且想重新创建,可 git branch -r -d origin/hexo git push origin :hexo git checkout -b hexo, 创建新hexo分支 将上层目录的hexo文件全部拷贝至 xxx.io 文件下 git add . git commit -m "add hexo branch" git push --set-upstream origin hexo 在远端创建hexo分支并上传文件, 如果有hexo的话,git push origin Repositories 已经存在两个branch了 从新的环境中开始从远端复原 git clone -b hexo https://github.com/SunshineJunFu/JunFu.github.io.git cd xx.io npm install hexo --save npm install npm install hexo-deployer-git hexo s, 检查复原效果 书写博客 hexo new name 编辑 xx.md 文件 git add . git commit -m something git push origin, 更新远端hexo文件,对应hexo branch hexo g -d, 更新远端静态网页文件,对应master branch","categories":[],"tags":[{"name":"hexo","slug":"hexo","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/hexo/"}]},{"title":"hexo 配置主题","slug":"setupBlog2","date":"2019-01-09T04:30:44.000Z","updated":"2019-02-17T07:18:54.658Z","comments":true,"path":"2019/01/09/setupBlog2/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/01/09/setupBlog2/","excerpt":"","text":"配置文件 站点文件_config.yml,修改Extension字段,配置theme,设置为indigo 设置头像,在根目录/source/ 创建images/, 存放头像图片 配置主题文件_config.yml, 可以参考indigo configuration hexo g -d 查看远程效果 hexo g, hexo s 查看本地效果 主题配置文件_config.yml 样例: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167# hexo-theme-indigo# https://github.com/yscoder/hexo-theme-indigo# reference : https://github.com/lrscy/lrscy.github.io/blob/hexo/themes/indigo/_config.yml# 添加新菜单项遵循以下规则# menu:# link: fontawesome图标,省略前缀,本主题前缀为 icon-,必须# text: About 菜单显示的文字,如果省略即默认与图标一致,首字母会转大写# url: /about 链接,绝对或相对路径,必须。# target: _blank 是否跳出,省略则在当前页面打开menu: home: text: Homepage url: / archives: url: /archives tags: url: /tags github: url: https://github.com/SunshineJunFu target: _blank# 你的头像urlavatar: /images/avatar.jpg# avatar linkavatar_link: /# 头像背景图brand: /img/brand.jpg# faviconfavicon: /favicon.ico# emailemail: fujun@mail.ustc.edu.cn# 设置 Android L Chrome 浏览器状态栏颜色color: '#3F51B5'# 页面标题tags_title: Tagsarchives_title: Archivescategories_title: Categories# 文章截断excerpt_render: falseexcerpt_length: 200excerpt_link: Read More...mathjax: true #falsearchive_yearly: true# 是否显示文章最后更新时间show_last_updated: true# 是否开启分享share: true# 是否开启打赏,关闭 reward: falsereward: false # title: 谢谢大爷~ # wechat: /img/wechat.jpg #微信,关闭设为 false # alipay: /img/alipay.jpg #支付宝,关闭设为 false# 是否开启搜索search: true# 是否大屏幕下文章页隐藏导航hideMenu: true# 是否开启toc# toc: falsetoc: list_number: true # 是否显示数字排序# 文章页留言内容,hexo中所有变量及辅助函数等均可调用,具体请查阅 hexo.iopostMessage: #这里可以写作者留言,标签和 hexo 中所有变量及辅助函数等均可调用,示例:<a href="<%- url_for(page.path).replace(/index\\.html$/, '') %>" target="_blank" rel="external"><%- page.permalink.replace(/index\\.html$/, '') %></a># 站长统计,如要开启,输入CNZZ站点id,如 cnzz: 1255152447cnzz: false# 百度统计,如要开启,改为你的 keybaidu_tongji: false# 腾讯分析,如要开启,输入站点idtajs: false# googlegoogle_analytics: truegoogle_site_verification: true# sogou站长验证 http://zhanzhang.sogou.com/sogou_site_verification: false# lessless: compress: true paths: - source/css/style.less# 以下评论插件开启一个即可# 是否开启 disqusdisqus_shortname: false# 是否开启友言评论, 填写友言用户iduyan_uid: false# 是否使用 gitment,https://github.com/imsun/gitmentgitment: false# gitment:# owner:# repo:# client_id:# client_secret:# Valine Comment system. https://valine.js.orgvaline: enable: true # 如果你想使用valine,请将值设置为 true appId: jeA0VlYdrPRbE0nMW3DV5gow-gzGzoHsz # your leancloud appId appKey: QvgEiq6wSQKvTmKUUM5pcMJh # your leancloud appKey notify: false # Mail notify verify: true # Verify code avatar: mm # Gravatar style : mm/identicon/monsterid/wavatar/retro/hide placeholder: share your ideas # Comment Box placeholder guest_info: nick,mail # Comment header info pageSize: 10 # comment list page size# 是否开启Hyper Comments,填写id则启用,false则禁用。http://hypercomments.com# Hyper Comments support. Write your id here, or false to disablehyper_id: false# 规范网址# 让搜索引擎重定向你的不同域名、不同子域、同域不同目录的站点到你期望的路径# https://support.google.com/webmasters/answer/139066# 假设配置为 canonical: http://imys.net,那么从搜索引擎中 www.imys.net 进入会重定向到 imys.netcanonical: false# 版权起始年份since_year: 2015# 用户页面中作者相关的描述性文字,如不需要设为 falseabout: false #用户页面中作者相关的描述性文字,如不需要设为 false# “不蒜子”访问量统计,详见 http://ibruce.info/2015/04/04/busuanzi/counter: truevisit_counter: site_uv: UV: # 注意 中文: site_pv: PV:# 动态定义titletitle_change: normal: Hi! Welcome Back! leave: Where are you!# 设置为 true 发布后将使用 unpkg cdn 最新的主题样式# 如果想让你的自定义样式生效,把此项设为 falsecdn: true# 设置为 true 将使用 lightbox render 图片lightbox: true# icp备案号 ICP_license: 京ICP备1234556号-1ICP_license: falsefeed: type: atom path: atom.xml limit: 0","categories":[],"tags":[{"name":"hexo","slug":"hexo","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/hexo/"}]},{"title":"hexo搭建个人博客","slug":"setupBlog1","date":"2019-01-09T04:29:58.000Z","updated":"2019-02-17T07:18:54.657Z","comments":true,"path":"2019/01/09/setupBlog1/","link":"","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/2019/01/09/setupBlog1/","excerpt":"","text":"配置环境安装node.js 登陆 node.js 官网,根据对应的操作系统,选择相应的版本 安装node.js 在命令行里, 运行node -v, 若有版本信息,则安装成功, 反之亦然。 安装hexo 运行 npm install -g hexo-cli, 安装hexo 运行 hexo -v, 若有版本信息,则安装成功, 反之亦然。 运行 npm install hexo-deployer-git --save, 安装github上传包 安装git 登陆git下载网址, 根据对应的操作系统,选择相应的版本 安装git 在命令行里, 运行git --version, 若有版本信息,则安装成功, 反之亦然。 github 注册账号 建立一个Repositories,用于存放博客静态文件,名称格式最好为:用户名.github.io 设置远程,git remote add remoteName url, url 为 Repositories 选项setting中Github Pages提示的url 查看远程设置,git remote -v 重新配置,git remote set-url remoteName url 初次搭建博客创建本地文件 hexo init [blogsName] cd yourpath/blogsName 启动本地服务器,hexo s or hexo server 在浏览器中输入,localhost:4000, 查看有无界面, 有则成功 配置_config.yml 修改site字段,配置language,author,title,description, 支持的语言在language option 修改url字段,配置 url 和 根目录 root 修改Extension字段,配置theme,默认是landscape 修改deploy字段,配置type, repository, branch 示例如下:123456789101112131415161718192021222324252627# Sitetitle: Hexosubtitle:description: keep hungry and practice morekeywords:author: Jun Fulanguage: entimezone:# URL## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'url: https://github.com/SunshineJunFu/JunFu.github.ioroot: /JunFu.github.io/permalink: :year/:month/:day/:title/permalink_defaults:# Extensions## Plugins: https://hexo.io/plugins/## Themes: https://hexo.io/themes/theme: landscape# Deployment## Docs: https://hexo.io/docs/deployment.htmldeploy: type: git repository: https://github.com/SunshineJunFu/JunFu.github.io branch: master 上传至github 运行hexo g -d 点击对应Repositories 选项setting中Github Pages提示的url,查看效果 hexo 命令 hexo init blogsName, 创建文件夹 hexo generate,可简写为hexo g, 生成网页静态文件 hexo server,可简写为hexo s, 创建本地服务器 hexo deploy,可简写为hexo d, 上传至github hexo clean, 清理缓存 hexo new post Name, 创建博客 hexo new page Name, 创建网页 更多信息,可以参考hexo writing","categories":[],"tags":[{"name":"hexo","slug":"hexo","permalink":"https://github.com/SunshineJunFu/JunFu.github.io/tags/hexo/"}]}]}