作者 | Kajal Gupta
编译 | 聂震坤
作为机器学习下的一个分支,多任务学习的目标是让机器能同时处理多个任务。机器同时学习两个任务,而这两个任务又有助于学习其他任务。因为人可以同时处理多个任务,所以这也是机器模仿人类智慧的一种方式。对人来说,这些运算发生在复杂的大脑中,数十亿个神经元细胞进行相互作用。
多年来,研究者试图在机器学习领域效仿这一方法,这便是神经网络。当神经网络处理类似预测颜色的任务时,多任务可以极大地提高效率,因为它有助于分享跨任务的资源与参数,还减少了分开训练模型的时间。
进行多任务学习的四个步骤
创建数据集
建立神经网络架构
定义多任务丢失功能
训练
提出问题
为了执行这个任务,可提出一个简单的问题陈述:假设你想预测一朵花(玫瑰或雏菊)的类型以及它的颜色(红色,粉红色或白色)。这个问题完全适合多任务学习,因为我们希望在同一个网络中同时执行两件事情。在一个推论的结尾,将有两个分类的结果 - 花的类型及其颜色。
1. 创建数据集
对于所有的训练任务来说,最优先最重要的便是数据集。我们需要使用这个数据来训练神经网络。由于这是一个监督学习任务,数据还将包括每个图像的正确标签。
对于这个任务,将需要两个标签:花型和颜色的图像。用玫瑰和雏菊的谷歌图片,颜色为红色,粉红色和白色。最后,有三种不同颜色的玫瑰和雏菊的3200张图像。
在此步骤之后,需要将此数据集进行培训,验证和测试。我选择使用60%的图像用于训练,25%的图像用于验证,剩余的15%用于测试。我创建了三个单独的文本文件并存储了三个信息:图像路径、花型和颜色标签。花标签0将与玫瑰相关联,1关联菊花,彩色标签分别为0,1和2,分别为红色、粉红色和白色。
因此最后train.txt文件看起来是这样的:
/data/img1.jpg,0, 1
/data/img2.jpg,1, 2
/data/img3.jpg,1, 2
/data/img4.jpg,0, 0
/data/img5.jpg,0, 1
/data/img6.jpg,1, 1
.
.
.
2. 建立神经网络架构
在定义神经网络架构之前,应当首先将其可视化以便于理解:
在上图中,隐藏的节点称为“共享层”,因为这些层的重要性对于这两个任务是相同的。然后,我们有“任务特定层”,其中分别执行与每个任务相关的计算,而不在层之间共享参数。在这些任务特定的层中,特定的神经网络学习特定任务的信息。这些独立任务层中的每一个节点都有不同的输出。在此例子中,一个节点预测花朵为玫瑰或雏菊,另一个预测花的颜色是红色、粉红色或白色。
为了定义这个架构,我在TensorFlow中定义了SqueezeNet_v1.1体系结构,并修改了最后一层以执行多任务学习。我使用层直到fire8作为共享层,并在fire8作为界限将剩下层进行拆分,并将两个复制的剩余层分成两个任务。所以最终网络层看起来像这样:
(...previous network)
net = fire_module(net, 48, 192, scope='fire7')
net = fire_module(net, 64, 256, scope='fire8')
net = slim.max_pool2d(net, [3, 3], stride=2, scope='maxpool8')
## splitting network here
## ------------------ Network 1 - flower classification ------------
type_net = fire_module(net, 64, 256, scope='type_fire9')
type_net = slim.conv2d(type_net, 2, [1, 1], stride=1, padding=”VALID”, scope='type_conv10')
type_net = slim.avg_pool2d(type_net, [10, 10], padding="VALID", scope='type_avgpool10')
flower_type = tf.squeeze(type_net, [1, 2], name='flower_type')
## ------------------ Network 2 - color classification -------------
color_net = fire_module(net, 64, 256, scope='color_fire9')
color_net = slim.conv2d(color_net, 3, [1, 1], stride=1, padding=”VALID”, scope='color_conv10')
color_net = slim.avg_pool2d(color_net, [10, 10], scope='color_avgpool10')
flower_color = tf.squeeze(color_type, [1, 2], name='color_type')
3. 定义多任务丢失功能
在开始训练之前,定义丢失功能是很重要的,针对此任务的丢失功能如下:
flower_type_loss= slim.losses.softmax_cross_entropy(predicted_flower_type,original_flower_type)
flower_color_loss= slim.losses.softmax_cross_entropy(predicted_flower_color,original_flower_color)
定义丢失功能以后我们需要将其对两个任务分别进行优化。有两种方法来实现:
1. 为两个任务定义丢失功能,分开优化。
2. 为两个任务定义丢失功能,共同优化。
第一种方式适合于要执行交替培训。当拥有任务1数据与任务2数据,并交替进行培训时,可以交替调用优化器并优化网络。
如果想在优化同时进行学习,那么第二种方式更合适。只需添加损失并优化此损失。这保留了单独的任务特定的丢失功能,并同时进行训练。在此案例中,我想同时训练网络,所以使用这个方法。
total_loss =flower_type_loss + flower_color_loss
train =optimizer.minimize(total_loss)
不是单独优化两个损失,而是优化单个联合损失。我们定义优化器函数,它负责最小化total_loss。
4. 训练
一旦定义了神经网络架构,接下来就是对他进行训练了。此前已经创建了用于培训,验证和测试集的文本文件。所以第一个任务是阅读文件,并提取关于图像和标签的信息到网络。一旦完成,便可以开始多任务培训。
总结
在这篇文章中,笔者通过使用非常简单的问题来实现深度神经网络进行多任务学习。它可以推广到更复杂的问题,如识别面部表情和确定人脸特征。当要使用相同的网络执行类似的任务时,多任务学习是有帮助的。与不同的模型进行预测相比,这不仅减少了训练时间,而且减少了推理时间。在移动设备上最好使用此类方法,因为需要优化运行时消耗的内存,电池利用率和CPU使用率。
CSDN AI热衷分享 欢迎扫码关注