Tech Blog

NeuralProphet深度学习版Prophet

NeuralProphet 负有盛名,是 Facebook开发的新一代 Prophet 时间序列预测框架,堪称时间序列预测神器。但是它的API使用,调参,原理不太为大家所知,我们会花几期文章和视频,我们将由浅入深,由实践至原理,揭开其神秘面纱。

NeuralProphet 继承了 Prophet 模块可接受性的特点,将预测的值分解到趋势、季节性、AR、事件(节日)几个模块。其中 AR 部分的神经网络实现由 AR-Net: A simple Auto-Regressive Neural Network for time-series 这篇论文详细描述。此外,NeuralProphet 整体用 PyTorch 重新实现,主要特性如下

  • 使用 PyTorch 的优化,性能比原始 Prophet 快不少
  • 引入 AR-Net 建模时间序列自回归,并配有非线性层
  • 自定义损失和指标
  • 滞后协变量(lagged covariates) 和 AR 本地上下文特性 (local context)

尽管 NeuralProphet 有不少优势,但是使用起来小问题不断,主要表现为文档不甚详细,API 设计的比较智能(隐晦),坑不少。这一期我们来实战体验一下,后续会深入代码和论文。

相关论文链接:

安装NeuralProphet

使用命令通过 pip 就可以安装 NeuralProphet。

1
pip install neuralprophet==0.5.0

如果在 Jupyter Notebook 中使用 NeuralProphet,最好安装实时版本,允许你实时可视化模型损失。

1
pip install neuralprophet[live]==0.5.0

要注意一点,安装 neuralprophet 会关联安装 Pytorch CPU版本库,如果你需要使用 GPU 或者不希望覆盖原有的 Pytorch 版本,请手动安装。

此外,MyEncyclopedia 和往常一样,为大家准备了一个 docker 镜像,预装最新的 NeuralProphet 库,镜像中还包含预下载的数据集和本文所有的 Jupyter Notebook 代码。大家关注 MyEncyclopedia公众号,执行下面命令后网页打开 http://localhost:8888/ 开箱即用

1
2
docker pull myencyclopedia/neuralprophet-tut
docker run -p 8888:8888 myencyclopedia/neuralprophet-tut bash -c 'jupyter notebook --port 8888 --NotebookApp.token='' --NotebookApp.password='' --ip 0.0.0.0 --allow-root'

标准普尔 500 指数数据集

这次实战我们使用过去 10 年标准普尔 500 指数的每日股价数据。可以通过如下命令下载数据集,使用 docker 镜像的同学无需额外下载。

1
2
3
4
5
6
7
8
9
import pandas_datareader as pdr
from datetime import datetime
import matplotlib.pyplot as plt
%matplotlib inlinestart = datetime(2010, 12, 13)
end = datetime(2020, 12, 11)
df_sp500 = pdr.get_data_fred('sp500', start, end)
plt.figure(figsize=(10, 7))
plt.plot(df_sp500)
plt.title('S&P 500 Prices')

从图中我们可以清楚地看到标准普尔 500 指数总体呈上升趋势,其中有几个点的价格大幅上涨或下跌。我们可以将这些点视为趋势变化点。鉴于此,我们先从一个仅有趋势模块的 NeuralProphet 模型开始,逐渐加入季节性,AR和节日模块,观察其预测表现和API 具体使用。

使用 NeuralProphet,我们必须确保数据的格式包含如下两列:日期列名ds,目标变量列名 y

1
df_sp500 = df_sp500.reset_index().rename(columns={'DATE': 'ds', 'sp500': 'y'})

1
2
len(df_sp500[~df_sp500.y.isnull()])
>>> 2007

总结 SP 500 数据观察到的特点,后面会反复和过程变量做对比:

  • 总共2080条数据中非空数据有2007

  • 开始日期为 2012-12-24,结束日期 2020-12-11

  • 在上述有效时间段内,非交易的日期(周末,节日)没有在列。

模块一:趋势

使用 NeuralProphet,我们可以通过指定几个重要参数来对时间序列数据中的趋势进行建模。

  • n_changepoints — 指定趋势发生变化的点数。
  • trend_reg — 控制趋势变化点的正则化参数。较大的值 (~1–100) 将惩罚更多的变化点。较小的值 (~0.001–1.0) 将允许更多的变化点。
  • changepoints_range — 默认值 0.8,表示后20%的训练数据无 changepoints
1
2
3
4
5
6
model = NeuralProphet(n_changepoints=100,
trend_reg=0.05,
yearly_seasonality=False,
weekly_seasonality=False,
daily_seasonality=False,
epochs=100)

训练模型

1
df_train, df_val = model.split_df(df_sp500, freq="D", valid_p=0.2)
1
2
3
4
5
metrics = model.fit(df_train,
freq='D',
validation_df=df_val,
progress="plot"
)

训练最终趋于稳定。我们来看看 split_df API 的细节。

df_train 共1606 行,为前 80% 记录,df_val 共401 行,为后20% 记录,两者没有交集,合计 2007 行数据,等于 df_sp500 有效数据数。原来默认情况下 split_df 会扔掉 y 值为 NaN 数据。这里两者没有交集,大家注意对比启用AR后的数据切分两者会有交集。原有是启用自回归后,预测需要过去 k 个点作为输入。

预测验证集

接着来看看验证集,即 df_val 上的预测表现。

1
2
3
4
future = model.make_future_dataframe(df_sp500, periods=60, n_historic_predictions=True)
forecast = model.predict(future)
fig = model.plot(forecast)
fig.show()

make_future_dataframe 准备好待预测的数据格式,参数 periods=60n_historic_predictions=True 意义扩展 df_sp500 到未来60天后,同时保留所有所有现有 df_sp500 的数据点,这些历史点也将做预测。我们 dump 出 make_future_dataframe 后的 future 变量。

future 序列扩展了 df_sp500,有 y 值的共2007条,和 df_sp500 一致。时间扩展到了 2021-02-09,大约是 2021-12-11 后的60天,这个也和总条数 2140 一致,等于 df_sp500 总条数 2080 加上 periods=60 的部分。

接着来看 predict 后的 forecast 变量。y 列依然有 2007 条,多了 yhat1 和 trend 两列。

最后,model.plot(forecast) 会绘制出事实点和预测点的曲线,注意图中预测值比实际值要稍长一些,因为预测值到 2021-02-09,实际值仅到 2020-12-11

模块归因

1
fig_components = model.plot_components(forecast)

由于只启用了趋势,只有一个模块输出。

很明显,我们的模型捕捉到了标准普尔 500 指数的总体上涨趋势,但该模型存在欠拟合问题,尤其是当我们查看未知未来的60天的预测,更能发现问题。

仅预测未来

同样的预测代码,将n_historic_predictions 改成 False 会只预测未知未来60天。

1
2
3
4
future = model.make_future_dataframe(df_sp500, periods=60, n_historic_predictions=False)
forecast = model.predict(future)
fig = model.plot(forecast)
fig.show()

1
2
print(len(future), len(forecast))
>>> 60 60

根据上图,我们可以看到模型对未来的预测遵循一条直线,天天上涨的股票,还在这里看什么,还不赶紧去买!

模块二:季节性

真实世界的时间序列数据通常涉及季节性模式。即使对于股票市场也是如此,一月效应等趋势可能会逐年出现。我们可以通过添加年度季节性来使之前的模型更加完善。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
model = NeuralProphet(n_changepoints=100,
trend_reg=0.05,
yearly_seasonality=True,
weekly_seasonality=False,
daily_seasonality=False,
epochs=100)

df_train, df_val = model.split_df(df_sp500, freq="D", valid_p=0.2)

metrics = model.fit(df_train,
freq='D',
validation_df=df_val,
progress="bar"
)

预测验证集

和之前一条直线相比,现在对数据的预测显得更现实些。

模块归因

现在预测的 Y 值是两个部分的模块的加和了。

1
fig_components = model.plot_components(forecast)

标准普尔 500 指数预测具有年度季节性,包括历史数据。

仅预测未来

1
plot_forecast(model, sp500_data, periods=60, historic_predictions=False, highlight_steps_ahead=60)

根据上图,我们可以看到这个模型更真实一些,但仍然存在欠拟合问题。因此,我们再引入自回归模型 AR 来进一步拟合。

模块三:自回归 AR

AR-Net 是一种用于时间序列预测的自回归神经网络。自回归模型使用来自过去历史数据点来预测后续点,这就是自回归一词的来源。

例如,为了预测标准普尔 500 指数的价格,我们可以训练一个模型,使用过去 60 天的价格来预测未来 60 天的价格。分别对应以下代码中的n_lagsn_forecasts参数。

1
2
3
4
5
6
7
8
9
10
11
12
model = NeuralProphet(
n_forecasts=60,
n_lags=60,
changepoints_range=0.95,
n_changepoints=100,
yearly_seasonality=True,
weekly_seasonality=False,
daily_seasonality=False,
batch_size=32,
epochs=100,
learning_rate=1.0,
)

训练模型

1
2
3
4
5
6
df_train, df_val = model.split_df(df_sp500, freq="D", valid_p=0.2)
metrics = model.fit(df_train,
freq='D',
validation_df=df_val,
progress="plot"
)

切分训练和验证集代码一样,但是由于引入 AR,df_traindf_val 之间有60条数据重合,这是因为,在验证或者预测过程中,传入的 dataframe 前60条不做预测,从61条开始预测,预测会使用当前日期前60条作为 AR 模块的输入。

1
2
len(set(df_train.ds.tolist()).intersection(set(df_val.ds.tolist())))
>>> 60

不过奇怪的是,df_train 加上 df_val 总共有 2305 + 665 = 2970 条记录,时间跨度依然是 2012-12-24 至 2020-12-11。但是去除重复的60条记录后居然剩余2910 条, 比 df_sp500 2080 条记录数还要多不少。

这里笔者稍微花了点时间终于弄清楚:df_traindf_val 会填充 2012-12-24 至 2020-12-11 所有的 missing 日期,并使用插值填充 y!

预测验证集

这一次,我们将 periods 设成 0,也就是不扩展 df_sp500 时间到未知的未来。

1
future = model.make_future_dataframe(df_sp500, periods=0, n_historic_predictions=True)

1
forecast = model.predict(future)

forecast 格式变得复杂,引入了 yhat1, yhat2, ...,yhat60,ar1, ar2, ...,ar60 等众多列,这里的60对应于 n_forecasts=60

第一个预测值开始于 forecast 的第61条记录,对应于 n_lags = 60

1
forecast[~forecast.yhat1.isnull()]

1
2
fig = model.plot(forecast)
fig.show()

模块归因

1
fig_components = model.plot_components(forecast)

仅预测未来

1
2
3
4
future = model.make_future_dataframe(df_sp500, periods=60, n_historic_predictions=False)
forecast = model.predict(future)
fig = model.plot(forecast)
fig.show()

模块四:事件(节日)

我们还可以配置模型以考虑节假日因素,因为节假日很可能会影响股市走势。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
model = NeuralProphet(
n_forecasts=60,
n_lags=60,
changepoints_range=0.95,
n_changepoints=100,
yearly_seasonality=True,
weekly_seasonality=False,
daily_seasonality=False,
batch_size=32,
epochs=100,
learning_rate=1.0,
)

model = model.add_country_holidays("US", mode="additive", lower_window=-1, upper_window=1)

只需 add_country_holidays 一条语句就可以启用预定义的美国节假日。

1
plot_forecast(model, sp500_data, periods=60, historic_predictions=False, highlight_steps_ahead=60)

预测验证集

模块归因

1
fig_components = model.plot_components(forecast)

仅预测未来

1
2
3
4
future = model.make_future_dataframe(df_sp500, periods=60, n_historic_predictions=False)
forecast = model.predict(future)
fig = model.plot(forecast)
fig.show()

在入门机器人视觉和机器人运动后,开始逐步接触到了3D计算机视觉中的高阶数学概念,包括三维物体到二维图片的变换(术语称之为射影几何);三维欧氏空间的物体运动坐标系变换,分为主动变换(active transformations)和被动变换(passive transformation);另外在更高阶的计算机渲染中常会用到Mesh和黎曼曲面;此外,几何深度学习(Geometric Deep Learning)中也涉及到群论,李群等。这些迷之概念使得我对于本科高等数学课程(多元微积分,线性代数,概率论)后面的纯数学感到兴趣。本来一直觉得纯数学会非常难学,但是当我写了很多年代码和阅读了多个AI领域的众多论文之后,总有一些本质问题萦绕在心,得不到解释:

  • 代码抽象的极限在哪里?高阶纯函数编程?
  • 深度学习多个领域(CV,NLP,RL,GNN)是否有统一视角?目前深度学习的论文汗牛充栋,既有很多相似的pattern,也有每个领域的特性,是否有通用设计原则

第一个问题在范畴论(category theory)中广泛探讨,不过范畴论过于深奥,是抽象代数后的一门纯函数编程的理论基础。第二个问题在几何深度学习中被探讨。不过,这两个问题肯定不会被完全回答,但是,即使无法得到最好的解释和回答,就如同统计学中频率派和贝叶斯派各有所长,没有公认的一家通吃,但是对于这些根本问题的探究的阶段性成功也是非常有意义的。正如理查德·费曼的名言:

I would rather have questions that can't be answered than answers that can't be questioned

鉴于AI从业人员乃至程序员进阶掌握高阶数学的武器,我斗胆总结一份从我这个非数学系的理工毕业生角度出发的自学纯数学指南。以下所有课程视频都已经搬运到了我的B站频道(MyEncyclopedia公号)中,此外,视频课程有对应教材的也一并列出。

在学习这些知识时候,发现至今的联系是非常广泛的,这个倒是非常出乎我意料,也让学习非常有成就感。以下总结了若干贯穿所有领域的重要概念。

  • 群的最一般概念和离散数学群
  • 群论体系下构建的抽象代数结构
  • 有限维向量空间的线性映射和基变换,并且此视角下的矩阵(线性代数)理解
  • 从基变换的角度理解傅里叶变换,即傅里叶变换是函数表示的特殊的基。
  • 有限维向量空间上定义了距离(内积空间)后,向量空间有了几何结构。
  • 从线性映射推广到多变量线性映射(multilinear map),这是张量(Tensor)的数学意义
  • 从离散数学群论到连续函数映射,形成了微分流形(Differential Manifold)的概念。在此基础上进而发展出了李群,本质是为了解决例如旋转矩阵群虽然在乘法上封闭(因此组成群)但是在加法上不封闭的问题。
  • 一般群论扩展出范畴论,这是函数式编程的数学原理。

学习顺序

下图为我推荐的课程学习顺序。

当对张量和李群掌握充分后,原则上可以更上一层楼,学习广义相对论和量子力学。不过我并没有计划涉足这两个艰深的领域,也就不多言了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
graph TD;
map[高等线性代数] -->abs;
map[高等线性代数] -->T[Tensor];
group[群论]-->abs[抽象代数];
abs-->C[范畴论];
map-->F;
F-->W[小波变换];
F-->FA[泛函分析];
abs-->F[傅里叶变换];
T-->m[Manifold];
m-->L[李群];
T-->L;
L-->G[广义相对论];
L-->Q[量子力学];
1
2
3
4
5
6
7
8
9
graph TD;
map[高等线性代数] -->T[Tensor];
T-->m[Manifold];
m-->L[李群];
T-->L;
T-->G;
T-->Q;
L-->G[广义相对论];
L-->Q[量子力学];

线性映射下的高等线性代数

【Sheldon Axler】线性代数应该这样学

B站链接

https://www.bilibili.com/video/BV1Dm4y1c7Cn

评价

本课程的教师是配套同名教材线性代数应该这样学Linear Algebra Done Right)这本书的作者。课程和教材都是从线性映射(linear map)角度来看待矩阵。由最基本的向量空间和内积空间定义出发导出对偶空间(Dual Space),特征值,特征根,对角矩阵,正交基,直到最核心的谱论(Spectral theorem)。 此课程说实话不适宜第一次学线性代数的同学。同时,不适合数学系的,因为跟高代相比太浅;不适合工程类的,因为太深而且没有跟应用联系起来。但是,本书却广受赞誉,中文也有翻译本。其最大的特点是通过空间变换和矩阵联系起来,从最基本的定义导出矩阵中的最核心概念:特征值,特征根,对角矩阵,正交基等。

配套教材

【Nathaniel Johnston】 Advanced Linear Algebra

B站链接

https://www.bilibili.com/video/BV1uV4y157XE

Nathaniel Johnston Advanced Linear Algebra

评价

课程关于线性映射背后的基变换等讲述的非常清楚。不过对比Nathaniel Johnston的教材Advanced Linear Algebra and Matrix Algebra来说,视频课程只涉及到教材的一二章的内容,但并没有涉及到第三章Tensor的部分,有点可惜。视频包含很多向量空间和线性映射的例子和证明,可以作为线性代数应该这样学的很好补充。同时推荐教材第三章Tensor,适合作为Tensor概念的入门理论学习。

配套教材

【Matthew Macauley】Advanced Linear Algebra Math

B站链接

https://www.bilibili.com/video/BV1Me4y1a7Uk

Advanced Linear Algebra Math 4120 Modern Algebra, Matthew Macauley @ Clemson

评价

Matthew Macauley教授讲课节奏条理都很赞,示例也比较充足,他的多个数学课程都很棒,尤其是下面群论部分的Visual Group Theory最为经典。本课程可以作为上述两门自成体系的课程很好的补充,尤其是Tensor作为multilinear map的部分。课程对应教材为Peter Lax的经典老教材线性代数及其应用

配套教材

群论,抽象代数

【Matthew Macauley】可视化群论

B站链接

https://www.bilibili.com/video/BV1ka411378X

Visual Group Theory Math 4120 Modern Algebra, Matthew Macauley @ Clemson

配套教材

评价

课程基于Nathan Carter负有盛名的Visual Group Theory 这本非常非常棒的群论入门书。视频课程本身在教材的基础上补充了不少例子和定理证明,使抽象难以理解的群里严重降低了入门难度。我作为同时仔细看过视频和教材的读者,觉得视频课程有以下几个优势:首先是建立概念时一步一步带你walk through,比如最核心的群同态概念,使得概念的建立更加深刻形象;其次课程补充了不少代数方法的严格证明,有的时候,代数方法比视觉方法更显示了问题的本质和联系。强烈推荐视频和教材,因为群论是现代数学的基石。

【哈佛Benedict Gross】抽象代数

B站链接

https://www.bilibili.com/video/BV1Yt4y1F72S

【Harvard MATH E-222】 Abstract Algebra (Benedict Gross)

评价

很老的课程了,对应的教材为经典的 Michael Artin代数。学完本视频和配套教材会对抽象代数有扎实深入的理解。

配套教材

张量

eigenchris 系列

B站链接

  • 【eigenchris】 Tensors for Beginners https://www.bilibili.com/video/BV1zW4y1n7Cy

  • 【eigenchris】 Tensor Calculus https://www.bilibili.com/video/BV1Ae4y167ty

【eigenchris】 Tensors for Beginners

【eigenchris】 Tensor Calculus

评价

eigenchris 的 tensor 入门系列讲的应该是最好理解的,举了很多具体的例子,例如关于重要的概念行向量作为covector。可惜

XylyXylyX

B站链接

【XylyXylyX】 What is a Tensor https://www.bilibili.com/video/BV1NK411Q7p4

【XylyXylyX】 What is a Tensor

相关教材

并非上述两个视频课程的配套教材,我找到一些市面上不错的纯 Tensor 类入门书籍

李群

如之前所说,李群的本质是为了解决例如旋转矩阵群虽然在乘法上封闭(因此组成群)但是在加法上不封闭的问题。因为在做优化或者其他运算时,旋转代表的矩阵必然用到矩阵加法。李群的解决方式是将小量上的映射到李空间上做完运算后映射回李群。不过一般李群过于复杂,学习内容过于庞大,因此简单的入门李群本身也比较困难。

XylyXylyX

B站链接

【XylyXylyX】 Lie Groups and Lie Algebras] https://www.bilibili.com/video/BV1Z14y1j78c

【XylyXylyX】 Lie Groups and Lie Algebras

评价

XylyXylyX的李群视频是众多李群入门中比较不错的,有不少重复,适合初学。配套 Robert Gilmore的如下教材(教材后面部分过于复杂)。

配套教材

Jonathan Evans

B站链接

【Jonathan Evans】 Lie Groups and Lie Algebras

配套教材

视频有专门一节推荐了众多不错的教材,不过李群这个领域过于深奥,我也只是刚入门。因此在此仅列其一:Springer 的GTM(研究生数学系列)表示理论

傅里叶变换

傅里叶变换的本质是将函数分解成一组相对卷积算子的对角化基,是进阶泛函分析的重要概念。

【斯坦福 Brad Osgood】傅里叶变换和应用

B站链接

【Stanford】 The Fourier Transforms and its Applications

配套教材

可由下方地址下载 https://see.stanford.edu/materials/lsoftaee261/book-fall-07.pdf

微分流形

XylyXylyX

B站链接

【XylyXylyX】What is a Manifold

程序员的范畴论

B站链接

【Bartosz Milewski】 Category Theory for Programmers

【Bartosz Milewski】 Category Theory for Programmers II

【Bartosz Milewski】 Category Theory for Programmers III

配套教材

其他

B站链接

【NJ Wildberger】 Famous Math Problems

如果你是一个重度论文阅读者,一定会在自己的笔记本上全副武装。但是也许只是偶尔,也会心血来潮地在手机端查看一篇论文,此时,你打开的这篇从 Arxiv 下载的论文,就像下图上半部分所示,时间稍长,便会觉得文字,公式和图片不忍直视。你多么希望在手机端查看PDF,也像图中下半部分一样重新排版来轻松阅读。

Arxiv 论文手机智能重排和阅读服务

现在,MyEncyclopedia 推出了智能的手机端重排和阅读 arxiv 论文服务。手机端只需浏览器甚至在微信中就能将指定的 arxiv 论文重排成适应移动端的格式,并在线浏览。

具体效果如下

微信操作步骤

下面,以手机微信为例,讲解详细步骤。其他浏览器可以直接点击 https://mydoc.myencyclopedia.top/app,操作步骤类似。

  • 进入 MyEncyclopedia 公众号,回复 ? 点击 AI在线服务

  • 拷贝显示的口令

  • 返回到公众号后回复口令,登录使用服务

  • 输入 Arxiv ID,点击 Go to Page

  • 在新页面点击 Convert Html

  • 等待大约十几分钟,再次进入服务页面,此时,若下载转换任务成功,出现如下页面,点击View Html,即可在微信浏览器中完美查看论文了。

PDF 论文双列切割成单列服务

此外,也提供将 arxiv PDF从双列切割成单列服务。即上图中的Convert PDF 按钮,切割后的PDF文件可以在线浏览,或者下载到手机离线查看。也欢迎大家尝试。

斯坦福大学的 CS 课程上线了一门经典课程:《CS 25: Transformers United》。自 2017 年推出以来,Transformer 彻底改变了自然语言处理 (NLP)领域。现在,Transformer 在深度学习中被广泛使用,无论是计算机视觉 (CV)、强化学习 (RL)、生成对抗网络 (GAN)、语音甚至是生物学。除此之外,Transformer 还能够创建强大的语言模型(如 GPT-3),并在 AlphaFold2 中发挥了重要作用,该算法解决了蛋白质折叠问题。

目前这门课程在 Youtube 上日更连载中,地址为 https://www.youtube.com/playlist?list=PLoROMvodv4rNiJRchCzutFw5ItR_Z27CM

MyEncyclopedia Bilibili 为大家每日搬运同步视频,至今天7/16日已经有6集

明星讲课阵容

在今天公布的第一节课中,讲师为斯坦福大学硕士生 Divyansh Garg、软件工程师 Chetanya Rastogi(毕业于斯坦福大学)、软件工程师 Advay Pal(毕业于斯坦福大学)。

此外,第一节课的指导教授为 Christopher Manning,他是斯坦福大学计算机与语言学教授,也是将深度学习应用于自然语言处理领域的领军者。

从之前的课程描述来看,CS 25 课程邀请了来自不同领域关于 Transformer 研究的前沿人士进行客座讲座。OpenAI 的研究科学家 Mark Chen,主要介绍基于 Transformers 的 GPT-3、Codex;Google Brain 的科学家 Lucas Beyer,主要介绍 Transformer 在视觉领域的应用;Meta FAIR 科学家 Aditya Grover,主要介绍 RL 中的 Transformer 以及计算引擎等。

值得一提的是,AI 教父 Geoff Hinton 也带来了一次讲座。

课程明细

1. (Sep 20) Introduction to Transformers

Recommended Readings:

2. (Sept 27) Transformers in Language: GPT-3, Codex

Speaker: Mark Chen (OpenAI)

Recommended Readings: - Language Models are Few-Shot Learners
- Evaluating Large Language Models Trained on Code

3. (Oct 4) Applications in Vision

Speaker: Lucas Beyer (Google Brain)

Recommended Readings: - An Image is Worth 16x16 Words (Vision Transfomer)
- Additional Readings:
- How to train your ViT?

4. (Oct 11) Transformers in RL & Universal Compute Engines

Speaker: Aditya Grover (FAIR)

Recommended Readings: - Pretrained Transformers as Universal Computation Engines
- Decision Transformer: Reinforcement Learning via Sequence Modeling

5. (Oct 18) Scaling transformers

Speaker: Barret Zoph (Google Brain) with Irwan Bello and Liam Fedus

Recommended Readings: - Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity
- ST-MoE: Designing Stable and Transferable Sparse Expert Models

6. (Oct 25) Perceiver: Arbitrary IO with transformers

Speaker: Andrew Jaegle (DeepMind)

Recommended Readings: - Perceiver: General Perception with Iterative Attention
- Perceiver IO: A General Architecture for Structured Inputs & Outputs

7. (Nov 1) Self Attention & Non-Parametric Transformers

Speaker: Aidan Gomez (University of Oxford)

Recommended Readings: - Self-Attention Between Datapoints: Going Beyond Individual Input-Output Pairs in Deep Learning

8. (Nov 8) GLOM: Representing part-whole hierarchies in a neural network

Speaker: Geoffrey Hinton (UoT) Recommended Readings:

9. (Nov 15) Interpretability with transformers

Speaker: Chris Olah (AnthropicAI)

Recommended Readings: - Multimodal Neurons in Artificial Neural Networks Additional Readings: - The Building Blocks of Interpretability

10. (Nov 29) Transformers for Applications in Audio, Speech and Music: From Language Modeling to Understanding to Synthesis

Speaker: Prateek Verma (Stanford)

在这一期中,我们延续上一期 Bert 中文短句相似度计算 Docker CPU镜像,继续使用 huggingface transformersentence-transformer 类库,并将英语句子生成 bert embedding,然后引入 faiss 类库来建立索引,最后查询最接近的句子。

Docker 镜像获取方式

本期 docker 镜像获取方式为,关注 MyEncyclopedia 公众号后回复 docker-faiss-transformer 即可获取如下完整命令。

1
docker run -p 8888:8888 myencyclopedia/faiss-demo bash -c 'jupyter notebook --allow-root --port 8888 --NotebookApp.token= --ip 0.0.0.0'

然后打开浏览器,输入 http://localhost:8888/notebooks/faiss_demo.ipynb

faiss 简介

Faiss 的全称是Facebook AI Similarity Search,是由 Facebook 开发的适用于稠密向量匹配的开源库,作为向量化检索开山鼻祖,Faiss 提供了一套查询海量高维数据集的解决方案,它从两个方面改善了暴力搜索算法存在的问题:降低空间占用和加快检索速度。此外,Faiss 提供了若干种方法实现数据压缩,包括 PCA、Product-Quantization等。

Faiss 主要特性:

  • 支持相似度检索和聚类;
  • 支持多种索引方式;
  • 支持CPU和GPU计算;
  • 支持Python和C++调用;

Faiss 使用流程

使用 faiss 分成两部,第一步需要对原始向量建立索引文件,第二步再对索引文件进行向量 search 操作。

在第一次建立索引文件的时候,需要经过 trainadd 两个过程;后续如果有新的向量需要被添加到索引文件,只需要一个 add 操作来实现增量索引更新,但是如果增量的量级与原始索引差不多的话,整个向量空间就可能发生了一些变化,这个时候就需要重新建立整个索引文件,也就是再用全部的向量来走一遍 trainadd,至于具体是如何 trainadd的,就和特定的索引类型有关了。

1. IndexFlatL2 & indexFlatIP

对于精确搜索,例如欧式距离 faiss.indexFlatL2 或 内积距离 faiss.indexFlatIP,没有 train 过程,add 完直接可以 search

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import faiss 

# 建立索引, 定义为dimension d = 128
index = faiss.IndexFlatL2(d)

# add vectors, xb 为 (100000,128)大小的numpy
index.add(xb)
print(index.ntotal)
# 索引中向量的数量, 输出100000

# 求4-近邻
k = 4
# xq为query embedding, 大小为(10000,128)
D, I = index.search(xq, k)
## D shape (10000,4),表示每个返回点的embedding 与 query embedding的距离,
## I shape (10000,4),表示和query embedding最接近的k个物品id,
print(I[:5])

2. IndexIVFFlat

IndexFlatL2 的结果虽然精确,但当数据集比较大的时候,暴力搜索的时间复杂度很高,因此我们一般会使用其他方式的索引来加速。比如 IndexIVFFlat,将数据集在 train 阶段分割为几部分,技术术语为 Voronoi Cells,每个数据向量只能落在一个cell中。Search 时只需要查询query向量落在cell中的数据了,降低了距离计算次数。这个过程本质就是高维 KNN 聚类算法。search 阶段使用倒排索引来。

IndexIVFFlat 需要一个训练的阶段,其与另外一个索引 quantizer 有关,通过 quantizer 来判断属于哪个cell。IndexIVFFlat 在搜索阶段,引入了nlist(cell的数量)与nprob(执行搜索的cell数)参数。增大nprobe可以得到与brute-force更为接近的结果,nprobe就是速度与精度的调节器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import faiss
nlist = 100
k = 4

# 建立索引, 定义为dimension d = 128
quantizer = faiss.IndexFlatL2(d)

# 使用欧式距离 L2 建立索引。
index = faiss.IndexIVFFlat(quantizer, d, nlist, faiss.METRIC_L2)

## xb: (100000,128)
index.train(xb)
index.add(xb)
index.nprobe = 10 # 默认 nprobe 是 1 ,可以设置的大一些试试
D, I = index.search(xq, k)
print(I[-5:]) # 最后五次查询的结果

3. IndexIVFPQ

IndexFlatL2 和 IndexIVFFlat都要存储所有的向量数据。对于超大规模数据集来说,可能会不大现实。因此IndexIVFPQ 索引可以用来压缩向量,具体的压缩算法就是 Product-Quantization,注意,由于高维向量被压缩,因此 search 时候返回也是近似的结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import faiss

nlist = 100
# 每个向量分8段
m = 8
# 求4-近邻
k = 4
quantizer = faiss.IndexFlatL2(d) # 内部的索引方式依然不变
index = faiss.IndexIVFPQ(quantizer, d, nlist, m, 8) # 每个向量都被编码为8个字节大小
index.train(xb)
index.add(xb)
index.nprobe = 10
D, I = index.search(xq, k) # 检索
print(I[-5:])

在本期中,我们仅使用基本的 IndexIVFFlat 和 IndexFlatIP 完成 bert embedding 的索引和搜索,后续会有篇幅来解读 Product-Quantization 的论文原理和代码实践。

ag_news 新闻数据集

ag_news 新闻数据集 3.0 包含了英语新闻标题,training 部分包含 120000条数据, test 部分包含 7600条数据。

ag_news 可以通过 huggingface datasets API 自动下载

1
2
3
4
5
6
7
8
9
10
def load_dataset(part='test') -> List[str]:
ds = datasets.load_dataset("ag_news")
list_str = [r['text'] for r in ds[part]]
return list_str

list_str = load_dataset(part='train')
print(f'{len(list_str)}')
for s in list_str[:3]:
print(s)
print('\n')

显示前三条新闻标题为

1
2
3
4
5
6
7
8
9
120000
Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\band of ultra-cynics, are seeing green again.


Carlyle Looks Toward Commercial Aerospace (Reuters) Reuters - Private investment firm Carlyle Group,\which has a reputation for making well-timed and occasionally\controversial plays in the defense industry, has quietly placed\its bets on another part of the market.


Oil and Economy Cloud Stocks' Outlook (Reuters) Reuters - Soaring crude prices plus worries\about the economy and the outlook for earnings are expected to\hang over the stock market next week during the depth of the\summer doldrums.

sentence-transformer

和上一期一样,我们利用sentence-transformer 生成句子级别的embedding。其原理基于 Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks (https://arxiv.org/abs/1908.10084)这篇论文。基本思想很直接,将句子中的每个词的 bert embedding ,输进入一个池化层(pooling),例如选择最简单的平均池化层,将所有token embedding 的均值作为输出,便得到跟输入句子长度无关的一个定长的 sentence embedding。

结果展示

数据集 train 部分由于包含的样本比较多,需要一段时间生成 bert embedding,大家可以使用 load_dataset(part='test') 来快速体验。下面我们演示一个查询 how to make money 的最接近结果。

1
2
3
4
index = load_index('news_train.index')
list_id = query(model, index, 'how to make money')
for id in list_id:
print(list_str[id])
1
2
3
4
5
6
7
8
9
Profit From That Traffic Ticket Got a traffic ticket? Can't beat 'em? Join 'em by investing in the company that processes those tickets.

Answers in the Margins By just looking at operating margins, investors can find profitable industry leaders.

Types of Investors: Which Are You? Learn a little about yourself, and it may improve your performance.

Target Can Aim High Target can maintain its discount image while offering pricier services and merchandise.

Finance moves Ford into the black US carmaker Ford Motor returns to profit, as the money it makes from lending to customers outweighs losses from selling vehicles.

核心代码

所有可运行代码和数据都已经包含在 docker 镜像中了,下面列出核心代码

建立索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def train_flat(index_name, id_list, embedding_list, num_clusters):
import numpy as np
import faiss

dim = 768
m = 16

embeddings = np.asarray(embedding_list)

quantiser = faiss.IndexFlatIP(dim)
index = faiss.IndexIVFFlat(quantiser, dim, num_clusters, faiss.METRIC_INNER_PRODUCT)
index.train(embeddings) ## clustering

ids = np.arange(0, len(id_list))
ids = np.asarray(ids.astype('int64'))

index.add_with_ids(embeddings, ids)
print(index.is_trained)
print("Total Number of Embeddings in the index", index.ntotal)
faiss.write_index(index, index_name)

查询结果

1
2
3
4
5
6
7
def query(model, index, query_str: str) -> List[int]:
topk = 5
q_embed = model.encode([query_str])
D, I = index.search(q_embed, topk)
print(D)
print(I)
return I[0].tolist()

在这一期中,我们还是制作了一个集数据,模型,代码一体的 docker 环境,给大家开箱即用体验中文BERT句子embedding体验。具体地,我们基于 BERT-wwm-exthuggingface transformersentence-transformer 把玩中文句子embedding 并寻找和查询短语相似度最接近的句子。

Docker 镜像获取方式

本期 docker 镜像获取方式为,关注 MyEncyclopedia 公众号后回复 docker-sentence-transformer 即可获取镜像地址和启动命令。

哈工大讯飞中文 Bert

在中文预训练领域,哈工大讯飞联合实验室(HFL)发布的基于全词Mask的中文预训练模型 BERT-wwm-ext 是业界的标杆之一。BERT-wwm-ext 支持 Tensorflow, Pytorch (通过 huggingface transformer 接口)以及 PaddleHub 的接口或者类库,使用起来十分方便。下面的代码为官网中通过 huggingface transformer 接口直接下载并加载到 Pytorch 平台中。Github 地址为 https://github.com/ymcui/Chinese-BERT-wwm

1
2
3
4
5
from transformers import BertTokenizer, BertModel

model_name = 'hfl/chinese-bert-wwm'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)

通过 huggingface transformer 的好处在于 sentence-transformer 也支持 huggingface,因此,通过 huggingface,我们无需手动串联 BERT-wwm-extsentence-transformer,少写了不少代码。

sentence-transformer

sentence-transformer 顾名思义是利用 transformer 词向量的预训练模型来生成句子级别的embedding。原理基于这篇论文 Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks (https://arxiv.org/abs/1908.10084)。基本思想直接了当:将句子中的每个词经 bert embedding 后,输入池化层 (pooling),例如选择最简单的平均池化层,再将所有token embedding 的均值作为输出,便得到跟输入句子长度无关的一个定长的 sentence embedding。

下面的代码是其官网的一个基本例子,底层通过 huggingface 接口自动下载并加载 bert 词向量,并计算三句英语句子的 sentence embedding。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')

#Our sentences we like to encode
sentences = ['This framework generates embeddings for each input sentence',
'Sentences are passed as a list of string.',
'The quick brown fox jumps over the lazy dog.']

#Sentences are encoded by calling model.encode()
embeddings = model.encode(sentences)

#Print the embeddings
for sentence, embedding in zip(sentences, embeddings):
print("Sentence:", sentence)
print("Embedding:", embedding)
print("")

当然,我们也可以绕过 sentence-transformer API,直接使用 pytorch API 和 huggingface 手动实现平均池化层,生成句子的 sentence embedding。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from transformers import AutoTokenizer, AutoModel
import torch

#Mean Pooling - Take attention mask into account for correct averaging
def mean_pooling(model_output, attention_mask):
token_embeddings = model_output[0] #First element of model_output contains all token embeddings
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
sum_embeddings = torch.sum(token_embeddings * input_mask_expanded, 1)
sum_mask = torch.clamp(input_mask_expanded.sum(1), min=1e-9)
return sum_embeddings / sum_mask

#Sentences we want sentence embeddings for
sentences = ['This framework generates embeddings for each input sentence',
'Sentences are passed as a list of string.',
'The quick brown fox jumps over the lazy dog.']

#Load AutoModel from huggingface model repository
tokenizer = AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
model = AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")

#Tokenize sentences
encoded_input = tokenizer(sentences, padding=True, truncation=True, max_length=128, return_tensors='pt')

#Compute token embeddings
with torch.no_grad():
model_output = model(**encoded_input)

#Perform pooling. In this case, mean pooling
sentence_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])

中文最相近的句子

有了上面每个组件的使用方法,让我们生成下面中文句子的embedding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sentences = [
'今天晚上想吃牛排',
'MyEncyclopedia公众号全栈人工智能',
'人工智能需要懂很多数学么',
'上海疫情有完没完',
'教育部:连续7天社会面无疫情 高校可组织校园招聘',
'福建舰"下水!100秒看中国航母高光时刻',
'医保承担多少核酸检测费用?压力多大?',
'张家口过度防疫整改后又被曝光:要证明牛是阴性',
'上海多家银行天天排队爆满 有老人凌晨2点开始排队',
'A股不惧海外暴跌!走出独立行情沪指收复3300点',
'俄方称已准备好重启俄乌和谈',
'《自然》:奥密克戎感染后嗅觉丧失症状比原来少了'
]

接着我们给出如下三个短语的查询,找到和每个查询最匹配的三个句子

1
2
3
q1 = '码农的春天来了么'
q2 = '国际局势'
q3 = '健康'

运行结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Query: 码农的春天来了么

Top 3 most similar sentences in corpus:
人工智能需要懂很多数学么 (Cosine Score: 0.7606)
MyEncyclopedia公众号全栈人工智能 (Cosine Score: 0.7498)
上海疫情有完没完 (Cosine Score: 0.7449)

----------------------------------------------
Query: 国际局势

Top 3 most similar sentences in corpus:
俄方称已准备好重启俄乌和谈 (Cosine Score: 0.7041)
MyEncyclopedia公众号全栈人工智能 (Cosine Score: 0.6897)
上海疫情有完没完 (Cosine Score: 0.6888)

----------------------------------------------
Query: 健康

Top 3 most similar sentences in corpus:
上海疫情有完没完 (Cosine Score: 0.5882)
MyEncyclopedia公众号全栈人工智能 (Cosine Score: 0.5870)
今天晚上想吃牛排 (Cosine Score: 0.5815)

结果发现 上海疫情有完没完 是一切问题的关键。。。

完整代码

附上完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from sentence_transformers import SentenceTransformer

model_name = 'hfl/chinese-bert-wwm'
model = SentenceTransformer(model_name)

sentences = [
'今天晚上想吃牛排',
'MyEncyclopedia公众号全栈人工智能',
'人工智能需要懂很多数学么',
'上海疫情有完没完',
'教育部:连续7天社会面无疫情 高校可组织校园招聘',
'福建舰"下水!100秒看中国航母高光时刻',
'医保承担多少核酸检测费用?压力多大?',
'张家口过度防疫整改后又被曝光:要证明牛是阴性',
'上海多家银行天天排队爆满 有老人凌晨2点开始排队',
'A股不惧海外暴跌!走出独立行情沪指收复3300点',
'俄方称已准备好重启俄乌和谈',
'《自然》:奥密克戎感染后嗅觉丧失症状比原来少了'
]
sentence_embeddings = model.encode(sentences)

q1 = '码农的春天来了么'
q2 = '国际局势'
q3 = '健康'
queries = [q1, q2, q3]
query_embeddings = model.encode(queries)

import scipy

number_top_matches = 3
for query, query_embedding in zip(queries, query_embeddings):
distances = scipy.spatial.distance.cdist([query_embedding], sentence_embeddings, "cosine")[0]
results = zip(range(len(distances)), distances)
results = sorted(results, key=lambda x: x[1])
print("\nQuery:", query)
print("\nTop {} most similar sentences in corpus:".format(number_top_matches))

for idx, distance in results[0:number_top_matches]:
print(sentences[idx].strip(), "(Cosine Score: %.4f)" % (1-distance))

在这一期中,我们来体验两个知名的 NLP 预训练类库 flair 和 transformer 的 zero-shot 短文本分类。所谓zero-shot 的意思是完全不需要数据集来训练,直接掉包解决问题。和以往一样,本期的 docker 镜像已经预装了 flair,transformer,pytorch,jupyter notebook等包依赖,并且还预先下载了 flair 和 transformer 的两个预训练模型yahoo 短文本主题数据集,整个 docker 镜像达到12GB,为了就是让大家无需翻墙下载额外数据或者模型,并且使用CPU就能体验最新的NLP zero shot 文本分类。

Docker 镜像获取方式

关注 MyEncyclopedia 公众号后回复 docker-transformer-zero-shot 即可获取镜像地址和启动命令。

Flair zero shot

先来看一个 flair 短文本 zero shot 短文本分类的例子。下面的代码将句子 Spain beat Swiss for first Nations League win 归类到 politics, sportshealth 之一。

1
2
3
4
5
6
7
8
9
10
11
12
13
from flair.models import TARSClassifier
from flair.data import Sentence
import flair, torch
flair.device = torch.device('cpu')

text = 'Spain beat Swiss for first Nations League win'
tars = TARSClassifier.load('tars-base')
sentence = Sentence(text)
classes = ['politics', 'sports', 'health']
tars.predict_zero_shot(sentence, classes)

print(sentence)
print(sentence.to_dict())

最后两行输出如下,all labels 字段显示概率最高的是 sports类别,达到 0.99+。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Sentence: "Spain beat Swiss for first Nations League win" → sports (0.9952)
{
'text': 'Spain beat Swiss for first Nations League win',
'all labels': [{'value': 'sports', 'confidence': 0.9952359795570374}]
}

注意,在上面的代码中,`flair.device = torch.device('cpu')` 强制使用了 cpu 资源,否则 flair 默认使用 gpu 会报错。


## Transformer zero shot
再来看看大名鼎鼎的 transformer zero shot 的结果。这里使用了默认的 transformer zero shot 分类的模型 Transformer Bart,小伙伴们可以使用其他模型,但是有些不兼容 zero shot 分类。代码如下

​```python
from transformers import pipeline

text = 'Spain beat Swiss for first Nations League win'
classes = ['politics', 'sports', 'health']
classifier = pipeline("zero-shot-classification", device=-1)
result = classifier(text, classes, multi_label=False)

print(result)
print(result['labels'][0])

最后两行输出为

1
2
3
4
5
6
{
'sequence': 'Spain beat Swiss for first Nations League win',
'labels': ['sports', 'health', 'politics'],
'scores': [0.9476209878921509, 0.03594793379306793, 0.016431059688329697]
}
sports

resultlabels中会按照最大概率排序输出类别和对应的分数。对于这句句子,也分的相当准确,sports 为 0.94+。

也注意到 pipeline("zero-shot-classification", device=-1) 语句中 -1 表示强制使用 cpu。

Yahoo 短文本主题数据分类效果

最后,来看一个真实数据集中这两者的实际效果,yahoo_answers_topicshuggingface的一个短文本分类数据集,可以通过以下命令下载并加载

1
yahoo = load_dataset('yahoo_answers_topics')

它的具体类别为

1
2
3
4
5
6
7
8
9
10
11
12
[
'Society & Culture',
'Science & Mathematics',
'Health',
'Education & Reference',
'Computers & Internet',
'Sports',
'Business & Finance',
'Entertainment & Music',
'Family & Relationships',
'Politics & Government'
]

由于数量比较大,这里只取随机的1000个来测试,一些数据点如下

Text Topic
A Permanent resident of Canada may stay out of Canada 3 years without losing status. Politics & Government
The official major league opening game occurred on April 10, 2006, as the Cardinals defeated the Milwaukee Brewers 6-4. (Day Game) Sports
Hold down the Command key while dragging and dropping files. Computers & Internet

接着,对于每条短文本用 flair 和 transformer 来预测类别,最终统计准确率。

结果是 flair 准确率为 0.275,Transformer Bart 为 0.392,果然 transformer 显著胜出。其实,在 Yahoo数据集上取得 0.3 - 0.4 左右的效果已经不错了,毕竟有十个类别,全随机的准确率是 0.1。如果大家觉得这个效果一般的话,可以试试 tweet 情感分类数据集(具体在下面的链接中),Transformer 能达到惊人的 0.73。

下面附部分代码,完整代码可以从镜像中获得,或者感兴趣的小伙伴也可以访问

https://github.com/nlptown/nlp-notebooks/blob/master/Zero-Shot%20Text%20Classification.ipynb 获取所有五个数据集的代码,不过由于类库版本的关系,部分代码和模型或数据无法兼容,需要自行调试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def evaluate_flair(dataset, default_name='neutral'):
classifier = TARSClassifier.load('tars-base')
total, correct = 0, 0
for item, gold_label_idx in tqdm(zip(dataset["test_texts"], dataset["test_labels"]),
total=len(dataset["test_texts"])):
sentence = Sentence(item)
classifier.predict_zero_shot(sentence, dataset["class_names"])
sorted_labels = sorted(sentence.to_dict()['all labels'], key=lambda k: k['confidence'], reverse=True)
gold_label = dataset["class_names"][gold_label_idx]
if len(sorted_labels) > 0:
predicted_label = sorted_labels[0]['value']
else:
predicted_label = default_name
if predicted_label == gold_label:
correct += 1
total += 1

return correct / total

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def evaluate_huggingface(dataset):
classifier = pipeline("zero-shot-classification", device=-1)
correct = 0
predictions, gold_labels = [], []
for text, gold_label_idx in tqdm(zip(dataset["test_texts"], dataset["test_labels"]),
total=len(dataset["test_texts"])):

result = classifier(text, dataset["class_names"], multi_label=False)
predicted_label = result['labels'][0]

gold_label = dataset["class_names"][gold_label_idx]

predictions.append(predicted_label)
gold_labels.append(gold_label)

if predicted_label == gold_label:
correct += 1

accuracy = correct / len(predictions)
return accuracy

如果你是一个重度论文阅读者,一定会在自己的笔记本上全副武装。但是也许只是偶尔,也会心血来潮地在手机端查看一篇论文,此时,你打开的这篇从 Arxiv 下载的论文,就像下图上半部分所示,时间稍长,便会觉得文字,公式和图片不忍直视。你多么希望在手机端查看PDF,也像图中下半部分一样重新排版来轻松阅读。

Arxiv 论文手机智能重排和阅读服务

现在,MyEncyclopedia 推出了智能的手机端重排和阅读 arxiv 论文服务。手机端只需浏览器甚至在微信中就能将指定的 arxiv 论文重排成适应移动端的格式,并在线浏览。

具体效果如下

微信操作步骤

下面,以手机微信为例,讲解详细步骤。其他浏览器可以直接点击 https://mydoc.myencyclopedia.top/app,操作步骤类似。

  • 进入 MyEncyclopedia 公众号,回复 ? 点击 AI在线服务

  • 拷贝显示的口令

  • 返回到公众号后回复口令,登录使用服务

  • 输入 Arxiv ID,点击 Go to Page

  • 在新页面点击 Convert Html

  • 等待大约十几分钟,再次进入服务页面,此时,若下载转换任务成功,出现如下页面,点击View Html,即可在微信浏览器中完美查看论文了。

PDF 论文双列切割成单列服务

此外,也提供将 arxiv PDF从双列切割成单列服务。即上图中的Convert PDF 按钮,切割后的PDF文件可以在线浏览,或者下载到手机离线查看。也欢迎大家尝试。

五一期间突然发现我的B站频道一点一滴地攒到1000个粉丝1000个获赞了,微不足道的小成就,和很多粉丝过万甚至十几万的大UP主差的很远,不过就自然增长而言,B站上的流量不会像公众号那样随着时间的推移而减少,只要原创内容精良,可以一直发光发热下去,这一点和 Youtube 很类似。

原创方向

对于未来的原创计划我是很有信心的,会在之前的基础上做好几个方向的内容创造

  • 深度学习经典或前沿论文讲解,涉及到强化学习,NLP 和 CV 等通用方向。
  • 可视化基础的数学课程,例如正在制作连载中的 MIT18.06线性代数,还有未来的统计,优化等课程,。同样的,也会在合适的时候开始基础机器学习经典教程,计划中有 BishopPRML (Pattern Recognition & Machine Learning) 。这些经典教程都会精雕细琢,通过代码,尤其是 manim 可视化来完成。
  • 机器学习实践系列:用 docker 封装各种机器学习或者深度学习的代码教学实例。
  • 原创 AI 服务,例如目前更新中的 Mark-ME 等。

油管搬运大学

此外,平时我会经常从 Youtube 下载最新的各大名校的公开课。之后也会同时搬运一些,来源以 MITStanfordGoogleUC Berkeley 为主,课程类别不限于计算机,AI或者数学,以飨读者,同时我可以释放海量硬盘空间(家里已经有4台电脑,6个移动硬盘,总计20T的容量了 (lll¬ω¬))。

上次搬运 Microsoft Research 的杰出AI学者炉边雅谈系列时实现了自动提供中英文字幕,效果如下(中文字幕由油管机翻,效果一般般,看看就行)。

英文字幕

中文字幕

奇怪的是好像我无法在手机端加载字幕,有知道的同学能否告知一下?

Mark-ME 在几个月的开发之后,发布了 v0.3.0 版本。Mark-ME 致力于做最好的跨平台(Win, Mac, Linux)markdown 编辑器,面向AI辅助写作,一站式多平台发布。超越 Typoramdnice 等。本版本增加了不少高级的功能,包括

  • 导出兼容 mdnice 样式的微信公众号文章
  • mathpix 图片转 latex 代码
  • 通过 PicGo 上传本地图片到图床
  • 下载文字远程图片到本地

下载地址:

https://github.com/MyEncyclopedia/Mark-ME/releases/download/v0.3.0/Mark-ME.0.3.0.exe

Markdown 显示效果

1. 图片显示

注意,本地和远程图片都支持

2. 代码高亮

3. 数学公式

除了普通行内公式和块公式,还支持 Typoramdnice 不支持的扩展 Mathjax 表达式。例如图中的彩色矩阵。

同样的表达式在 Typoramdnice 中均不支持

4. 内嵌 Html 标签

完美显示内嵌 html 标签。

注意,第二个例子中内嵌了 svgdiv 标签,渲染结果为 \(x^2\)。这个功能很方便将 latex 导出成 svg 后嵌入 markdown 文章中,即保护了 latex 源码,也无需担心多平台的显示效果。后续会加强此功能。

兼容 mdnice 样式导出到微信公众号

mdnice 的样式填入右边的输入中,完美换皮。

Mathpix 图片转 Latex

下载远程图片到本地

通过 PicGo 上传本地图片到图床

其他

菜单展示

缩放

配置窗口

注册

一些高级功能虽然免费,但是需要用户注册 myencyclopedia,以便更好的了解用户。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×