• 记一次久违的重装Win10系统

    平时都有一个工具U盘,里面有各种工具,电脑有问题一般都能解决。前几天遇到一台电脑系统崩了,但我的工具U盘不在身边,另外是太久没遇到了,开始竟有点不知所措。后来尝试修复系统,不成功,唯有重装。在此记录一下过程,以备忘。

    一个新的引导设备还是需要的,例如一个空的U盘。

    先搞个 WinPE 吧。首先下载了 grub4dos,解压 grldr 等文件到根目录。然后忘了怎么写入 MBR 使U盘变成可启动。 grub4dos 里面有文档,阅读文档后发现其自带的 bootlace.com 可以完成这一任务,它可以在 DOS/Linux 下运行。我刚好有能用的 Linux 系统,运行

    sudo ./bootlace.com /dev/sdb1  # 根据实际情况修改路径

    即可。事后想起来用 bootice 会更方便。

    可以启动,写好 grub4dos 的 menu.lst 配置文件,把 WinPE 的 iso 文件放好,我用的是 wingwy-pe5.1-v1f1.iso(MD5为7F931189D41FE2B65FA07BE1B970F3A8),保证纯净、没有恶意代码。

    进了 PE 系统,mount Win10 的 iso,发现安装的时候又遇到了“我们无法创建新的分区,也找不到现有的分区”问题。改用 windows media creation tool 来创建一个最纯正的安装U盘,还是一样的问题。

    记得这个问题可以用安装器来解决。但是我还是选择先百度一波。发现可以用硬盘安装法,即提取 iso 的 boot文件夹、source文件夹、bootmgr文件到根目录即可。

    安装之前还想怎么备份原来的激活。百度告诉我,不需要备份,不需要填 key,可以直接安装。事实证明确实如此。

    搞了半天,最后发现其实只需要直接做硬盘安装,就完事了🤣。如果对于一个新的硬盘,在安装之前还需要另外用 bootice 设置一下 bootmgr 的引导,就可以安装了。

  • 用 Numba 加速你的 Python 代码,性能轻松大提升

    Numba 简介

    Numba 是 Python 的一个 JIT (just-in-time) 编译器,最适用于 NumPy 数组、函数,以及 Python 循环。基本上,用法就是给原来的 Python 函数加一个修饰器,当运行到经 Numba 修饰的函数时,它会被编译为机器码,之后再调用时,就能以机器码的速度来执行了。

    按我上手使用的经验来看,Numba 对原代码的改动不是太大,对能加速的部分,加速效果明显;对不支持的加速的 Python 语句/第三方库,可以选择不使用 numba 来规避。这是我选择 Numba 的原因。

    首先:应该编译(优化)什么?

    由于 Numba 本身的限制(稍后介绍),不能做到对整个程序完全的优化。实际上,也没必要这样做——只需要优化真正耗时间的部分即可。

    怎么找到真正耗时间的部分?除了靠直觉,还可以借用工具来分析,例如 Python 自带的 cProfile,还有 line_profiler 等,这里不再细讲。

    安装

    可以通过 conda 或 pip,一个命令安装:
    conda / pip install numba

    什么样的代码能加速?

    按照官方文档的示例代码,如果代码中含有很多数学运算、使用 NumPy,或者有不少 Python 的 for 循环(Python 性能大忌),那么 Numba 就能给你很好的效果。尤其是多重 for 循环,可以获得极大的加速。

    例如,下面这段代码,就能享受到 JIT:

    from numba import jit
    import numpy as np
    
    x = np.arange(100).reshape(10, 10)
    
    @jit(nopython=True)  # 设置为"nopython"模式 有更好的性能
    def go_fast(a):  # 第一次调用时会编译
        trace = 0
        for i in range(a.shape[0]):   # Numba likes loops
            trace += np.tanh(a[i, i]) # Numba likes NumPy functions
        return a + trace              # Numba likes NumPy broadcasting
    
    print(go_fast(x))

    但是,类似下面的代码,Numba 就没什么效果:

    from numba import jit
    import pandas as pd
    
    x = {'a': [1, 2, 3], 'b': [20, 30, 40]}
    
    @jit
    def use_pandas(a):  # 这个函数就加速不了
        df = pd.DataFrame.from_dict(a) # Numba 不支持 pd.DataFrame
        df += 1                        # Numba 也不支持这个
        return df.cov()                # 和这个
    
    print(use_pandas(x))

    总之,Numba 应付不了 pandas。以我的经验,需要把 DataFrame 转成 np.ndarray,再输入给 Numba。

    要强制用 nopython 模式

    刚才 work 的代码中,@jit(nopython=True) 这里传入了 nopython 这个参数,而不 work 的代码中,就没有这个参数。为什么呢?

    这是因为,@jit 实际上有两种模式,分为别 nopython 和 object 模式。只有 nopython 模式,才是能真正大幅加速的模式。而 nopython 模式只支持部分的 Python 和 NumPy 函数,如果运行时用到了不支持的函数/方法,程序就会崩掉 (例如刚才不能加速的例子) 。如果不强制设定 nopython 模式,编译函数失败时,会回退到 object 模式,程序虽然不会崩,但却偏离了我们给它加速的本意。

    我既然用了 Numba,我就希望它能真正地发挥作用。所以我选择强制开启 nopython ,如果不能加速,不如让它直接抛 exception。

    阅读更多…
  • 安利一个美股历史数据Python库:yfinance

    相比A股和港股,(免费的)美股的数据没有那么容易拿到,而适合Python的source/library就更少了。

    最近找到一个免费、轻量的Python库——yfinance。整个库只有几个文件,数据从yahoo下载,免费无限制。安装及使用教程见上面的链接。

    无需申请token,即装即用,和tushare一样方便,值得拥有。赶紧 pip install 一个吧。

    附上 github 上的一点使用文档:

    import yfinance as yf
    
    msft = yf.Ticker("MSFT")
    
    # get stock info
    msft.info
    
    # get historical market data
    hist = msft.history(period="max")
    
    # show actions (dividends, splits)
    msft.actions
    
    # show dividends
    msft.dividends
    
    # show splits
    msft.splits
    
    # show financials
    msft.financials
    msft.quarterly_financials
  • (PyTorch)使用 LSTM 预测时间序列(股票)

    目标

    学习使用 LSTM 来预测时间序列,本文中使用上证指数的收盘价。

    运行环境

    Python 3.5+, PyTorch 1.1.0, tushare

    数据获取与处理

    首先用 tushare 下载上证指数的K线数据,然后作标准化处理。

    import numpy as np
    import tushare as ts
    
    data_close = ts.get_k_data('000001', start='2018-01-01', index=True)['close'].values  # 获取上证指数从20180101开始的收盘价的np.ndarray
    data_close = data_close.astype('float32')  # 转换数据类型
    
    # 将价格标准化到0~1
    max_value = np.max(data_close)
    min_value = np.min(data_close)
    data_close = (data_close - min_value) / (max_value - min_value)
    原始数据:上证指数从2018-01-01到2019-05-24的收盘价(未标准化处理)

    把K线数据进行分割,每 DAYS_FOR_TRAIN 个收盘价对应 1 个未来的收盘价。例如K线为 [1,2,3,4,5], DAYS_FOR_TRAIN=3,那么将会生成2组数据:
    第1组的输入是 [1,2,3],对应输出 4;
    第2组的输入是 [2,3,4],对应输出 5。

    然后只使用前70%的数据用于训练,剩下的不用,用来与实际数据进行对比。

    DAYS_FOR_TRAIN = 10
    
    def create_dataset(data, days_for_train=5) -> (np.array, np.array):
        """
            根据给定的序列data,生成数据集
            
            数据集分为输入和输出,每一个输入的长度为days_for_train,每一个输出的长度为1。
            也就是说用days_for_train天的数据,对应下一天的数据。
    
            若给定序列的长度为d,将输出长度为(d-days_for_train+1)个输入/输出对
        """
        dataset_x, dataset_y= [], []
        for i in range(len(data)-days_for_train):
            _x = data[i:(i+days_for_train)]
            dataset_x.append(_x)
            dataset_y.append(data[i+days_for_train])
        return (np.array(dataset_x), np.array(dataset_y))
    
    dataset_x, dataset_y = create_dataset(data_close, DAYS_FOR_TRAIN)
    
    # 划分训练集和测试集,70%作为训练集
    train_size = int(len(dataset_x) * 0.7)
    
    train_x = dataset_x[:train_size]
    train_y = dataset_y[:train_size]
    
    # 将数据改变形状,RNN 读入的数据维度是 (seq_size, batch_size, feature_size)
    train_x = train_x.reshape(-1, 1, DAYS_FOR_TRAIN)
    train_y = train_y.reshape(-1, 1, 1)
    
    # 转为pytorch的tensor对象
    train_x = torch.from_numpy(train_x)
    train_y = torch.from_numpy(train_y)
    阅读更多…
  • 在 Google 云搭建深度学习平台

    大家都知道,Google有一个很方便的 Colab ,而且到目前为止,还是免费的,并且 GPU 和 TPU 也是免费的。那为什么还要自己搞呢?因为 Colab 每个 session 只能用12小时,之后环境和数据不会保留,并且也不能进一步自定义配置和性能。Google 云给新注册的用户提供了$300 USD的赠金,非常适合学生党和个人的小项目。下面就开始体验吧。

    创建用户

    如果还没有 Google Cloud 用户,前往 Google Cloud 注册一个。这里需要一张 Visa / Mastercard 信用卡,没有的话我也帮不了你..然后$300 USD额度就到手了。

    申请 GPU 额度

    一开始的用户是没有 GPU 额度的,就算创建了带 GPU 的实例,也不能启动。请参照申请提升配额的步骤提交申请,把 GPU 的 0 改为更大的数值。在此之前,平台应该会让你把用户升级为付费账号,也就是说,如果送的额度用完了,就会从你的信用卡扣钱(注意要省着用了)。申请提升配额的页面中写可能要一两天来处理申请,但是我提交之后一小时内就批了。

    阅读更多…
  • 使用 Z3 Solver 求解逻辑题

    Z3 是一个由 Microsoft Research 开发的定理求解器。它可以用在很多方面,如软/硬件的验证与测试、约束求解、混合系统的分析、安全、生物,以及求解几何等问题[1]。Z3 主要由 C++ 开发,但它支持被 .NET、C、C++、Java、Python 等语言调用。本文使用其 Python binding。

    在网上看到有不少解方程和约束条件的使用,我在此补充它在命题逻辑方面的例子。

    安装

    非Windows平台可尝试直接安装:

    pip install z3-solver

    Windows平台由于编译环境比较复杂,Pypi 中只有没这么新的版本,指定旧版本安装:

    pip install z3-solver==4.5.1.0.post2

    例题 1

    一军用仓库被窃,公安部门已掌握如下线索:①甲、乙、丙三人至少有一个是窃贼;②如甲是窃贼,则乙一定是同案犯;③盗窃发生时,乙正在影剧院看电影。由此可以推出( )。

    A.甲、乙、丙都是窃贼
    B.甲和乙都是窃贼
    C.丙是窃贼
    D.甲是窃贼

    阅读更多…
  • 一图流解释 Alpha-Beta 剪枝(Alpha-Beta Pruning)

    Alpha-Beta剪枝用于裁剪搜索树中不需要搜索的树枝,以提高运算速度。它基本的原理是:

    • 当一个 Min 节点的 β值≤任何一个父节点的α值时 ,剪掉该节点的所有子节点
    • 当一个 Max 节点的 α值≥任何一个父节点的β值时 ,剪掉该节点的所有子节点

    下面为只使用 MiniMax 和使用 Alpha-Beta 剪枝的简单对比。

    MiniMax search without alpha-beta pruning
    MiniMax search with alpha-beta pruning

    需要注意的是,剪枝的效果与树节点的访问顺序有关。

    Alpha-Beta剪枝的伪代码如下:

    Initialize MAX_VALUE(node,game,-∞,∞)
    
    function MAX_VALUE(state,game,α,β) returns the minimax value of state
        inputs: state, current state in game
                game, game description
                α, the best score for MAX along the path to state
                β, the best score for MIN along the path to state
    
        if CUTOFF_TEST(state) then return EVAL(state)
        for each s in SUCCESSORS(state) do
            α = MAX(α, MIN_VALUE(s,game,α,β))
            if α ≥ β then return β
        end
        return α
    
    function MIN_VALUE(state,game,α,β) returns the minimax value of state
        if CUTOFF-TEST(state) then return EVAL(state)
        for each s in SUCCESSORS(state) do
            β = MIN(β, MAX_VALUE(s,game,α,β))
            if α ≥ β then return α
        end
        return β

    下面用一个例子说明。规定从左节点开始展开。原搜索树为:

    阅读更多…
  • 使用 Python OpenCV 3.4.x 进行 SIFT 特征检测与匹配

    前言

    Harris算法和Shi-Tomasi 算法,由于算法原理,具有旋转不变性,在目标图片发生旋转时依然能够获得相同的角点。但是如果对图像进行缩放以后,再使用之前的算法就会检测不出来,如图:

    图像放大,窗口不变,导致检测结果发生变化

    在2004年,University of British Columbia 的 D.Lowe 在他的论文 Distinctive Image Features from Scale-Invariant Keypoints 中提出了一个新的算法,Scale Invariant Feature Transform (简称SIFT),它可以提取关键点及计算其描述符。OpenCV的文档指出这篇论文容易理解,推荐阅读。

    SIFT算法主要有4个步骤,详情请见文末的相关参考。

    流程

    1. 尺度空间极值检测(Scale-space Extrema Detection)
    2. 关键点定位(Keypoint Localization)
    3. 方向分配(Orientation Assignment)
    4. 关键点描述符(Keypoint Descriptor)
    阅读更多…
  • 霍夫变换(Hough Transform)

    简介

    霍夫变换(Hough Transform)最初用于检测图像中的直线或者圆等几何图形,主要应用在图像分析、计算机视觉和数字图像处理领域。后来经过拓展,可适用于任意图形的检测,及一些参数取值的检测。

    霍夫直线变换的基本思想

    如果两点 (xi, yi) 和 (xj, yj) 都在一条直线上,那么它们在x-y平面上有相同的斜率和y轴的截距。

    对于一个点 (xi, yi) ,经过直线 yi = axi + b,其中a为斜率,b为y轴截距。可以把该式改写为 b = (-xi)a+ yi ,使a为自变量,b为因变量,a可取[amin, amax],代入a可求出对应的b值。a和b的关系可以在参数空间(即a-b平面)上作图。把参数空间分隔为一个一个格子(累加器),然后把 (a, b) 对应的格子A(a, b) 加 1。
    也就是说,一个点可以使参数空间的一系列累加器都加 1。

    对于另外一个点 (xj, yj) ,把 yj = axj + b 改写为 b = (-xj)a+ yj ,作同样的操作,对应的一系列累加器加1。

    阅读更多…