在大型数据集上的培训
神经网络非常适于在大型数据集上进行培训,甚至是那些太大而不适合内存的数据集. 培训神经网络最流行的算法(例如,NetTrain 中的 "ADAM" 或 "RMSProp") 是称之为随机梯度下降方法的变体. 在该方法中,从完全培训的数据集中随机采样一小批数据并用于执行参数更新. 因此,神经网络是在线学习算法的一个范例,它不需要整个培训数据集储存在内存. 这与支持向量机 (SVM) 和随机森林算法是相反的,它们一般需要在培训时,整个数据集存在于内存中.
然而,如果把 NetTrain 用于不需要适合内存的数据集上,则需要特殊的处理,因为整个培训数据集不能加载进 Wolfram 语言会话中. 有两种方法可以培训这么大的数据集. 第一种方法是,用户编写一个生成器函数 f,计算时,可以从外部资源,例如,磁盘或数据库加载一小批数据. NetTrain[net,f,…] 在每个培训批迭代中调用 f,因此只在内存中保留单批培训数据. 这是进行脱离核心学习最灵活的方法. 然而,它取决于用户来确保 f 的计算足够快来避免降速网络培训(这个对于在完全强大的 GPU 上的培训尤其重要)并且从整个培训数据集中正确的进行采样.
查找 ExampleData 中的文件:
- 可能的话,使用 NetEncoder,它的实现已被高度优化.
- NetTrain 加载下一批培训数据且在前一批培训数据上并行进行培训迭代. 因此,数据加载和预处理只影响培训速度,如果比单个培训迭代慢的话. 这很大程度依赖于网络的复杂性和训练网络的硬件.
- 当使用生成器函数 f,确保它足够快以避免减慢培训. 为此,使用生成器函数创建能适于内存的培训数据的一个拷贝,使用例如,dataset=f[<"BatchSize"->1000 >],并测量速度,其中, NetTrain 使用 NetTrain[net,dataset,"MeanInputsPerSecond",TimeGoal->30] 操作这些数据. 然后,把它与 NetTrain[net,f,"MeanInputsPerSecond",TimeGoal->30] 的数据生成器的速度进行比较. 如果生成器更慢,那么优化 f 或接受这个慢速作为脱离核心培训的代价.
- 使用 NVIDIA GPU 进行培训. 使用 NetTrain 中的 TargetDevice 选项完成. GPU 上的培训比只在 CPU 上的培训要快一个数量级. 原因是由于网络计算一般在 GPU 上更快. 另外,数据加载和预处理更快,因为,CPU 可以完全聚焦该任务.
该范例显示如何在 MNIST 数据集上培训网络,其中,图像以 "JPEG" 文件形式存在磁盘上而不是内存中. 虽然没有必要培训 MNIST,但是该方法可用于在 TB 级图像数据集(例如:ImageNet 数据集)上培训网络.
我们可以使用特殊语法 NetTrain[net,{File[…]class1,…},…] 以及把 "Image" NetEncoder 附加在 net 的输入口上. 也可以使用更灵活的 NetTrain 生成器函数语法显示如何重现.
准备数据
首先,需要创建一个 MNIST 脱离核心的版本,格式为 {File[…]class1,…}.
把图像以 "JPEG" 文件的形式存在默认的临时目录 $TemporaryDirectory 中. 每个导出的文件也需要一个唯一的名称. 创建唯一名称的一个好方法是使用 Hash 函数,该函数为每个唯一图像返回一个唯一的哈希值.
当培训图像时,一般情况下,网络需要图像是单个尺寸、颜色空间等. 在 LeNet 情况下,期望图像是灰度的且尺寸为 2828. 如果从磁盘读取的图像已经与网络期待的符合,一般会加速培训,否则,每次从磁盘加载时,需要转换. 如果图像不符合,那么推荐修改 exportImage,使用 ConformImages 使图像符合.
导出图像并创建格式为 {File[…]->class,…} 的新的培训和测试集:
显示新培训集的 RandomSample:
获取两个培训集的 ByteCount:
简单的脱离核心培训
用 NetInitialize 初始化网络并把它应用于文件中:
用生成器函数培训
我们也可以使用更多的 NetTrain 的一般生成器语法. 该方法更灵活,允许自定义图像处理、数据增强等.
导入与 NetEncoder 性能
我们假设您已经熟悉 MongoLink 和 MongoDB 数据库. 如果不熟悉,在继续前,推荐阅读 MongoLink Introduction 教程.
并且假设 MongoDB 服务器是运行在默认的主机和端口的本地服务器上. 对于本地运行 MongoDB 服务器的平台独立的介绍,请参见这里.
数据插入
使用 MongoGetCollection 创建一个集合:
构建分类网络
构建一个唯一标签列表,每个范例用 MongoCollectionDistinct 分配:
构建一个生成器函数
这等同于在集合上使用 RandomSample:
定义使用于 NetTrain 的生成器函数:
培训数据有两种主要有效的格式,生成器函数可以生成:范例列表关联 {<key1val11,key2val21,… >,<key1val12,… >,…} 由生成器产生,或单个 Association,每个键有范例值列表 <key1->{val11,val12,…},key2{val21,val22,…},… >. 生成器函数输出 out 的一种格式可以通过 Transpose[out,AllowedHeads->All] 转换成其他.
MongoDB 使用 $group 聚合阶段直接生成讲范例组合在一起的第二种格式. 这比产生第一种格式更有效.
培训网络
这种方法存在一个问题:测试集合上的性能是在每批已被培训后计算的,与通常情况相比,是在单个通过整个培训数据集(一个回合)之后计算的. 当使用生成器,NetTrain 不知道一个回合的大小,除非我们明确指定.
使用 MongoCollectionCount 获取集合中范例的总数: