深度学习笔记34_函数式API之多输出模型构建

Posted 瓦力人工智能

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习笔记34_函数式API之多输出模型构建相关的知识,希望对你有一定的参考价值。

多输出模型

社交模型的构建

这里我们先来看个例子,通过一个网络来试图预测数据的不同性质,一个网络中:

  • 输入:某个匿名人士在社交媒体发帖一系列文章

  • 预测个人属性:

    • 年龄

    • 性别

    • 收入水平

这个就是一个典型的一个输入,多个输出的模型,具体的coding如下。

多头输出模型案例
from keras import layers
from keras import Input
from keras.models import Model

 # 最常用的前50000词语
vocabulary_size = 50000
# 收入为10个等级
num_income_groups = 10

# shape = (None,) 表示输入的长度是可变的
# 输入的格式类型是:整数序列
# name='posts' 对输入进行命名
posts_input = Input(shape=(None,),dtype='int32',name='posts')
# # 将输入嵌入维度为256的向量
embedded_posts = layers.Embedding(256,vocabulary_size)(posts_input)
x = layers.Conv1D(128,5,activation='relu')(embedded_posts)
x = layers.MaxPooling1D(5)(x)
x = layers.Conv1D(256,5,activation = 'relu')(x)
x = layers.Conv1D(256,5,activation='relu')(x)
x = layers.MaxPooling1D(5)(x)
x = layers.Conv1D(256,5,activation='relu')(x)
x = layers.Conv1D(256,5,activation='relu')(x)
# 求全局的MAX池化,这里全局指的是整个steps
x = layers.GlobalMaxPooling1D()(x)
x = layers.Dense(128,activation='relu')(x)

# 对于每一个输出层进行命名
age_prediction = layers.Dense(1,name='age')(x)
income_prediction = layers.Dense(num_income_groups,
                                activation='softmax',
                                name = 'income')(x)
gender_prediction = layers.Dense(1,
                                 activation='sigmoid',
                                name = 'gender')(x)

# 创建模型,模型的输出是三个数据构成一个列表
model = Model(posts_input,
             [age_prediction,
             income_prediction,
             gender_prediction])

社交模型编译 - 损失函数处理

这里我们需要对于不同的输入指定不同的损失函数:

  • 年龄:标量回归

  • 性别:二分类

  • 收入:多分类
    所以对于不同的损失函数,需要训练的过程也不同,但是梯度下降要求仅仅对一个标量进行最小化,所以我们需要将这三个不同的损失值合并称为一个标量。这里一个简单的方法就是:

  • 对所有的损失值求和

对于在keras中我们可以这样处理:

在编译函数compile中,使用列表或者使用字典将不同的输出指定不同的损失,然后将得到的损失值相加得到一个全局损失值,然后在训练过程中将相加的那个损失进行最小化.

具体的coding如下

# 使用列表的形式,要与模型建立的是输出要对应
model.compile(optimizer='rmsprop',
             loss = ['mse',
                     'categorical_crossentropy',
                    'binary_crossentropy'])
# 使用字典的形式
# 这里也是需要输出层具有名称时
model.compile(optimizer='rmsprop',
             loss= {'age':'mse',
                'income''categorical_crossentropy',
                'gender''binary_crossentropy'

             })

损失值权重的分配

上面的相加是比较粗暴的直接相加,这里需要考虑两个问题:

  • 每个损失值的度量不一样,各个损失值的范围不一样

    • 比如age:得出的结果可能在3-5左右

    • gender:交叉熵损失值可能在0.1左右

  • 每个损失值贡献不一样,需要分配不同的权重
    为了平衡这些损失值的贡献,我们这里需要对损失值进行权重的赋值.比如:交叉熵que
    具体coding如下:

# 使用列表的形式,要与模型建立的是输出要对应
model.compile(optimizer='rmsprop',
             loss = ['mse',
                     'categorical_crossentropy',
                    'binary_crossentropy'],
             loss_weights=[0.25,1.0,10.])
# 使用字典的形式
# 这里也是需要输出层具有名称时
model.compile(optimizer='rmsprop',
             loss= {'age':'mse',
                'income''categorical_crossentropy',
                'gender''binary_crossentropy'

             },
              loss_weights={
                  'age':0.25,
                  'imcome':1.,
                  'gender':10.

              }
             )

多输出模型的训练

对于多输出模型,要将标签数据对应与模型中的目标数据.我们可以使用Numpy数据组成的列表或者字典.

# 训练函数中,多输出模型的列表数据
model.fit(posts,
          [age_targets,income_targets,gender_targets],
         epochs=10,
         batch_size=64)

# 训练函数中,多输出模型的字典数据
# 这里也是需要输出层具有名称时
model.fit(posts,
          {'age':age_targets,
           'income':income_targets,
           'gender':gender_targets},
         epochs=10,
         batch_size=64)

多输入多输出模型

本例子参考Keras 文档的关于试图预测Twitter上的一条新闻有多少转发和点赞数,来说明多输入多输出模型,利用函数API里处理大量交织的数据流.

输入的数据:

  • 新闻标题本身

  • 辅助输入来接收额外的数据: 新闻标题的发布的时间等

输出的数据:

  • 辅助输出

    • 较早地在模型中使用主损失函数,是深度学习模型的一个良好正则方法

    • 插入辅助损失,使得即使在模型主损失很高的情况下,LSTM 层和 Embedding 层都能被平稳地训练

  • 主输出

具体的模型结构如下图:

多输入多输出模型

具体的coding如下:

from keras.layers import Input,Embedding,LSTM,Dense
from keras.models import Model

 # 最常用的前10000词语
vocabulary_size = 10000

# shape = (100,) 表示输入是一个含有100个整数序列,
# 每个整数在1到10000之间的
# 输入的格式类型是:整数序列
# name='main_input' 对输入进行命名
main_input = Input(shape=(100,),
                   dtype='int32',
                   name='main_input')
# Embedding 层将输入序列编码为一个稠密向量的序列,
# 每个向量维度为 512。
# 使用最常用的前10000词语
# 输入的长度100,同上面main_input
x = Embedding(output_dim=512,
              input_dim=10000,
              input_length=100)(main_input)

# LSTM 层把向量序列转换成单个向量,
# 它包含整个序列的上下文信息
lstm_out = LSTM(32)(x)
# 这里直接来一个辅助输出
# 作用是:
# 1.使得即使在模型主损失很高的情况下,
#LSTM 层和 Embedding 层都能被平稳地训练
# 2. 较早地在模型中使用主损失函数,是一个良好正则方法 
auxiliary_output = Dense(1,
                         activation='sigmoid',
                         name='aux_output')(lstm_out)

# 引入辅助输入数据
auxiliary_input = Input(shape=(5,),name = 'aux_input')
# 结合辅助数据
x = keras.layers.concatenate([lstm_out,auxiliary_input])

# 堆叠多个全连接网络层
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)

# 最后添加主要的逻辑回归层
main_output = Dense(1, a
                    ctivation='sigmoid',
                    name='main_output')(x)

# 定义一个多输入多输出模型
model = Model(inputs=[main_input,auxiliary_input],
              outputs=[main_output,auxiliary_output]
             )
# 这里做了一个简写,因为这里的两个损失函数选的是一样,
# 这里对于辅助损失值分配一个0.2的权重
model.compile(optimizer='rmsprop',
             loss='binary_crossentropy',
             loss_weights=[1.,0.2])
# 另外一种列表的写法
model.compile(optimizer='rmsprop',
             loss=['binary_crossentropy',
                   'binary_crossentropy'],
             loss_weights=[1.,0.2])

# 传入的数据也是两个,和两个标签数据
model.fit([headline_data,additional_data],
         [labels,labels],
         epochs=50,
         batch_size=32)

# 使用字典的写法

model.compile(optimizer='rmsprop',
              losss = {'main_output':'binary_crossentropy',
                       'aux_output':'binary_crossentropy'},
              loss_weight=[1.,0.2]
             )
# 要跟前面的name对应
model.fit(
    {'main_input':headline_data,
     'aux_input': additional_data},
    {'main_output':labels,
     'aux_output':labels},
    epochs=50,
    batch_size=32
)

分享关于人工智能,机器学习,深度学习以及计算机视觉的好文章,同时自己对于这个领域学习心得笔记。想要一起深入学习人工智能的小伙伴一起结伴学习吧!扫码上车!

瓦力人工智能 - 扫码上车


以上是关于深度学习笔记34_函数式API之多输出模型构建的主要内容,如果未能解决你的问题,请参考以下文章

深度学习笔记33_函数式API及多输入模型的建立

深度学习笔记36_函数式API之共享层(模型)的应用

深度学习-Tensorflow Keras使用函数式API构建复杂模型

如何使用Keras函数式API进行深度学习?

如何使用 Keras Function API 进行深度学习

深度学习时间序列预测:LSTM算法构建时间序列单变量模型预测空气质量(PM2.5)+代码实战