macOS 查看监听指定端口的进程(Linux 等价 netstat -ntlp)

lsof -n -i4TCP:$PORT | grep LISTEN
lsof -n -iTCP:$PORT | grep LISTEN
lsof -n -i:$PORT | grep LISTEN

其中$PORT替换为指定的端口号,或者是用英文逗号连接的一组端口号。

from

git 命令行中文乱码的解决方法

git config --global core.quotepath false

找回 telnet 命令 on macOS High Sierra 10.13.*

macOS 升级到 High Sierra 后,telnet 命令竟然不见了!身为码畜,是可忍孰不可忍……

安装 Homebrew

如果你还没有安装过 Homebrew,先用下面的命令安装上:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装 telnet

也是一条命令的事儿……

brew install telnet

The END

TensorFlow API 用法详解:tf.equal

equal(
    x,
    y,
    name=None
)

对输入的 xy 两个 Tensor 逐元素(element-wise)做 (x == y) 逻辑比较,返回 bool 类型的 Tensor

参数

  • x 只支持以下类型:half, float32, float64, uint8, int8, int16, int32, int64, complex64, quint8, qint8, qint32, string, bool, complex128
  • y 的类型必须与 x 相同
  • name 给这个操作取一个名称,可选

返回

  • bool 类型的 Tensor

特性

  • 支持 broadcasting,详见 Numpy 文档

示例

基本用法:xy 拥有相同的 shape

import tensorflow as tf

a = tf.constant([1, 2], tf.int32)
b = tf.constant([2, 2], tf.int32)
with tf.Session() as sess:
    print(sess.run(tf.equal(a, b))) # 输出 [False  True]

broadcasting 用法:xy 不同 shape

x = tf.constant(["hehe", "haha", "hoho", "kaka"], tf.string)
y = tf.constant("hoho", tf.string)
with tf.Session() as sess:
    print(sess.run(tf.equal(x, y)))
# 输出 [False False  True False]

注意观察上面这个栗子,实际解决了在一个数组中查找某个元素索引(index)的问题,这个特性配合 tf.cast 在生成 one-hot 向量时将会特别有用。

a = tf.constant([[1], [2]], tf.int32)
b = tf.constant([[2, 1]], tf.int32)
with tf.Session() as sess:
    print(sess.run(tf.equal(a, b)))
# 输出
# [[False  True]
#  [ True False]]

TensorFlow 实战 02:用 DNN 做 MNIST 手写数字识别

学一门新的语言,第一个实战例子总是打印 hello world;在机器学习领域,也有一个 hello world,那就是 MNIST 手写数字识别——当然,它可比打印字符串有意义多了。

什么是 MNIST

MNIST 是深度学习巨巨 Yann LeCun 维护的一套手写数字图像数据库,包含 60000 个训练样本和 10000 个测试样本,所有这些图像已经做过规范化及居中处理,拥有同样的固定尺寸,使用起来非常方便。下面是其中几个例子。

MNIST

我们要做什么

很明显,我们马上要开始编写第一个 TensorFlow 程序,一个有实际应用价值的深度神经网络(DNN)——虽然只有 2 个隐层,做 MNIST 手写数字识别,484 很鸡冻……

Let's do it, but how?

万事开头难,迈出第一步非常关键。为了避免陷入对无限发散的未知知识点(技能树)的恐慌,我们尽量将注意力集中在主线任务上,旁枝末节以后慢慢看,当然,楼主假设你还是会写基本的 Python 的。废话不多说,动手吧!

读取 MNIST 数据

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

input_data 封装了 MNIST 数据的下载、解析功能,read_data_sets() 返回三部分数据:55000 个训练样本 mnist.train,5000 个验证样本 mnist.validation(注意到没有,这 5000 是从原始的 60000 个训练样本上拿出来的),10000 个测试样本 mnist.test

每个样本都包含一个手写数字图像 x 和一个对应的标签 y,训练集的图像和标签可以通过 mnist.train.imagesmnist.train.labels 读取,验证集和测试集同理。图像的尺寸是 28x28 像素,每个像素值代表 [0,1] 的笔划强度,我们可以把图像数据理解为一个长度为 784 的数组,也就是一个 784 维的向量。标签的取值为 [0,9] ,表示从 0 到 9 这 10 个数字,这里我们把标签处理成 10 维 one-hot 向量以方便对应 DNN 的输出。

建立 DNN 模型

接下来我们搭建一个拥有 2 个隐层的 DNN 模型,第一层拥有 1024 个神经元,第二层拥有 625 个神经元,使用 ReLU 作为激活函数,并在输入层和隐层各层都使用 dropout 机制避免模型发生过拟合,这些概念暂时不懂也没有关系,把实验做完,不懂的再去查。

import tensorflow as tf

X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])
p_keep_input = tf.placeholder(tf.float32)
p_keep_hidden = tf.placeholder(tf.float32)


def init_weights(shape):
    return tf.Variable(tf.random_normal(shape, stddev=0.01))


w_h = init_weights([784, 1024])
w_h2 = init_weights([1024, 625])
w_o = init_weights([625, 10])


def model(X, w_h, w_h2, w_o, p_keep_input, p_keep_hidden):
    X = tf.nn.dropout(X, p_keep_input)

    h = tf.nn.relu(tf.matmul(X, w_h))
    h = tf.nn.dropout(h, p_keep_hidden)

    h2 = tf.nn.relu(tf.matmul(h, w_h2))
    h2 = tf.nn.dropout(h2, p_keep_hidden)

    return tf.matmul(h2, w_o)


py_x = model(X, w_h, w_h2, w_o, p_keep_input, p_keep_hidden)

训练模型

为了训练模型,必须有一个指标衡量模型的好坏,这个指标就是损失(loss 或 cost),loss 越接近于 0 表明模型的输出越接近于真实的标签,我们选择最常用的交叉熵 cross-entropy 作为损失函数, RMSProp 优化算法做梯度下降

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=py_x, labels=Y))
train_op = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost)

评估模型

我们把模型输出的标签与真实的标签进行比较,并将比较结果转换为一个取值 [0, 1] 的浮点数作为准确率指标。

predict_acc = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(py_x, 1), tf.argmax(Y, 1)), tf.float32))

接下来,我们该启动程序了:

epoch_count = 20000
batch_size = 50
keep_input = 0.8
keep_hidden = 0.75

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    step = 0
    for i in xrange(epoch_count):
        step += 1
        batch_x, batch_y = mnist.train.next_batch(batch_size)
        sess.run(train_op, feed_dict={X: batch_x, Y: batch_y, p_keep_input: keep_input, p_keep_hidden: keep_hidden})
        if step % 100 == 0:
            loss, acc = sess.run([cost, predict_acc], feed_dict={X: batch_x, Y: batch_y, p_keep_input: 1., p_keep_hidden: 1.})
            print("Epoch: {}".format(step), "\tLoss: {:.6f}".format(loss), "\tTraining Accuracy: {:.5f}".format(acc))
    print("Testing Accuracy: {:0.5f}".format(sess.run(predict_acc, feed_dict={X: mnist.test.images, Y: mnist.test.labels, p_keep_input: 1., p_keep_hidden: 1.})))

整个训练过程共 20000 步,每步使用 50 个一组的随机样本做训练,每训练 100 步输出一次训练准确率,全部训练结束后使用测试集 mnist.test 评估准确率。

我们的 DNN 模型很简单,同时也很争气,准确率大概是 98.26%,有没有感觉到一种成就感……

小提示

虽然实验做完了,结果也还算不错,但此刻我们应该冷静下来认真做一下回顾,把整篇文章中不太明白的概念整理出来,深入地去做一下理论知识学习。这里推荐一本免费的电子书:Neural Networks and Deep Learning,拿来入门非常合适。

TensorFlow 实战 01:安装 GPU 版本的开发环境 (Ubuntu)

这里将介绍如何在 Ubuntu 16.04 LTS 系统上搭建 支持 GPU 的 TensorFlow 1.4.0 开发环境。

是否需要 GPU 支持?

这取决于你有没有一块儿支持 CUDA 的 NVIDIA 显卡。如果没有,只能选择 CPU 版本。如果有,继续往下看。

安装 NVIDIA 依赖

  1. 安装 CUDA Toolkit 9.0:在 CUDA Downloads 页面选择操作系统及版本,安装类型选择deb (network),最后会给出一个下载链接和一系列的命令,类似:
    sudo dpkg -i cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
    sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
    sudo apt-get update
    sudo apt-get install cuda
    
    修改 PATH 环境变量
    export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
    
    修改 LD_LIBRARY_PATH 环境变量
    export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
    
  2. 安装显卡驱动,目前最新的驱动版本是 384
    sudo apt install nvidia-384
    
    驱动安装成功后,可以使用下面的命令查看显卡状态:
    nvidia-smi
    
  3. 安装 cuDNN 7,在 cuDNN下载页面 点击 Download 并填写调查问卷后,根据自己的系统环境下载对应的安装包并安装,以下是 64 位系统的示例:
    sudo dpkg -i libcudnn7_7.0.3.11-1+cuda9.0_amd64.deb
    sudo dpkg -i libcudnn7-dev_7.0.3.11-1+cuda9.0_amd64.deb
    sudo dpkg -i libcudnn7-doc_7.0.3.11-1+cuda9.0_amd64.deb
    
  4. 安装 libcupti-dev库
    sudo apt install libcupti-dev
    
    修改 LD_LIBRARY_PATH 环境变量
    export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH
    

安装 TensorFlow

安装预编译的包或者从源码编译都是可行的。

原生 pip 安装

python 2.7/3.n 都可以。

  1. 先安装并升级 pip
    # for Python 2.7
    sudo apt-get install python-pip python-dev
    sudo pip install -U pip setuptools
    # for Python 3.n
    sudo apt-get install python3-pip python3-dev
    sudo pip3 install -U pip setuptools
    
  2. 安装 tensorflow,根据需求只执行一条命令即可
    pip install tensorflow      # Python 2.7; CPU support (no GPU support)
    pip3 install tensorflow     # Python 3.n; CPU support (no GPU support)
    pip install tensorflow-gpu  # Python 2.7; GPU support
    pip3 install tensorflow-gpu # Python 3.n; GPU support
    

源码编译安装

  1. git 下载源码仓库,切到 r1.4 分支
    git clone https://github.com/tensorflow/tensorflow
    git checkout r1.4
    
  2. 安装 bazel
    sudo apt-get install openjdk-8-jdk
    echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
    curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
    sudo apt-get update && sudo apt-get install bazel
    
  3. 安装 TensorFlow 的 Python 依赖
    sudo apt-get install python-numpy python-dev python-pip python-wheel     # for Python 2.7
    sudo apt-get install python3-numpy python3-dev python3-pip python3-wheel # for Python 3.n
    
  4. 执行安装配置,务必注意每一步的选择
    cd tensorflow # 进入第 1 步克隆的仓库根目录
    ./configure
    Please specify the location of python. [Default is /usr/bin/python]: /usr/bin/python2.7
    Found possible Python library paths:
    /usr/local/lib/python2.7/dist-packages
    /usr/lib/python2.7/dist-packages
    Please input the desired Python library path to use.  Default is [/usr/lib/python2.7/dist-packages]
    Using python library path: /usr/local/lib/python2.7/dist-packages
    Do you wish to build TensorFlow with MKL support? [y/N]
    No MKL support will be enabled for TensorFlow
    Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]:
    Do you wish to use jemalloc as the malloc implementation? [Y/n]
    jemalloc enabled
    Do you wish to build TensorFlow with Google Cloud Platform support? [y/N]
    No Google Cloud Platform support will be enabled for TensorFlow
    Do you wish to build TensorFlow with Hadoop File System support? [y/N]
    No Hadoop File System support will be enabled for TensorFlow
    Do you wish to build TensorFlow with the XLA just-in-time compiler (experimental)? [y/N]
    No XLA support will be enabled for TensorFlow
    Do you wish to build TensorFlow with VERBS support? [y/N]
    No VERBS support will be enabled for TensorFlow
    Do you wish to build TensorFlow with OpenCL support? [y/N]
    No OpenCL support will be enabled for TensorFlow
    Do you wish to build TensorFlow with CUDA support? [y/N] Y
    CUDA support will be enabled for TensorFlow
    Do you want to use clang as CUDA compiler? [y/N]
    nvcc will be used as CUDA compiler
    Please specify the Cuda SDK version you want to use, e.g. 7.0. [Leave empty to default to CUDA 8.0]: 9.0
    Please specify the location where CUDA 8.0 toolkit is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
    Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]:
    Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 6.0]: 7
    Please specify the location where cuDNN 6 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
    Please specify a list of comma-separated Cuda compute capabilities you want to build with.
    You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus.
    Please note that each additional compute capability significantly increases your build time and binary size. [Default is: "3.5,5.2"]: 6.1
    Do you wish to build TensorFlow with MPI support? [y/N] 
    MPI support will not be enabled for TensorFlow
    Configuration finished
    
  5. 编译生成 pip 包
    bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
    bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
    
  6. 安装生成好的 pip 包,具体的 whl 包在 /tmp/tensorflow_pkg 目录下,文件名可能略有不同
    sudo pip install /tmp/tensorflow_pkg/tensorflow-1.4.0-cp27-cp27mu-linux_x86_64.whl
    

验证一下是否装成功了

  1. 启动 Python
    $ python
    
  2. 逐行敲入下面的代码
    # Python
    import tensorflow as tf
    hello = tf.constant('Hello, TensorFlow!')
    sess = tf.Session()
    print(sess.run(hello))
    
    如果能看到下面的输出
    Hello, TensorFlow!
    
    恭喜你,安装成功了……

更多的细节

请参考详细的官方文档

  1. Installing TensorFlow on Ubuntu
  2. Installing TensorFlow from Sources
  3. NVIDIA CUDA Installation Guide for Linux
  4. NVIDIA cuDNN
  5. CUDA GPUs

使用 wget 下载 HTTP 目录

Solution

wget -r -np -nH --cut-dirs=3 -R index.html http://hostname/aaa/bbb/ccc/ddd/

Explanation

  • It will download all files and subfolders in ddd directory
  • recursively (-r)
  • not going to upper directory, like ccc/... (-np)
  • not saving files to hostname folder (-nH)
  • but to ddd omitting first 3 folders aaa, bbb, ccc (--cut-dirs=3)
  • excluding index.html files (-R index.html)

Reference

http://bmwieczorek.wordpress.com/2008/10/01/wget-recursively-download-all-files-from-certain-directory-listed-by-apache/

Via

https://stackoverflow.com/questions/23446635/how-to-download-http-directory-with-all-files-and-sub-directories-as-they-appear

北京联通烽火 HG260GS-U GPON 自行更换华为 HG8240 GPON(桥接路由拨号 + IPTV)

基本情况

设备 固件
HG260GS-U G00L 3.01
HG8240 回家查了再补上

折腾目标

  1. HG8240 替换 HG260GS-U(如果只是打算破解 HG260GS-U,可参考这个帖子
  2. HG8240 桥接路由拨号,楼主是 Netgear R6400
  3. 北京联通 IPTV 要能看,直播也要能看
  4. 楼主家没有固话,有固话可能会涉及到 SIP 或者 H264 配置

设置步骤

  1. 通过无线/有线连接 HG260GS-U 光猫,浏览器打开 http://192.168.1.1 并使用 user 账号登录后,打开 http://192.168.1.1/backupsettings.conf 把配置文件下载回来,大约 50-60kb 的样子,先复制一份做后悔药;
  2. 打开配置文件 backupsettings.conf(据说最好不要用 Windows 记事本,可能会自动添加 BOM 头造成配置文件损坏的问题。原谅楼主用的是苹果本,没有亲自试过),搜索 Telnet,把 <Enable>FALSE</Enable> 修改为 <Enable>TRUE</Enable>
    <Telnet>
    <Enable>TRUE</Enable>
    </Telnet>
    
  3. 浏览器打开 http://192.168.1.1/updatesettings.html 将改完的配置上传,光猫自动重启后,Telnet 功能已经开启;
  4. telnet 命令连接光猫,输入用户名 admin 和密码 admin 登录进去:
    telnet 192.168.1.1
    
  5. 查看 sn 并保存下来,后面会用到:
    get sn
    
  6. 打开 http://192.168.1.1状态——网络侧信息——WAN 口连接信息页面上各个端口的详细信息表格拍个照,后面需要我们手工设置到华为光猫里;
  7. 网线直连 HG8240 光猫,把电脑的有线连接 IP 修改为 192.168.100.2,子网掩码 255.255.255.0,网关 192.168.100.1
  8. 打开 http://192.168.100.1 使用用户名 telecomadmin 和密码 admintelecom 登录进去;
  9. LAN 设置里把 LAN1LAN4 都选中,点应用;
  10. 设置 TR069:在 WAN 配置里点击新建,选中使能,服务选 TR069,类型选路由,IP 获取方式选 PPPoE,用户名和密码在第 1 步得到的配置文件里,密码是用 base64 加密的,随便搜个在线工具解密就好,VLAN ID 和 802.1 优先级,按第 6 步拍的照片里对应的数字填;
  11. 设置网络:在 WAN 配置里点击新建,选中使能,服务选 INTERNET,类型选桥接,桥接类型选 PPPoE 桥接,LAN 口绑定 LAN1 到 LAN3,VLAN ID 和 802.1 优先级,按第 6 步拍的照片里对应的数字填;
  12. 没有固话的纯占位设置:在 WAN 配置里点击新建,选中使能,服务选 VOIP,类型选路由,VLAN ID 和 802.1 优先级,按第 6 步拍的照片里对应的数字填;
  13. 设置 IPTV:在 WAN 配置里点击新建,选中使能,服务选 INTERNET,类型选桥接,桥接类型选 IP 桥接,IP 获取方式选 DHCP多播 VLAN ID 一定要填,不然直播频道没法看,具体值也从第 1 步得到的配置文件里找,LAN 口绑定 LAN4,VLAN ID 和 802.1 优先级,按第 6 步拍的照片里对应的数字填;
  14. 用 telnet 命令连接光猫,输入用户名 root 和密码 admin 登录进去:
    telnet 192.168.100.1
    
  15. 设置 sn 为 HG260GS-U 的 sn:
    set sn snid <刚才保存下来的sn,输入的时候不要带这里的尖括号>
    
  16. 把光纤连接到 HG8240 上,LAN1 口用网线连接到路由器的 WAN 口;
  17. 进入路由器设置 PPPoE 拨号,拨号成功后就可以上网了;
  18. IPTV 机顶盒用网线连接到 HG8240 的 LAN4 口,敲黑板,是光猫的 LAN4 口,不是路由器的 LAN4,别弄错了;
  19. 没了,网能上,IPTV 也能看了;
  20. 哦对了,在系统工具里记得保存配置到 Flash,不然光猫重启后配置丢光光;

几条弯路

  1. HG260GS-U 的 web 管理后台,不管是用 CUAdmin 还是 fiberhomehg2x0 都已经无法登录了,修改配置文件开启隐藏账号都没有用,不用试了;
  2. HG260GS-U 广为流传的 http://192.168.1.1/logoffaccount.html 也没法打开了,不用试了;

iPhone 锁屏 WebSocket 断开后的自动重连 (JavaScript)

This is no exception either. Talk is cheap, I'll show you the code.

    var newSocket = function() {
        ws = new WebSocket(wsUri);
        ws.onopen = function(evt) {
            // send a request
            if ($('#tag').val().length > 0) {
                var req = {info: $('#tag').val()}
                ws.send(JSON.stringify(req))
            }
        }
        ws.onclose = function(evt) {
            reconnectSocket()
        }
        ws.onmessage = function(evt) {
            // do what you wanna do
        }
        ws.onerror = function(evt) {
        }
    };

    var reconnectSocket = function() {
        if (!ws || ws.readyState == WebSocket.CLOSED) {
            newSocket()
        }
    };

    $('#btn-go').click(function() {
        reconnectSocket()
        return false
    })

Go 语言 switch/case 的一个小坑

前几天竟然被 switch/case 坑了一小下,坦白讲,能掉进这个坑,纯粹是基本语法不过关,把 Go 当成 C++ 了。

下面是一个简化后的粟子,通过一个人的名字来判断我认不认识他,最初写下这段代码的期望结果是:如果 nameJohnKenny,把 i_knew_him 置为 true,表示我认识这两个人,别人(默认)不认识。熟悉 C++ 的同学一定知道我为什么这样写。

var i_knew_him bool = false
switch name {
case "John":
case "Kenny":
    i_knew_him = true
}

但我们现在写的是 Go 语言,执行结果不一样了(敲黑板

我的好朋友 John 迎面走了过来,我却假装不认识他,i_knew_him = true 根本没有执行到,因为这条表达式只属于 case "Kenny"……

正确的写法是什么样的呢?

case "John", "Kenny":
    i_knew_him  = true

详见 Go 语言规范

<全文完>