Music-dl: Listen to what you want

python库:Music-dl 是一个基于Python3的命令行工具,可以从多个网站搜索和下载音乐,方便寻找音乐,解决不知道哪个网站有版权的问题。工具的本意是聚合搜索,API 是从公开的网络中获得,不是破解版,也听不了付费歌曲。

功能

  • 部分歌曲支持无损音乐
  • 优先搜索高品质音乐(无损 -> 320K -> 128K)
  • 支持 HTTP 和 SOCKS 代理
  • 支持多线程搜索
  • 支持搜索结果去重和排序
  • 支持搜索关键字高亮
  • 支持下载歌词和封面(部分)

注意:仅支持Python3,建议使用 Python3.5 以上版本

安装

使用pip安装(推荐,注意前面有一个py):

$ pip3 install pymusic-dl

手动安装(最新):

$ git clone https://github.com/0xHJK/music-dl.git
$ cd music-dl
$ python3 setup.py install

不安装直接运行:

$ git clone https://github.com/0xHJK/music-dl.git
$ cd music-dl
$ pip3 install -r requirements.txt
$ ./music-dl

# 或 python3 music-dl

在以下环境测试通过:

系统名称系统版本Python版本
macOS10.143.7.0
macOS10.133.7.0
WindowsWindows 7 x643.7.2
WindowsWindows 10 x643.7.2
Ubuntu16.04 x643.5.2

使用方式

v3.0预览版命令有较大的改变,建议先查看帮助

$ music-dl --help
Usage: music-dl [OPTIONS]

  Search and download music from netease, qq, kugou, baidu and xiami.
  Example: music-dl -k "周杰伦"

Options:
  --version             Show the version and exit.
  -k, --keyword TEXT    搜索关键字,歌名和歌手同时输入可以提高匹配(如 空帆船 朴树)
  -u, --url TEXT        通过指定的歌曲URL下载音乐
  -p, --playlist TEXT   通过指定的歌单URL下载音乐
  -s, --source TEXT     Supported music source: qq netease kugou baidu
  -n, --number INTEGER  Number of search results
  -o, --outdir TEXT     Output directory
  -x, --proxy TEXT      Proxy (e.g. http://127.0.0.1:1087)
  -v, --verbose         Verbose mode
  --lyrics              同时下载歌词
  --cover               同时下载封面
  --nomerge             不对搜索结果列表排序和去重
  --help                Show this message and exit.
  • 默认搜索qq netease kugou baidu ,每个数量限制为5,保存目录为当前目录。
  • 指定序号时可以使用1-5 7 10的形式。
  • 默认对搜索结果排序和去重,排序顺序按照歌手和歌名排序,当两者都相同时保留最大的文件。
  • 无损音乐歌曲数量较少,如果没有无损会显示320K或128K。
  • 支持http代理和socks代理,格式形如-x http://127.0.0.1:1087-x socks5://127.0.0.1:1086

一键网易云签到+听歌300首

tools.wgudu.com

BLEU—机器翻译评价方法

Bleu[1]是IBM在2002提出的,用于机器翻译任务的评价,发表在ACL,引用次数10000+,原文题目是“BLEU: a Method for Automatic Evaluation of Machine Translation”。

它的总体思想就是准确率,假如给定标准译文reference,神经网络生成的句子是candidate,句子长度为n,candidate中有m个单词出现在reference,m/n就是bleu的1-gram的计算公式。

BLEU还有许多变种。根据n-gram可以划分成多种评价指标,常见的指标有BLEU-1、BLEU-2、BLEU-3、BLEU-4四种,其中n-gram指的是连续的单词个数为n。

BLEU-1衡量的是单词级别的准确性,更高阶的bleu可以衡量句子的流畅性。

计算公式:

分子释义

神经网络生成的句子是candidate,给定的标准译文是reference。

1) 第一个求和符号统计的是所有的candidate,因为计算时可能有多个句子,

2)第二个求和符号统计的是一条candidate中所有的n−gram,而 [公式] 表示某一个n−gram在reference中的个数。

所以整个分子就是在给定的candidate中有多少个n-gram词语出现在reference中。

分母释义

前两个求和符号和分子中的含义一样,Count(n-gram’)表示n−gram′在candidate中的个数,综上可知,分母是获得所有的candidate中n-gram的个数。

改进版的BLEU计算方法

改进思路:对于某个词组出现的次数,在保证不大于candidate中出现的个数的情况下,然后再reference寻找词组出现的最多次。

评价机器翻译结果通常使用BLEU(Bilingual Evaluation Understudy)。对于模型预测序列中任意的子序列,BLEU考察这个子序列是否出现在标签序列中。

具体来说,设词数为n的子序列的精度为pn​。它是预测序列与标签序列匹配词数为n的子序列的数量与预测序列中词数为n的子序列的数量之比。举个例子,假设标签序列为A、B、C、D、E、F,预测序列为ABB、C、D,那么p1=4/5,p2=3/4,p3=1/3,p4=0。设

lenlabel​和lenpred分别为标签序列和预测序列的词数,那么,BLEU的定义为

$$
\exp \left(\min \left(0,1-\frac{l e n_{\text {label }}}{l e n_{\text {pred }}}\right)\right) \prod_{n=1}^{k} p_{n}^{1 / 2^{n}}
$$
其中 \(k\) 是我们希望匹配的子序列的最大词数。可以看到当预测 序列和标签序列完全一致时,BLEU为 1 。
因为匹配较长子序列比匹配较短子序列更难,BLEU对匹配较长 子序列的精度赋予了更大权重。例如,当 \( p_{n} \) 固定在 \( 0.5 \) 时,随在 \( n \) 的增大, \( 0.5^{1 / 2} \approx 0.7,0.5^{1 / 4} \approx 0.84,0.5^{1 / 8} \approx$ $0.92,0.5^{1 / 16} \approx 0.96 \) 。另外,模型预测较短序列往往会得到 较高 \( p_{n} \) 值。因此,上式中连乘项前面的系数是为了惩罚较短的 输出而设的。举个例子,当 \(k=2 \) 时,假设标签序列为 A 、 B 、 C 、 D 、 E 、 F ,而预测序列为 A 、 B 。虽然 \( p_{1}=p_{2}=1 \) ,但惩罚系数 \( \exp (1-6 / 2) \approx 0.14\) , 因此BLEU也接近 0.14 。

python实现:

def bleu(pred_tokens, label_tokens, k):
    len_pred, len_label = len(pred_tokens), len(label_tokens)
    score = math.exp(min(0, 1 - len_label / len_pred))
    for n in range(1, k + 1):
        num_matches, label_subs = 0, collections.defaultdict(int)
        for i in range(len_label - n + 1):
            label_subs[''.join(label_tokens[i: i + n])] += 1
        for i in range(len_pred - n + 1):
            if label_subs[''.join(pred_tokens[i: i + n])] > 0:
                num_matches += 1
                label_subs[''.join(pred_tokens[i: i + n])] -= 1
        score *= math.pow(num_matches / (len_pred - n + 1), math.pow(0.5, n))
    return score

接下来,定义一个辅助打印函数:

def score(input_seq, label_seq, k):
    pred_tokens = translate(encoder, decoder, input_seq, max_seq_len)
    label_tokens = label_seq.split(' ')
    print('bleu %.3f, predict: %s' % (bleu(pred_tokens, label_tokens, k),
                                      ' '.join(pred_tokens)))

一些注意事项

一般给出的reference是4句话,之所以给出多个句子,是因为单个句子可能无法和生成的句子做很好地匹配。

比如”你好”,reference是”hello”,机器给出的译文是”how are you”,机器给出的词语每一个一个词匹配上这个reference,那么BLEU值是0,这显然是有问题的。所以reference越多样化,匹配成功概率越高。

torch模型的保存和读取

pytorch中模型的保存和读取:torch.load torch.save

1、读取tensor

我们可以直接使用save函数和load函数分别存储和读取Tensorsave使用Python的pickle实用程序将对象进行序列化,然后将序列化的对象保存到disk,使用save可以保存各种对象,包括模型、张量和字典等。而load使用pickle unpickle工具将pickle的对象文件反序列化为内存

import torch
from torch import nn

x = torch.ones(3)
torch.save(x, 'x.pt')
x2 = torch.load('x.pt')\

存储一个Tensor列表并读回内存。
y = torch.zeros(4)
torch.save([x, y], 'xy.pt')
xy_list = torch.load('xy.pt')
xy_list

存储并读取一个从字符串映射到Tensor的字典。

torch.save({'x': x, 'y': y}, 'xy_dict.pt')
xy = torch.load('xy_dict.pt')
xy

读写模型:

在PyTorch中,Module的可学习参数(即权重和偏差),模块模型包含在参数中(通过model.parameters()访问)。state_dict是一个从参数名称隐射到参数Tesnor的字典对象。

1、将模型和参数都保存和读取

torch.save(model, PATH)

model = torch.load(PATH)

2、只存储模型参数(state_dict)

torch.save(model.state_dict(), PATH) # 推荐的文件后缀名是pt或pth

加载:

model = TheModelClass(*args, **kwargs)

model.load_state_dict(torch.load(PATH))

圣诞快乐