import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pylab
from pandas import DataFrame, Seriesplt.rcParams['font.sans-serif'] = ['SimHei']  #指定默认字体
plt.rcParams['axes.unicode_minus'] = False  #解决保存图像是负号'-'显示为方块的问题'''
利用 Keras 函数式 API,你可以构建类图(graph-like)模型、在不同的输入之间共享某一层,并且还可以像使用 Python 函数一样使用Keras模型。Keras回调函数和TensorBoard基于浏览器的可视化工具,让你可以在训练过程中监控模型有些任务需要多模态(multimodal)输入。这些任务合并来自不同输入源的数据,并使用不同类型的神经层处理不同类型的数据
'''
#函数式API简介
from keras.models import Sequential,Model
from keras import layers
from keras import Input# seq_model=Sequential()
# seq_model.add(layers.Dense(32,activation='relu',input_shape=(64,)))
# seq_model.add(layers.Dense(32,activation='relu'))
# seq_model.add(layers.Dense(10,activation='softmax'))#上述模型对应的函数式API实现
#Keras 会在后台检索从 input_tensor 到 output_tensor 所包含的每一层, 并将这些层组合成一个类图的数据结构,即一个 Model
input_tensor=Input(shape=(64,))
x=layers.Dense(32,activation='relu')(input_tensor)
x=layers.Dense(32,activation='relu')(x)
output_tensor=layers.Dense(10,activation='softmax')(x)
model=Model(input_tensor,output_tensor)#Model类将输入张量和输出张量转换为一个模型
model.summary()#多输入模型
'''
通常情况下,这种模型会在某一时刻用一个 可以组合多个张量的层将不同的输入分支合并,张量组合方式可能是相加、连接等。这通常利 用 Keras的合并运算来实现,比如 keras.layers.add、keras.layers.concatenate 等
'''
from keras.utils import to_categorical
#用函数式API实现双输入问答模型
'''
典型的问答模型有两个输入:一个自然语言描述的问题和一个文本片段(比如新闻文章),后者提供用于回答问题的信息。然后模型要生成一个回答,在最简单的情况下,这个回答只包含一个词,可以通过对某个预定义的词表做 softmax 得到设置了两个独立分支,首先 将文本输入和问题输入分别编码为表示向量,然后连接这些向量,最后,在连接好的表示上添加一个 softmax 分类器
'''
text_vocabulary_size=10000
question_vocabulary_size=10000
answer_vocabulary_size=500
text_input=Input(shape=(None,),dtype='int32',name='text')#文本输入是一个长度可变的整数序列。注意,你可以选择对输入进行命名
embedded_text=layers.Embedding(text_vocabulary_size,64)(text_input)#将输入嵌入长度为 64 的向量
encoded_text=layers.LSTM(32)(embedded_text)#利用 LSTM 将向量编码为单个向量
question_input=Input(shape=(None,),dtype='int32',name='question')
embedded_question=layers.Embedding(question_vocabulary_size,32)(question_input)#对问题进行相同的处理(使用不同的层实例)
encoded_question=layers.LSTM(16)(embedded_question)
concatenated=layers.concatenate([embedded_text,encoded_question],axis=-1)#将编码后的问题和文本连接起来
answer=layers.Dense(answer_vocabulary_size,activation='softmax')(concatenated)#在上面添加一个 softmax 分类器
model = Model([text_input, question_input], answer) #在模型实例化时,指定 两个输入和输出
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy', metrics=['acc'])#训练这个双输入模型,有两个可用的 API:我们可以向模型输入一个由Numpy数组组成的列表; 或者也可以输入一个将输入名称映射为 Numpy数组的字典。当然, 只有输入具有名称时才能使用后一种方法
num_samples=1000
max_length=100
text=np.random.randint(1,text_vocabulary_size,size=(num_samples,max_length))
question=np.random.randint(1,question_vocabulary_size,size=(num_samples,max_length))
answers=np.random.randint(answer_vocabulary_size,size=(num_samples))
answers=to_categorical(answers,answer_vocabulary_size)#返回输入的二进制矩阵表示
model.fit([text,question],answers,epochs=10,batch_size=128)#方法一
# model.fit({'text':text,'question':question},answers,epochs=10,batch_size=128)#方法二,使用输入组成的字典来拟合(只有对输入进行命名之后才能用这种方法)#多输出模型
'''
一个简单的例子,一个网络试图同时预测数据的不同性质,比如一个网络,输入某个匿名人士的一系列社交媒体发帖,然后尝试预测那个人的属性,比如年龄、性别和收入水平
'''vocabulary_size=50000
num_income_groups=10
posts_input=Input(shape=(None,),dtype='int32',name='posts')
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)
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 中,你可以在编译时使用损失组成的列表或字典来为不同输出指定不同损失,然后将得到的损失值相加得到一个全局损失,并在训练过程中将这个损失最小化。
'''
#多输出模型的编译选项:多重损失
model.compile(optimizer='rmsprop',loss=['mse','categorical_crossentropy','binary_crossentropy'])
# model.compile(optimizer='rmsprop', loss={'age': 'mse',
# 'income': 'categorical_crossentropy', 'gender': 'binary_crossentropy'})'''
严重不平衡的损失贡献会导致模型表示针对单个损失值最大的任务优先进行优化,而不考虑其他任务的优化。
为了解决这个问题,我们可以为每个损失值对最终损失的贡献分配不同的权重。如果不同的损失值具有不同的取值范围,那么这一方法尤其有用,
比如, 用于年龄回归任务的均方误差(MSE)损失值通常在 3~5左右,而用于性别分类任务的交叉熵损失值可能低至 0.1。在这种情况下,为了平衡不同损失的贡献,我们可以让交叉熵损失的权重取10,而MSE损失的权重取 0.5。
'''
#损失加权
model.compile(optimizer='rmsprop',loss=['mse','categorical_crossentropy','binary_crossentropy'],loss_weights=[0.25,1.,10.])#将数据输入到模型中
#与多输入模型相同,多输出模型的训练输入数据可以是 Numpy数组组成的列表或字典
# model.fit(posts, [age_targets, income_targets, gender_targets], epochs=10, batch_size=64)#层组成的有向无环图(多输入和多输出模型)
'''
Keras 中的神经网络可以是层组成的任意有向无环图(directed acyclic graph)。无环(acyclic)这个限定词很重要,即这些图不能有循环。张量 x 不能成为生成 x 的 某一层的输入。唯一允许的处理循环(即循环连接)是循环层的内部循环
'''
#一些常见的神经网络组件都以图的形式实现。两个著名的组件是 Inception 模块和残差连接。
#Inception V3
#假设x为4D张量shape=(samples,height,width,channels)
branch_a=layers.Conv2D(128,1,activation='relu',strides=2)(x)branch_b=layers.Conv2D(128,1,activation='relu')(x)
branch_b=layers.Conv2D(128,3,activation='relu',strides=2)(branch_b)branch_c=layers.AveragePooling2D(3,strides=2)(x)
branch_c=layers.Conv2D(128,3,activation='relu')(branch_c)branch_d=layers.Conv2D(128,1,activation='relu')(x)
branch_d=layers.Conv2D(128,3,activation='relu')(branch_d)
branch_d=layers.Conv2D(128,3,activation='relu',strides=2)(branch_d)output=layers.concatenate([branch_a,branch_b,branch_c,branch_d],axis=-1)#完整的Inception V3架构内置于Keras中,位置在keras.applications.inception_v3.InceptionV3,其中包括在 ImageNet 数据集上预训练得到的权重。
# Xception,它也是 Keras 的 applications 模块的一部分#残差连接(residual connection)
'''
2015 年末,来自微软的何恺明等人在 ILSVRC ImageNet 挑战赛中获胜,其中引入了这一方法[HE K, ZHANG X, REN S, et al. Deep residual learning for image recognition [C]//Conference on Computer Vision and Pattern Recognition, 2016]
残差连接解决了困扰所有大规模深度学习模型的两个共性问题:梯度消失和表示瓶颈。通常来说,向任何多于 10 层的模型中添加残差连接,都可能会有所帮助。残差连接是让前面某层的输出作为后面某层的输入,从而在序列网络中有效地创造了一条捷径。前面层的输出没有与后面层的激活连接在一起,而是与后面层的激活相加(这里假设两个激活的形状相同)。如果它们的形状不同,我们可以用
一个线性变换将前面层的激活改变成目标形状(例如,这个线性变换可以是不带激活的 Dense 层;对于卷积特征图,可以是不带激活 1×1 卷积)
'''
#如果特征图的尺寸相同,在 Keras 中实现残差连接的方法如下,用的是恒等残差连接(identity residual connection)
# 例子依然假设我们有一个四维输入张量 x
x=...
y=layers.Conv2D(128,3,activation='relu',padding='same')(x)
y = layers.Conv2D(128, 3, activation='relu', padding='same')(y)
y = layers.Conv2D(128, 3, activation='relu', padding='same')(y)
y = layers.add([y, x])#将原始 x 与输出特征相加#如果特征图的尺寸不同,实现残差连接的方法如下,用的是线性残差连接(linear residual connection)。同样,假设我们有一个四维输入张量 x
x=...
z = layers.Conv2D(128, 3, activation='relu', padding='same')(x)#对 x 进行变换,"same" 表示“填充后输出的宽度和高度与输入相同”
z = layers.Conv2D(128, 3, activation='relu', padding='same')(z)
z = layers.MaxPooling2D(2, strides=2)(z)
residual = layers.Conv2D(128, 1, strides=2, padding='same')(x)#使用 1×1 卷积,将原始 x 张量线性下采样为与 y 具有相同的形状
z=layers.add([z,residual])#将残差张量与输出特征相加'''
深度学习中的表示瓶颈在 Sequential 模型中,每个连续的表示层都构建于前一层之上,这意味着它只能访问前一层激活中包含的信息。如果某一层太小(比如特征维度太低),那么模型将会受限于该层激活中能够塞入多少信息你可以通过类比信号处理来理解这个概念:假设你有一条包含一系列操作的音频处理流水线,每个操作的输入都是前一个操作的输出,如果某个操作将信号裁剪到低频范围(比如 0~15 kHz),那么下游操作将永远无法恢复那些被丢弃的频段。任何信息的丢失都是永久性的。残差连接可以将较早的信息重新注入到下游数据中,从而部分解决了深度学习模型的这一问题深度学习中的梯度消失反向传播是用于训练深度神经网络的主要算法,其工作原理是将来自输出损失的反馈信号 向下传播到更底部的层。如果这个反馈信号的传播需要经过很多层,那么信号可能会变得非常 微弱,甚至完全丢失,导致网络无法训练。这个问题被称为梯度消失(vanishing gradient)我们已经知道 LSTM 层是如何在循环网络中解决这 个问题的:它引入了一个携带轨道(carry track),可以在与主处理轨道平行的轨道上传播信息。残差连接在前馈深度网络中的工作原理与此类似,但它更加简单:它引入了一个纯线性的信息携带轨道,与主要的层堆叠方向平行,从而有助于跨越任意深度的层来传播梯度。
'''#共享层权重
'''如果你对一个层实例调用两次,而不是每次调用都实例化一个新层,那么每次调用可以重复使用相同的权重。这样你可以构建具有共享分支的模型,即几个分支全都共享相同的知识并执行相同的运算。也就是说,这些分支共享相同的表示,并同时对不同的输入集合学习这些表示。假设一个模型想要评估两个句子之间的语义相似度。这个模型有两个输入(需 要比较的两个句子).两个输入句子是可以互换的,因为语义相似度是一种对称
关系,A相对于B的相似度等于B相对于A的相似度。因此,学习两个单独的模型来分别处理两个输入句子是没有道理的。相反,你需要用一个 LSTM层来处理两个句子。这个 LSTM 层的表示(即它的权重)是同时基于两个输入来学习的。我们将其称为连体 LSTM(Siamese LSTM)或共享 LSTM(shared LSTM)模型。
'''
#使用 Keras 函数式 API 中的层共享(层重复使用)
left_data=...
right_data=...
targets=...
lstm=layers.LSTM(32)#实例化LSTM层
left_input=Input(shape=(None,128))#构建模型的左分支:输入是长度 128 的向量组成的变长序列
left_output=lstm(left_input)
right_input=Input(shape=(None,128))#构建模型的右分支:如果调用已有的层实例,那么就会重复使用它的权重
right_output=lstm(right_input)merged=layers.concatenate([left_output,right_output],axis=-1)
predictions=layers.Dense(1,activation='sigmoid')(merged)#构建一个分类器model=Model([left_input,right_input],predictions)
model.fit([left_data,right_data],targets)#将模型实例化并训练:训练这种 模型时,基于两个输入对 LSTM 层的权重进行更新#将模型作为层---‘将模型看作更大的层’
#Sequential 类和 Model 类都是如此。这意味着你可以在一个输入张量上调用模型,并得到一个输出张量
#一个简单的例子,就是一个使用双摄像头作为输入的视觉模型:两个平行的摄像头,相距几厘米(一英寸)。这样的模型可以感知深度
from keras import applicationsxception_base=applications.Xception(weights=None,include_top=False)#图像处理基础模型是 Xception 网络(只包括卷积基)left_input=Input(shape=(250,250,3))#输入是 250×250 的RGB图像
right_input=Input(shape=(250,250,3))
left_features=xception_base(left_input)#对相同的视觉模型调用两次
right_features=xception_base(right_input)
merged_features=layers.concatenate([left_features,right_features],axis=-1)#合并后的特征包含来自左右两个视觉输入中的信息

python深度学习--Keras函数式API(多输入,多输出,类图模型)相关推荐

  1. 《Python 深度学习》刷书笔记 Chapter 4 关于电影评论模型的进一步探讨

    文章目录 电影评论模型的进一步改进 4-3 原始模型 4-4 容量更小的模型 4-5 容量更大的模型 4-6 向模型中添加L2权重正则化 写在最后 电影评论模型的进一步改进 我们将在这一节使用实验的方 ...

  2. Python 深度学习,你的 Keras 准备好了吗?

    点击上方"AI有道",选择"置顶"公众号 重磅干货,第一时间送达 前天我在公众号推荐了<Python Deep Learning>这本书.该书是由  ...

  3. 怎么装python的keras库_Keras 教程: Python 深度学习终极入门指南

    在这篇 Keras 教程中, 你将学到如何用 Python 建立一个卷积神经网络! 事实上, 我们将利用著名的 MNIST 数据集, 训练一个准确度超过 99% 的手写数字分类器. 开始之前, 请注意 ...

  4. 利用深度学习(Keras)进行癫痫分类-Python案例

    目录 癫痫介绍 数据集 Keras深度学习案例 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区 QQ交流群:903290195 癫痫介绍 癫痫,即俗称"羊癫风",是由多种 ...

  5. [学习笔记] python深度学习---第三章 神经网络入门

    一.神经网络剖析 1. 训练神经网络主要围绕以下四个方面: (1) 层,多个层组合成网络(或模型). (2)输入数据和相应的目标. (3)损失函数,即用于学习的反馈信号. (4)优化器,决定学习过程如 ...

  6. Python 深度学习架构实用指南:第一、二部分

    原文:Hands-On Deep Learning Architectures with Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自[ApacheCN 深度学习 译文集] ...

  7. Python深度学习篇

    Python深度学习篇一<什么是深度学习> Excerpt 在过去的几年里,人工智能(AI)一直是媒体大肆炒作的热点话题.机器学习.深度学习 和人工智能都出现在不计其数的文章中,而这些文章 ...

  8. Python深度学习-快速指南

    Python深度学习-快速指南 (Python Deep Learning - Quick Guide) Python深度学习-简介 (Python Deep Learning - Introduct ...

  9. 我最喜欢的9个 Python深度学习库

    本文为数盟原创译文 如果你对深度学习和卷积神经网络感兴趣,但是并不知道从哪里开始,也不知道使用哪种库,那么这里就为你提供了许多帮助. 在这篇文章里,我详细解读了9个我最喜欢的Python深度学习库. ...

最新文章

  1. 【iOS】Mapkit的使用:地图显示、定位、大头针、气泡等
  2. Winform中实现读取xml配置文件并动态配置DevExpress的RadioGroup的选项
  3. git 使用_Git使用总结
  4. MGW——美团点评高性能四层负载均衡
  5. sql server 2005 COUNT_BIG (Transact-SQL)
  6. 键值数据库LevelDB的优缺点及性能分析
  7. angular 控件css_Angular父组件内修改子组件的样式
  8. poj 1094 Sorting It All Out 很好的拓扑排序,让我对拓扑排序有了一个很好的写法!!!
  9. php循环,die/exit脚本执行控制,文件载入及错误控制
  10. LTE-OA系统架构图
  11. mysql正则时间格式_用正则表达式校验时间格式的正确性
  12. 学习笔记1--汽车发展史及发展趋势
  13. 电子计算机是采用什么进制法,计算机内部使用什么进制
  14. RuntimeError:CuDNN error:CUDNN_STATUS_EXECUTION_FAILED
  15. ngx 之 location
  16. GitHub使用之路
  17. 防火墙技术及其在校园网中的设计方案
  18. 【PATB1041】考试座位号(题解+拓展)
  19. 逆向学习litevm篇
  20. Landsat5数据下载中国地区1988年

热门文章

  1. VASP MAGMOM设置
  2. Python实现抓狐狸小游戏
  3. 一不小心,登上支付宝开发者社区热文榜单Top3
  4. 工行银企互联接入详解(5)--使用Java调用银企互联接口
  5. 第三个页面:构建新闻详情页面
  6. python一个tab键是几个空格_python中tab键是什么意思
  7. android下载管理器怎么用,如何启用Android下载管理器
  8. 千里独行Thousands of miles to ride alone
  9. 洛谷P1508Likecloud-吃、吃、吃 ----- Only my water can help me
  10. 为什么两个向量垂直,点积为0