写点什么

NanoNets:数据不足时如何深度学习

  • 2017-04-04
  • 本文字数:5141 字

    阅读完需:约 17 分钟

我认为实现人工智能的难度无异于建造火箭。需要有一个强大的引擎,还有大量的燃料。如果空有强大的引擎但缺乏燃料,火箭肯定是无法上天的。如果只有一个单薄的引擎,有再多燃料也无法起飞。如果要造火箭,强大的引擎和大量燃料是必不可少的。

以此来类比深度学习的话,深度学习引擎可以看作火箭引擎,而我们为算法提供的海量数据可以看作是燃料。?—? Andrew Ng

最近深度学习技术突然开始大肆流行,并在语言翻译、玩策略游戏,以及无人驾驶汽车等涉及到数百万数据量的领域取得了醒目的成果。使用深度学习技术解决问题的过程中,最常见的障碍在于训练模型过程中所需的海量数据。需要如此多的数据,原因在于机器在学习的过程中会在模型中遇到大量参数。

例如这些模型中常见的参数数量范围包括:

VGGNet

DeepVideo

GNMT

用途

识别图像并分类

识别视频并分类

翻译

输入

图像

视频

英语文本

输出

100 种类别

47 种类别

法语文本

参数数量

1.4 亿个

约 1 亿个

3.8 亿个

数据规模

120 万张已分类图片

110 万个已分类视频

6 百万语句对,3.4 亿个单词

数据集

ILSVRC-2012

Sports-1M

WMT’14

深度学习模型的细节

神经网络(即深度学习)是一种分层式结构,但又能堆叠在一起(就像乐高积木)

深度学习技术其实就是一种大规模神经网络,我们可以将这种网络看作一种流程图,数据从一端进入,相互引用 / 了解后从另一端输出。我们还可以将神经网络拆分成多个部分,从任何一部分中得到自己需要的推理结果。也许无法得到有意义的结果,但依然可以这样做,例如 Google DeepDream 就是这样做的。

规模(模型) ∝ 规模(数据) ∝ 复杂度(问题)

在模型的规模和所需数据量的规模之间存在一种有趣的近似于线性的关系。基本推论在于,对于特定的问题(例如类别的数量),模型必须足够大,以便得到数据之间的关系(例如图片中的材质和形状,文本中的语法,以及语音中的音素)。模型中的前序层可以识别所输入内容中不同组成之间的高级别关系(例如边缘和模式),后续层可以识别有助于最终做决策所需的信息,这些信息通常有助于区分不同的结果。因此如果问题的复杂度较高(例如图像分类),所需的参数数量和数据量就会非常大。

(点击放大图像)

AlexNet 在每个环节“看到”的内容

迁移学习来搭救!

在面对某一领域的具体问题时,通常可能无法得到构建模型所需规模的数据。然而在一个模型训练任务中针对某种类型数据获得的关系也可以轻松地应用于同一领域的不同问题。这种技术也叫做迁移学习(Transfer Learning)

Qiang Yang、Sinno Jialin Pan,“A Survey on Transfer Learning”,IEEE Transactions on Knowledge & Data Engineering,vol. 22, no. , pp. 1345–1359, October 2010, doi:10.1109/TKDE.2009.191

迁移学习就像是一个没人愿意保守的最高机密。尽管业内人人皆知,但外界毫不知情。

谷歌搜索中,机器学习、深度学习,以及迁移学习三个关键字的搜索趋势变化

根据 Awesome?—?Most Cited Deep Learning Papers 所公布的深度学习领域最主要的论文统计,超过 50% 的论文使用了某种形式的迁移学习或预训练。对于资源(数据和计算能力)有限的人,迁移学习技术的重要性与日俱增,然而这一概念尚未得到应有程度的社会影响。最需要这种技术的人甚至至今都不知道这种技术的存在。

如果深度学习是圣杯,数据是守门人,那么迁移学习就是大门钥匙。

借助迁移学习技术,我们可以直接使用预训练过的模型,这种模型已经通过大量容易获得的数据集进行过训练(虽然是针对完全不同的任务进行训练的,但输入的内容完全相同,只不过输出的结果不同)。随后从中找出输出结果可重用的层。我们可以使用这些层的输出结果充当输入,进而训练出一个所需参数的数量更少,规模也更小的网络。这个小规模网络只需要了解特定问题的内部关系,同时已经通过预培训模型学习过数据中蕴含的模式。通过这种方式,即可将经过训练检测猫咪的模型重新用于再现梵高的画作

迁移学习技术的另一个重大收益在于可以对模型进行完善的“通用化”。大型模型往往会与数据过度拟合(Overfit),例如建模所用数据量远远超过隐含的现象数量,在处理未曾见过的数据时效果可能不如测试时那么好。由于迁移学习可以让模型看到不同类型的数据,因此可以习得更出色的底层规则。

过度拟合,更像是学习过程中的死记硬背。?—? James Faghmous

迁移学习可减小数据量

假设想要终结裙子到底是蓝黑色还是白金色的争议,首先需要收集大量已获证实是蓝黑色和白金色的裙子图片。如果要使用类似上文提到的方式(包含 1.4 亿个参数!)自行构建一个准确的模型并对其进行训练,至少需要准备 120 万张图片,这基本上是无法实现的。这时候可以试试迁移学习。

如果使用迁移学习技术,训练所需的参数数量计算方式如下:

参数的数量 = [规模 (输入) + 1] * [规模 (输出) + 1]

= [2048+1]*[1+1]~ 4098 个参数

所需参数数量由 1.4*10? 个减少至 4*103 个,降低了五个数量级!只要收集不到 100 个图片就够了。松了口气!

如果实在没耐心继续阅读,希望立刻知道裙子的颜色,可以直接跳至本文末尾看看如何自行构建一个这样的模型。

迁移学习循序渐进指南?—? 使用示例进行情绪分析

在这个示例中共有 72 篇影评。

  1. 62 篇不包含明确的情绪,将用于对模型进行预训练
  2. 8 篇包含明确的情绪,将用于对模型进行训练
  3. 2 篇包含明确的情绪,将用于对模型进行测试

由于只有 8 个包含标签的句子(包含明确情绪的句子),因此首先可以预训练模型进行上下文预测。如果只使用这 8 个句子训练模型,准确度可达 50%(这样的准确度和抛硬币差不多)。

我们将使用迁移学习技术解决这个问题,首先使用 62 个句子训练模型,随后使用第一个模型的部分内容,以此为基础训练出一个情绪分类器。使用随后 8 个句子进行训练后,用最后 2 个句子测试得到了 100% 的精确度。

第 1 步

我们将训练一个对词语之间的关系进行建模的网络。将句子中包含的一个词语传递进去,并尝试预测该词语出现在同一个句子中。在下列代码中嵌入的矩阵其大小为 vocabulary x embedding_size,其中存储了代表每个词语的向量(这里的大小为“4”)。

复制代码
graph = tf.Graph()
with graph.as_default():
train_inputs = tf.placeholder(tf.int32, shape=[batch_size])
train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])
valid_dataset = tf.constant(valid_examples, dtype=tf.int32)
with tf.device('/cpu:0'):
embeddings = tf.Variable(tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
embed = tf.nn.embedding_lookup(embeddings, train_inputs)
nce_weights = tf.Variable(tf.truncated_normal([vocabulary_size, embedding_size], stddev=1.0 / math.sqrt(embedding_size)))
nce_biases = tf.Variable(tf.zeros([vocabulary_size]))
loss = tf.reduce_mean(tf.nn.nce_loss(nce_weights, nce_biases, embed, train_labels, num_sampled, vocabulary_size))
optimizer = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keep_dims=True))
normalized_embeddings = embeddings / norm
valid_embeddings = tf.nn.embedding_lookup(normalized_embeddings, valid_dataset)
similarity = tf.matmul(valid_embeddings, normalized_embeddings, transpose_b=True)
init = tf.global_variables_initializer()

pretraining_model.py 托管于 GitHub,查看源文件

第 2 步

我们继续对这个图表进行训练,让相同上下文中出现的词语可以获得类似的向量表征。我们会对这些句子进行预处理,移除所有停用词(Stop word)并实现标记化(Tokenizing)。随后一次传递一个词语,尽量缩短该词语向量与周边词语之间的距离,并扩大与上下文不包含的随机词语之间的距离。

复制代码
with tf.Session(graph=graph) as session:
init.run()
average_loss = 0
for step in range(10001):
batch_inputs, batch_labels = generate_batch(batch_size, num_skips, skip_window)
feed_dict = {train_inputs: batch_inputs, train_labels: batch_labels}
_, loss_val, normalized_embeddings_np = session.run([optimizer, loss, normalized_embeddings], feed_dict=feed_dict)
average_loss += loss_val
final_embeddings = normalized_embeddings.eval()

training_the_pretrained_model.py 托管于 GitHub,查看源文件

第 3 步

随后我们会试着预测句子的情绪。目前已经有 10 个(8 个训练用,2 个测试用)句子带有正面和负面的标签。由于上一步得到的模型已经包含从所有词语中习得的向量,并且这些向量的数值属性可以代表词语的上下文,借此可进一步简化情绪的预测。

此时我们并不直接使用句子,而是将句子的向量设置为所含全部词语的平均值(这一任务实际上是通过类似 LSTM 的技术实现的)。句子向量将作为输入传递到网络中,输出结果为内容为正面或负面的分数。我们用到了一个隐藏的中间层,并通过带有标签的句子对模型进行训练。如你所见,虽然每次只是用了 10 个样本,但这个模型实现了 100% 的准确度。

复制代码
input = tf.placeholder("float", shape=[None, x_size])
y = tf.placeholder("float", shape=[None, y_size])
w_1 = tf.Variable(tf.random_normal((x_size, h_size), stddev=0.1))
w_2 = tf.Variable(tf.random_normal((h_size, y_size), stddev=0.1))
h = tf.nn.sigmoid(tf.matmul(X, w_1))
yhat = tf.matmul(h, w_2)
predict = tf.argmax(yhat, dimension=1)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(yhat, y))
updates = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
sess = tf.InteractiveSession()
init = tf.initialize_all_variables()
sess.run(init)
for epoch in range(1000):
for i in range(len(train_X)):
sess.run(updates, feed_dict={X: train_X[i: i + 1], y: train_y[i: i + 1]})
train_accuracy = numpy.mean(numpy.argmax(train_y, axis=1) == sess.run(predict, feed_dict={X: train_X, y: train_y}))
test_accuracy = numpy.mean(numpy.argmax(test_y, axis=1) == sess.run(predict, feed_dict={X: test_X, y: test_y}))
print("Epoch = %d, train accuracy=%.2f%%, test accuracy=%.2f%%" % (epoch+1,100.*train_accuracy,100.* test_accuracy))

training_the_sentiment_model.py 托管于 GitHub,查看源文件

虽然这只是个示例,但可以发现在迁移学习技术的帮助下,精确度从50% 飞速提升至100%。若要查看完整范例和代码请访问下列地址:

https://gist.github.com/prats226/9fffe8ba08e378e3d027610921c51a78

迁移学习的一些真实案例

图像识别:图像增强风格转移对象检测皮肤癌检测

文字识别: Zero Shot 翻译情绪分类

迁移学习实现过程中的难点

虽然可以用更少量的数据训练模型,但该技术的运用有着更高的技能要求。只需要看看上述例子中硬编码参数的数量,并设想一下要在模型训练完成前不断调整这些参数,迁移学习技术使用的难度之大可想而知。

迁移学习技术目前面临的问题包括:

  1. 找到预训练所需的大规模数据集
  2. 决定用来预训练的模型
  3. 两种模型中任何一种无法按照预期工作都将比较难以调试
  4. 不确定为了训练模型还需要额外准备多少数据
  5. 使用预训练模型时难以决定在哪里停止
  6. 在预训练模型的基础上,确定模型所需层和参数的数量
  7. 托管并提供组合后的模型
  8. 当出现更多数据或更好的技术后,对预训练模型进行更新

数据科学家难觅。找到能发现数据科学家的人其实一样困难。?—? Krzysztof Zawadzki

NanoNets 让迁移学习变得更简单

亲身经历过这些问题后,我们开始着手通过构建支持迁移学习技术的云端深度学习服务,并尝试通过这种简单易用的服务解决这些问题。该服务中包含一系列预训练的模型,我们已针对数百万个参数进行过训练。你只需要上传自己的数据(或在网络上搜索数据),该服务即可针对你的具体任务选择最适合的模型,在现有预训练模型的基础上建立新的 NanoNet,将你的数据输入到 NanoNet 中进行处理。

NanoNets 的迁移学习技术(该架构仅为基本呈现)

构建你的首个 NanoNet(图像分类)

  1. 在这里选择你要处理的分类。
  2. 一键点击开始搜索网络并构建模型(你也可以上传自己的图片)。
  3. 解决蓝金裙子的争议(模型就绪后我们会通过简单易用的 Web 界面让你上传测试图片,同时还提供了不依赖特定语言的 API)。

若要开始构建你的第一个 NanoNet,请访问: www.nanonets.ai

作者 Sarthak Jain 阅读英文原文 NanoNets : How to use Deep Learning when you have Limited Data


感谢杜小芳对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-04-04 17:587855
用户头像

发布了 283 篇内容, 共 107.5 次阅读, 收获喜欢 62 次。

关注

评论

发布
暂无评论
发现更多内容

FFmpeg介绍

Loken

音视频 5月月更

稳扎稳打步步为营 英特尔GPU将在消费市场和数据中心全面开花

科技新消息

CUDA优化之PReLU性能调优

OneFlow

性能优化 cuda PReLU 朴素实现

数据库连接池 -Druid 源码学习(六)

wjchenge

Druid 数据库连接池

FinClip小程序+Rust(一):夹心饼架构

Speedoooo

rust 前端框架 小程序容器

FinClip小程序+Rust(四):端到端融合

Speedoooo

rust 前端框架 小程序容器

ABBYY2022全新版PDF文字识别功能

茶色酒

学Python运维,这知识点你肯定会遇到,【必收藏之】nginx 域名跳转相关配置

梦想橡皮擦

5月月更

前端常用的站点导航

刘帅强

FinClip小程序+Rust(五):用内联SVG实现二维码

Speedoooo

rust 前端框架 小程序容器

FinClip小程序里如何安全使用SVG

Speedoooo

rust SVG 前端框架 小程序容器

网站开发进阶(六十八)CSS3媒体查询@media

No Silver Bullet

5月月更 媒体查询 设备自适应 hsl

Druid 连接池源码阅读 06

石小天

总结

Geek_36cc7c

战“码”先锋直播预告丨如何成为一名优秀的OpenHamrony贡献者?

OpenHarmony开发者

OpenHarmony 贡献代码

Magento 和 WordPress 的区别

海拥(haiyong.site)

WordPress 5月月更

一种经典的客户关系管理系统(CRM)订单模型的设计与实现

汪子熙

CRM SAP 客户关系管理系统 5月月更 订单模型

熊磊:成功移植OpenHarmony到多套开发板,是最开心的事

OpenHarmony开发者

开发板 OpenHarmony

FinClip小程序+Rust(三):一个加密钱包

Speedoooo

rust 前端框架 小程序容器

druid源码学习六

Nick

jdk JMX Druid

Qt软件开发_解决中文路径无法识别问题

DS小龙哥

5月月更

RocketMQ—Producer(五)路由队列选择

IT巅峰技术

架构 RocketMQ java

Dockerfile 的最佳实践 | Dockerfile 你写的都对么?

xcbeyond

最佳实践 镜像 Dockerfile

层层剖析一次 HTTP POST 请求事故

vivo互联网技术

HTTP CORS XSS 跨域 waf

Linux下玩转nginx系列(五)---nginx实现负载均衡

anyRTC开发者

nginx Linux 负载均衡 音视频

推荐几个机器学习的好资源

AIWeker

人工智能 深度学习 5月月更

马斯克推崇的柏拉图式元宇宙,PlatoFarm早已验证出答案

股市老人

AIRIOT物联网低代码平台如何配置三菱PLC驱动?

AIRIOT

物联网 PLC 驱动配置

FinClip小程序+Rust(二):环境搭建

Speedoooo

rust 前端框架 小程序容器

AIrserver2022手机软件无线投屏电脑屏幕

茶色酒

AirServer

Kubernetes下web服务的性能测试三部曲之三:横向扩容

程序员欣宸

Java Kubernetes 5月月更

NanoNets:数据不足时如何深度学习_语言 & 开发_Sarthak Jain_InfoQ精选文章